@lmctl-ai/lmctl 0.2.37 → 0.2.39
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/README.md +16 -0
- package/THIRD_PARTY_NOTICES.md +35 -0
- package/bin/lmbee +2 -0
- package/bin/lmscript +3 -0
- package/build-info.json +1 -0
- package/dist/cli/index.js +569 -494
- package/dist/cli/schema.sql +0 -169
- package/dist/cli/script.js +273 -266
- package/dist/lmbee.js +960 -0
- package/dist/lmscript.js +388 -0
- package/dist/public/app.js +379 -0
- package/dist/public/index.html +78 -0
- package/dist/public/styles.css +160 -0
- package/dist/schema.sql +455 -0
- package/dist/vendor-webui/index.html +18 -0
- package/dist/vendor-webui/local.js +231 -0
- package/dist/vendor-webui/styles.css +1852 -0
- package/package.json +12 -7
- package/dist/cli/batch.d.ts +0 -2
- package/dist/cli/busy-evidence.d.ts +0 -27
- package/dist/cli/chat-cycle.d.ts +0 -59
- package/dist/cli/chat-exec.d.ts +0 -91
- package/dist/cli/chat-policy.d.ts +0 -22
- package/dist/cli/chat.d.ts +0 -14
- package/dist/cli/code-resolver.d.ts +0 -8
- package/dist/cli/common.d.ts +0 -57
- package/dist/cli/context.d.ts +0 -12
- package/dist/cli/cost.d.ts +0 -2
- package/dist/cli/export.d.ts +0 -2
- package/dist/cli/hello.d.ts +0 -10
- package/dist/cli/index.d.ts +0 -3
- package/dist/cli/infra.d.ts +0 -78
- package/dist/cli/init.d.ts +0 -21
- package/dist/cli/intent-input.d.ts +0 -16
- package/dist/cli/intent-match.d.ts +0 -30
- package/dist/cli/intent-sessions.d.ts +0 -24
- package/dist/cli/intent-team.d.ts +0 -25
- package/dist/cli/intent.d.ts +0 -22
- package/dist/cli/ls.d.ts +0 -2
- package/dist/cli/mailbox-cli.d.ts +0 -6
- package/dist/cli/managed.d.ts +0 -62
- package/dist/cli/mcp-install.d.ts +0 -23
- package/dist/cli/mcp.d.ts +0 -2
- package/dist/cli/model.d.ts +0 -21
- package/dist/cli/paths.d.ts +0 -50
- package/dist/cli/plan-wizard.d.ts +0 -42
- package/dist/cli/plan.d.ts +0 -20
- package/dist/cli/queue-delivery.d.ts +0 -122
- package/dist/cli/quickrun.d.ts +0 -14
- package/dist/cli/ratelimit.d.ts +0 -2
- package/dist/cli/remote-fetch.d.ts +0 -7
- package/dist/cli/run-queries.d.ts +0 -82
- package/dist/cli/running.d.ts +0 -5
- package/dist/cli/save-script.d.ts +0 -41
- package/dist/cli/script.d.ts +0 -6
- package/dist/cli/seed-flight.d.ts +0 -2
- package/dist/cli/self-identity.d.ts +0 -25
- package/dist/cli/session-idle.d.ts +0 -118
- package/dist/cli/status.d.ts +0 -22
- package/dist/cli/tail.d.ts +0 -18
- package/dist/cli/target-resolver.d.ts +0 -139
- package/dist/cli/team-status.d.ts +0 -91
- package/dist/cli/teamfile-compat.d.ts +0 -116
- package/dist/cli/teamfile-store.d.ts +0 -18
- package/dist/cli/teamfile-template.d.ts +0 -47
- package/dist/cli/template-env.d.ts +0 -25
- package/dist/cli/terminal-lock.d.ts +0 -25
- package/dist/cli/terminal.d.ts +0 -23
- package/dist/cli/time-filter.d.ts +0 -10
- package/dist/cli/update-notifier.d.ts +0 -11
- package/dist/cli/version-util.d.ts +0 -23
- package/dist/config/seed_templates.d.ts +0 -1
- package/dist/db/backfill-event-log.d.ts +0 -26
- package/dist/db/delegation.d.ts +0 -37
- package/dist/db/escalation_vocab.d.ts +0 -45
- package/dist/db/event-log.d.ts +0 -40
- package/dist/db/index.d.ts +0 -1213
- package/dist/db/inflight-acquire.d.ts +0 -70
- package/dist/db/invocation-event-projections.d.ts +0 -65
- package/dist/db/ledger-identity.test.d.ts +0 -1
- package/dist/db/live-event-projections.d.ts +0 -92
- package/dist/db/migrate.d.ts +0 -51
- package/dist/db/open-readonly.d.ts +0 -2
- package/dist/db/process-liveness.d.ts +0 -37
- package/dist/db/sqlite.d.ts +0 -53
- package/dist/db/sqlite.test.d.ts +0 -1
- package/dist/db/terminal-lock.d.ts +0 -14
- package/dist/db/tracked-invocation-reconcile.d.ts +0 -52
- package/dist/db/tracked-invocation.d.ts +0 -116
- package/dist/mcp/dispatch.d.ts +0 -45
- package/dist/mcp/mediation.d.ts +0 -128
- package/dist/mcp/path-warning.d.ts +0 -7
- package/dist/mcp/server.d.ts +0 -63
- package/dist/mcp/tools.d.ts +0 -24
- package/dist/providers/adapter.d.ts +0 -271
- package/dist/providers/adapters/agy-adapter.d.ts +0 -18
- package/dist/providers/adapters/claude-adapter.d.ts +0 -20
- package/dist/providers/adapters/codex-adapter.d.ts +0 -22
- package/dist/providers/adapters/copilot-adapter.d.ts +0 -16
- package/dist/providers/adapters/dsh-adapter.d.ts +0 -89
- package/dist/providers/adapters/gemini-adapter.d.ts +0 -44
- package/dist/providers/adapters/hermes-adapter.d.ts +0 -71
- package/dist/providers/adapters/index.d.ts +0 -35
- package/dist/providers/adapters/kimi-adapter.d.ts +0 -16
- package/dist/providers/adapters/lmplayer-adapter.d.ts +0 -14
- package/dist/providers/adapters/opencode-adapter.d.ts +0 -11
- package/dist/providers/adapters/pi-adapter.d.ts +0 -17
- package/dist/providers/adapters/print-turn.d.ts +0 -29
- package/dist/providers/adapters/qwen-adapter.d.ts +0 -11
- package/dist/providers/agy.d.ts +0 -32
- package/dist/providers/base-adapter.d.ts +0 -110
- package/dist/providers/base.d.ts +0 -12
- package/dist/providers/binary-check.d.ts +0 -102
- package/dist/providers/bundle.d.ts +0 -124
- package/dist/providers/claude-mock.d.ts +0 -90
- package/dist/providers/claude.d.ts +0 -21
- package/dist/providers/codex-config.d.ts +0 -15
- package/dist/providers/codex.d.ts +0 -25
- package/dist/providers/config/init-config.d.ts +0 -43
- package/dist/providers/config/model-selection-lint.d.ts +0 -70
- package/dist/providers/config/team-config.d.ts +0 -184
- package/dist/providers/config/types.d.ts +0 -146
- package/dist/providers/config/user-config.d.ts +0 -88
- package/dist/providers/copilot.d.ts +0 -21
- package/dist/providers/debug.d.ts +0 -128
- package/dist/providers/dsh-sidecar.d.ts +0 -65
- package/dist/providers/dsh-zstd.d.ts +0 -27
- package/dist/providers/dsh.d.ts +0 -37
- package/dist/providers/frontmatter.d.ts +0 -46
- package/dist/providers/gemini-session-reader.d.ts +0 -151
- package/dist/providers/gemini.d.ts +0 -39
- package/dist/providers/hermes.d.ts +0 -90
- package/dist/providers/index.d.ts +0 -423
- package/dist/providers/kimi.d.ts +0 -37
- package/dist/providers/model-catalog.d.ts +0 -145
- package/dist/providers/model-suggestions.d.ts +0 -4
- package/dist/providers/one-shot-timeout.d.ts +0 -1
- package/dist/providers/opencode-config.d.ts +0 -62
- package/dist/providers/opencode.d.ts +0 -40
- package/dist/providers/parsers/acp.d.ts +0 -71
- package/dist/providers/parsers/codex-app-server.d.ts +0 -60
- package/dist/providers/parsers/stream-json.d.ts +0 -57
- package/dist/providers/passive-readers/agy.d.ts +0 -155
- package/dist/providers/passive-readers/copilot.d.ts +0 -173
- package/dist/providers/passive-readers/dsh.d.ts +0 -34
- package/dist/providers/passive-readers/kimi.d.ts +0 -44
- package/dist/providers/passive-readers/opencode.d.ts +0 -89
- package/dist/providers/passive-readers/qwen.d.ts +0 -151
- package/dist/providers/passive-readers/shared.d.ts +0 -138
- package/dist/providers/passive-session-reader.d.ts +0 -188
- package/dist/providers/path-utils.d.ts +0 -1
- package/dist/providers/pi.d.ts +0 -32
- package/dist/providers/pricing.d.ts +0 -107
- package/dist/providers/qwen.d.ts +0 -22
- package/dist/providers/ratelimit/agy.d.ts +0 -22
- package/dist/providers/ratelimit/claude-auth.d.ts +0 -13
- package/dist/providers/ratelimit/claude.d.ts +0 -6
- package/dist/providers/ratelimit/codex.d.ts +0 -7
- package/dist/providers/ratelimit/kimi-auth.d.ts +0 -15
- package/dist/providers/ratelimit/kimi.d.ts +0 -6
- package/dist/providers/ratelimit/schema.d.ts +0 -28
- package/dist/providers/ratelimit-readings.d.ts +0 -19
- package/dist/providers/registry.d.ts +0 -31
- package/dist/providers/resume.d.ts +0 -43
- package/dist/providers/seed-instruction.d.ts +0 -3
- package/dist/providers/self-session-env.d.ts +0 -21
- package/dist/providers/session-limit.d.ts +0 -9
- package/dist/providers/strip-ansi.d.ts +0 -5
- package/dist/providers/transport-errors.d.ts +0 -94
- package/dist/providers/transport-lifecycle.d.ts +0 -63
- package/dist/providers/transport-wrappers.d.ts +0 -110
- package/dist/providers/transports/acp-profiles/config-option-step.d.ts +0 -24
- package/dist/providers/transports/acp-profiles/copilot.d.ts +0 -12
- package/dist/providers/transports/acp-profiles/gemini.d.ts +0 -22
- package/dist/providers/transports/acp-profiles/hermes.d.ts +0 -27
- package/dist/providers/transports/acp-profiles/index.d.ts +0 -19
- package/dist/providers/transports/acp-profiles/kimi.d.ts +0 -24
- package/dist/providers/transports/acp-profiles/opencode.d.ts +0 -26
- package/dist/providers/transports/acp-profiles/types.d.ts +0 -258
- package/dist/providers/transports/acp-rpc.d.ts +0 -18
- package/dist/providers/transports/acp.d.ts +0 -217
- package/dist/providers/transports/codex-app-server.d.ts +0 -190
- package/dist/providers/transports/hold-open.d.ts +0 -120
- package/dist/providers/transports/manager.d.ts +0 -21
- package/dist/providers/transports/stream-json.d.ts +0 -162
- package/dist/providers/transports/types.d.ts +0 -56
- package/dist/providers/types.d.ts +0 -154
- package/dist/providers/yolo-contract.d.ts +0 -131
- package/dist/script/adapter.d.ts +0 -104
- package/dist/script/batch-script.d.ts +0 -7
- package/dist/script/index.d.ts +0 -3
- package/dist/script/lmbee-module.d.ts +0 -2
- package/dist/script/lmscript.d.ts +0 -616
- package/dist/shared/policy.d.ts +0 -74
- package/dist/shared-lib/db.d.ts +0 -25
- package/dist/shared-lib/passive-session-reader.d.ts +0 -2
- package/dist/shared-lib/provider-parse.d.ts +0 -6
- package/dist/templates/basedir.d.ts +0 -52
- package/dist/uri/lmctl_uri.d.ts +0 -38
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Passive (read-only, bounded, certified) reader for GitHub Copilot CLI sessions.
|
|
3
|
-
*
|
|
4
|
-
* ## What the native store actually is (real records, not assumed)
|
|
5
|
-
*
|
|
6
|
-
* Copilot writes one append-only event log per session:
|
|
7
|
-
* `$HOME/.copilot/session-state/<uuid>/events.jsonl` (+ a `workspace.yaml`).
|
|
8
|
-
* Each line is a JSON object `{ type, id, timestamp, data }`. The event TYPES seen
|
|
9
|
-
* locally: `session.start`, `session.model_change`, `session.info`,
|
|
10
|
-
* `system.message`, `user.message`, `assistant.turn_start`, `assistant.message`,
|
|
11
|
-
* `assistant.turn_end`, `tool.execution_start`, `tool.execution_complete`,
|
|
12
|
-
* `session.shutdown`.
|
|
13
|
-
*
|
|
14
|
-
* ## Token semantics — the copilot warning, verified on disk
|
|
15
|
-
*
|
|
16
|
-
* lmbi's directive: "Copilot has cumulative per-model shutdown totals and some
|
|
17
|
-
* per-message usage; NEVER distribute a session total over responses without
|
|
18
|
-
* evidence." Measured against real sessions:
|
|
19
|
-
*
|
|
20
|
-
* - `assistant.message.outputTokens` IS a genuine PER-RESPONSE count.
|
|
21
|
-
* - There is NO per-message input / cache / reasoning field anywhere on the wire.
|
|
22
|
-
* Those counters exist only in `session.shutdown.modelMetrics` snapshots.
|
|
23
|
-
*
|
|
24
|
-
* CORRECTED (real evidence, not the original assumption): `session.shutdown`
|
|
25
|
-
* is NOT a proven session-wide cumulative. A session can carry MANY shutdown
|
|
26
|
-
* events (measured: up to 24 in one real session), and a shutdown's
|
|
27
|
-
* `requests.count`/`outputTokens` can be far smaller than the session's real
|
|
28
|
-
* total turn count/output sum (measured: a 201-turn session's last shutdown
|
|
29
|
-
* reported `requests.count=7`, `outputTokens=1984` against a real per-message
|
|
30
|
-
* sum of 82,375 — a ~97.6% undercount). So each shutdown snapshot's semantics
|
|
31
|
-
* are `"reported_scope_unknown"`, never asserted cumulative.
|
|
32
|
-
*
|
|
33
|
-
* Therefore each response record here carries `tokens.output` (real, per-message)
|
|
34
|
-
* and leaves `input_uncached` / `input_cached` / `input_cache_write` NULL — the
|
|
35
|
-
* shutdown snapshot's input is NEVER divided across responses. Every shutdown
|
|
36
|
-
* snapshot is surfaced SEPARATELY and RAW as `CopilotSessionUsage` (see
|
|
37
|
-
* `readCopilot`/`readWithUsage`) — never spread over the per-response rows,
|
|
38
|
-
* never emitted as a fabricated pseudo-response, and never renamed/normalized
|
|
39
|
-
* into this reader's own canonical token vocabulary (that's lmbi's own
|
|
40
|
-
* downstream decision to make, not this reader's).
|
|
41
|
-
*
|
|
42
|
-
* ## Identity, revision, attribution
|
|
43
|
-
*
|
|
44
|
-
* - `response_id` = `assistant.message.data.messageId` (a real uuid); never
|
|
45
|
-
* invented. Repeated events for one messageId sum their `outputTokens`.
|
|
46
|
-
* - The revision is the sha256 of the exact `events.jsonl` bytes (extraction-
|
|
47
|
-
* semantics-tagged, see EXTRACTION_SEMANTICS) with
|
|
48
|
-
* a dev/ino/size/mtime recheck: a live append caught mid-write is `partial`,
|
|
49
|
-
* never a clean revision, and a file not ending on a record boundary is refused.
|
|
50
|
-
* - Prompt admission: `user.message.data.content` bytes attach to the FIRST
|
|
51
|
-
* assistant response of the same `interactionId`; later responses in that
|
|
52
|
-
* interaction are a real 0 (the prompt was already admitted). A response whose
|
|
53
|
-
* interaction has no visible user admission (truncated history / system-driven
|
|
54
|
-
* turn) gets an unknown coverage marker — "no input" cannot be certified.
|
|
55
|
-
*
|
|
56
|
-
* ## File / external-I/O (bx2), conservative by contract
|
|
57
|
-
*
|
|
58
|
-
* `create` ({path,file_text}) and `apply_patch` (<patch string>) are KNOWN writes
|
|
59
|
-
* with measurable added bytes. `view` ({path}) is a KNOWN read whose bytes are
|
|
60
|
-
* NULL — the result content is line-decorated with no clean chunk to count, so the
|
|
61
|
-
* honest size is unavailable (not guessed). `report_intent` is internal control
|
|
62
|
-
* (neither direction). Everything else opaque (`bash`/`read_bash`/`write_bash`/
|
|
63
|
-
* `stop_bash`/`list_bash`/`rg`/`glob`/`sql`/`fetch_*`/…) is unknown in BOTH
|
|
64
|
-
* directions, forcing that direction's aggregate NULL.
|
|
65
|
-
*/
|
|
66
|
-
import type { ReadLimits, Snapshot, Source, SourceState } from "../passive-session-reader.js";
|
|
67
|
-
export declare const COPILOT_PROVIDER = "copilot";
|
|
68
|
-
/**
|
|
69
|
-
* One event line of a copilot `events.jsonl`. Only the fields this reader reads.
|
|
70
|
-
*/
|
|
71
|
-
interface CopilotEvent {
|
|
72
|
-
type?: unknown;
|
|
73
|
-
id?: unknown;
|
|
74
|
-
timestamp?: unknown;
|
|
75
|
-
data?: unknown;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* One native model's RAW `session.shutdown` counters. Field NAMES are copied
|
|
79
|
-
* directly from the native wire (`usage.inputTokens` -> `input_tokens`,
|
|
80
|
-
* `tokenDetails.input.tokenCount` -> `input_other_tokens`, etc.) — this reader
|
|
81
|
-
* does NOT compute, clamp, infer, or rename a "canonical uncached" figure here.
|
|
82
|
-
* Per lmbi's explicit instruction: raw naming preserves the native facts while
|
|
83
|
-
* this snapshot's own window/scope semantics remain unproven; normalizing
|
|
84
|
-
* (e.g. `input_uncached = input_tokens - cache_read_tokens`) is a downstream
|
|
85
|
-
* decision for the consumer, not this reader's to bake in.
|
|
86
|
-
*/
|
|
87
|
-
export interface CopilotModelUsage {
|
|
88
|
-
model: string;
|
|
89
|
-
requests_count: number | null;
|
|
90
|
-
/** `usage.inputTokens`, copied as-is. */
|
|
91
|
-
input_tokens: number | null;
|
|
92
|
-
/** `tokenDetails.input.tokenCount`, copied as-is — a real native "fresh"
|
|
93
|
-
* figure, narrower than `input_tokens`. NOT a canonical uncached total. */
|
|
94
|
-
input_other_tokens: number | null;
|
|
95
|
-
cache_read_tokens: number | null;
|
|
96
|
-
cache_write_tokens: number | null;
|
|
97
|
-
output_tokens: number | null;
|
|
98
|
-
reasoning_tokens: number | null;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* One native `session.shutdown` EVENT, with every model in its `modelMetrics`
|
|
102
|
-
* grouped underneath (mirrors the native shape: one event, many models) —
|
|
103
|
-
* surfaced beside, never inside, the per-response rows.
|
|
104
|
-
*
|
|
105
|
-
* CORRECTED (real evidence, not assumption): a session can carry MULTIPLE
|
|
106
|
-
* `session.shutdown` events (measured: up to 24 in one real session on this box),
|
|
107
|
-
* and a shutdown's `requests.count`/`usage.outputTokens` can be far smaller than
|
|
108
|
-
* the session's real total turn count/output sum (measured: a 201-turn session's
|
|
109
|
-
* last shutdown reported `requests.count=7`, `outputTokens=1984` against a real
|
|
110
|
-
* per-message sum of 82,375 — a ~97.6% undercount). So this is NOT a proven
|
|
111
|
-
* session-wide cumulative; `semantics: "reported_scope_unknown"` reflects that
|
|
112
|
-
* honestly. Every shutdown event is retained (never "last wins", exact
|
|
113
|
-
* duplicate `native_id` replays coalesce to one), each with its own native
|
|
114
|
-
* event id/timestamp, so later analysis isn't precluded by discarding earlier
|
|
115
|
-
* snapshots.
|
|
116
|
-
*/
|
|
117
|
-
export interface CopilotSessionUsage {
|
|
118
|
-
/** The `session.shutdown` event's own top-level `id` (a real uuid). An event
|
|
119
|
-
* with no real id is never given a fabricated one — it is excluded from this
|
|
120
|
-
* array entirely (an explicit capture gap, not silently-fine metadata). */
|
|
121
|
-
native_id: string;
|
|
122
|
-
/** The `session.shutdown` event's own top-level `timestamp`, canonicalized. */
|
|
123
|
-
recorded_at: string | null;
|
|
124
|
-
kind: "copilot_session_shutdown";
|
|
125
|
-
semantics: "reported_scope_unknown";
|
|
126
|
-
models: CopilotModelUsage[];
|
|
127
|
-
}
|
|
128
|
-
export interface CopilotReadResult {
|
|
129
|
-
snapshot: Snapshot;
|
|
130
|
-
/** null when the session has no shutdown event with a real id yet (live/torn,
|
|
131
|
-
* or every shutdown event on this session lacked an id) — normal. */
|
|
132
|
-
sessionUsage: CopilotSessionUsage[] | null;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Extract the per-response snapshot AND the retained session-usage snapshots
|
|
136
|
-
* (scope-unknown, never asserted cumulative) from a parsed copilot event log.
|
|
137
|
-
* Pure and deterministic. A malformed event never throws; the
|
|
138
|
-
* whole snapshot is only refused (`partial`) when a response row count exceeds the
|
|
139
|
-
* budget — otherwise unrecognized shapes degrade to conservative NULL markers.
|
|
140
|
-
*/
|
|
141
|
-
export declare function readCopilot(events: CopilotEvent[], source: Source, revision: string, limits: ReadLimits): CopilotReadResult;
|
|
142
|
-
export interface CopilotPassiveReaderOptions {
|
|
143
|
-
/** Defaults to `$HOME/.copilot/session-state`. */
|
|
144
|
-
copilotSessionStateDir?: string;
|
|
145
|
-
}
|
|
146
|
-
export declare class CopilotPassiveReader {
|
|
147
|
-
private readonly sessionStateDir;
|
|
148
|
-
constructor(options?: CopilotPassiveReaderOptions);
|
|
149
|
-
/**
|
|
150
|
-
* Enumerate up to `cap` sources ordered by real path. `afterKey` (a
|
|
151
|
-
* `source_id\0sessionid` sourceKey) continues a previous page. Discovery is a
|
|
152
|
-
* single-level scan of the session-state directory (no deep recursion), so
|
|
153
|
-
* there is no traversal budget to exhaust — `truncated` is always false.
|
|
154
|
-
*/
|
|
155
|
-
discover(limits: ReadLimits, cap: number, afterKey?: string | null): Promise<{
|
|
156
|
-
sources: Source[];
|
|
157
|
-
truncated: boolean;
|
|
158
|
-
}>;
|
|
159
|
-
/**
|
|
160
|
-
* A source is ours only when its real path is `<dir>/events.jsonl` contained by
|
|
161
|
-
* the session-state directory AND `<dir>` basename is the claimed session id.
|
|
162
|
-
*/
|
|
163
|
-
private matches;
|
|
164
|
-
inspect(source: Source, limits: ReadLimits): Promise<SourceState>;
|
|
165
|
-
/** Contract-shaped read: per-response Snapshot only. Use `readWithUsage` to also
|
|
166
|
-
* obtain the retained session-usage snapshots that must not be distributed
|
|
167
|
-
* over responses (see the module header — their scope is unproven, never
|
|
168
|
-
* asserted cumulative). */
|
|
169
|
-
read(source: Source, revision: string, limits: ReadLimits): Promise<Snapshot>;
|
|
170
|
-
readWithUsage(source: Source, revision: string, limits: ReadLimits): Promise<CopilotReadResult>;
|
|
171
|
-
}
|
|
172
|
-
export declare function createCopilotPassiveReader(options?: CopilotPassiveReaderOptions): CopilotPassiveReader;
|
|
173
|
-
export {};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { ReadLimits, Snapshot, Source, SourceState } from "../passive-session-reader.js";
|
|
2
|
-
export declare const DSH_PROVIDER = "dsh";
|
|
3
|
-
interface DshRecord {
|
|
4
|
-
type?: unknown;
|
|
5
|
-
seq?: unknown;
|
|
6
|
-
time?: unknown;
|
|
7
|
-
data?: unknown;
|
|
8
|
-
}
|
|
9
|
-
export interface DshPassiveReaderOptions {
|
|
10
|
-
/** Defaults to `$DSH_HOME/sessions`, then `~/.dsh/sessions`. */
|
|
11
|
-
dshHome?: string;
|
|
12
|
-
maxDiscoveryTraversalVisits?: number;
|
|
13
|
-
}
|
|
14
|
-
export declare function readDsh(records: DshRecord[], source: Source, revision: string, limits: ReadLimits): Snapshot;
|
|
15
|
-
export declare class DshPassiveReader {
|
|
16
|
-
private readonly sessionsDir;
|
|
17
|
-
private readonly maxDiscoveryTraversalVisits;
|
|
18
|
-
constructor(options?: DshPassiveReaderOptions);
|
|
19
|
-
/**
|
|
20
|
-
* Enumerate up to `cap` sources ordered by real path. `afterPath` continues a
|
|
21
|
-
* previous page. The caller owns cursor encoding and the cross-provider merge.
|
|
22
|
-
*/
|
|
23
|
-
discover(limits: ReadLimits, cap: number, afterPath?: string | null): Promise<{
|
|
24
|
-
sources: Source[];
|
|
25
|
-
truncated: boolean;
|
|
26
|
-
}>;
|
|
27
|
-
/** Ours only when a real, non-symlink `session.jsonl.zstd` whose parent dir name
|
|
28
|
-
* is the claimed session id. */
|
|
29
|
-
private matches;
|
|
30
|
-
inspect(source: Source, limits: ReadLimits): Promise<SourceState>;
|
|
31
|
-
read(source: Source, revision: string, limits: ReadLimits): Promise<Snapshot>;
|
|
32
|
-
}
|
|
33
|
-
export declare function createDshPassiveReader(options?: DshPassiveReaderOptions): DshPassiveReader;
|
|
34
|
-
export {};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { ReadLimits, Snapshot, Source, SourceState } from "../passive-session-reader.js";
|
|
2
|
-
export declare const KIMI_PROVIDER = "kimi";
|
|
3
|
-
export interface KimiPassiveReaderOptions {
|
|
4
|
-
/** Defaults to `$KIMI_CODE_HOME`, then `~/.kimi-code`. */
|
|
5
|
-
kimiHome?: string;
|
|
6
|
-
maxDiscoveryTraversalVisits?: number;
|
|
7
|
-
}
|
|
8
|
-
interface WireLine {
|
|
9
|
-
type?: unknown;
|
|
10
|
-
agentId?: unknown;
|
|
11
|
-
event?: unknown;
|
|
12
|
-
time?: unknown;
|
|
13
|
-
model?: unknown;
|
|
14
|
-
modelAlias?: unknown;
|
|
15
|
-
turnStep?: unknown;
|
|
16
|
-
input?: unknown;
|
|
17
|
-
origin?: unknown;
|
|
18
|
-
promptId?: unknown;
|
|
19
|
-
protocol_version?: unknown;
|
|
20
|
-
usage?: unknown;
|
|
21
|
-
}
|
|
22
|
-
export declare function readKimi(lines: WireLine[], source: Source, revision: string, limits: ReadLimits): Snapshot;
|
|
23
|
-
export declare class KimiPassiveReader {
|
|
24
|
-
private readonly home;
|
|
25
|
-
private readonly sessionsDir;
|
|
26
|
-
private readonly indexPath;
|
|
27
|
-
private readonly maxDiscoveryTraversalVisits;
|
|
28
|
-
constructor(options?: KimiPassiveReaderOptions);
|
|
29
|
-
/**
|
|
30
|
-
* Enumerate up to `cap` agent-wire sources ordered by real path. `afterPath`
|
|
31
|
-
* continues a previous page. Unions the directory walk with the append-only
|
|
32
|
-
* index so a missing/damaged index still recovers sessions.
|
|
33
|
-
*/
|
|
34
|
-
discover(limits: ReadLimits, cap: number, afterPath?: string | null): Promise<{
|
|
35
|
-
sources: Source[];
|
|
36
|
-
truncated: boolean;
|
|
37
|
-
}>;
|
|
38
|
-
private unionIndex;
|
|
39
|
-
private matches;
|
|
40
|
-
inspect(source: Source, limits: ReadLimits): Promise<SourceState>;
|
|
41
|
-
read(source: Source, revision: string, limits: ReadLimits): Promise<Snapshot>;
|
|
42
|
-
}
|
|
43
|
-
export declare function createKimiPassiveReader(options?: KimiPassiveReaderOptions): KimiPassiveReader;
|
|
44
|
-
export {};
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Passive (read-only, bounded, certified) reader for OpenCode sessions.
|
|
3
|
-
*
|
|
4
|
-
* ## Relationship to lmplayer (the investigated finding, from real stores)
|
|
5
|
-
*
|
|
6
|
-
* lmplayer IS an opencode fork/wrapper, and the two share the opencode SQLite
|
|
7
|
-
* schema EXACTLY: `message(id,session_id,time_created,time_updated,data)`,
|
|
8
|
-
* `part(id,message_id,session_id,time_created,time_updated,data)`,
|
|
9
|
-
* `session(id,project_id,…)`, with the per-row `data` column holding JSON. Verified
|
|
10
|
-
* on this box: an opencode assistant `message.data` is
|
|
11
|
-
* `{parentID, role:"assistant", tokens:{input,output,reasoning,cache:{read,write}},
|
|
12
|
-
* modelID, providerID, time:{created,completed}}` and a tool `part.data` is
|
|
13
|
-
* `{type:"tool", tool, callID, state:{status,input,output,metadata:{display}}}` —
|
|
14
|
-
* byte-for-byte the shapes the dispatcher's lmplayer reader already handles.
|
|
15
|
-
*
|
|
16
|
-
* What DIFFERS is ONLY the store location and the label:
|
|
17
|
-
* - opencode canonical store: `$XDG_DATA_HOME/opencode/opencode.db` (large, live)
|
|
18
|
-
* and `…/opencode/opencode-local.db`, plus `$XDG_CONFIG_HOME/opencode/opencode.db`.
|
|
19
|
-
* - lmplayer store: `$XDG_DATA_HOME/lmplayer/opencode*.db` (with extra
|
|
20
|
-
* lmplayer-only `session_job*` tables — the source of the
|
|
21
|
-
* `session-job-notification` synthetic part type, filtered here too).
|
|
22
|
-
*
|
|
23
|
-
* So this reader reuses the lmplayer extraction verbatim but labels every source
|
|
24
|
-
* `provider:"opencode"` — NEVER "lmplayer", even though the SQLite shape is
|
|
25
|
-
* identical (lmbi's explicit "no cross-provider mislabeling" requirement). The
|
|
26
|
-
* label flows from `source.provider`, which discovery sets to `"opencode"`.
|
|
27
|
-
*
|
|
28
|
-
* LANDMINE for wiring: the `OPENCODE_DB` env var currently routes the dispatcher's
|
|
29
|
-
* LMPLAYER default paths — pointing it at the opencode store would label opencode
|
|
30
|
-
* data as `lmplayer`. This reader deliberately does NOT read that env; an explicit
|
|
31
|
-
* store override goes through `OpencodePassiveReaderOptions.dbPaths`.
|
|
32
|
-
*
|
|
33
|
-
* De-duplicate the mirrored helpers (parseApplyPatch / classifyTool / firstPath /
|
|
34
|
-
* writeInputBytes / sqliteRevision / the row reader) against the dispatcher's own
|
|
35
|
-
* copies at wiring time.
|
|
36
|
-
*/
|
|
37
|
-
import type { ReadLimits, Snapshot, Source, SourceState } from "../passive-session-reader.js";
|
|
38
|
-
export declare const OPENCODE_PROVIDER = "opencode";
|
|
39
|
-
/** opencode's own canonical stores (NOT lmplayer's, NOT the OPENCODE_DB env). */
|
|
40
|
-
export declare function defaultOpencodeDbPaths(): string[];
|
|
41
|
-
interface OpencodeMessageRow extends Record<string, unknown> {
|
|
42
|
-
id: string;
|
|
43
|
-
time_created: number;
|
|
44
|
-
time_updated: number;
|
|
45
|
-
data: string;
|
|
46
|
-
}
|
|
47
|
-
interface OpencodePartRow extends Record<string, unknown> {
|
|
48
|
-
id: string;
|
|
49
|
-
message_id: string;
|
|
50
|
-
time_created: number;
|
|
51
|
-
time_updated: number;
|
|
52
|
-
data: string;
|
|
53
|
-
}
|
|
54
|
-
/** Extract per-response metadata from an opencode session's rows. Verbatim
|
|
55
|
-
* lmplayer logic, labeled through `source.provider` (= "opencode"). */
|
|
56
|
-
export declare function readOpencodeRows(source: Source, revision: string, rows: {
|
|
57
|
-
messages: OpencodeMessageRow[];
|
|
58
|
-
parts: OpencodePartRow[];
|
|
59
|
-
}, limits: ReadLimits): Snapshot;
|
|
60
|
-
export interface OpencodePassiveReaderOptions {
|
|
61
|
-
/** Overrides the default opencode store paths (does NOT read `OPENCODE_DB`). */
|
|
62
|
-
dbPaths?: string[];
|
|
63
|
-
sqliteBusyTimeoutMs?: number;
|
|
64
|
-
}
|
|
65
|
-
/** Keyset watermark for cross-DB discovery (one page continues after this key). */
|
|
66
|
-
export interface OpencodeDiscoveryCursor {
|
|
67
|
-
source_id: string;
|
|
68
|
-
sessionid: string;
|
|
69
|
-
}
|
|
70
|
-
export declare class OpencodePassiveReader {
|
|
71
|
-
private readonly dbPaths;
|
|
72
|
-
private readonly sqliteBusyTimeoutMs;
|
|
73
|
-
constructor(options?: OpencodePassiveReaderOptions);
|
|
74
|
-
private openDb;
|
|
75
|
-
/**
|
|
76
|
-
* Enumerate up to `cap` sources ordered by `source_id\0sessionid`, deduped by
|
|
77
|
-
* session id (the first configured DB that holds it is canonical). `after`
|
|
78
|
-
* continues a previous page. Bounded SQL (`LIMIT`) — no traversal budget, so
|
|
79
|
-
* `truncated` is always false.
|
|
80
|
-
*/
|
|
81
|
-
discover(limits: ReadLimits, cap: number, after?: OpencodeDiscoveryCursor | null): Promise<{
|
|
82
|
-
sources: Source[];
|
|
83
|
-
truncated: boolean;
|
|
84
|
-
}>;
|
|
85
|
-
inspect(source: Source, limits: ReadLimits): SourceState;
|
|
86
|
-
read(source: Source, revision: string, limits: ReadLimits): Snapshot;
|
|
87
|
-
}
|
|
88
|
-
export declare function createOpencodePassiveReader(options?: OpencodePassiveReaderOptions): OpencodePassiveReader;
|
|
89
|
-
export {};
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Passive (read-only, bounded, certified) reader for Qwen Code sessions.
|
|
3
|
-
*
|
|
4
|
-
* ## Why this reader does not follow either of qwen.ts's own headers
|
|
5
|
-
*
|
|
6
|
-
* `src/providers/qwen.ts` carries two conflicting claims: its file header says
|
|
7
|
-
* "Qwen Code is a Claude Code fork — same JSONL session format", while its
|
|
8
|
-
* `QwenUsageMetadata` comment says "Qwen Code is a Gemini CLI fork; usageMetadata
|
|
9
|
-
* follows Gemini API semantics". Neither label alone describes the records on
|
|
10
|
-
* disk, so this reader was written from the records instead. What a census of
|
|
11
|
-
* every `*.jsonl` under the local projects store actually shows (1155 records,
|
|
12
|
-
* 0 parse failures):
|
|
13
|
-
*
|
|
14
|
-
* - The ENVELOPE is Claude-shaped: `uuid`, `parentUuid`, `sessionId`,
|
|
15
|
-
* `timestamp`, `type`, `cwd`, `version`, `gitBranch` on 1155/1155 records.
|
|
16
|
-
* - The record TYPES diverge from Claude: `system` (592), `assistant` (276),
|
|
17
|
-
* `tool_result` (238), `user` (49). Claude folds tool results into `user`
|
|
18
|
-
* rows; qwen gives them their own type. That makes a `user` row an
|
|
19
|
-
* unambiguous external prompt admission here — no tool_result sniffing.
|
|
20
|
-
* - Usage exists in TWO shapes simultaneously, so "which fork" is the wrong
|
|
21
|
-
* question:
|
|
22
|
-
* 1. `assistant.usageMetadata` — Gemini camelCase
|
|
23
|
-
* (`promptTokenCount` / `candidatesTokenCount` / `thoughtsTokenCount` /
|
|
24
|
-
* `totalTokenCount` / `cachedContentTokenCount`), on 276 records, with
|
|
25
|
-
* NO per-response identity of any kind.
|
|
26
|
-
* 2. `system` rows with `subtype:"ui_telemetry"` and
|
|
27
|
-
* `systemPayload.uiEvent["event.name"] === "qwen-code.api_response"` —
|
|
28
|
-
* snake_case (`input_token_count` / `output_token_count` /
|
|
29
|
-
* `cached_content_token_count` / `thoughts_token_count` /
|
|
30
|
-
* `total_token_count`), on 289 records, each carrying a native
|
|
31
|
-
* `response_id` (`chatcmpl-…`).
|
|
32
|
-
*
|
|
33
|
-
* This reader treats shape (2) as authoritative, because it is the ONLY source
|
|
34
|
-
* with a native per-response id — the contract forbids fabricating a
|
|
35
|
-
* `response_id` out of an envelope uuid — and it strictly covers shape (1)
|
|
36
|
-
* (289 ≥ 276; the extra 13 are `subagent_name` responses that have no
|
|
37
|
-
* top-level assistant row at all).
|
|
38
|
-
*
|
|
39
|
-
* ## Token semantics: measured, not assumed
|
|
40
|
-
*
|
|
41
|
-
* All 289 local api_response records satisfy, with zero violations:
|
|
42
|
-
* input_token_count + output_token_count === total_token_count
|
|
43
|
-
* cached_content_token_count <= input_token_count
|
|
44
|
-
* thoughts_token_count <= output_token_count
|
|
45
|
-
*
|
|
46
|
-
* i.e. cached is a SUBSET of input and thoughts a SUBSET of output — Gemini
|
|
47
|
-
* semantics, now verified on real records rather than inherited from a comment.
|
|
48
|
-
* The three invariants are re-checked at read time; a violation makes the whole
|
|
49
|
-
* snapshot `partial` rather than emitting numbers whose meaning we cannot stand
|
|
50
|
-
* behind.
|
|
51
|
-
*
|
|
52
|
-
* `input_cache_write` is NULL, not 0: no cache-write counter exists anywhere in
|
|
53
|
-
* this wire (no such key on any of the 289 records), so its value is unrecorded,
|
|
54
|
-
* not known-zero.
|
|
55
|
-
*
|
|
56
|
-
* `model_provider` is NULL. The nearest native field is `auth_type`
|
|
57
|
-
* (`openai` / `qwen-oauth` locally), which is an AUTHENTICATION method, not a
|
|
58
|
-
* model-provider identity; reporting `qwen-oauth` as a provider would be a
|
|
59
|
-
* mislabel. See the note in the owner report.
|
|
60
|
-
*/
|
|
61
|
-
import type { ReadLimits, Snapshot, Source, SourceState } from "../passive-session-reader.js";
|
|
62
|
-
import { type TokenValues } from "./shared.js";
|
|
63
|
-
export declare const QWEN_PROVIDER = "qwen";
|
|
64
|
-
/** One raw line of a qwen chat transcript. Only fields this reader reads. */
|
|
65
|
-
interface QwenLine {
|
|
66
|
-
uuid?: unknown;
|
|
67
|
-
parentUuid?: unknown;
|
|
68
|
-
sessionId?: unknown;
|
|
69
|
-
type?: unknown;
|
|
70
|
-
subtype?: unknown;
|
|
71
|
-
timestamp?: unknown;
|
|
72
|
-
message?: unknown;
|
|
73
|
-
systemPayload?: unknown;
|
|
74
|
-
}
|
|
75
|
-
export interface QwenPassiveReaderOptions {
|
|
76
|
-
/**
|
|
77
|
-
* Discovery roots, in the caller's preferred order. Defaults to the live store
|
|
78
|
-
* plus every retained backup store (see `defaultQwenProjectRoots`).
|
|
79
|
-
*/
|
|
80
|
-
qwenProjectsDirs?: string[];
|
|
81
|
-
maxDiscoveryTraversalVisits?: number;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Default qwen discovery roots.
|
|
85
|
-
*
|
|
86
|
-
* `~/.qwen.bk1/projects` is a RETAINED ACCOUNT HISTORY store, not a redundant
|
|
87
|
-
* copy to skip. Verified on this box: 30 transcripts there against 27 in the
|
|
88
|
-
* live root, with **zero identity overlap** — 0 shared file names, 0 shared
|
|
89
|
-
* in-record `sessionId`s and 0 shared `response_id`s — over disjoint telemetry
|
|
90
|
-
* spans (backup 2026-03-14 → 04-12, live 2026-04-14 → 07-02). Excluding it
|
|
91
|
-
* would silently drop 89 real responses from any cost total.
|
|
92
|
-
*/
|
|
93
|
-
export declare function defaultQwenProjectRoots(): string[];
|
|
94
|
-
/**
|
|
95
|
-
* Map one api_response telemetry event onto the contract's four token slots.
|
|
96
|
-
* Returns null when a required counter is missing/not a non-negative integer, or
|
|
97
|
-
* when any of the three measured invariants fails — the caller turns that into a
|
|
98
|
-
* `partial` snapshot rather than guessing.
|
|
99
|
-
*/
|
|
100
|
-
export declare function qwenTokens(event: Record<string, unknown>): TokenValues | null;
|
|
101
|
-
export declare function readQwen(lines: QwenLine[], source: Source, revision: string, limits: ReadLimits): Snapshot;
|
|
102
|
-
/**
|
|
103
|
-
* Do the records agree with the session id the caller asked for? True when no
|
|
104
|
-
* record names a session at all (nothing to contradict) or when every named
|
|
105
|
-
* session equals `sessionid`. False on any disagreement, including a transcript
|
|
106
|
-
* that names two different sessions.
|
|
107
|
-
*/
|
|
108
|
-
export declare function qwenRecordsMatchSession(lines: QwenLine[], sessionid: string): boolean;
|
|
109
|
-
export declare class QwenPassiveReader {
|
|
110
|
-
/**
|
|
111
|
-
* Resolved discovery roots, in configured order. Exposed so a caller can map a
|
|
112
|
-
* `source_id` back to the root it came from without re-deriving the defaults.
|
|
113
|
-
*/
|
|
114
|
-
readonly roots: readonly string[];
|
|
115
|
-
private readonly maxDiscoveryTraversalVisits;
|
|
116
|
-
constructor(options?: QwenPassiveReaderOptions);
|
|
117
|
-
/**
|
|
118
|
-
* Enumerate up to `cap` sources across EVERY configured root, ordered by real
|
|
119
|
-
* path. `afterPath` continues a previous page; real-path order is total, so one
|
|
120
|
-
* cursor resumes the merged stream correctly.
|
|
121
|
-
*
|
|
122
|
-
* ## Provenance and cross-root identity
|
|
123
|
-
*
|
|
124
|
-
* `source_id` is the file's absolute real path, so it names the root a session
|
|
125
|
-
* came from (`…/.qwen/projects/…` vs `…/.qwen.bk1/projects/…`) without any
|
|
126
|
-
* extra field on the shared `Source` shape. Two sessions that happen to share a
|
|
127
|
-
* `sessionid` across roots therefore stay two DISTINCT sources with distinct
|
|
128
|
-
* `source_id`s, and both are read.
|
|
129
|
-
*
|
|
130
|
-
* This reader performs **no identity dedup** — that is the consumer's job, on
|
|
131
|
-
* real ids. The only collapsing done here is by real path, which removes a file
|
|
132
|
-
* reachable through two configured roots (e.g. one root symlinked inside
|
|
133
|
-
* another); that is the same physical file, never two sessions that merely look
|
|
134
|
-
* alike. Nothing is ever dropped because a similarly-named file exists
|
|
135
|
-
* elsewhere.
|
|
136
|
-
*/
|
|
137
|
-
discover(limits: ReadLimits, cap: number, afterPath?: string | null): Promise<{
|
|
138
|
-
sources: Source[];
|
|
139
|
-
truncated: boolean;
|
|
140
|
-
}>;
|
|
141
|
-
/**
|
|
142
|
-
* A source_id is only ours when it is a real, non-symlink file contained by one
|
|
143
|
-
* of the configured roots AND its basename is the claimed session id. Both
|
|
144
|
-
* checks run before any read.
|
|
145
|
-
*/
|
|
146
|
-
private matches;
|
|
147
|
-
inspect(source: Source, limits: ReadLimits): Promise<SourceState>;
|
|
148
|
-
read(source: Source, revision: string, limits: ReadLimits): Promise<Snapshot>;
|
|
149
|
-
}
|
|
150
|
-
export declare function createQwenPassiveReader(options?: QwenPassiveReaderOptions): QwenPassiveReader;
|
|
151
|
-
export {};
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Self-contained primitives for the per-provider passive readers that live in
|
|
3
|
-
* this directory (agy, qwen).
|
|
4
|
-
*
|
|
5
|
-
* WHY THIS FILE EXISTS: the equivalent helpers inside
|
|
6
|
-
* `src/providers/passive-session-reader.ts` are module-private, and that file is
|
|
7
|
-
* concurrently owned by the discovery-fairness redesign. Re-implementing the
|
|
8
|
-
* handful we need here keeps this slice landable without touching the shared
|
|
9
|
-
* dispatcher. Only the PUBLIC contract types are imported from it, so there is
|
|
10
|
-
* exactly one definition of the wire shape.
|
|
11
|
-
*
|
|
12
|
-
* At wiring time these should be de-duplicated against the dispatcher's own
|
|
13
|
-
* copies (see PASSIVE_EXTRACTION_SEMANTICS below — that constant in particular
|
|
14
|
-
* MUST stay equal to the dispatcher's `EXTRACTION_SEMANTICS`).
|
|
15
|
-
*/
|
|
16
|
-
import type { ExternalIoEntry, PricingFacts, ReadLimits } from "../passive-session-reader.js";
|
|
17
|
-
/**
|
|
18
|
-
* Extraction-semantics tag folded into every revision string.
|
|
19
|
-
*
|
|
20
|
-
* MUST equal `EXTRACTION_SEMANTICS` in `../passive-session-reader.ts` (currently
|
|
21
|
-
* "bx3"). A revision is compared by lmbi as a plain string, so a reader emitting
|
|
22
|
-
* a different tag for the same native bytes would look permanently un-indexed.
|
|
23
|
-
* Bump both together whenever extraction semantics change — this file's real
|
|
24
|
-
* de-dup against the dispatcher's copy is still pending (see file header);
|
|
25
|
-
* until then a bump here is easy to miss, as happened with the bx2→bx3 change.
|
|
26
|
-
*/
|
|
27
|
-
export declare const PASSIVE_EXTRACTION_SEMANTICS = "bx3";
|
|
28
|
-
export type FileDirection = "read" | "written";
|
|
29
|
-
export interface FileObservation {
|
|
30
|
-
path: string;
|
|
31
|
-
bytes: number | null;
|
|
32
|
-
}
|
|
33
|
-
export interface TokenValues {
|
|
34
|
-
input_uncached: number | null;
|
|
35
|
-
input_cached: number | null;
|
|
36
|
-
input_cache_write: number | null;
|
|
37
|
-
output: number | null;
|
|
38
|
-
}
|
|
39
|
-
export declare const EMPTY_TOKENS: TokenValues;
|
|
40
|
-
export declare function record(value: unknown): Record<string, unknown> | null;
|
|
41
|
-
export declare function nonnegativeInteger(value: unknown): number | null;
|
|
42
|
-
/** Non-negative integer counter, or null. Used for pricing_facts counts. */
|
|
43
|
-
export declare function optCount(value: unknown): number | null;
|
|
44
|
-
export declare function canonicalTimestamp(value: unknown): string | null;
|
|
45
|
-
export declare function checkedLimits(limits: ReadLimits): void;
|
|
46
|
-
/**
|
|
47
|
-
* Deterministic UTF-16 code-unit ordering for opaque identifiers/paths. ICU
|
|
48
|
-
* collation can differ across Node builds; two processes must agree on cursor
|
|
49
|
-
* order, so code-unit comparison is the safe primitive.
|
|
50
|
-
*/
|
|
51
|
-
export declare function compareCodeUnits(left: string, right: string): number;
|
|
52
|
-
/**
|
|
53
|
-
* Per-response file observations keyed by (call id, direction, path) — the
|
|
54
|
-
* "smallest honest unit". Two DIFFERENT call ids to the same path stay separate;
|
|
55
|
-
* a replayed record of the SAME call id coalesces (first recorded wins).
|
|
56
|
-
* `bytes` is UTF-8 content size: a number (including 0), or null when the
|
|
57
|
-
* content is genuinely unavailable.
|
|
58
|
-
*/
|
|
59
|
-
export declare class ObservationSet {
|
|
60
|
-
private readonly map;
|
|
61
|
-
record(callId: string, direction: FileDirection, path: unknown, bytes: number | null): void;
|
|
62
|
-
files(direction: FileDirection): FileObservation[];
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Collector for non-file external-I/O entries. Deduplicates by native
|
|
66
|
-
* (id, direction, kind); a MEASURED id-less entry is never deduplicated
|
|
67
|
-
* (content/byte dedup is forbidden by the contract), while id-less null-byte
|
|
68
|
-
* coverage markers may merge (one unknown marker forces NULL as well as two).
|
|
69
|
-
*/
|
|
70
|
-
export declare class ExternalIoSet {
|
|
71
|
-
private readonly map;
|
|
72
|
-
record(entry: ExternalIoEntry): void;
|
|
73
|
-
entries(): ExternalIoEntry[];
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Per-direction aggregate: numeric ONLY when the whole direction is known —
|
|
77
|
-
* `files` non-null with every byte numeric AND every external_io entry in this
|
|
78
|
-
* direction numeric. ANY null contributor → null (never a partial sum posing as
|
|
79
|
-
* a total). A fully-classified direction with no contributors → 0.
|
|
80
|
-
*/
|
|
81
|
-
export declare function aggregateDirection(files: FileObservation[] | null, io: ExternalIoEntry[] | null, direction: FileDirection): number | null;
|
|
82
|
-
/**
|
|
83
|
-
* Build a validated pricing_facts object, dropping fields that are not present
|
|
84
|
-
* as non-negative integers and enforcing the two invariants: reasoning ≤ output,
|
|
85
|
-
* and (5m + 1h) cache-write TTL counts ≤ the known cache-write total. Returns
|
|
86
|
-
* null when nothing valid is present. A recorded 0 is preserved (0 ≠ unknown).
|
|
87
|
-
*/
|
|
88
|
-
export declare function buildPricingFacts(raw: {
|
|
89
|
-
cacheWrite5m?: unknown;
|
|
90
|
-
cacheWrite1h?: unknown;
|
|
91
|
-
reasoning?: unknown;
|
|
92
|
-
webSearch?: unknown;
|
|
93
|
-
webFetch?: unknown;
|
|
94
|
-
}, outputTokens: number | null, cacheWriteTotal: number | null): PricingFacts | null;
|
|
95
|
-
export declare function isInternalControlTool(name: unknown): boolean;
|
|
96
|
-
/** Record an opaque/uncertified tool call as unknown in BOTH directions. */
|
|
97
|
-
export declare function recordUnattributedBoth(io: ExternalIoSet, callId: string | null): void;
|
|
98
|
-
/**
|
|
99
|
-
* UTF-8 byte size of the content WRITTEN by a write call, taken from the call's
|
|
100
|
-
* OWN input (never the file on disk). Returns 0 for a genuinely empty write,
|
|
101
|
-
* null when no content field is present.
|
|
102
|
-
*/
|
|
103
|
-
export declare function writeInputBytes(input: unknown): number | null;
|
|
104
|
-
/**
|
|
105
|
-
* Resolve `path` to its real location and require it to be a regular,
|
|
106
|
-
* non-symlink file contained by one of `roots`. Returns the real path, or null.
|
|
107
|
-
*/
|
|
108
|
-
export declare function containedRealFile(path: string, roots: string[]): Promise<string | null>;
|
|
109
|
-
/**
|
|
110
|
-
* Read a JSONL file within the byte budget and hash its exact native bytes.
|
|
111
|
-
* Returns null when the file is missing, oversized, or changed underneath the
|
|
112
|
-
* read (dev/ino/size/mtime re-checked after) — a torn read is never reported as
|
|
113
|
-
* a clean revision.
|
|
114
|
-
*/
|
|
115
|
-
export declare function jsonlRevision(path: string, limits: ReadLimits): Promise<{
|
|
116
|
-
revision: string;
|
|
117
|
-
data: Buffer;
|
|
118
|
-
} | null>;
|
|
119
|
-
/**
|
|
120
|
-
* Parse a complete JSONL buffer. Returns null when the file does not end on a
|
|
121
|
-
* record boundary (a live append caught mid-line) or any line is not a JSON
|
|
122
|
-
* object — a torn/partial file is never silently treated as complete.
|
|
123
|
-
*/
|
|
124
|
-
export declare function parseJsonl<T>(data: Buffer, limits: ReadLimits): T[] | null;
|
|
125
|
-
/** Minimal read-only `node:sqlite` surface used by the sqlite-backed readers. */
|
|
126
|
-
export interface SqliteStatement {
|
|
127
|
-
all(...params: unknown[]): unknown[];
|
|
128
|
-
get(...params: unknown[]): unknown;
|
|
129
|
-
}
|
|
130
|
-
export interface SqliteDatabase {
|
|
131
|
-
close(): void;
|
|
132
|
-
exec(sql: string): void;
|
|
133
|
-
prepare(sql: string): SqliteStatement;
|
|
134
|
-
}
|
|
135
|
-
export type SqliteDatabaseConstructor = new (path: string, options?: {
|
|
136
|
-
open?: boolean;
|
|
137
|
-
readOnly?: boolean;
|
|
138
|
-
}) => SqliteDatabase;
|