@lmctl-ai/lmctl 0.2.38 → 0.2.40

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.
Files changed (202) hide show
  1. package/README.md +16 -0
  2. package/bin/lmbee +2 -0
  3. package/bin/lmscript +3 -0
  4. package/build-info.json +1 -0
  5. package/dist/cli/index.js +485 -460
  6. package/dist/cli/schema.sql +0 -169
  7. package/dist/cli/script.js +246 -246
  8. package/dist/lmbee.js +960 -0
  9. package/dist/lmscript.js +388 -0
  10. package/dist/public/app.js +379 -0
  11. package/dist/public/index.html +78 -0
  12. package/dist/public/styles.css +160 -0
  13. package/dist/schema.sql +455 -0
  14. package/dist/vendor-webui/index.html +18 -0
  15. package/dist/vendor-webui/local.js +231 -0
  16. package/dist/vendor-webui/styles.css +1852 -0
  17. package/package.json +11 -7
  18. package/dist/cli/batch.d.ts +0 -2
  19. package/dist/cli/busy-evidence.d.ts +0 -27
  20. package/dist/cli/chat-cycle.d.ts +0 -59
  21. package/dist/cli/chat-exec.d.ts +0 -91
  22. package/dist/cli/chat-policy.d.ts +0 -22
  23. package/dist/cli/chat.d.ts +0 -14
  24. package/dist/cli/code-resolver.d.ts +0 -8
  25. package/dist/cli/common.d.ts +0 -57
  26. package/dist/cli/context.d.ts +0 -12
  27. package/dist/cli/cost.d.ts +0 -2
  28. package/dist/cli/export.d.ts +0 -2
  29. package/dist/cli/hello.d.ts +0 -10
  30. package/dist/cli/index.d.ts +0 -3
  31. package/dist/cli/infra.d.ts +0 -78
  32. package/dist/cli/init.d.ts +0 -8
  33. package/dist/cli/intent-input.d.ts +0 -16
  34. package/dist/cli/intent-match.d.ts +0 -30
  35. package/dist/cli/intent-sessions.d.ts +0 -24
  36. package/dist/cli/intent-team.d.ts +0 -25
  37. package/dist/cli/intent.d.ts +0 -22
  38. package/dist/cli/ls.d.ts +0 -2
  39. package/dist/cli/mailbox-cli.d.ts +0 -6
  40. package/dist/cli/managed.d.ts +0 -62
  41. package/dist/cli/mcp-install.d.ts +0 -23
  42. package/dist/cli/mcp.d.ts +0 -2
  43. package/dist/cli/model.d.ts +0 -21
  44. package/dist/cli/paths.d.ts +0 -50
  45. package/dist/cli/plan-wizard.d.ts +0 -42
  46. package/dist/cli/plan.d.ts +0 -20
  47. package/dist/cli/queue-delivery.d.ts +0 -122
  48. package/dist/cli/quickrun.d.ts +0 -14
  49. package/dist/cli/ratelimit.d.ts +0 -2
  50. package/dist/cli/remote-fetch.d.ts +0 -7
  51. package/dist/cli/run-queries.d.ts +0 -82
  52. package/dist/cli/running.d.ts +0 -5
  53. package/dist/cli/save-script.d.ts +0 -41
  54. package/dist/cli/script.d.ts +0 -6
  55. package/dist/cli/seed-flight.d.ts +0 -2
  56. package/dist/cli/self-identity.d.ts +0 -25
  57. package/dist/cli/session-idle.d.ts +0 -118
  58. package/dist/cli/status.d.ts +0 -22
  59. package/dist/cli/tail.d.ts +0 -18
  60. package/dist/cli/target-resolver.d.ts +0 -139
  61. package/dist/cli/team-status.d.ts +0 -91
  62. package/dist/cli/teamfile-compat.d.ts +0 -116
  63. package/dist/cli/teamfile-store.d.ts +0 -18
  64. package/dist/cli/teamfile-template.d.ts +0 -47
  65. package/dist/cli/template-env.d.ts +0 -25
  66. package/dist/cli/terminal-lock.d.ts +0 -25
  67. package/dist/cli/terminal.d.ts +0 -23
  68. package/dist/cli/time-filter.d.ts +0 -10
  69. package/dist/cli/update-notifier.d.ts +0 -11
  70. package/dist/cli/version-util.d.ts +0 -23
  71. package/dist/config/seed_templates.d.ts +0 -1
  72. package/dist/db/backfill-event-log.d.ts +0 -26
  73. package/dist/db/delegation.d.ts +0 -37
  74. package/dist/db/escalation_vocab.d.ts +0 -45
  75. package/dist/db/event-log.d.ts +0 -40
  76. package/dist/db/index.d.ts +0 -1213
  77. package/dist/db/inflight-acquire.d.ts +0 -70
  78. package/dist/db/invocation-event-projections.d.ts +0 -65
  79. package/dist/db/ledger-identity.test.d.ts +0 -1
  80. package/dist/db/live-event-projections.d.ts +0 -92
  81. package/dist/db/migrate.d.ts +0 -51
  82. package/dist/db/open-readonly.d.ts +0 -2
  83. package/dist/db/process-liveness.d.ts +0 -37
  84. package/dist/db/sqlite.d.ts +0 -53
  85. package/dist/db/sqlite.test.d.ts +0 -1
  86. package/dist/db/terminal-lock.d.ts +0 -14
  87. package/dist/db/tracked-invocation-reconcile.d.ts +0 -52
  88. package/dist/db/tracked-invocation.d.ts +0 -116
  89. package/dist/mcp/dispatch.d.ts +0 -45
  90. package/dist/mcp/mediation.d.ts +0 -128
  91. package/dist/mcp/path-warning.d.ts +0 -7
  92. package/dist/mcp/server.d.ts +0 -63
  93. package/dist/mcp/tools.d.ts +0 -24
  94. package/dist/providers/adapter.d.ts +0 -271
  95. package/dist/providers/adapters/agy-adapter.d.ts +0 -18
  96. package/dist/providers/adapters/claude-adapter.d.ts +0 -20
  97. package/dist/providers/adapters/codex-adapter.d.ts +0 -22
  98. package/dist/providers/adapters/copilot-adapter.d.ts +0 -16
  99. package/dist/providers/adapters/dsh-adapter.d.ts +0 -89
  100. package/dist/providers/adapters/gemini-adapter.d.ts +0 -44
  101. package/dist/providers/adapters/hermes-adapter.d.ts +0 -71
  102. package/dist/providers/adapters/index.d.ts +0 -35
  103. package/dist/providers/adapters/kimi-adapter.d.ts +0 -16
  104. package/dist/providers/adapters/lmplayer-adapter.d.ts +0 -14
  105. package/dist/providers/adapters/opencode-adapter.d.ts +0 -11
  106. package/dist/providers/adapters/pi-adapter.d.ts +0 -17
  107. package/dist/providers/adapters/print-turn.d.ts +0 -29
  108. package/dist/providers/adapters/qwen-adapter.d.ts +0 -11
  109. package/dist/providers/agy.d.ts +0 -32
  110. package/dist/providers/base-adapter.d.ts +0 -110
  111. package/dist/providers/base.d.ts +0 -12
  112. package/dist/providers/binary-check.d.ts +0 -102
  113. package/dist/providers/bundle.d.ts +0 -124
  114. package/dist/providers/claude-mock.d.ts +0 -90
  115. package/dist/providers/claude.d.ts +0 -21
  116. package/dist/providers/codex-config.d.ts +0 -15
  117. package/dist/providers/codex.d.ts +0 -25
  118. package/dist/providers/config/init-config.d.ts +0 -59
  119. package/dist/providers/config/init-edit.d.ts +0 -3
  120. package/dist/providers/config/init-file.d.ts +0 -20
  121. package/dist/providers/config/init-write.d.ts +0 -2
  122. package/dist/providers/config/model-selection-lint.d.ts +0 -70
  123. package/dist/providers/config/team-config.d.ts +0 -184
  124. package/dist/providers/config/types.d.ts +0 -146
  125. package/dist/providers/config/user-config.d.ts +0 -88
  126. package/dist/providers/copilot.d.ts +0 -21
  127. package/dist/providers/debug.d.ts +0 -128
  128. package/dist/providers/dsh-sidecar.d.ts +0 -65
  129. package/dist/providers/dsh-zstd.d.ts +0 -27
  130. package/dist/providers/dsh.d.ts +0 -37
  131. package/dist/providers/frontmatter.d.ts +0 -46
  132. package/dist/providers/gemini-session-reader.d.ts +0 -151
  133. package/dist/providers/gemini.d.ts +0 -39
  134. package/dist/providers/hermes.d.ts +0 -90
  135. package/dist/providers/index.d.ts +0 -423
  136. package/dist/providers/kimi.d.ts +0 -37
  137. package/dist/providers/model-catalog.d.ts +0 -145
  138. package/dist/providers/model-suggestions.d.ts +0 -4
  139. package/dist/providers/one-shot-timeout.d.ts +0 -1
  140. package/dist/providers/opencode-config.d.ts +0 -62
  141. package/dist/providers/opencode.d.ts +0 -40
  142. package/dist/providers/parsers/acp.d.ts +0 -71
  143. package/dist/providers/parsers/codex-app-server.d.ts +0 -60
  144. package/dist/providers/parsers/stream-json.d.ts +0 -57
  145. package/dist/providers/passive-readers/agy.d.ts +0 -155
  146. package/dist/providers/passive-readers/copilot.d.ts +0 -173
  147. package/dist/providers/passive-readers/dsh.d.ts +0 -34
  148. package/dist/providers/passive-readers/kimi.d.ts +0 -44
  149. package/dist/providers/passive-readers/opencode.d.ts +0 -89
  150. package/dist/providers/passive-readers/qwen.d.ts +0 -151
  151. package/dist/providers/passive-readers/shared.d.ts +0 -138
  152. package/dist/providers/passive-session-reader.d.ts +0 -188
  153. package/dist/providers/path-utils.d.ts +0 -1
  154. package/dist/providers/pi.d.ts +0 -32
  155. package/dist/providers/pricing.d.ts +0 -107
  156. package/dist/providers/qwen.d.ts +0 -22
  157. package/dist/providers/ratelimit/agy.d.ts +0 -22
  158. package/dist/providers/ratelimit/claude-auth.d.ts +0 -13
  159. package/dist/providers/ratelimit/claude.d.ts +0 -6
  160. package/dist/providers/ratelimit/codex.d.ts +0 -7
  161. package/dist/providers/ratelimit/kimi-auth.d.ts +0 -15
  162. package/dist/providers/ratelimit/kimi.d.ts +0 -6
  163. package/dist/providers/ratelimit/schema.d.ts +0 -28
  164. package/dist/providers/ratelimit-readings.d.ts +0 -19
  165. package/dist/providers/registry.d.ts +0 -31
  166. package/dist/providers/resume.d.ts +0 -43
  167. package/dist/providers/seed-instruction.d.ts +0 -3
  168. package/dist/providers/self-session-env.d.ts +0 -21
  169. package/dist/providers/session-limit.d.ts +0 -9
  170. package/dist/providers/strip-ansi.d.ts +0 -5
  171. package/dist/providers/transport-errors.d.ts +0 -94
  172. package/dist/providers/transport-lifecycle.d.ts +0 -63
  173. package/dist/providers/transport-wrappers.d.ts +0 -110
  174. package/dist/providers/transports/acp-profiles/config-option-step.d.ts +0 -24
  175. package/dist/providers/transports/acp-profiles/copilot.d.ts +0 -12
  176. package/dist/providers/transports/acp-profiles/gemini.d.ts +0 -22
  177. package/dist/providers/transports/acp-profiles/hermes.d.ts +0 -27
  178. package/dist/providers/transports/acp-profiles/index.d.ts +0 -19
  179. package/dist/providers/transports/acp-profiles/kimi.d.ts +0 -24
  180. package/dist/providers/transports/acp-profiles/opencode.d.ts +0 -26
  181. package/dist/providers/transports/acp-profiles/types.d.ts +0 -258
  182. package/dist/providers/transports/acp-rpc.d.ts +0 -18
  183. package/dist/providers/transports/acp.d.ts +0 -217
  184. package/dist/providers/transports/codex-app-server.d.ts +0 -190
  185. package/dist/providers/transports/hold-open.d.ts +0 -120
  186. package/dist/providers/transports/manager.d.ts +0 -21
  187. package/dist/providers/transports/stream-json.d.ts +0 -162
  188. package/dist/providers/transports/types.d.ts +0 -56
  189. package/dist/providers/types.d.ts +0 -154
  190. package/dist/providers/yolo-contract.d.ts +0 -131
  191. package/dist/script/adapter.d.ts +0 -107
  192. package/dist/script/batch-script.d.ts +0 -7
  193. package/dist/script/index.d.ts +0 -3
  194. package/dist/script/init-environment.d.ts +0 -8
  195. package/dist/script/lmbee-module.d.ts +0 -2
  196. package/dist/script/lmscript.d.ts +0 -647
  197. package/dist/shared/policy.d.ts +0 -74
  198. package/dist/shared-lib/db.d.ts +0 -25
  199. package/dist/shared-lib/passive-session-reader.d.ts +0 -2
  200. package/dist/shared-lib/provider-parse.d.ts +0 -6
  201. package/dist/templates/basedir.d.ts +0 -52
  202. package/dist/uri/lmctl_uri.d.ts +0 -38
