Sign In

execbro-sdk

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

execbro-sdk - npm Package Compare versions

Comparing version
0.5.5
to
0.6.0
+2
dist/flowpoint.d.ts
import { FlowpointOptions } from './types';
export declare function flowpoint(options: FlowpointOptions): void;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.flowpoint = flowpoint;
function flowpoint(options) {
const g = globalThis.__EXECBRO__ ?? globalThis.__RN_AI_DEVTOOLS__;
if (!g || typeof g.addFlowpoint !== 'function') {
return;
}
g.addFlowpoint(options);
}
import { FlowpointEntry, FlowpointOptions, FlowpointSnapshot } from './types';
export declare class FlowpointBuffer {
readonly contextId: string;
private entries;
private maxSize;
private seqCounter;
private currentRuns;
constructor(maxSize?: number);
add(options: FlowpointOptions): void;
getAll(): FlowpointEntry[];
getSnapshot(): FlowpointSnapshot;
clear(): number;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FlowpointBuffer = void 0;
function randomId(length) {
let id = '';
while (id.length < length) {
id += Math.random().toString(36).slice(2);
}
return id.slice(0, length);
}
class FlowpointBuffer {
constructor(maxSize = 500) {
this.contextId = randomId(8);
this.entries = [];
this.seqCounter = 0;
this.currentRuns = new Map();
this.maxSize = maxSize;
}
add(options) {
const { name, step, meta, level, begin } = options;
if (begin || !this.currentRuns.has(name)) {
this.currentRuns.set(name, randomId(4));
}
const entry = {
seq: ++this.seqCounter,
t: Date.now(),
name,
step,
run: this.currentRuns.get(name),
level: level ?? 'info',
};
if (meta !== undefined) {
entry.meta = meta;
}
if (this.entries.length >= this.maxSize) {
this.entries.shift();
}
this.entries.push(entry);
}
getAll() {
return [...this.entries];
}
getSnapshot() {
return { contextId: this.contextId, entries: [...this.entries] };
}
clear() {
const count = this.entries.length;
this.entries = [];
this.currentRuns.clear();
return count;
}
}
exports.FlowpointBuffer = FlowpointBuffer;
+2
-0
import { NetworkBuffer } from './networkBuffer';
import { ConsoleBuffer } from './consoleBuffer';
import { FlowpointBuffer } from './flowpointBuffer';
import { DevToolsGlobal, Capabilities } from './types';

@@ -11,2 +12,3 @@ declare global {

consoleBuffer: ConsoleBuffer;
flowpointBuffer: FlowpointBuffer;
stores: Record<string, unknown>;

@@ -13,0 +15,0 @@ navigation: unknown;

@@ -11,3 +11,3 @@ "use strict";

function exposeGlobal(options) {
const { networkBuffer, consoleBuffer, stores, navigation, custom, capabilities } = options;
const { networkBuffer, consoleBuffer, flowpointBuffer, stores, navigation, custom, capabilities } = options;
const devtools = {

@@ -23,2 +23,6 @@ version: SDK_VERSION,

clearConsole: () => consoleBuffer.clear(),
addFlowpoint: (options) => flowpointBuffer.add(options),
getFlowpointEntries: () => flowpointBuffer.getAll(),
getFlowpointSnapshot: () => flowpointBuffer.getSnapshot(),
clearFlowpoints: () => flowpointBuffer.clear(),
};

@@ -25,0 +29,0 @@ globalThis.__EXECBRO__ = devtools;

+2
-1
import { InitOptions } from './types';
export type { InitOptions, NetworkEntry, ConsoleEntry, Capabilities, DevToolsGlobal, } from './types';
export { flowpoint } from './flowpoint';
export type { InitOptions, NetworkEntry, ConsoleEntry, Capabilities, DevToolsGlobal, FlowpointEntry, FlowpointOptions, FlowpointLevel, FlowpointSnapshot, } from './types';
export declare function init(options?: InitOptions): void;
export declare function _resetForTesting(): void;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.flowpoint = void 0;
exports.init = init;

@@ -7,2 +8,3 @@ exports._resetForTesting = _resetForTesting;

const consoleBuffer_1 = require("./consoleBuffer");
const flowpointBuffer_1 = require("./flowpointBuffer");
const networkInterceptor_1 = require("./networkInterceptor");

@@ -13,2 +15,4 @@ const consoleInterceptor_1 = require("./consoleInterceptor");

const fastRefreshRecorder_1 = require("./fastRefreshRecorder");
var flowpoint_1 = require("./flowpoint");
Object.defineProperty(exports, "flowpoint", { enumerable: true, get: function () { return flowpoint_1.flowpoint; } });
let initialized = false;

@@ -25,2 +29,3 @@ function init(options) {

const consoleBuffer = new consoleBuffer_1.ConsoleBuffer(options?.maxConsoleEntries ?? 500);
const flowpointBuffer = new flowpointBuffer_1.FlowpointBuffer(options?.maxFlowpointEntries ?? 500);
const stores = options?.stores ?? {};

@@ -34,2 +39,3 @@ const navigation = options?.navigation ?? null;

consoleBuffer,
flowpointBuffer,
stores,

@@ -44,2 +50,3 @@ navigation,

render: false,
flowpoints: true,
},

@@ -46,0 +53,0 @@ });

export interface InitOptions {
maxNetworkEntries?: number;
maxConsoleEntries?: number;
maxFlowpointEntries?: number;
stores?: Record<string, unknown>;

@@ -33,2 +34,23 @@ navigation?: unknown;

}
export type FlowpointLevel = 'info' | 'warn' | 'error';
export interface FlowpointOptions {
name: string;
step: string;
meta?: unknown;
level?: FlowpointLevel;
begin?: boolean;
}
export interface FlowpointEntry {
seq: number;
t: number;
name: string;
step: string;
run: string;
level: FlowpointLevel;
meta?: unknown;
}
export interface FlowpointSnapshot {
contextId: string;
entries: FlowpointEntry[];
}
export interface Capabilities {

@@ -40,2 +62,3 @@ network: boolean;

render: boolean;
flowpoints: boolean;
}

@@ -52,2 +75,6 @@ export interface DevToolsGlobal {

clearConsole: () => number;
addFlowpoint: (options: FlowpointOptions) => void;
getFlowpointEntries: () => FlowpointEntry[];
getFlowpointSnapshot: () => FlowpointSnapshot;
clearFlowpoints: () => number;
}

@@ -54,0 +81,0 @@ export interface RnGlobalsNamespace {

{
"name": "execbro-sdk",
"version": "0.5.5",
"version": "0.6.0",
"description": "Companion SDK for ExecBro (npm: execbro) — captures network requests for AI-powered React Native debugging.",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -114,2 +114,5 @@ # execbro-sdk

// Max flowpoint entries to buffer (default: 500)
maxFlowpointEntries: 500,
// State store references for AI access

@@ -133,2 +136,33 @@ stores: {

## Flowpoints — instrument and verify flows
`flowpoint()` drops structured, timestamped breadcrumbs grouped by flow, so an AI agent
(via the ExecBro MCP tools `get_flowpoints`, `wait_for_flowpoint`, `verify_flow`) can
verify what actually happened inside a flow instead of inferring it from console logs.
```js
import { flowpoint } from "execbro-sdk";
async function addToCart(item) {
flowpoint({ name: "add-to-cart", step: "start", begin: true });
await clearCart();
flowpoint({ name: "add-to-cart", step: "cleared", meta: { removed: 3 } });
try {
await addItem(item);
flowpoint({ name: "add-to-cart", step: "item-added" });
} catch (e) {
flowpoint({ name: "add-to-cart", step: "failed", meta: { reason: e.message }, level: "error" });
}
}
```
- `name` — the flow (grouping key, keep it stable and low-cardinality)
- `step` — the point within the flow (what verification asserts against)
- `meta` — optional free-form payload (object, string, anything JSON-ish)
- `level` — `'info'` (default) | `'warn'` | `'error'`
- `begin: true` — marks a new run of the flow, separating repeated attempts
Safe to leave in your code: like everything else in this SDK, `flowpoint()` is a
silent no-op in production builds and costs nothing.
## How it works

@@ -214,2 +248,3 @@

navigation: true, // true if navigation was passed
flowpoints: true,
render: false, // future: render profiling

@@ -234,2 +269,8 @@ },

clearConsole(), // returns number of entries cleared
// Flowpoints
addFlowpoint(options), // used by the flowpoint() helper
getFlowpointEntries(), // all buffered flowpoints
getFlowpointSnapshot(), // { contextId, entries } — used by the MCP drain
clearFlowpoints(), // returns number of entries cleared
}

@@ -236,0 +277,0 @@ ```