indusagi-coding-agent 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/_decls/entry.ts +18 -0
- package/src/_decls/guardrails.ts +35 -0
- package/src/_decls/index.ts +26 -0
- package/src/addons/contract.ts +236 -0
- package/src/addons/dispatch/event-dispatcher.ts +164 -0
- package/src/addons/dispatch/index.ts +25 -0
- package/src/addons/dispatch/tool-interceptor.ts +208 -0
- package/src/addons/host.ts +225 -0
- package/src/addons/index.ts +112 -0
- package/src/addons/manifest.ts +158 -0
- package/src/addons/sandbox.ts +170 -0
- package/src/addons/surface.ts +78 -0
- package/src/boot/auth-vault.ts +195 -0
- package/src/boot/boot.ts +138 -0
- package/src/boot/contract.ts +238 -0
- package/src/boot/heap.ts +59 -0
- package/src/boot/index.ts +28 -0
- package/src/boot/invocation.ts +93 -0
- package/src/boot/runners/addon-wiring.ts +153 -0
- package/src/boot/runners/checkpoint.ts +169 -0
- package/src/boot/runners/delegate-runner.ts +294 -0
- package/src/boot/runners/index.ts +13 -0
- package/src/boot/runners/link-runner.ts +45 -0
- package/src/boot/runners/memdir.ts +168 -0
- package/src/boot/runners/oneshot-runner.ts +58 -0
- package/src/boot/runners/read-state.ts +90 -0
- package/src/boot/runners/registry.ts +42 -0
- package/src/boot/runners/repl-runner.ts +143 -0
- package/src/boot/runners/server-mode.ts +121 -0
- package/src/boot/runners/session.ts +641 -0
- package/src/boot/server-token.ts +148 -0
- package/src/boot/stages.ts +167 -0
- package/src/boot/upgrade/apply.ts +94 -0
- package/src/boot/upgrade/index.ts +13 -0
- package/src/boot/upgrade/upgrades.ts +289 -0
- package/src/briefing/compose.ts +150 -0
- package/src/briefing/context-docs.ts +19 -0
- package/src/briefing/contract.ts +717 -0
- package/src/briefing/index.ts +31 -0
- package/src/briefing/macros.ts +97 -0
- package/src/briefing/skills.ts +47 -0
- package/src/capability-deck/bridge-ledger/index.ts +27 -0
- package/src/capability-deck/bridge-ledger/key.ts +67 -0
- package/src/capability-deck/bridge-ledger/ledger.ts +131 -0
- package/src/capability-deck/bridge-ledger/network.ts +117 -0
- package/src/capability-deck/builtin-bridge.ts +312 -0
- package/src/capability-deck/cards/bg-process-card.ts +335 -0
- package/src/capability-deck/cards/index.ts +115 -0
- package/src/capability-deck/cards/memory-card.ts +146 -0
- package/src/capability-deck/cards/plan-file.ts +97 -0
- package/src/capability-deck/cards/plan-tools.ts +185 -0
- package/src/capability-deck/cards/saas-card.ts +183 -0
- package/src/capability-deck/cards/task-card.ts +207 -0
- package/src/capability-deck/cards/todo-card.ts +168 -0
- package/src/capability-deck/cards/workflow-card.ts +247 -0
- package/src/capability-deck/contract.ts +388 -0
- package/src/capability-deck/index.ts +48 -0
- package/src/capability-deck/manifest.ts +109 -0
- package/src/capability-deck/provision.ts +169 -0
- package/src/channels/contract.ts +191 -0
- package/src/channels/framer.ts +50 -0
- package/src/channels/index.ts +101 -0
- package/src/channels/link/dialog.ts +129 -0
- package/src/channels/link/driver.ts +190 -0
- package/src/channels/link/index.ts +34 -0
- package/src/channels/link/server.ts +134 -0
- package/src/channels/oneshot.ts +90 -0
- package/src/channels/ops.ts +65 -0
- package/src/channels/session-ops.ts +81 -0
- package/src/conductor/bash-guard.ts +599 -0
- package/src/conductor/catalog/catalog.ts +116 -0
- package/src/conductor/catalog/index.ts +8 -0
- package/src/conductor/catalog/matcher.ts +134 -0
- package/src/conductor/conductor.ts +234 -0
- package/src/conductor/contract.ts +842 -0
- package/src/conductor/diagnostics.ts +227 -0
- package/src/conductor/index.ts +33 -0
- package/src/conductor/permissions.ts +588 -0
- package/src/conductor/quota-error.ts +49 -0
- package/src/conductor/signal-hub/hub.ts +46 -0
- package/src/conductor/signal-hub/index.ts +2 -0
- package/src/conductor/signal-hub/translate.test.ts +81 -0
- package/src/conductor/signal-hub/translate.ts +74 -0
- package/src/conductor/skill-parse/index.ts +2 -0
- package/src/conductor/skill-parse/parse.ts +108 -0
- package/src/conductor/transcript-store/index.ts +22 -0
- package/src/conductor/transcript-store/serialize.ts +116 -0
- package/src/conductor/transcript-store/store.ts +205 -0
- package/src/console/auth-status.ts +56 -0
- package/src/console/components/AgentsView.ts +165 -0
- package/src/console/components/BackgroundAgents.ts +155 -0
- package/src/console/components/Banner.ts +334 -0
- package/src/console/components/Composer.ts +94 -0
- package/src/console/components/StatusBar.ts +49 -0
- package/src/console/components/TerminalConsole.ts +1090 -0
- package/src/console/components/WorkingIndicator.ts +98 -0
- package/src/console/components/banner-sweep.ts +24 -0
- package/src/console/components/welcome.ts +74 -0
- package/src/console/contract.ts +630 -0
- package/src/console/index.ts +34 -0
- package/src/console/input/complete.ts +127 -0
- package/src/console/input/dir-reader.ts +34 -0
- package/src/console/input/index.ts +23 -0
- package/src/console/input/keymap.ts +159 -0
- package/src/console/input/paste.ts +104 -0
- package/src/console/mount.ts +56 -0
- package/src/console/overlays/approval-queue.ts +57 -0
- package/src/console/overlays/approval.ts +130 -0
- package/src/console/overlays/auth.ts +342 -0
- package/src/console/overlays/boards.ts +308 -0
- package/src/console/overlays/host.ts +36 -0
- package/src/console/overlays/index.ts +26 -0
- package/src/console/overlays/pickers.ts +258 -0
- package/src/console/overlays/sessions.ts +190 -0
- package/src/console/reducer.ts +182 -0
- package/src/console/slash/builtins.ts +81 -0
- package/src/console/slash/commands/dynamic.ts +83 -0
- package/src/console/slash/commands/integrations.ts +695 -0
- package/src/console/slash/commands/shared.ts +75 -0
- package/src/console/slash/commands/transcript.ts +263 -0
- package/src/console/slash/commands/workbench.ts +246 -0
- package/src/console/slash/index.ts +15 -0
- package/src/console/slash/registry.ts +70 -0
- package/src/console/slash/resolve.ts +63 -0
- package/src/console/startup.ts +209 -0
- package/src/console/theme/adapter.ts +45 -0
- package/src/console/theme/index.ts +7 -0
- package/src/console/theme/palette.ts +68 -0
- package/src/console/theme/resolve.ts +39 -0
- package/src/console/theme/tokens.ts +71 -0
- package/src/entry.ts +55 -0
- package/src/guardrails.ts +37 -0
- package/src/index.ts +18 -0
- package/src/insight/channel.ts +88 -0
- package/src/insight/contract.ts +185 -0
- package/src/insight/index.ts +110 -0
- package/src/insight/recorder.ts +213 -0
- package/src/insight/redaction.ts +157 -0
- package/src/insight/replay.ts +158 -0
- package/src/insight/sampling.ts +70 -0
- package/src/insight/serialize.ts +50 -0
- package/src/insight/sinks/console.ts +64 -0
- package/src/insight/sinks/file.ts +40 -0
- package/src/insight/sinks/index.ts +24 -0
- package/src/insight/sinks/stream.ts +54 -0
- package/src/integrations/sarvam/attach.ts +239 -0
- package/src/integrations/sarvam/config.ts +156 -0
- package/src/integrations/sarvam/index.ts +25 -0
- package/src/integrations/sarvam/sarvam.test.ts +60 -0
- package/src/integrations/sarvam/types.ts +27 -0
- package/src/integrations/zoho/attach.ts +342 -0
- package/src/integrations/zoho/config.ts +125 -0
- package/src/integrations/zoho/index.ts +27 -0
- package/src/integrations/zoho/types.ts +21 -0
- package/src/integrations/zoho/zoho.test.ts +50 -0
- package/src/kit/clipboard-image.ts +107 -0
- package/src/kit/external-editor.ts +48 -0
- package/src/kit/image.ts +59 -0
- package/src/kit/index.ts +51 -0
- package/src/kit/shell.ts +19 -0
- package/src/kit/tool-fetch.ts +85 -0
- package/src/launch/catalog.ts +148 -0
- package/src/launch/contract.ts +187 -0
- package/src/launch/credentials.ts +625 -0
- package/src/launch/index.ts +98 -0
- package/src/launch/invocation/attachments.ts +179 -0
- package/src/launch/invocation/flags.ts +196 -0
- package/src/launch/invocation/index.ts +25 -0
- package/src/launch/invocation/read.ts +260 -0
- package/src/launch/invocation/usage.ts +67 -0
- package/src/launch/login.ts +324 -0
- package/src/launch/oauth.test.ts +18 -0
- package/src/launch/oauth.ts +203 -0
- package/src/launch/packages.ts +194 -0
- package/src/launch/pickers.ts +189 -0
- package/src/runtime-bridge/bridges/_drive.ts +96 -0
- package/src/runtime-bridge/bridges/builtins.ts +68 -0
- package/src/runtime-bridge/bridges/claude-cli.ts +123 -0
- package/src/runtime-bridge/bridges/codex-cli.ts +142 -0
- package/src/runtime-bridge/bridges/index.ts +33 -0
- package/src/runtime-bridge/bridges/indusagi-cli.ts +155 -0
- package/src/runtime-bridge/broker.ts +227 -0
- package/src/runtime-bridge/contract.ts +122 -0
- package/src/runtime-bridge/index.ts +79 -0
- package/src/runtime-bridge/sink.ts +180 -0
- package/src/sessions/contract.ts +81 -0
- package/src/sessions/index.ts +13 -0
- package/src/sessions/library.ts +229 -0
- package/src/settings/contract.ts +114 -0
- package/src/settings/index.ts +32 -0
- package/src/settings/manager.ts +117 -0
- package/src/transcript-export/index.ts +45 -0
- package/src/transcript-export/publish.ts +260 -0
- package/src/transcript-export/sgr.ts +315 -0
- package/src/transcript-export/template.ts +272 -0
- package/src/transcript-export/theme-bridge.ts +150 -0
- package/src/window-budget/budget/estimate.ts +135 -0
- package/src/window-budget/budget/gate.ts +33 -0
- package/src/window-budget/budget/index.ts +16 -0
- package/src/window-budget/budget/slice.ts +56 -0
- package/src/window-budget/condenser.ts +58 -0
- package/src/window-budget/contract.ts +184 -0
- package/src/window-budget/index.ts +19 -0
- package/src/window-budget/microcompact.ts +95 -0
- package/src/window-budget/rehydrate.ts +136 -0
- package/src/window-budget/summarize/condense.ts +103 -0
- package/src/window-budget/summarize/index.ts +14 -0
- package/src/window-budget/summarize/prompt.ts +149 -0
- package/src/workflow-engine/agent-runner.ts +181 -0
- package/src/workflow-engine/display.ts +224 -0
- package/src/workflow-engine/engine.ts +294 -0
- package/src/workflow-engine/index.ts +23 -0
- package/src/workflow-engine/parse.ts +172 -0
- package/src/workflow-engine/structured-output.ts +35 -0
- package/src/workspace/brand.ts +29 -0
- package/src/workspace/index.ts +18 -0
- package/src/workspace/locator.ts +103 -0
- package/src/workspace/runtime-detect.ts +64 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Signal channel — the in-memory pipe between the recorder and the sinks.
|
|
3
|
+
*/
|
|
4
|
+
import type { Signal, SignalChannel, SignalEmit, SignalStream } from "./contract.js";
|
|
5
|
+
|
|
6
|
+
interface Subscriber {
|
|
7
|
+
buffer: Signal[];
|
|
8
|
+
waiter: ((value: { value: Signal; done: false } | { value: undefined; done: true }) => void) | null;
|
|
9
|
+
done: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createChannel(): SignalChannel {
|
|
13
|
+
const subscribers = new Set<Subscriber>();
|
|
14
|
+
let closed = false;
|
|
15
|
+
|
|
16
|
+
function deliver(sub: Subscriber, signal: Signal): void {
|
|
17
|
+
if (sub.waiter !== null) {
|
|
18
|
+
const resolve = sub.waiter;
|
|
19
|
+
sub.waiter = null;
|
|
20
|
+
resolve({ value: signal, done: false });
|
|
21
|
+
} else {
|
|
22
|
+
sub.buffer.push(signal);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const emit: SignalEmit = (signal) => {
|
|
27
|
+
if (closed) return;
|
|
28
|
+
for (const sub of subscribers) {
|
|
29
|
+
deliver(sub, signal);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function close(): void {
|
|
34
|
+
if (closed) return;
|
|
35
|
+
closed = true;
|
|
36
|
+
for (const sub of subscribers) {
|
|
37
|
+
sub.done = true;
|
|
38
|
+
if (sub.waiter !== null && sub.buffer.length === 0) {
|
|
39
|
+
const resolve = sub.waiter;
|
|
40
|
+
sub.waiter = null;
|
|
41
|
+
resolve({ value: undefined, done: true });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function stream(): SignalStream {
|
|
47
|
+
const sub: Subscriber = { buffer: [], waiter: null, done: closed };
|
|
48
|
+
subscribers.add(sub);
|
|
49
|
+
const iterator = {
|
|
50
|
+
next(): Promise<{ value: Signal; done: false } | { value: undefined; done: true }> {
|
|
51
|
+
const buffered = sub.buffer.shift();
|
|
52
|
+
if (buffered !== undefined) {
|
|
53
|
+
return Promise.resolve({ value: buffered, done: false });
|
|
54
|
+
}
|
|
55
|
+
if (sub.done) {
|
|
56
|
+
subscribers.delete(sub);
|
|
57
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
58
|
+
}
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
sub.waiter = resolve;
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
return(): Promise<{ value: undefined; done: true }> {
|
|
64
|
+
subscribers.delete(sub);
|
|
65
|
+
sub.waiter = null;
|
|
66
|
+
sub.buffer.length = 0;
|
|
67
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
[Symbol.asyncIterator]() {
|
|
72
|
+
return iterator;
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
emit,
|
|
79
|
+
stream,
|
|
80
|
+
get size(): number {
|
|
81
|
+
return subscribers.size;
|
|
82
|
+
},
|
|
83
|
+
get closed(): boolean {
|
|
84
|
+
return closed;
|
|
85
|
+
},
|
|
86
|
+
close,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Insight contract — the FROZEN type surface of the unified tracing system.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export type TrailId = string & { readonly __brand: "TrailId" };
|
|
6
|
+
export type ProbeId = string & { readonly __brand: "ProbeId" };
|
|
7
|
+
|
|
8
|
+
export const ID_WIDTHS = {
|
|
9
|
+
trail: 16,
|
|
10
|
+
probe: 8,
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
export function asTrailId(raw: string): TrailId {
|
|
14
|
+
return raw as TrailId;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function asProbeId(raw: string): ProbeId {
|
|
18
|
+
return raw as ProbeId;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type ProbeKind = "run" | "turn" | "tool" | "model" | "custom";
|
|
22
|
+
|
|
23
|
+
export const PROBE_KINDS: readonly ProbeKind[] = ["run", "turn", "tool", "model", "custom"];
|
|
24
|
+
|
|
25
|
+
export type ProbeStatus = "open" | "ok" | "error";
|
|
26
|
+
export type ProbeOutcome = "ok" | "error";
|
|
27
|
+
|
|
28
|
+
export interface ProbeFault {
|
|
29
|
+
readonly message: string;
|
|
30
|
+
readonly name?: string;
|
|
31
|
+
readonly stack?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type ProbeAttributes = Readonly<Record<string, unknown>>;
|
|
35
|
+
|
|
36
|
+
export interface Probe {
|
|
37
|
+
readonly id: ProbeId;
|
|
38
|
+
readonly trailId: TrailId;
|
|
39
|
+
readonly parentId: ProbeId | null;
|
|
40
|
+
readonly kind: ProbeKind;
|
|
41
|
+
readonly name: string;
|
|
42
|
+
readonly startedAt: number;
|
|
43
|
+
readonly endedAt?: number;
|
|
44
|
+
readonly status: ProbeStatus;
|
|
45
|
+
readonly attributes: ProbeAttributes;
|
|
46
|
+
readonly fault?: ProbeFault;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface ClosedProbe extends Probe {
|
|
50
|
+
readonly endedAt: number;
|
|
51
|
+
readonly status: ProbeOutcome;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function isClosedProbe(probe: Probe): probe is ClosedProbe {
|
|
55
|
+
return probe.status !== "open" && typeof probe.endedAt === "number";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ProbeHandle {
|
|
59
|
+
readonly trailId: TrailId;
|
|
60
|
+
readonly id: ProbeId;
|
|
61
|
+
readonly sampled: boolean;
|
|
62
|
+
note(attributes: ProbeAttributes): void;
|
|
63
|
+
child(kind: ProbeKind, name: string, attributes?: ProbeAttributes): ProbeHandle;
|
|
64
|
+
fail(error: unknown): void;
|
|
65
|
+
close(outcome?: ProbeOutcome): void;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const NOOP_HANDLE: ProbeHandle = Object.freeze({
|
|
69
|
+
trailId: "" as TrailId,
|
|
70
|
+
id: "" as ProbeId,
|
|
71
|
+
sampled: false,
|
|
72
|
+
note(): void {
|
|
73
|
+
/* no-op */
|
|
74
|
+
},
|
|
75
|
+
child(): ProbeHandle {
|
|
76
|
+
return NOOP_HANDLE;
|
|
77
|
+
},
|
|
78
|
+
fail(): void {
|
|
79
|
+
/* no-op */
|
|
80
|
+
},
|
|
81
|
+
close(): void {
|
|
82
|
+
/* no-op */
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
export type SignalPhase = "open" | "update" | "close";
|
|
87
|
+
|
|
88
|
+
export interface OpenSignal {
|
|
89
|
+
readonly phase: "open";
|
|
90
|
+
readonly probe: Probe;
|
|
91
|
+
readonly at: number;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface UpdateSignal {
|
|
95
|
+
readonly phase: "update";
|
|
96
|
+
readonly probe: Probe;
|
|
97
|
+
readonly at: number;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface CloseSignal {
|
|
101
|
+
readonly phase: "close";
|
|
102
|
+
readonly probe: ClosedProbe;
|
|
103
|
+
readonly at: number;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export type Signal = OpenSignal | UpdateSignal | CloseSignal;
|
|
107
|
+
|
|
108
|
+
export function isCloseSignal(signal: Signal): signal is CloseSignal {
|
|
109
|
+
return signal.phase === "close";
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export type SignalEmit = (signal: Signal) => void;
|
|
113
|
+
|
|
114
|
+
export interface SampleGate {
|
|
115
|
+
admit(rootName: string): boolean;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface FixedGates {
|
|
119
|
+
readonly always: SampleGate;
|
|
120
|
+
readonly never: SampleGate;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export type SignalStream = AsyncIterable<Signal>;
|
|
124
|
+
|
|
125
|
+
export interface Sink {
|
|
126
|
+
readonly id: string;
|
|
127
|
+
drain(stream: SignalStream): Promise<void>;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface OpenTrailInput {
|
|
131
|
+
readonly name: string;
|
|
132
|
+
readonly kind?: ProbeKind;
|
|
133
|
+
readonly trailId?: TrailId;
|
|
134
|
+
readonly attributes?: ProbeAttributes;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface Recorder {
|
|
138
|
+
readonly service: string;
|
|
139
|
+
readonly enabled: boolean;
|
|
140
|
+
openTrail(input: OpenTrailInput): ProbeHandle;
|
|
141
|
+
scope(trailId: TrailId): TrailRecorder;
|
|
142
|
+
flush(): Promise<void>;
|
|
143
|
+
shutdown(): Promise<void>;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface TrailRecorder {
|
|
147
|
+
readonly trailId: TrailId;
|
|
148
|
+
readonly sampled: boolean;
|
|
149
|
+
open(kind: ProbeKind, name: string, attributes?: ProbeAttributes): ProbeHandle;
|
|
150
|
+
child(parentId: ProbeId, kind: ProbeKind, name: string, attributes?: ProbeAttributes): ProbeHandle;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export const REDACTED_TOKEN = "[insight:scrubbed]" as const;
|
|
154
|
+
export type RedactedToken = typeof REDACTED_TOKEN;
|
|
155
|
+
|
|
156
|
+
export interface RedactionRule {
|
|
157
|
+
readonly id: string;
|
|
158
|
+
readonly key?: string | RegExp;
|
|
159
|
+
readonly value?: RegExp;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface RedactionOptions {
|
|
163
|
+
readonly maxStringLength?: number;
|
|
164
|
+
readonly omitKeys?: readonly string[];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export interface SecretRedactor {
|
|
168
|
+
readonly rules: readonly RedactionRule[];
|
|
169
|
+
scrubValue(value: unknown): unknown;
|
|
170
|
+
scrubAttributes(attributes: ProbeAttributes): ProbeAttributes;
|
|
171
|
+
scrub(probe: Probe): Probe;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export const PASSTHRU_REDACTOR: SecretRedactor = Object.freeze({
|
|
175
|
+
rules: Object.freeze([]),
|
|
176
|
+
scrubValue(value: unknown): unknown {
|
|
177
|
+
return value;
|
|
178
|
+
},
|
|
179
|
+
scrubAttributes(attributes: ProbeAttributes): ProbeAttributes {
|
|
180
|
+
return attributes;
|
|
181
|
+
},
|
|
182
|
+
scrub(probe: Probe): Probe {
|
|
183
|
+
return probe;
|
|
184
|
+
},
|
|
185
|
+
});
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
// Type declarations recovered from dist/types (no runtime body)
|
|
3
|
+
/**
|
|
4
|
+
* Insight subsystem — public barrel.
|
|
5
|
+
*
|
|
6
|
+
* `insight/` is the agent's single observability plane. It re-exports the FROZEN
|
|
7
|
+
* contract: the id model ({@link TrailId} / {@link ProbeId}), the immutable
|
|
8
|
+
* {@link Probe} value and its functional {@link ProbeHandle} (with the shared
|
|
9
|
+
* sampled-out {@link NOOP_HANDLE}), the wire {@link Signal} union, the
|
|
10
|
+
* {@link SampleGate} admission contract, the {@link Sink} drain interface, the
|
|
11
|
+
* {@link Recorder} / {@link TrailRecorder} facades, and the
|
|
12
|
+
* {@link SecretRedactor} attribute processor (with its {@link REDACTED_TOKEN}).
|
|
13
|
+
*
|
|
14
|
+
* Behaviour modules (the recorder, the flush buffer, the console / file / stream
|
|
15
|
+
* sinks, the redactor implementation, the agent and stream bridges, the session
|
|
16
|
+
* rehydrator, the ledger, and the dashboard panel) are added to this barrel as
|
|
17
|
+
* they land; consumers import the insight surface from `src/insight` rather than
|
|
18
|
+
* reaching into individual modules.
|
|
19
|
+
*/
|
|
20
|
+
export type {
|
|
21
|
+
TrailId,
|
|
22
|
+
ProbeId,
|
|
23
|
+
ProbeKind,
|
|
24
|
+
ProbeStatus,
|
|
25
|
+
ProbeOutcome,
|
|
26
|
+
ProbeFault,
|
|
27
|
+
ProbeAttributes,
|
|
28
|
+
Probe,
|
|
29
|
+
ClosedProbe,
|
|
30
|
+
ProbeHandle,
|
|
31
|
+
SignalPhase,
|
|
32
|
+
OpenSignal,
|
|
33
|
+
UpdateSignal,
|
|
34
|
+
CloseSignal,
|
|
35
|
+
Signal,
|
|
36
|
+
SignalEmit,
|
|
37
|
+
SampleGate,
|
|
38
|
+
FixedGates,
|
|
39
|
+
SignalStream,
|
|
40
|
+
Sink,
|
|
41
|
+
OpenTrailInput,
|
|
42
|
+
Recorder,
|
|
43
|
+
TrailRecorder,
|
|
44
|
+
RedactedToken,
|
|
45
|
+
RedactionRule,
|
|
46
|
+
RedactionOptions,
|
|
47
|
+
SecretRedactor,
|
|
48
|
+
} from "./contract.js";
|
|
49
|
+
export {
|
|
50
|
+
ID_WIDTHS,
|
|
51
|
+
asTrailId,
|
|
52
|
+
asProbeId,
|
|
53
|
+
PROBE_KINDS,
|
|
54
|
+
isClosedProbe,
|
|
55
|
+
NOOP_HANDLE,
|
|
56
|
+
isCloseSignal,
|
|
57
|
+
REDACTED_TOKEN,
|
|
58
|
+
PASSTHRU_REDACTOR,
|
|
59
|
+
} from "./contract.js";
|
|
60
|
+
export {
|
|
61
|
+
alwaysGate,
|
|
62
|
+
neverGate,
|
|
63
|
+
ratioGate,
|
|
64
|
+
isRatioGate,
|
|
65
|
+
hash32,
|
|
66
|
+
trailScore,
|
|
67
|
+
FIXED_GATES,
|
|
68
|
+
type RatioGate,
|
|
69
|
+
} from "./sampling.js";
|
|
70
|
+
export { createChannel, type SignalChannel } from "./channel.js";
|
|
71
|
+
export {
|
|
72
|
+
createRecorder,
|
|
73
|
+
mintTrailId,
|
|
74
|
+
mintProbeId,
|
|
75
|
+
faultOf,
|
|
76
|
+
type RecorderOptions,
|
|
77
|
+
type InsightRecorder,
|
|
78
|
+
} from "./recorder.js";
|
|
79
|
+
export { createRedactor, DEFAULT_REDACTOR, DEFAULT_REDACTION_RULES } from "./redaction.js";
|
|
80
|
+
export {
|
|
81
|
+
encodeRecord,
|
|
82
|
+
decodeRecord,
|
|
83
|
+
signalToRecord,
|
|
84
|
+
recordIsClose,
|
|
85
|
+
RECORD_VERSION,
|
|
86
|
+
LINE_FEED,
|
|
87
|
+
type TraceRecord,
|
|
88
|
+
} from "./serialize.js";
|
|
89
|
+
export {
|
|
90
|
+
createConsoleSink,
|
|
91
|
+
createFileSink,
|
|
92
|
+
createStreamSink,
|
|
93
|
+
createCollectorSink,
|
|
94
|
+
type ConsoleSinkOptions,
|
|
95
|
+
type LineWriter,
|
|
96
|
+
type FileSinkOptions,
|
|
97
|
+
type StreamSinkOptions,
|
|
98
|
+
type SignalWriter,
|
|
99
|
+
type CollectorSink,
|
|
100
|
+
} from "./sinks/index.js";
|
|
101
|
+
export {
|
|
102
|
+
readLines,
|
|
103
|
+
readRecords,
|
|
104
|
+
replaySignals,
|
|
105
|
+
replayProbes,
|
|
106
|
+
replayTrails,
|
|
107
|
+
type ChunkSource,
|
|
108
|
+
type ReplayOptions,
|
|
109
|
+
type ReplayedTrail,
|
|
110
|
+
} from "./replay.js";
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recorder — the trail/probe factory at the head of the pipeline.
|
|
3
|
+
*/
|
|
4
|
+
import { randomBytes } from "node:crypto";
|
|
5
|
+
import { createChannel, type SignalChannel } from "./channel.js";
|
|
6
|
+
import {
|
|
7
|
+
asProbeId,
|
|
8
|
+
asTrailId,
|
|
9
|
+
ID_WIDTHS,
|
|
10
|
+
NOOP_HANDLE,
|
|
11
|
+
PASSTHRU_REDACTOR,
|
|
12
|
+
type OpenTrailInput,
|
|
13
|
+
type Probe,
|
|
14
|
+
type ProbeAttributes,
|
|
15
|
+
type ProbeFault,
|
|
16
|
+
type ProbeHandle,
|
|
17
|
+
type ProbeId,
|
|
18
|
+
type ProbeKind,
|
|
19
|
+
type ProbeOutcome,
|
|
20
|
+
type Recorder,
|
|
21
|
+
type SampleGate,
|
|
22
|
+
type SecretRedactor,
|
|
23
|
+
type Signal,
|
|
24
|
+
type Sink,
|
|
25
|
+
type TrailId,
|
|
26
|
+
type TrailRecorder,
|
|
27
|
+
} from "./contract.js";
|
|
28
|
+
import { alwaysGate, isRatioGate, neverGate } from "./sampling.js";
|
|
29
|
+
|
|
30
|
+
export function mintTrailId(): TrailId {
|
|
31
|
+
return asTrailId(randomBytes(ID_WIDTHS.trail).toString("hex"));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function mintProbeId(): ProbeId {
|
|
35
|
+
return asProbeId(randomBytes(ID_WIDTHS.probe).toString("hex"));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface RecorderOptions {
|
|
39
|
+
readonly service?: string;
|
|
40
|
+
readonly enabled?: boolean;
|
|
41
|
+
readonly gate?: SampleGate;
|
|
42
|
+
readonly redactor?: SecretRedactor;
|
|
43
|
+
readonly sinks?: readonly Sink[];
|
|
44
|
+
readonly now?: () => number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface InsightRecorder extends Recorder {
|
|
48
|
+
readonly channel: SignalChannel;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function faultOf(error: unknown): ProbeFault {
|
|
52
|
+
if (error instanceof Error) {
|
|
53
|
+
const fault: { message: string; name?: string; stack?: string } = {
|
|
54
|
+
message: error.message,
|
|
55
|
+
name: error.name,
|
|
56
|
+
};
|
|
57
|
+
if (typeof error.stack === "string") {
|
|
58
|
+
fault.stack = error.stack;
|
|
59
|
+
}
|
|
60
|
+
return Object.freeze(fault);
|
|
61
|
+
}
|
|
62
|
+
return Object.freeze({ message: String(error) });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function createRecorder(options: RecorderOptions = {}): InsightRecorder {
|
|
66
|
+
const service = options.service ?? "insight";
|
|
67
|
+
const enabled = options.enabled ?? true;
|
|
68
|
+
const gate: SampleGate = enabled ? options.gate ?? alwaysGate : neverGate;
|
|
69
|
+
const redactor = options.redactor ?? PASSTHRU_REDACTOR;
|
|
70
|
+
const now = options.now ?? Date.now;
|
|
71
|
+
const channel = createChannel();
|
|
72
|
+
const drains: Promise<void>[] = [];
|
|
73
|
+
for (const sink of options.sinks ?? []) {
|
|
74
|
+
drains.push(sink.drain(channel.stream()));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const route = (signal: Signal): void => {
|
|
78
|
+
const scrubbed = redactor.scrub(signal.probe);
|
|
79
|
+
if (scrubbed === signal.probe) {
|
|
80
|
+
channel.emit(signal);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (signal.phase === "close") {
|
|
84
|
+
channel.emit({
|
|
85
|
+
phase: "close",
|
|
86
|
+
probe: scrubbed as Probe & { endedAt: number; status: ProbeOutcome },
|
|
87
|
+
at: signal.at,
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
channel.emit({ phase: signal.phase, probe: scrubbed, at: signal.at });
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
function admit(trailId: TrailId, rootName: string): boolean {
|
|
95
|
+
if (!enabled) return false;
|
|
96
|
+
if (isRatioGate(gate)) return gate.verdict(trailId);
|
|
97
|
+
return gate.admit(rootName);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function openProbe(
|
|
101
|
+
trailId: TrailId,
|
|
102
|
+
parentId: ProbeId | null,
|
|
103
|
+
kind: ProbeKind,
|
|
104
|
+
name: string,
|
|
105
|
+
attributes: ProbeAttributes,
|
|
106
|
+
): ProbeHandle {
|
|
107
|
+
const id = mintProbeId();
|
|
108
|
+
const startedAt = now();
|
|
109
|
+
interface Cell {
|
|
110
|
+
probe: Probe;
|
|
111
|
+
closed: boolean;
|
|
112
|
+
}
|
|
113
|
+
const cell: Cell = {
|
|
114
|
+
probe: Object.freeze({
|
|
115
|
+
id,
|
|
116
|
+
trailId,
|
|
117
|
+
parentId,
|
|
118
|
+
kind,
|
|
119
|
+
name,
|
|
120
|
+
startedAt,
|
|
121
|
+
status: "open" as const,
|
|
122
|
+
attributes: Object.freeze({ ...attributes }),
|
|
123
|
+
}),
|
|
124
|
+
closed: false,
|
|
125
|
+
};
|
|
126
|
+
route({ phase: "open", probe: cell.probe, at: startedAt });
|
|
127
|
+
const handle: ProbeHandle = {
|
|
128
|
+
trailId,
|
|
129
|
+
id,
|
|
130
|
+
sampled: true,
|
|
131
|
+
note(extra: ProbeAttributes): void {
|
|
132
|
+
if (cell.closed) return;
|
|
133
|
+
cell.probe = Object.freeze({
|
|
134
|
+
...cell.probe,
|
|
135
|
+
attributes: Object.freeze({ ...cell.probe.attributes, ...extra }),
|
|
136
|
+
});
|
|
137
|
+
route({ phase: "update", probe: cell.probe, at: now() });
|
|
138
|
+
},
|
|
139
|
+
child(childKind: ProbeKind, childName: string, childAttrs: ProbeAttributes = {}): ProbeHandle {
|
|
140
|
+
if (cell.closed) return NOOP_HANDLE;
|
|
141
|
+
return openProbe(trailId, id, childKind, childName, childAttrs);
|
|
142
|
+
},
|
|
143
|
+
fail(error: unknown): void {
|
|
144
|
+
if (cell.closed) return;
|
|
145
|
+
cell.probe = Object.freeze({
|
|
146
|
+
...cell.probe,
|
|
147
|
+
status: "error" as const,
|
|
148
|
+
fault: faultOf(error),
|
|
149
|
+
});
|
|
150
|
+
route({ phase: "update", probe: cell.probe, at: now() });
|
|
151
|
+
},
|
|
152
|
+
close(outcome?: ProbeOutcome): void {
|
|
153
|
+
if (cell.closed) return;
|
|
154
|
+
cell.closed = true;
|
|
155
|
+
const endedAt = now();
|
|
156
|
+
const status: ProbeOutcome =
|
|
157
|
+
outcome ?? (cell.probe.status === "error" ? "error" : "ok");
|
|
158
|
+
const closed = Object.freeze({
|
|
159
|
+
...cell.probe,
|
|
160
|
+
endedAt,
|
|
161
|
+
status,
|
|
162
|
+
});
|
|
163
|
+
cell.probe = closed;
|
|
164
|
+
route({ phase: "close", probe: closed, at: endedAt });
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
return handle;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function openTrail(input: OpenTrailInput): ProbeHandle {
|
|
171
|
+
const trailId = input.trailId ?? mintTrailId();
|
|
172
|
+
if (!admit(trailId, input.name)) {
|
|
173
|
+
return NOOP_HANDLE;
|
|
174
|
+
}
|
|
175
|
+
return openProbe(trailId, null, input.kind ?? "run", input.name, input.attributes ?? {});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function scope(trailId: TrailId): TrailRecorder {
|
|
179
|
+
const sampled = admit(trailId, service);
|
|
180
|
+
return {
|
|
181
|
+
trailId,
|
|
182
|
+
sampled,
|
|
183
|
+
open(kind: ProbeKind, name: string, attrs: ProbeAttributes = {}): ProbeHandle {
|
|
184
|
+
if (!sampled) return NOOP_HANDLE;
|
|
185
|
+
return openProbe(trailId, null, kind, name, attrs);
|
|
186
|
+
},
|
|
187
|
+
child(parentId: ProbeId, kind: ProbeKind, name: string, attrs: ProbeAttributes = {}): ProbeHandle {
|
|
188
|
+
if (!sampled) return NOOP_HANDLE;
|
|
189
|
+
return openProbe(trailId, parentId, kind, name, attrs);
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async function flush(): Promise<void> {
|
|
195
|
+
await Promise.resolve();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async function shutdown(): Promise<void> {
|
|
199
|
+
await flush();
|
|
200
|
+
channel.close();
|
|
201
|
+
await Promise.allSettled(drains);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return {
|
|
205
|
+
service,
|
|
206
|
+
enabled,
|
|
207
|
+
channel,
|
|
208
|
+
openTrail,
|
|
209
|
+
scope,
|
|
210
|
+
flush,
|
|
211
|
+
shutdown,
|
|
212
|
+
};
|
|
213
|
+
}
|