@@ -1,258 +0,0 @@
1
- /**
2
- * `AcpProviderProfile` — the per-provider half of the ACP transport.
3
- *
4
- * transports/acp.ts is the generic protocol engine (RPC channel,
5
- * lifecycle/abort/hold-open scaffolding, initialize → session/load|new →
6
- * session/prompt skeleton, resume contract). Everything that used to be a
7
- * per-provider `if (tool === …)` branch lives behind this interface in
8
- * `acp-profiles/{kimi,opencode,copilot,gemini,hermes}.ts`.
9
- *
10
- * Conventions (binding, from the batch-redesign v2 review):
11
- * - Hooks receive ONE typed context object (no two-argument hooks):
12
- * permissionMode, model, effort, acpMode, purpose ('chat' | 'probe'),
13
- * and a warnings channel. Hook-specific inputs arrive on an extension
14
- * of that object (AcpSpawnContext, AcpSessionContext, …).
15
- * - Ordering/failure policy of post-open configuration is explicit
16
- * per-profile DATA: `sessionSetup` array order is the wire order and
17
- * each step declares `onFailure: "fail-closed" | "non-fatal"`. The
18
- * driver interprets the policy; profiles never branch on it inline.
19
- * - Result handling uses stateful hooks: gemini's replay isolation lives
20
- * in the output processor via `isolateResult`; kimi's runtime-dead
21
- * detection is the `onExitFinalization` telemetry hook. There are no
22
- * stateless classifyResult/filterStderr result transforms.
23
- * - `requireResume` is the generic driver's resume contract, NOT a
24
- * profile capability.
25
- */
26
- import type { PermissionMode } from "../../yolo-contract.js";
27
- import type { AcpRpcChannel } from "../acp-rpc.js";
28
- /**
29
- * ACP session mode ids this transport may set. Kept as a closed type so a
30
- * typo cannot reach the wire as an unrecognized mode id.
31
- */
32
- export type AcpMode = "default" | "accept_edits" | "dont_ask";
33
- /** Why an ACP process is being spawned. */
34
- export type AcpPurpose = "chat" | "probe";
35
- /**
36
- * Typed context handed to every profile hook.
37
- */
38
- export interface AcpProfileContext {
39
- /** Resolved permission mode for this spawn ("yolo" is the default). */
40
- readonly permissionMode: PermissionMode;
41
- /** Per-session model override, when the caller declared one. */
42
- readonly model?: string;
43
- /** Per-session effort / variant override, when the caller declared one. */
44
- readonly effort?: string;
45
- /**
46
- * Explicit ACP `session/set_mode` mode id, validated by the driver
47
- * against the profile's `modeVocabulary` before spawn (fail-closed).
48
- */
49
- readonly acpMode?: AcpMode;
50
- readonly purpose: AcpPurpose;
51
- /**
52
- * Warnings channel. Strings pushed here are human-readable records of
53
- * provider config the turn proceeded past; for purpose "chat" they land
54
- * on `AcpResult.warnings` (task #232), for purpose "probe" they are
55
- * probe evidence.
56
- */
57
- readonly warnings: {
58
- push(warning: string): void;
59
- };
60
- }
61
- /** preSpawn hook context: the profile context plus the spawn target. */
62
- export interface AcpSpawnContext extends AcpProfileContext {
63
- readonly cwd: string;
64
- /** The already-built spawn environment; profiles may mutate it. */
65
- readonly env: NodeJS.ProcessEnv;
66
- }
67
- /** afterSessionOpen step context: the profile context plus the open session. */
68
- export interface AcpSessionContext extends AcpProfileContext {
69
- readonly sessionId: string;
70
- /** Raw `session/new` / `session/load` response (model catalogs, currentModelId…). */
71
- readonly response: Record<string, unknown>;
72
- readonly sendRpc: AcpRpcChannel["sendRpc"];
73
- }
74
- /** onExitFinalization hook context: the finalized turn result. */
75
- export interface AcpFinalizeContext extends AcpProfileContext {
76
- readonly sessionId: string;
77
- readonly result: string;
78
- readonly stopReason: string;
79
- readonly exitCode: number | null;
80
- }
81
- /**
82
- * Bundle-open identity verification context: everything a profile needs to
83
- * prove the requested session was genuinely loaded.
84
- */
85
- export interface AcpSessionIdentityContext extends AcpProfileContext {
86
- readonly requestedSessionId: string;
87
- /** Raw `session/load` response (its sessionId echo, if any, was already
88
- * checked by the driver: a DIFFERENT echoed id always fails before this
89
- * hook runs). */
90
- readonly loadResponse: Record<string, unknown>;
91
- readonly cwd: string;
92
- /** The spawn env — provider-home overrides (KIMI_CODE_HOME etc.) reach
93
- * the verifier through here. */
94
- readonly env: NodeJS.ProcessEnv;
95
- }
96
- /**
97
- * Per-profile session-identity strategy for BUNDLE open (`openAcpSession`
98
- * strict mode). The driver never falls back to "assume the requested id":
99
- * a profile must declare how a genuine load is proven.
100
- *
101
- * - Providers whose session/load echoes the session id need nothing here:
102
- * the driver's exact-echo check is the whole strategy (default when this
103
- * field is absent — and the absence of an echo then fails closed).
104
- * - Providers whose load does NOT echo an id declare a hook:
105
- * kimi verifies via its on-disk session store; hermes relies on its
106
- * fail-closed load (a non-throwing load IS the proof — see the profile).
107
- */
108
- export interface AcpSessionIdentity {
109
- /** Verify at bundle open that the requested session was genuinely loaded.
110
- * Throw on failure. Only called when the load response carried no
111
- * contradicting echo. */
112
- verifyLoadedSession(ctx: AcpSessionIdentityContext): Promise<void> | void;
113
- /**
114
- * Cheap between-messages re-check (catches an external re-seed/delete
115
- * mid-bundle before the next prompt is sent). Optional — providers whose
116
- * identity is pinned by the live process need nothing here (the per-turn
117
- * expectedSession check upstream catches teamfile rotation).
118
- */
119
- recheckSession?(ctx: {
120
- requestedSessionId: string;
121
- cwd: string;
122
- env: NodeJS.ProcessEnv;
123
- }): Promise<void> | void;
124
- }
125
- /** Structured description of a session-step failure, built by the step. */
126
- export interface AcpStepFailure {
127
- /** errorLog event name. The driver merges `{ event, provider, ...fields }`. */
128
- readonly event: string;
129
- readonly fields: Record<string, unknown>;
130
- /** Human-readable stderr line (trailing newline included), when surfaced there. */
131
- readonly stderrLine?: string;
132
- /** Warnings-channel entry — the config the turn proceeded past. */
133
- readonly warning?: string;
134
- /** Thrown message; used only by fail-closed steps. */
135
- readonly message: string;
136
- }
137
- /**
138
- * One ordered post-open configuration step (after session/new|load, before
139
- * the first prompt).
140
- */
141
- export interface AcpSessionStep {
142
- /** Stable id for logs and tests, e.g. "permission-mode" | "session-mode" | "model" | "effort". */
143
- readonly id: string;
144
- /**
145
- * Failure policy — profile DATA, interpreted by the driver:
146
- * - "fail-closed": a rejected step aborts the turn before
147
- * session/prompt (a provider that refused the posture can hang on its
148
- * first tool call).
149
- * - "non-fatal": record the failure (errorLog + stderr + warnings
150
- * channel) and proceed with whatever config was already active.
151
- */
152
- readonly onFailure: "fail-closed" | "non-fatal";
153
- applies(ctx: AcpSessionContext): boolean;
154
- run(ctx: AcpSessionContext): Promise<void>;
155
- describeFailure(ctx: AcpSessionContext, error: unknown): AcpStepFailure;
156
- /** dlogv line on success (debug-gated). */
157
- successLog?(ctx: AcpSessionContext): string;
158
- }
159
- /** Options for the opencode profile's probe entry point. */
160
- export interface OpenCodeAcpConfigProbeOptions {
161
- cwd: string;
162
- model: string;
163
- effort?: string;
164
- env?: NodeJS.ProcessEnv;
165
- binaryPath?: string;
166
- timeoutMs?: number;
167
- }
168
- export type OpenCodeAcpConfigProbeResult = {
169
- status: "verified";
170
- } | {
171
- status: "rejected";
172
- option: "model" | "effort";
173
- value: string;
174
- error: string;
175
- } | {
176
- status: "unavailable";
177
- reason: "spawn" | "handshake" | "timeout";
178
- error?: string;
179
- };
180
- export interface AcpProviderProfile {
181
- /** Provider key: "kimi" | "opencode" | "copilot" | "gemini" | "hermes". */
182
- readonly name: string;
183
- /** Default binary; per-call overridable via `AcpOptions.binaryPath`. */
184
- readonly binary: string;
185
- /**
186
- * Static base argv (the historical ACP_TOOLS entry). Per-call rewrites
187
- * (permission mode, model) happen in `argv()` — never by mutating this.
188
- */
189
- readonly baseArgs: readonly string[];
190
- /**
191
- * Effective spawn argv for the resolved context. Absorbs the base args
192
- * plus plan-mode rewrites (gemini's `-y` → `--approval-mode plan` swap)
193
- * and spawn-time model flags (gemini `--model`). May warn (copilot
194
- * plan/model gaps) or throw (hermes plan refusal).
195
- */
196
- argv(ctx: AcpProfileContext): string[];
197
- /**
198
- * Which mode the YOLO argv pre-flight asserts against the produced argv:
199
- * the effective permission mode (default), or always "yolo" for
200
- * providers that deliberately keep their yolo flag in plan mode
201
- * (copilot).
202
- */
203
- readonly yoloAssertion?: "effective" | "always-yolo";
204
- /**
205
- * Pre-spawn filesystem/env preparation: opencode installs its runtime
206
- * permission config, hermes sets HERMES_YOLO_MODE. Runs before the
207
- * cwd-existence pre-check (historical ordering).
208
- */
209
- preSpawn?(ctx: AcpSpawnContext): void;
210
- /**
211
- * ACP `session/set_mode` vocabulary for providers whose permission
212
- * posture is an ACP mode ladder (hermes). `known` is what the provider
213
- * implements, `selectable` the subset lmctl is willing to drive a member
214
- * into. Absent ⇒ the provider declares no vocabulary and any acpMode
215
- * request is rejected fail-closed before spawn.
216
- */
217
- readonly modeVocabulary?: {
218
- known: readonly AcpMode[];
219
- selectable: readonly AcpMode[];
220
- };
221
- /**
222
- * Ordered post-open configuration steps. Array order IS the wire order
223
- * (kimi: permission mode before model; hermes: set_mode before
224
- * set_model; opencode: model before effort). Per-step failure policy is
225
- * the step's `onFailure`.
226
- */
227
- readonly sessionSetup?: readonly AcpSessionStep[];
228
- /**
229
- * Result-text isolation applied INSIDE the stateful output processor
230
- * (parsers/acp.ts) — gemini's latest-agent-message replay isolation.
231
- */
232
- readonly isolateResult?: (text: string) => string;
233
- /**
234
- * Bundle-open session-identity strategy (see AcpSessionIdentity).
235
- * Absent ⇒ the driver requires an exact sessionId echo in the load
236
- * response and fails closed without one.
237
- */
238
- readonly sessionIdentity?: AcpSessionIdentity;
239
- /**
240
- * Structured telemetry emitted during exit finalization, after the
241
- * output processor has produced the final result (kimi runtime-dead).
242
- */
243
- onExitFinalization?(ctx: AcpFinalizeContext): void;
244
- /**
245
- * Filters provider-known-benign stderr blocks out of the no-result
246
- * error report (kimi's notifications/initialized -32601 block). This is
247
- * error-path stderr hygiene, not a result transform.
248
- */
249
- filterExpectedStderr?(stderr: string): string;
250
- /**
251
- * Separate probe entry point (opencode only): verifies the provider's
252
- * live per-session model/effort contract WITHOUT prompting. It
253
- * intentionally differs from the chat spawn — no runtime
254
- * permission-config install, and a rejected model/effort option is
255
- * reported as probe evidence rather than absorbed as a warning.
256
- */
257
- readonly probe?: (opts: OpenCodeAcpConfigProbeOptions) => Promise<OpenCodeAcpConfigProbeResult>;
258
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * ACP JSON-RPC 2.0 channel over a spawned child's stdin/stdout.
3
- *
4
- * Pure protocol plumbing shared by the chat engine (transports/acp.ts)
5
- * and profile-owned entry points that run their own spawn/RPC lifecycle
6
- * (the opencode config probe in transports/acp-profiles/opencode.ts).
7
- */
8
- import type { ChildProcess } from "node:child_process";
9
- export interface AcpRpcChannel {
10
- sendRpc(method: string, params?: Record<string, unknown>): Promise<Record<string, unknown>>;
11
- sendNotification(method: string, params?: Record<string, unknown>): void;
12
- close(error?: Error): void;
13
- }
14
- export declare function createAcpRpcChannel(child: ChildProcess, opts: {
15
- provider: string;
16
- onEvent?: (event: Record<string, unknown>) => void;
17
- onNotification?: (event: Record<string, unknown>) => void;
18
- }): AcpRpcChannel;
@@ -1,217 +0,0 @@
1
- /**
2
- * Generic ACP (Agent Client Protocol) transport — the protocol engine.
3
- *
4
- * Works with any CLI tool that supports ACP (Gemini, Copilot, OpenCode, Kimi,
5
- * Hermes). Spawns the tool and communicates via ACP JSON-RPC 2.0 over
6
- * stdin/stdout.
7
- *
8
- * Protocol:
9
- * initialize → session/new (or session/load) → session/prompt
10
- * ← session/update (agent_message_chunk, streaming)
11
- * ← result with stopReason
12
- *
13
- * Everything provider-specific (argv shapes, plan-mode rewrites, config
14
- * installs, post-open mode/model/effort configuration, result isolation,
15
- * exit telemetry, the opencode config probe) lives behind
16
- * `AcpProviderProfile` in `./acp-profiles/`; this file is the generic
17
- * driver: RPC channel lifecycle, abort/hold-open scaffolding, the
18
- * initialize → load/new → prompt skeleton, and the resume contract
19
- * (`requireResume` — deliberately NOT a profile capability).
20
- *
21
- * `sendAcpPrompt` is internally phased (spawn → open → configure → prompt
22
- * → finalize) so a future `openAcpSession(profile, opts)` bundle seam can
23
- * hoist the spawn+open phases out of the per-turn prompt phase without
24
- * restructuring (batch redesign, item 2/3).
25
- */
26
- import { type HoldOpenOptions } from "./hold-open.js";
27
- import { type PermissionMode } from "../yolo-contract.js";
28
- import { type AcpResult } from "../parsers/acp.js";
29
- import { ACP_TOOLS_FOR_TEST } from "./acp-profiles/index.js";
30
- import type { AcpMode } from "./acp-profiles/types.js";
31
- import { detectKimiRuntimeDead } from "./acp-profiles/kimi.js";
32
- import { probeOpenCodeAcpConfig } from "./acp-profiles/opencode.js";
33
- export { acpSessionIdFromResponse, acpStopReasonFromResponse, createAcpOutputProcessor, isolateGeminiLatestAgentMessage, supportsAcp, } from "../parsers/acp.js";
34
- export type { AcpOutputProcessor, AcpOutputProcessorResult, AcpResult, } from "../parsers/acp.js";
35
- export { ACP_TOOLS_FOR_TEST, detectKimiRuntimeDead, probeOpenCodeAcpConfig };
36
- export type { AcpMode } from "./acp-profiles/types.js";
37
- export type { OpenCodeAcpConfigProbeOptions, OpenCodeAcpConfigProbeResult, } from "./acp-profiles/types.js";
38
- export interface AcpOptions {
39
- /** Existing session ID to load. If omitted, creates a new session. */
40
- sessionId?: string;
41
- cwd: string;
42
- env?: NodeJS.ProcessEnv;
43
- /** Tool name — determines the provider profile (binary, argv, hooks) */
44
- tool: string;
45
- /**
46
- * Override the spawned binary path. When set, this exact path is
47
- * spawned (with the profile's standard ACP args) instead of the
48
- * profile's default binary. Used for troubleshooting custom
49
- * builds. (Task 63 fix 3.)
50
- */
51
- binaryPath?: string;
52
- /** If true, failed session/load is an error. If false, falls back to session/new. */
53
- requireResume?: boolean;
54
- /**
55
- * Per-session model override. Honored for Gemini via a
56
- * spawn-time `--model` flag and for OpenCode/Kimi via ACP
57
- * `session/set_config_option`. Format: `providerID/modelID` (e.g.
58
- * `anthropic/claude-3-5-sonnet-20241022`). Copilot does not expose
59
- * a per-session ACP model selection surface.
60
- */
61
- model?: string;
62
- /**
63
- * Per-session effort / variant override. OpenCode uses ACP configId
64
- * `"effort"`. Kimi 0.28.x exposes only an on/off thinking toggle,
65
- * so its model-defined effort cannot be overridden here.
66
- */
67
- effort?: string;
68
- /**
69
- * Teamfile alias of the spawned member, retained for diagnostics and
70
- * provider-specific policy.
71
- */
72
- alias?: string;
73
- /**
74
- * Permission mode for this turn (default "yolo"). How "plan" is
75
- * realized is profile policy: gemini's argv swaps `-y` for
76
- * `--approval-mode plan`, kimi sets its protocol-level mode to "plan",
77
- * copilot keeps `--yolo` and warns (no plan flag exists), opencode is
78
- * config-file based, and hermes refuses plan mode outright.
79
- *
80
- * Caveat (gemini): plan mode in gemini-cli filters `write_file` by
81
- * workspace path only; `run_shell_command` can still escape. A
82
- * follow-up will tighten the sandbox for plan mode.
83
- */
84
- permissionMode?: PermissionMode;
85
- /** Called for each text delta */
86
- onDelta?: (text: string) => void;
87
- /** Called for each raw JSON-RPC event */
88
- onEvent?: (event: Record<string, unknown>) => void;
89
- /** Abort signal — kills the provider process when aborted */
90
- signal?: AbortSignal;
91
- /**
92
- * Defer closing the child's stdin past the turn's result while the session
93
- * still has outstanding `run_in_background` dispatches (task #68, extended to
94
- * ACP). Absent ⇒ the exact pre-existing synchronous close. See
95
- * {@link HoldOpenOptions}.
96
- */
97
- holdOpen?: HoldOpenOptions;
98
- /**
99
- * Explicit ACP `session/set_mode` mode id to apply to the session on
100
- * every spawn, after `session/new`/`session/load` completes.
101
- *
102
- * Needed by providers whose ACP mode ladder is NOT covered by an argv
103
- * permission flag and NOT expressible through lmctl's own
104
- * `permissionMode` vocabulary. Hermes is the only such provider today:
105
- * its ladder (`default`/`accept_edits`/`dont_ask`) governs the file-EDIT
106
- * gate, which `HERMES_YOLO_MODE` does not approve, so the mode must be
107
- * set per process or every edit stalls on a
108
- * `session/request_permission` round-trip this client cannot answer.
109
- *
110
- * Validated at the call site against the profile's mode vocabulary —
111
- * an unconfigured value throws fail-closed (`assertAcpModeSupported`)
112
- * rather than being forwarded as an unknown mode id.
113
- */
114
- acpMode?: AcpMode;
115
- }
116
- /**
117
- * Fail-closed guard for `AcpOptions.acpMode`. Throws for a provider whose
118
- * profile declares no mode vocabulary (nothing to validate against ⇒
119
- * never guess) and for a mode outside the vocabulary's selectable subset.
120
- */
121
- export declare function assertAcpModeSupported(tool: string, mode: AcpMode): void;
122
- export declare function filterExpectedAcpStderr(tool: string, stderr: string): string;
123
- /**
124
- * Send a prompt via ACP to any supported tool.
125
- */
126
- export declare function sendAcpPrompt(prompt: string, opts: AcpOptions): Promise<AcpResult>;
127
- /**
128
- * Per-turn options for an open ACP bundle session. The spawn-time profile
129
- * context (permissionMode, model, effort, acpMode) was fixed at open; a
130
- * turn only carries its streaming callbacks and an abort signal.
131
- */
132
- export interface AcpSessionTurnOptions {
133
- /** Called for each text delta belonging to THIS turn. */
134
- onDelta?: (text: string) => void;
135
- /** Called for each raw JSON-RPC event during THIS turn. */
136
- onEvent?: (event: Record<string, unknown>) => void;
137
- /**
138
- * Abort signal for THIS turn. Abortion rejects the turn with
139
- * `Error("Aborted")`, sends a best-effort `session/cancel`
140
- * notification, and leaves the session open and usable — the child is
141
- * NOT killed (contrast with `sendAcpPrompt`, where abort terminates the
142
- * one-shot process). Chunks a provider still emits for the cancelled
143
- * turn are dropped by the output processor.
144
- */
145
- signal?: AbortSignal;
146
- }
147
- export interface AcpSessionTurnResult {
148
- result: string;
149
- sessionId: string;
150
- stopReason: string;
151
- durationMs: number;
152
- /**
153
- * The open-time profile configuration warnings (task #232 model/effort
154
- * drops) are reported on the FIRST turn's result — in bundle mode the
155
- * profile's sessionSetup runs once at open, not per spawn.
156
- */
157
- warnings?: string[];
158
- /** See AcpOutputProcessorResult.sawActivity. */
159
- sawActivity: boolean;
160
- }
161
- /**
162
- * An open ACP bundle session: one provider process serving many prompts.
163
- *
164
- * Lifecycle contract (agreed in the batch-redesign v2 review before
165
- * implementation; pinned by tests/providers/acp-bundle.test.ts):
166
- *
167
- * - Per-turn completion boundary: a turn ends at its `session/prompt`
168
- * result. The stateful output processor is retained across turns and
169
- * reset per turn (`beginTurn`), so chunks arriving after the boundary
170
- * (provider replay trailing a load, late deltas) never leak into the
171
- * next turn's result.
172
- * - Cancellation: aborting a turn rejects that turn, sends
173
- * `session/cancel`, and keeps the session usable.
174
- * - Hold-open policy: the process is NOT closed between turns — the
175
- * persistence IS the hold (the per-turn stdin close of
176
- * `sendAcpPrompt` is suppressed). `close()` runs the caller's
177
- * `holdOpen` outstanding-work check ONCE before ending stdin, so the
178
- * final turn's background dispatches are not orphaned.
179
- * - Unexpected exit: a mid-bundle process exit rejects the in-flight
180
- * turn and every later turn with an error naming the number of
181
- * completed prompts.
182
- * - Idempotent, bounded close: `close()` may be called repeatedly and
183
- * during an in-flight turn; a child that ignores stdin EOF is
184
- * terminated after a bounded wait — close never hangs.
185
- * - Identity: open requires `session/load` to return the EXACT
186
- * requested session id (no fallback to the requested id, no
187
- * session/new fallback) before prompt 1 is sent.
188
- */
189
- export interface AcpSession {
190
- readonly tool: string;
191
- /** The verified session id (exact match to the requested id). */
192
- readonly sessionId: string;
193
- /** Successfully completed turns — the count bundle errors report. */
194
- readonly completedTurns: number;
195
- sendTurn(prompt: string, opts?: AcpSessionTurnOptions): Promise<AcpSessionTurnResult>;
196
- close(): Promise<void>;
197
- }
198
- export interface AcpSessionOptions extends AcpOptions {
199
- /**
200
- * Shutdown cap: how long close() waits for the child to exit after
201
- * stdin EOF before escalating to the terminate ladder (which is itself
202
- * bounded by the same cap per step). Default 2000ms. Exists so tests
203
- * and operator-driven shutdowns can tighten the bound.
204
- */
205
- closeTimeoutMs?: number;
206
- }
207
- /**
208
- * Open a persistent ACP session for `opts.tool`: spawn → initialize →
209
- * session/load (strict identity, fail-closed) → profile sessionSetup —
210
- * everything `sendAcpPrompt` does per turn EXCEPT the prompt phase, which
211
- * becomes `session.sendTurn`.
212
- *
213
- * `requireResume` is implied: a bundle without its exact teamfile session
214
- * is always an error. `opts.signal` is intentionally not consulted here —
215
- * bundle cancellation is per turn (`AcpSessionTurnOptions.signal`).
216
- */
217
- export declare function openAcpSession(opts: AcpSessionOptions): Promise<AcpSession>;
@@ -1,190 +0,0 @@
1
- /**
2
- * Codex app-server transport.
3
- *
4
- * Spawns `codex app-server --listen stdio://` and communicates via
5
- * JSON-RPC 2.0 over stdin/stdout. The process stays alive for the
6
- * full conversation — no one-shot timeout.
7
- *
8
- * Protocol:
9
- * initialize → thread/start or thread/resume → turn/start
10
- * ← item/agentMessage/delta (streaming)
11
- * ← turn/completed
12
- */
13
- import { type HoldOpenOptions } from "./hold-open.js";
14
- import { type PermissionMode } from "../yolo-contract.js";
15
- import { type CodexInitializePayload } from "../parsers/codex-app-server.js";
16
- export { buildCodexThreadResumeParams, buildCodexThreadStartParams, classifyCodexErrorDisposition, codexSandboxForPermissionMode, createCodexAgentAccumulator, createCodexTurnState, flushCodexAgentAccumulator, processCodexAgentNotification, recordCodexErrorNotification, resolveCodexTurnCompletion, } from "../parsers/codex-app-server.js";
17
- export type { AgentMessageItemState, AgentMessagePhase, CodexAgentAccumulatorState, CodexErrorDisposition, CodexInitializePayload, CodexItemMismatchInfo, CodexTurnState, } from "../parsers/codex-app-server.js";
18
- /**
19
- * Build the JSON-RPC `initialize` params for the codex app-server.
20
- * Mirrors the reference client at
21
- * openai/codex-plugin-cc/plugins/codex/scripts/lib/app-server.mjs:25-41.
22
- *
23
- * Includes `clientInfo.title` and `capabilities.experimentalApi: false`
24
- * explicitly. `version` is sourced from package.json at load time rather
25
- * than a string literal so bumps aren't silently out-of-sync.
26
- *
27
- * We intentionally do NOT set `capabilities.optOutNotificationMethods`
28
- * (which their plugin uses to suppress agentMessage/reasoning deltas) —
29
- * lmctl consumes every delta for live `onDelta` progress.
30
- */
31
- export declare function buildInitializePayload(): CodexInitializePayload;
32
- /**
33
- * Backward-compat shim for the prior local helper. Forwards to
34
- * `transportRpcErrorFromResponse` from the shared transport-errors
35
- * module so existing tests / external callers continue to work.
36
- *
37
- * The returned object is now a `TransportRpcError` instance — still
38
- * an `Error`, still has `.rpcCode` and `.data` (mapped to `.rpcData`),
39
- * but the latter are typed and named consistently with the other
40
- * transports.
41
- *
42
- * @deprecated Construct `TransportRpcError` directly via
43
- * `transportRpcErrorFromResponse(message, errorObj)`.
44
- */
45
- export declare function createRpcError(message: string, data?: unknown): Error & {
46
- rpcCode?: number;
47
- data?: unknown;
48
- };
49
- export interface CodexAppServerResult {
50
- result: string;
51
- threadId: string;
52
- turnId: string;
53
- durationMs: number;
54
- exitCode: number | null;
55
- }
56
- export interface CodexAppServerOptions {
57
- /** Codex thread ID to resume. If provided, uses thread/resume with writable sandbox. */
58
- threadId?: string;
59
- cwd: string;
60
- env?: NodeJS.ProcessEnv;
61
- /** Called for each text delta (for live output) */
62
- onDelta?: (text: string) => void;
63
- /** Called for each raw JSON-RPC event */
64
- onEvent?: (event: Record<string, unknown>) => void;
65
- /**
66
- * Override the spawned codex binary path. Used for troubleshooting
67
- * with a custom codex-rs build. When set, the transport spawns this
68
- * exact path instead of looking up `codex` on PATH. (Task 63 fix 3.)
69
- */
70
- binaryPath?: string;
71
- /** Abort signal — kills the provider process when aborted */
72
- signal?: AbortSignal;
73
- /** Provider-specific model name, passed through Codex config and RPC overrides. */
74
- model?: string;
75
- /**
76
- * Teamfile alias of the spawned member. Used only as a fallback for
77
- * old callers that did not pass `isLead`.
78
- */
79
- alias?: string;
80
- /** Role-based Lead signal from teamfile resolution. */
81
- isLead?: boolean;
82
- /**
83
- * Permission mode for this turn (default "yolo").
84
- *
85
- * Codex's permission selection is wire-protocol level — both
86
- * `thread/start` and `thread/resume` carry a `sandbox` param:
87
- *
88
- * yolo → "danger-full-access" (historical default)
89
- * plan → "read-only" (codex refuses workspace writes)
90
- *
91
- * `approvalPolicy` stays `"never"` in both modes because lmctl
92
- * has no UI for forwarding permission prompts.
93
- */
94
- permissionMode?: PermissionMode;
95
- }
96
- /**
97
- * Fork a codex thread via the app-server `thread/fork` JSON-RPC method.
98
- *
99
- * Why app-server and not the bundled `codex fork` CLI: `codex fork` is
100
- * unconditionally TUI-only (`run_interactive_tui` in
101
- * codex-rs/cli/src/main.rs:793-817), refusing non-TTY stdin with
102
- * "Error: stdin is not a terminal". The app-server protocol exposes
103
- * the same fork capability as a clean RPC.
104
- *
105
- * Empirical response shape (Phase B0 verified, codex-cli 0.121.0):
106
- *
107
- * { id, result: { thread: {
108
- * id: "<NEW-THREAD-ID>",
109
- * forkedFromId: "<source-id>",
110
- * path: "~/.codex/sessions/.../<new-id>.jsonl",
111
- * turns: [...carried-over history...],
112
- * cwd, status: { type: "idle" }, ... } } }
113
- *
114
- * The forked thread is persisted to disk by codex BEFORE the response
115
- * returns — no `turn/start` needed to materialize it.
116
- *
117
- * @param sourceThreadId Existing codex thread id to fork from.
118
- * @param opts.cwd Working directory for the spawned app-server.
119
- * Codex inherits this into the forked thread's cwd.
120
- * @param opts.binaryPath Optional override of the codex binary path.
121
- * @returns The new thread id codex minted for the fork.
122
- */
123
- export declare function forkCodexThread(sourceThreadId: string, opts?: {
124
- cwd?: string;
125
- binaryPath?: string;
126
- }): Promise<string>;
127
- /**
128
- * Send a prompt to Codex via the app-server protocol.
129
- * Returns the assembled response text when the turn completes.
130
- */
131
- export declare function sendCodexPrompt(prompt: string, opts: CodexAppServerOptions): Promise<CodexAppServerResult>;
132
- export interface CodexSessionOptions extends CodexAppServerOptions {
133
- /**
134
- * Shutdown cap: how long close() waits for a natural exit after stdin
135
- * EOF before escalating to the (internally bounded) terminate ladder.
136
- * Default 2000ms.
137
- */
138
- closeTimeoutMs?: number;
139
- /**
140
- * Outstanding-work check run ONCE at close() before stdin ends (same
141
- * policy as the ACP/stream-json bundles: the persistence IS the hold,
142
- * close honors the final turn's background dispatches).
143
- */
144
- holdOpen?: HoldOpenOptions;
145
- }
146
- export interface CodexSessionTurnOptions {
147
- onDelta?: (text: string) => void;
148
- onEvent?: (event: Record<string, unknown>) => void;
149
- /**
150
- * Abort THIS turn: rejects the turn with `Error("Aborted")` and sends a
151
- * best-effort `turn/interrupt` — the app-server has a real cancel verb,
152
- * so the bundle stays usable for the next turn (unlike stream-json).
153
- */
154
- signal?: AbortSignal;
155
- }
156
- export interface CodexSessionTurnResult {
157
- text: string;
158
- sessionId: string;
159
- turnId: string;
160
- durationMs: number;
161
- }
162
- /**
163
- * An open codex app-server bundle session: one process serving many
164
- * prompts via repeated `turn/start` on the resumed thread. The lifecycle
165
- * contract is in src/providers/bundle.ts; the codex-specific decisions:
166
- *
167
- * - Per-turn completion boundary: the `turn/completed` notification
168
- * (codex's authoritative end-of-turn signal, including its deferred
169
- * terminal-error resolution via resolveCodexTurnCompletion).
170
- * - Identity: thread/resume must return the EXACT requested thread id.
171
- * The resume→thread/start fallback is DISABLED in bundle mode — a
172
- * failed resume aborts the open, never silently starts a new thread
173
- * (requireResume parity with the ACP bundle).
174
- * - Cancellation: `turn/interrupt` keeps the bundle usable.
175
- */
176
- export interface CodexBundleSession {
177
- readonly provider: "codex";
178
- readonly sessionId: string;
179
- readonly completedTurns: number;
180
- sendTurn(prompt: string, opts?: CodexSessionTurnOptions): Promise<CodexSessionTurnResult>;
181
- close(): Promise<void>;
182
- }
183
- /**
184
- * Open a persistent codex app-server session. See {@link CodexBundleSession}.
185
- */
186
- export declare function openCodexSession(opts: CodexSessionOptions): Promise<CodexBundleSession>;
187
- /**
188
- * Check if a tool should use the Codex app-server transport.
189
- */
190
- export declare function supportsCodexAppServer(tool: string): boolean;