@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,120 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transport-agnostic "hold stdin open past the turn's result while the session's
|
|
3
|
-
* own dispatched work is still outstanding" mechanism. Extracted verbatim from
|
|
4
|
-
* stream-json.ts (task #68) so every transport — stream-json AND acp — shares
|
|
5
|
-
* ONE copy of this subtle concurrency code instead of re-deriving it.
|
|
6
|
-
*
|
|
7
|
-
* The ALGORITHM lives here once; each transport supplies its own {@link
|
|
8
|
-
* HoldOpenHooks} over its own child/abort/event state. Behavior is identical to
|
|
9
|
-
* the original inline stream-json implementation (its full test suite is the
|
|
10
|
-
* regression proof).
|
|
11
|
-
*/
|
|
12
|
-
export type HoldOpenReleaseReason = "cleared" | "max-hold" | "check-error" | "child-exited" | "aborted";
|
|
13
|
-
export interface HoldOpenOptions {
|
|
14
|
-
/**
|
|
15
|
-
* True while the session being run still has outstanding dispatched work
|
|
16
|
-
* that must survive this process. Checked once on the first result event
|
|
17
|
-
* (fast path: false → close immediately), then every `pollMs` while true.
|
|
18
|
-
* A thrown/rejected check counts as "no outstanding work" — the check
|
|
19
|
-
* must never be able to wedge the turn open. A check that never settles
|
|
20
|
-
* cannot wedge it either: each call races the remaining `maxHoldMs`
|
|
21
|
-
* budget and the abort signal, so the ceiling is a real hard bound.
|
|
22
|
-
*/
|
|
23
|
-
hasOutstandingWork: () => Promise<boolean> | boolean;
|
|
24
|
-
/** Poll interval while work is outstanding. Default 2000ms. */
|
|
25
|
-
pollMs?: number;
|
|
26
|
-
/**
|
|
27
|
-
* Quiescence window required AFTER a hold before the close proceeds: the
|
|
28
|
-
* check must keep reporting "no outstanding work" for this long. Measured
|
|
29
|
-
* from the LATER of "the work cleared" and "the child last emitted an event",
|
|
30
|
-
* and never expires while a turn is mid-flight. Covers the dispatched work's
|
|
31
|
-
* lease-release → process-exit → completion-notification hand-off, which a
|
|
32
|
-
* window measured from the lease alone would close stdin in the middle of.
|
|
33
|
-
* Deliberately applies ONLY after an actual hold. Default 5000ms; 0 disables.
|
|
34
|
-
*/
|
|
35
|
-
settleMs?: number;
|
|
36
|
-
/**
|
|
37
|
-
* Hard ceiling on how long the close may be deferred — last-resort insurance
|
|
38
|
-
* against a row that stays "live" forever. Callers default this to the
|
|
39
|
-
* agent_inflight TTL. On expiry the close proceeds (today's behavior), never
|
|
40
|
-
* a hang. Default 8 hours.
|
|
41
|
-
*/
|
|
42
|
-
maxHoldMs?: number;
|
|
43
|
-
/**
|
|
44
|
-
* Short, bounded window to wait for the FIRST agent_inflight lease to appear
|
|
45
|
-
* when a background job was launched this turn (see
|
|
46
|
-
* HoldOpenHooks.wasBackgroundJobLaunched) but no lease has registered yet — a
|
|
47
|
-
* nested `lmctl chat` has real startup latency before it takes its lease.
|
|
48
|
-
* Only ever applies before any hold, and only when a background job was
|
|
49
|
-
* observed; short-circuits the instant the lease appears (zero cost to a
|
|
50
|
-
* fast-registering dispatch). Distinct from `maxHoldMs`: this bounds ONLY the
|
|
51
|
-
* first-appearance race, not a held wait. Default 1000ms.
|
|
52
|
-
*/
|
|
53
|
-
backgroundGraceMs?: number;
|
|
54
|
-
/** Called once when the close is first deferred (for logging). */
|
|
55
|
-
onHold?: () => void;
|
|
56
|
-
/**
|
|
57
|
-
* Called EXACTLY ONCE per turn once the hold path has finished, including the
|
|
58
|
-
* fast path (`held: false`, reason `"cleared"`). Callers use it both to log
|
|
59
|
-
* and to dispose resources the check acquired, so it must not be conditional
|
|
60
|
-
* on having actually held — decide what is worth logging from `held`/`reason`.
|
|
61
|
-
*/
|
|
62
|
-
onRelease?: (info: {
|
|
63
|
-
elapsedMs: number;
|
|
64
|
-
held: boolean;
|
|
65
|
-
reason: HoldOpenReleaseReason;
|
|
66
|
-
}) => void;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Per-transport state the hold loop reads. Each transport wires these to its own
|
|
70
|
-
* abort flag, child-exit flag, turn-in-flight tracking, last-activity timestamp,
|
|
71
|
-
* and stdin-close primitive.
|
|
72
|
-
*/
|
|
73
|
-
export interface HoldOpenHooks {
|
|
74
|
-
/** The turn was aborted (caller signalled). */
|
|
75
|
-
isAborted: () => boolean;
|
|
76
|
-
/** The child process has already exited on its own. */
|
|
77
|
-
hasChildExited: () => boolean;
|
|
78
|
-
/** A turn is currently mid-flight (events seen since the last result). The
|
|
79
|
-
* settle window never expires while this is true. */
|
|
80
|
-
isTurnInFlight: () => boolean;
|
|
81
|
-
/** Epoch ms of the child's last emitted event/notification. */
|
|
82
|
-
lastEventAtMs: () => number;
|
|
83
|
-
/** Close the child's stdin (idempotent / harmless if already gone). */
|
|
84
|
-
closeStdin: () => void;
|
|
85
|
-
/** Abort signal, raced inside each never-settling check. */
|
|
86
|
-
signal?: AbortSignal;
|
|
87
|
-
/** Provider label for the max-hold errorLog + verbose logs. */
|
|
88
|
-
label: string;
|
|
89
|
-
/**
|
|
90
|
-
* True once a background job (e.g. an ACP `run_in_background` tool call) was
|
|
91
|
-
* observed launching this turn, and stays true for the rest of the turn. When
|
|
92
|
-
* true, the first "nothing outstanding" result gets a short grace window for
|
|
93
|
-
* the nested lease to register instead of the zero-latency fast close. Absent
|
|
94
|
-
* (stream-json, and any turn with no background launch) ⇒ treated as false ⇒
|
|
95
|
-
* the fast path is byte-for-byte unchanged.
|
|
96
|
-
*/
|
|
97
|
-
wasBackgroundJobLaunched?: () => boolean;
|
|
98
|
-
}
|
|
99
|
-
/** Shared with the result-grace-timeout fallback (transports/stream-json.ts)
|
|
100
|
-
* so the two independent uses of `hasOutstandingWork` can't drift apart. */
|
|
101
|
-
export declare const DEFAULT_MAX_HOLD_MS: number;
|
|
102
|
-
/** Sentinel for "the check did not settle within its allotted budget". */
|
|
103
|
-
declare const CHECK_TIMED_OUT: unique symbol;
|
|
104
|
-
/**
|
|
105
|
-
* Await `check` but never longer than `budgetMs`, and never past an abort.
|
|
106
|
-
* Without this a `hasOutstandingWork` that never settles would park the hold
|
|
107
|
-
* loop forever — `maxHoldMs` is only consulted between awaits, so it would not
|
|
108
|
-
* be the hard ceiling it advertises. Exported for the result-grace-timeout
|
|
109
|
-
* fallback (transports/stream-json.ts), which awaits the SAME
|
|
110
|
-
* `hasOutstandingWork` check and needs the identical never-wedge guarantee.
|
|
111
|
-
*/
|
|
112
|
-
export declare function settleCheckWithin(check: Promise<boolean> | boolean, budgetMs: number, signal: AbortSignal | undefined): Promise<boolean | typeof CHECK_TIMED_OUT>;
|
|
113
|
-
/**
|
|
114
|
-
* Schedule the turn's stdin close, optionally deferred while the session's own
|
|
115
|
-
* dispatched work is outstanding. Without `hold` this is the exact pre-existing
|
|
116
|
-
* synchronous `closeStdin()` — no promise, no extra tick. Call AT MOST ONCE per
|
|
117
|
-
* turn (callers guard their own first-result transition).
|
|
118
|
-
*/
|
|
119
|
-
export declare function scheduleHoldOpenClose(hold: HoldOpenOptions | undefined, hooks: HoldOpenHooks): void;
|
|
120
|
-
export {};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transport manager — selects and creates transport handles.
|
|
3
|
-
*
|
|
4
|
-
* Replaces the provider-specific if/else branching in work-cmd.ts
|
|
5
|
-
* with a single unified interface.
|
|
6
|
-
*/
|
|
7
|
-
import type { TransportHandle, TransportType, TransportOptions } from "./types.js";
|
|
8
|
-
import type { UserConfig } from "../config/types.js";
|
|
9
|
-
export declare function selectTransport(tool: string): TransportType;
|
|
10
|
-
export declare function transportLabel(type: TransportType, tool: string): string;
|
|
11
|
-
export interface CreateTransportOpts extends TransportOptions {
|
|
12
|
-
/** User config — needed for one-shot fallback command building */
|
|
13
|
-
userConfig?: UserConfig;
|
|
14
|
-
/** Profile override — for one-shot */
|
|
15
|
-
profile?: string;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Create a transport handle for the given tool.
|
|
19
|
-
* Automatically selects the best transport.
|
|
20
|
-
*/
|
|
21
|
-
export declare function createTransport(opts: CreateTransportOpts): TransportHandle;
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Claude Code stream-json transport.
|
|
3
|
-
*
|
|
4
|
-
* Spawns `claude -p --input-format stream-json --output-format stream-json`
|
|
5
|
-
* and communicates via NDJSON on stdin/stdout. The process stays alive for
|
|
6
|
-
* the full conversation — no one-shot timeout.
|
|
7
|
-
*
|
|
8
|
-
* Protocol (reverse-engineered from Claude Agent SDK):
|
|
9
|
-
* stdin: {"type":"user","message":{"role":"user","content":"..."}}
|
|
10
|
-
* stdout: {"type":"system","subtype":"init",...}
|
|
11
|
-
* {"type":"assistant","message":{...},...}
|
|
12
|
-
* {"type":"result","subtype":"success","result":"...","session_id":"..."}
|
|
13
|
-
*/
|
|
14
|
-
import { type PermissionMode } from "../yolo-contract.js";
|
|
15
|
-
import { type HoldOpenOptions } from "./hold-open.js";
|
|
16
|
-
export type { HoldOpenReleaseReason } from "./hold-open.js";
|
|
17
|
-
export type StreamJsonHoldOpenOptions = HoldOpenOptions;
|
|
18
|
-
import { type StreamJsonResult } from "../parsers/stream-json.js";
|
|
19
|
-
export { aggregateResultEvents, createStreamJsonProcessor, joinResultTurns, supportsStreamJson, } from "../parsers/stream-json.js";
|
|
20
|
-
export type { AggregatedResultEvents, StreamJsonProcessor, StreamJsonResult, } from "../parsers/stream-json.js";
|
|
21
|
-
/**
|
|
22
|
-
* Deferred stdin-close contract (BUG-chat-client-death-interrupts-receiver-
|
|
23
|
-
* live-session, "root cause pinned exactly" section).
|
|
24
|
-
*
|
|
25
|
-
* Closing `child.stdin` on the first `result` event makes `claude -p` exit
|
|
26
|
-
* the moment its visible turn text is done — with zero regard for any
|
|
27
|
-
* `run_in_background` dispatches the session fired during that turn. Those
|
|
28
|
-
* children die with the exiting host process and their completion
|
|
29
|
-
* notifications are never delivered. The durable signal for "this session
|
|
30
|
-
* still has outstanding dispatched work" is an `agent_inflight` row whose
|
|
31
|
-
* SENDER is this session's own identity, held by a live pid — state lmctl
|
|
32
|
-
* already owns.
|
|
33
|
-
*
|
|
34
|
-
* The transport stays DB-free: the caller supplies `hasOutstandingWork` as
|
|
35
|
-
* an opaque callback (queue-delivery builds it from the receiver identity +
|
|
36
|
-
* DAL). When the option is absent, the close is the same synchronous
|
|
37
|
-
* `child.stdin.end()` as before — zero added latency. When present, ONE
|
|
38
|
-
* check runs on the first result event; only if it reports outstanding work
|
|
39
|
-
* does the transport enter a poll loop.
|
|
40
|
-
*/
|
|
41
|
-
export interface StreamJsonOptions {
|
|
42
|
-
sessionId?: string;
|
|
43
|
-
cwd: string;
|
|
44
|
-
env?: NodeJS.ProcessEnv;
|
|
45
|
-
/** Called for each raw NDJSON event from stdout (for logging/debugging) */
|
|
46
|
-
onEvent?: (event: Record<string, unknown>) => void;
|
|
47
|
-
/** Called when streaming text arrives (for live output) */
|
|
48
|
-
onText?: (text: string) => void;
|
|
49
|
-
/**
|
|
50
|
-
* Permission mode for this turn.
|
|
51
|
-
*
|
|
52
|
-
* - "yolo" (default) — historical behavior; append the provider's
|
|
53
|
-
* permission-bypass flag (`--dangerously-skip-permissions` for
|
|
54
|
-
* claude, `--approval-mode yolo` for qwen). Required for
|
|
55
|
-
* non-interactive runs; if the provider asks for a permission
|
|
56
|
-
* mid-turn lmctl has no UI to forward the request.
|
|
57
|
-
* - "plan" — append the provider's plan-mode flag
|
|
58
|
-
* instead (`--permission-mode plan` for claude,
|
|
59
|
-
* `--approval-mode plan` for qwen). The provider should refuse
|
|
60
|
-
* workspace-modifying tool calls in this mode. Use for research /
|
|
61
|
-
* exploration sessions.
|
|
62
|
-
*
|
|
63
|
-
* Default is "yolo" so callers that omit the field preserve the
|
|
64
|
-
* pre-existing argv shape exactly.
|
|
65
|
-
*/
|
|
66
|
-
permissionMode?: PermissionMode;
|
|
67
|
-
/** Tool name — determines the binary and permission flags */
|
|
68
|
-
tool?: string;
|
|
69
|
-
/**
|
|
70
|
-
* Override the spawned binary path. When set, this exact path is
|
|
71
|
-
* spawned instead of looking up `tool` in TOOL_BINARY. Permission
|
|
72
|
-
* flags are still resolved via `tool`. Used for troubleshooting
|
|
73
|
-
* with custom Claude Code builds. (Task 63 fix 3.)
|
|
74
|
-
*/
|
|
75
|
-
binaryPath?: string;
|
|
76
|
-
/** Abort signal — kills the provider process when aborted */
|
|
77
|
-
signal?: AbortSignal;
|
|
78
|
-
/** Provider-specific model name, appended as `--model <name>`. */
|
|
79
|
-
model?: string;
|
|
80
|
-
/**
|
|
81
|
-
* When set, the first-result stdin close is deferred while the caller
|
|
82
|
-
* reports outstanding dispatched work. See {@link StreamJsonHoldOpenOptions}.
|
|
83
|
-
*/
|
|
84
|
-
holdOpen?: StreamJsonHoldOpenOptions;
|
|
85
|
-
}
|
|
86
|
-
export declare function formatProviderNoResultError(params: {
|
|
87
|
-
tool: string;
|
|
88
|
-
exitCode: number | null;
|
|
89
|
-
stderr: string;
|
|
90
|
-
}): string;
|
|
91
|
-
/**
|
|
92
|
-
* Send a prompt via the stream-json protocol (Claude Code / Qwen).
|
|
93
|
-
* Returns the final result text when the turn completes.
|
|
94
|
-
*/
|
|
95
|
-
export declare function sendPrompt(prompt: string, opts: StreamJsonOptions): Promise<StreamJsonResult>;
|
|
96
|
-
export interface StreamJsonSessionOptions extends StreamJsonOptions {
|
|
97
|
-
/**
|
|
98
|
-
* Shutdown cap: how long close() waits for a natural exit after stdin
|
|
99
|
-
* EOF before escalating to the (internally bounded) terminate ladder.
|
|
100
|
-
* Also bounds the open-phase wait for the provider's init event.
|
|
101
|
-
* Default 2000ms (close) / 30000ms (init).
|
|
102
|
-
*/
|
|
103
|
-
closeTimeoutMs?: number;
|
|
104
|
-
/**
|
|
105
|
-
* Override the session-file roots used by the bundle identity check.
|
|
106
|
-
* Default: the provider's standard projects dir under the user home
|
|
107
|
-
* (`~/.claude/projects`, `~/.qwen/projects`). Exists for tests and
|
|
108
|
-
* custom provider homes.
|
|
109
|
-
*/
|
|
110
|
-
sessionFileRoots?: string[];
|
|
111
|
-
}
|
|
112
|
-
export interface StreamJsonSessionTurnOptions {
|
|
113
|
-
onText?: (text: string) => void;
|
|
114
|
-
onEvent?: (event: Record<string, unknown>) => void;
|
|
115
|
-
/**
|
|
116
|
-
* Abort THIS turn. stream-json has no verified cancel verb, so
|
|
117
|
-
* cancellation is TERMINAL for the bundle: the turn rejects with
|
|
118
|
-
* `Error("Aborted")` and the child gets the same graceful-shutdown
|
|
119
|
-
* ladder a one-shot abort gets. Later turns fail fast.
|
|
120
|
-
*/
|
|
121
|
-
signal?: AbortSignal;
|
|
122
|
-
}
|
|
123
|
-
export interface StreamJsonSessionTurnResult {
|
|
124
|
-
result: string;
|
|
125
|
-
sessionId: string;
|
|
126
|
-
durationMs: number;
|
|
127
|
-
numTurns: number;
|
|
128
|
-
/** Stall-grace fallback marker (text_done), same convention as
|
|
129
|
-
* StreamJsonResult.warnings. */
|
|
130
|
-
warnings?: string[];
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* An open stream-json bundle session: one provider process serving many
|
|
134
|
-
* prompts. The lifecycle contract is in src/providers/bundle.ts; the
|
|
135
|
-
* transport-specific decisions:
|
|
136
|
-
*
|
|
137
|
-
* - Per-turn completion boundary: the turn's `result` event. A fresh
|
|
138
|
-
* StreamJsonProcessor per turn, so accumulated text/results never leak
|
|
139
|
-
* across turns; events arriving with no turn in flight update activity
|
|
140
|
-
* bookkeeping only (never accumulated, never armed timers).
|
|
141
|
-
* - The stall-grace machinery (text_done / tool_use_silence timers) is
|
|
142
|
-
* retained and re-armed per turn; a text_done fire resolves the turn
|
|
143
|
-
* from accumulated text with a warning exactly like the one-shot path
|
|
144
|
-
* (and ends the process, so the bundle is dead afterwards).
|
|
145
|
-
* - Identity: the session FILE's header is checked at open (requireResume
|
|
146
|
-
* parity — no file, no bundle) and re-checked before every sendTurn
|
|
147
|
-
* (catches an external re-seed mid-bundle); the provider's init event
|
|
148
|
-
* must agree with the requested session id.
|
|
149
|
-
* - Cancellation is terminal (no verified cancel verb in stream-json).
|
|
150
|
-
*/
|
|
151
|
-
export interface StreamJsonSession {
|
|
152
|
-
readonly tool: string;
|
|
153
|
-
readonly sessionId: string;
|
|
154
|
-
readonly completedTurns: number;
|
|
155
|
-
sendTurn(prompt: string, opts?: StreamJsonSessionTurnOptions): Promise<StreamJsonSessionTurnResult>;
|
|
156
|
-
close(): Promise<void>;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Open a persistent stream-json session (`claude`/`qwen`). See
|
|
160
|
-
* {@link StreamJsonSession} for the contract.
|
|
161
|
-
*/
|
|
162
|
-
export declare function openStreamJsonSession(opts: StreamJsonSessionOptions): Promise<StreamJsonSession>;
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared transport interfaces.
|
|
3
|
-
*
|
|
4
|
-
* All provider transports implement TransportHandle so the caller
|
|
5
|
-
* (work-cmd, serve) doesn't need provider-specific branching.
|
|
6
|
-
*/
|
|
7
|
-
export type TransportType = "stream-json" | "codex-app-server" | "acp" | "one-shot";
|
|
8
|
-
export interface TurnResult {
|
|
9
|
-
text: string;
|
|
10
|
-
sessionId: string;
|
|
11
|
-
durationMs: number;
|
|
12
|
-
stopReason?: string;
|
|
13
|
-
numTurns?: number;
|
|
14
|
-
}
|
|
15
|
-
export interface TransportOptions {
|
|
16
|
-
sessionId?: string;
|
|
17
|
-
cwd: string;
|
|
18
|
-
env?: NodeJS.ProcessEnv;
|
|
19
|
-
tool: string;
|
|
20
|
-
/**
|
|
21
|
-
* If true, the transport must resume the given sessionId or fail.
|
|
22
|
-
* If false, a failed resume may fall back to a new session.
|
|
23
|
-
* Set to true for `--session`, false for `--team` or new sessions.
|
|
24
|
-
*/
|
|
25
|
-
requireResume?: boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Called with each text delta as it arrives from the provider.
|
|
28
|
-
* Used by the SSE streaming endpoint to push incremental text to the browser.
|
|
29
|
-
*/
|
|
30
|
-
onDelta?: (text: string) => void;
|
|
31
|
-
/**
|
|
32
|
-
* Signal to abort/cancel the turn. When aborted, the transport should
|
|
33
|
-
* kill the provider process and reject the sendTurn promise.
|
|
34
|
-
*/
|
|
35
|
-
signal?: AbortSignal;
|
|
36
|
-
/** Provider-specific model override, when the selected transport supports it. */
|
|
37
|
-
model?: string;
|
|
38
|
-
/** Provider-specific effort / variant override, when the selected transport supports it. */
|
|
39
|
-
effort?: string;
|
|
40
|
-
/** Teamfile alias, when provider setup needs alias-specific behavior. */
|
|
41
|
-
alias?: string;
|
|
42
|
-
/** Provider binary override. */
|
|
43
|
-
progPath?: string;
|
|
44
|
-
/**
|
|
45
|
-
* Permission mode — `"yolo"` (default) or `"plan"`. The transport
|
|
46
|
-
* substitutes the per-provider argv / JSON-RPC params accordingly.
|
|
47
|
-
* See `src/providers/yolo-contract.ts`.
|
|
48
|
-
*/
|
|
49
|
-
permissionMode?: import("../yolo-contract.js").PermissionMode;
|
|
50
|
-
}
|
|
51
|
-
export interface TransportHandle {
|
|
52
|
-
readonly type: TransportType;
|
|
53
|
-
readonly tool: string;
|
|
54
|
-
/** Send a prompt and get the response. Manages the full lifecycle internally. */
|
|
55
|
-
sendTurn(prompt: string): Promise<TurnResult>;
|
|
56
|
-
}
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
export type ProviderName = "claude" | "codex" | "gemini" | "copilot" | "opencode" | "lmplayer" | "qwen" | "agy" | "kimi" | "dsh" | "hermes" | "pi" | "ClaudeMock";
|
|
2
|
-
export interface SessionTokenUsage {
|
|
3
|
-
inputTokens?: number;
|
|
4
|
-
cachedInputTokens?: number;
|
|
5
|
-
cacheWriteInputTokens?: number;
|
|
6
|
-
outputTokens?: number;
|
|
7
|
-
reasoningOutputTokens?: number;
|
|
8
|
-
totalTokens?: number;
|
|
9
|
-
}
|
|
10
|
-
export interface SessionSummary {
|
|
11
|
-
provider: ProviderName;
|
|
12
|
-
sessionId: string;
|
|
13
|
-
slug?: string;
|
|
14
|
-
cwd: string;
|
|
15
|
-
createdAt: Date;
|
|
16
|
-
modifiedAt: Date;
|
|
17
|
-
model?: string;
|
|
18
|
-
cliVersion?: string;
|
|
19
|
-
startCommand?: string;
|
|
20
|
-
firstUserMessage?: string;
|
|
21
|
-
lastUserMessage?: string;
|
|
22
|
-
messageCount: number;
|
|
23
|
-
filePath: string;
|
|
24
|
-
filePaths?: string[];
|
|
25
|
-
totalInputTokens?: number;
|
|
26
|
-
totalCachedInputTokens?: number;
|
|
27
|
-
totalCacheWriteInputTokens?: number;
|
|
28
|
-
totalOutputTokens?: number;
|
|
29
|
-
totalReasoningOutputTokens?: number;
|
|
30
|
-
lastInputTokens?: number;
|
|
31
|
-
lastTokenUsage?: SessionTokenUsage;
|
|
32
|
-
modelContextWindow?: number;
|
|
33
|
-
}
|
|
34
|
-
export interface SessionDetail extends SessionSummary {
|
|
35
|
-
/** Native external prompt text, excluding injected context and internal rows.
|
|
36
|
-
* When present (even empty), authoritative over user-role transcript messages. */
|
|
37
|
-
userPrompts?: string[];
|
|
38
|
-
gitBranch?: string;
|
|
39
|
-
turnStatus?: "in_progress" | "complete" | "aborted";
|
|
40
|
-
messages: ConversationMessage[];
|
|
41
|
-
}
|
|
42
|
-
export type MessageRole = "user" | "assistant" | "system" | "tool_use" | "tool_result" | "thinking";
|
|
43
|
-
export interface ConversationMessage {
|
|
44
|
-
role: MessageRole;
|
|
45
|
-
timestamp: Date;
|
|
46
|
-
content: string;
|
|
47
|
-
toolName?: string;
|
|
48
|
-
toolInput?: string;
|
|
49
|
-
toolInputData?: Record<string, unknown>;
|
|
50
|
-
toolCallId?: string;
|
|
51
|
-
backgroundTaskId?: string;
|
|
52
|
-
toolDetailedContent?: string;
|
|
53
|
-
stopReason?: string;
|
|
54
|
-
model?: string;
|
|
55
|
-
}
|
|
56
|
-
export interface WatchPathInfo {
|
|
57
|
-
directory: string;
|
|
58
|
-
filePattern: RegExp;
|
|
59
|
-
}
|
|
60
|
-
export interface WatchTarget {
|
|
61
|
-
provider: ProviderName;
|
|
62
|
-
directory: string;
|
|
63
|
-
recursive: boolean;
|
|
64
|
-
filePattern?: RegExp;
|
|
65
|
-
}
|
|
66
|
-
export interface SessionProvider {
|
|
67
|
-
name: ProviderName;
|
|
68
|
-
discoverSessions(): Promise<SessionSummary[]>;
|
|
69
|
-
loadSession(sessionId: string): Promise<SessionDetail | null>;
|
|
70
|
-
resolveSessionPath(sessionId: string): Promise<string | null>;
|
|
71
|
-
deleteSession(sessionId: string): Promise<boolean>;
|
|
72
|
-
getWatchPaths?(): WatchPathInfo[];
|
|
73
|
-
}
|
|
74
|
-
export interface DeleteOptions {
|
|
75
|
-
provider?: ProviderName;
|
|
76
|
-
force?: boolean;
|
|
77
|
-
json?: boolean;
|
|
78
|
-
}
|
|
79
|
-
export interface MutationResult {
|
|
80
|
-
success: boolean;
|
|
81
|
-
sessionId: string;
|
|
82
|
-
provider?: ProviderName;
|
|
83
|
-
filePath: string;
|
|
84
|
-
error?: string;
|
|
85
|
-
}
|
|
86
|
-
export interface ListOptions {
|
|
87
|
-
provider?: ProviderName;
|
|
88
|
-
workspace?: string;
|
|
89
|
-
limit?: number;
|
|
90
|
-
from?: string;
|
|
91
|
-
to?: string;
|
|
92
|
-
json?: boolean;
|
|
93
|
-
}
|
|
94
|
-
export interface ViewOptions {
|
|
95
|
-
provider?: ProviderName;
|
|
96
|
-
detailed?: boolean;
|
|
97
|
-
noTools?: boolean;
|
|
98
|
-
noThinking?: boolean;
|
|
99
|
-
toolDetails?: boolean;
|
|
100
|
-
json?: boolean;
|
|
101
|
-
}
|
|
102
|
-
export interface ExtractOptions {
|
|
103
|
-
provider?: ProviderName;
|
|
104
|
-
detailed?: boolean;
|
|
105
|
-
last?: number;
|
|
106
|
-
}
|
|
107
|
-
export interface DumpMessage {
|
|
108
|
-
role: "user" | "assistant";
|
|
109
|
-
content: string;
|
|
110
|
-
}
|
|
111
|
-
export interface DumpResult {
|
|
112
|
-
success: boolean;
|
|
113
|
-
messages: DumpMessage[];
|
|
114
|
-
error?: string;
|
|
115
|
-
}
|
|
116
|
-
export interface DumpOptions {
|
|
117
|
-
provider?: ProviderName;
|
|
118
|
-
format?: "text" | "bundle";
|
|
119
|
-
}
|
|
120
|
-
export type LoadMode = "patch" | "transplant";
|
|
121
|
-
export interface LoadOptions {
|
|
122
|
-
provider?: ProviderName;
|
|
123
|
-
force?: boolean;
|
|
124
|
-
dryRun?: boolean;
|
|
125
|
-
preserve?: boolean;
|
|
126
|
-
mode?: LoadMode;
|
|
127
|
-
}
|
|
128
|
-
export interface EditableEntry {
|
|
129
|
-
role: "user" | "assistant";
|
|
130
|
-
recordIndex: number;
|
|
131
|
-
contentPath: string;
|
|
132
|
-
identityKey: string;
|
|
133
|
-
content: string;
|
|
134
|
-
}
|
|
135
|
-
export interface SessionBundle {
|
|
136
|
-
schemaVersion: 2;
|
|
137
|
-
provider: ProviderName;
|
|
138
|
-
toolVersion: string;
|
|
139
|
-
source: {
|
|
140
|
-
sessionId: string;
|
|
141
|
-
cwd: string;
|
|
142
|
-
dumpedAt: string;
|
|
143
|
-
};
|
|
144
|
-
raw: {
|
|
145
|
-
type: "jsonl" | "json";
|
|
146
|
-
records: string[];
|
|
147
|
-
};
|
|
148
|
-
editable: EditableEntry[];
|
|
149
|
-
}
|
|
150
|
-
export interface BundleResult {
|
|
151
|
-
success: boolean;
|
|
152
|
-
bundle?: SessionBundle;
|
|
153
|
-
error?: string;
|
|
154
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* YOLO contract — every provider transport spawns its CLI in
|
|
3
|
-
* full-auto / permission-bypass mode. Hardcoded; not user-configurable.
|
|
4
|
-
*
|
|
5
|
-
* Why this is non-negotiable: lmctl drives provider sessions
|
|
6
|
-
* non-interactively. If the provider asks for a tool-use permission,
|
|
7
|
-
* there is no human at the prompt and lmctl has no UI for forwarding
|
|
8
|
-
* the request. The session hangs until the per-tool internal timeout
|
|
9
|
-
* fires (could be 30+ minutes), with no recovery path.
|
|
10
|
-
*
|
|
11
|
-
* The opencode06 incident exposed this concretely: opencode was
|
|
12
|
-
* spawned without any permission-bypass flag, sent
|
|
13
|
-
* `session/request_permission` for its first bash tool call, lmctl
|
|
14
|
-
* silently dropped the request, opencode hung for 42+ minutes. See
|
|
15
|
-
* `commit 1cc1766` for the safety-net (reply with -32601) and this
|
|
16
|
-
* module for the upstream fix (force YOLO so the request is never
|
|
17
|
-
* sent in the first place).
|
|
18
|
-
*
|
|
19
|
-
* Users who want permission prompts should use the provider's CLI
|
|
20
|
-
* directly, not through lmctl. That's a deliberate scope boundary.
|
|
21
|
-
*
|
|
22
|
-
* ## Coverage
|
|
23
|
-
*
|
|
24
|
-
* Argv-based providers — flag must appear in the spawn argv:
|
|
25
|
-
* claude → --dangerously-skip-permissions (stream-json transport)
|
|
26
|
-
* qwen → --approval-mode yolo (stream-json transport)
|
|
27
|
-
* gemini → -y (acp transport)
|
|
28
|
-
* copilot → --yolo (acp transport)
|
|
29
|
-
* agy → --dangerously-skip-permissions (one-shot print transport)
|
|
30
|
-
* lmplayer → --dangerously-skip-permissions (one-shot run transport)
|
|
31
|
-
* opencode → --dangerously-skip-permissions (acp transport)
|
|
32
|
-
*
|
|
33
|
-
* pi (NOT argv-based): pi has no tool-permission prompts by design —
|
|
34
|
-
* there is no approval UI to hang on, so no bypass flag exists or is
|
|
35
|
-
* needed. Routed through PROTOCOL_LEVEL_YOLO like codex so
|
|
36
|
-
* assertYoloFlagPresent documents the stance at every spawn.
|
|
37
|
-
*
|
|
38
|
-
* Codex (NOT argv-based): the `codex app-server` JSON-RPC speaks YOLO
|
|
39
|
-
* via per-call `thread/start` / `thread/resume` params:
|
|
40
|
-
* approvalPolicy: "never"
|
|
41
|
-
* sandbox: "danger-full-access"
|
|
42
|
-
* These are asserted in `codex-app-server.ts` (see `sendCodexPrompt`),
|
|
43
|
-
* but are NOT covered by `assertYoloFlagPresent` here because the
|
|
44
|
-
* argv carries no flag — codex's YOLO is wire-protocol-level.
|
|
45
|
-
*/
|
|
46
|
-
/**
|
|
47
|
-
* Required YOLO flag(s) per argv-based provider. Each entry is a
|
|
48
|
-
* sequence of consecutive argv tokens (e.g. `["--approval-mode",
|
|
49
|
-
* "yolo"]`) that must appear in the spawn args for the contract to
|
|
50
|
-
* hold. Single-token entries (e.g. `["--yolo"]`) just check for the
|
|
51
|
-
* one token's presence.
|
|
52
|
-
*
|
|
53
|
-
* **Note: opencode is NOT here.** Opencode's ACP mode rejects every
|
|
54
|
-
* permission-bypass argv flag (verified empirically — `--dangerously-
|
|
55
|
-
* skip-permissions` is a `run`-subcommand-only flag, not recognized
|
|
56
|
-
* by `opencode acp`). Opencode's YOLO is satisfied via the
|
|
57
|
-
* `permission: "allow"` key in `<cwd>/.opencode/opencode.json`,
|
|
58
|
-
* written by `installOpencodeConfig` (see
|
|
59
|
-
* src/providers/opencode-config.ts). It belongs in the protocol-level
|
|
60
|
-
* set below, same shape as codex.
|
|
61
|
-
*/
|
|
62
|
-
export declare const YOLO_FLAGS: Record<string, string[]>;
|
|
63
|
-
/**
|
|
64
|
-
* lmctl-controlled permission mode for a single chat call.
|
|
65
|
-
*
|
|
66
|
-
* - `"yolo"` — full-auto / permission-bypass (the historical default;
|
|
67
|
-
* what every spawn does without `--permission-mode`).
|
|
68
|
-
* - `"plan"` — provider should refuse tool calls that would write
|
|
69
|
-
* to the workspace, rather than prompt or auto-approve.
|
|
70
|
-
*
|
|
71
|
-
* Plan mode is for research / exploration sessions where the agent
|
|
72
|
-
* should produce a plan only and never modify the workspace. See
|
|
73
|
-
* `PERMISSION_FLAGS` (below) for the per-provider argv substitution.
|
|
74
|
-
*
|
|
75
|
-
* IMPORTANT (gemini caveat): gemini's `--approval-mode plan` only
|
|
76
|
-
* filters `write_file` by workspace path — an agent can still escape
|
|
77
|
-
* via `run_shell_command` (e.g. `bash -c 'echo > /tmp/x'`). This is
|
|
78
|
-
* a known limitation in gemini-cli; a tighter sandbox for plan mode
|
|
79
|
-
* is tracked as a follow-up. For this layer, plan mode means
|
|
80
|
-
* "ask the provider for plan-mode behavior" — guarantees depend on
|
|
81
|
-
* the provider.
|
|
82
|
-
*/
|
|
83
|
-
export type PermissionMode = "plan" | "yolo";
|
|
84
|
-
/**
|
|
85
|
-
* Per-provider argv tokens for the two permission modes, for the
|
|
86
|
-
* providers whose permission selection is argv-based. The `yolo`
|
|
87
|
-
* column mirrors `YOLO_FLAGS` (preserved as the historical default);
|
|
88
|
-
* the `plan` column carries the substitution applied when the CLI
|
|
89
|
-
* receives `--permission-mode plan`.
|
|
90
|
-
*
|
|
91
|
-
* Verified against the actual provider CLIs:
|
|
92
|
-
*
|
|
93
|
-
* claude : --dangerously-skip-permissions vs --permission-mode plan
|
|
94
|
-
* qwen : --approval-mode yolo vs --approval-mode plan
|
|
95
|
-
* gemini : -y vs --approval-mode plan
|
|
96
|
-
*
|
|
97
|
-
* Codex and opencode are not here — they are protocol-/config-level
|
|
98
|
-
* (see `PROTOCOL_LEVEL_YOLO`). Codex's plan-mode substitution lives in
|
|
99
|
-
* the `sandbox: "danger-full-access"` → `sandbox: "read-only"` swap in
|
|
100
|
-
* codex-app-server.ts. Opencode plan mode is not yet wired and
|
|
101
|
-
* preserves the yolo (config-file) behavior.
|
|
102
|
-
*
|
|
103
|
-
* Copilot is not here — its CLI lacks a plan-mode flag in `--acp`
|
|
104
|
-
* mode (verified). Copilot in plan mode keeps `--yolo` so it doesn't
|
|
105
|
-
* hang on permission prompts; the limitation is documented in
|
|
106
|
-
* acp.ts.
|
|
107
|
-
*/
|
|
108
|
-
export declare const PERMISSION_FLAGS: Record<string, Record<PermissionMode, string[]>>;
|
|
109
|
-
/**
|
|
110
|
-
* Resolve the argv tokens for `provider` under `mode`. Falls back to
|
|
111
|
-
* the yolo token sequence when no plan-mode entry exists, so the
|
|
112
|
-
* assertion in `assertYoloFlagPresent` stays meaningful for providers
|
|
113
|
-
* that do not yet support plan mode.
|
|
114
|
-
*/
|
|
115
|
-
export declare function flagsForPermissionMode(provider: string, mode: PermissionMode): string[] | undefined;
|
|
116
|
-
/**
|
|
117
|
-
* Defense-in-depth pre-flight: assert that the YOLO flag for
|
|
118
|
-
* `provider` is present in `args` immediately before `spawn()` is
|
|
119
|
-
* called. Throws `TransportConnectionError` (and emits an
|
|
120
|
-
* unconditional debug-log record) on missing flag — catches the
|
|
121
|
-
* regression class "future refactor accidentally dropped the YOLO
|
|
122
|
-
* flag from the spawn args."
|
|
123
|
-
*
|
|
124
|
-
* Unknown providers (not in `YOLO_FLAGS` or `PROTOCOL_LEVEL_YOLO`)
|
|
125
|
-
* are treated as a hard error — the contract is global; new providers
|
|
126
|
-
* must opt in explicitly.
|
|
127
|
-
*
|
|
128
|
-
* Codex short-circuits with success — its YOLO is in the JSON-RPC
|
|
129
|
-
* params and verified separately at the call site.
|
|
130
|
-
*/
|
|
131
|
-
export declare function assertYoloFlagPresent(provider: string, args: readonly string[], mode?: PermissionMode): void;
|