@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,128 +0,0 @@
1
- /**
2
- * Workflow-microservice mediation CORE (sub-problem 1, Phase 1).
3
- *
4
- * Transport-agnostic by construction: this module imports NO MCP/server
5
- * code and performs NO I/O of its own — it is a pure, synchronous snapshot
6
- * read over the canonical DB via the existing DAL surface (the SAME
7
- * surface the apicli routes call). The later transports wrap THIS:
8
- * - B (pull tools, Phase 3): an `observe` MCP tool returns observe()'s view.
9
- * - A (SDK push, Phase 4): a session loop polls observe() and emits
10
- * notifications/elicitation.
11
- * Neither requires a core rewrite.
12
- *
13
- * Reuse map (design §3/§4):
14
- * - `step` rows via `dal.listStepsForRun` (rows written once per
15
- * state/node execution by `dal.insertStep`, src/db/index.ts) — the
16
- * per-transition observable. NOT `session_event` (subordinate agent
17
- * activity), NOT a parallel stream.
18
- * - run lifecycle via `dal.getRun` → `run.current_state` /
19
- * `run.terminal_state` / `run.paused_at` (written by
20
- * `setRunCurrentState` / `setRunTerminalState` / the resume path).
21
- *
22
- * Deadlock class (#12/#30) stays designed-out: observe() is a stateless
23
- * read that returns immediately. It performs no self-call and never
24
- * blocks waiting for the run to terminate — callers poll it.
25
- */
26
- import type { Dal, RunRow, StepRow } from '../db/index.js';
27
- /** Minimal read surface the core needs — keeps it transport/Dal-agnostic. */
28
- export interface MediationReader {
29
- getRun(id: number): RunRow | null;
30
- listStepsForRun(run_id: number): StepRow[];
31
- /**
32
- * Job→run linkage for the invoke handle. `job.run_id` is set the moment
33
- * the worker creates the run — atomically inside `dal.insertRun`
34
- * (src/db/index.ts `setJobRun`), and was historically reinforced by the
35
- * queue worker (moved to lmbee with the daemon, 2026-09-27). Null
36
- * until then. EXISTING linkage — no new table/path.
37
- */
38
- getJob(id: number): {
39
- run_id: number | null;
40
- } | null;
41
- }
42
- export type RunStatus = 'not_found' | 'queued' | 'running' | 'paused' | 'terminal';
43
- /** One normalized node transition (1:1 with a `step` row). */
44
- export interface Transition {
45
- step_id: number;
46
- state_name: string;
47
- outcome: string | null;
48
- status_detail: string | null;
49
- started_at: string;
50
- ended_at: string | null;
51
- }
52
- export interface RunObservation {
53
- /**
54
- * The resolved run id, or `null` when observing by job handle and the
55
- * worker has not created the run yet (transitional `status:'queued'`).
56
- */
57
- run_id: number | null;
58
- status: RunStatus;
59
- /** run.current_state — the node the run is at / next (may be `__paused__:<state>`). */
60
- current_state: string | null;
61
- /** run.terminal_state — non-null once the run has ended. */
62
- terminal_state: string | null;
63
- /** terminal_state !== null. The terminal signal — never dropped. */
64
- terminal: boolean;
65
- /** paused_at set, or current_state carries the engine `__paused__:` prefix. */
66
- paused: boolean;
67
- /** Step rows AFTER `sinceStepId`, ascending — the per-transition delta. */
68
- transitions: Transition[];
69
- /** Max step id observed (full set), or null if none — the observe cursor. */
70
- latest_step_id: number | null;
71
- }
72
- /**
73
- * Snapshot the canonical state of one managed-workflow run as a normalized
74
- * transition view. `sinceStepId` (default 0) yields only transitions with
75
- * `step_id > sinceStepId` for incremental observation; `status` and
76
- * `latest_step_id` are always computed from the FULL step set so a cursored
77
- * caller still gets correct queued/running/terminal classification.
78
- *
79
- * Pure read, returns immediately — no held self-call, never blocks to
80
- * terminal (the #12/#30 deadlock class is structurally impossible here).
81
- */
82
- export declare function observe(reader: MediationReader, runId: number, sinceStepId?: number): RunObservation;
83
- /** Observe a managed run by run id OR by the invoke job handle. */
84
- export interface RunHandle {
85
- run_id?: number;
86
- /** The job id returned by invoke (POST /api/jobs). Resolved via getJob. */
87
- job_id?: number;
88
- }
89
- /**
90
- * Consumable entrypoint for the invoke→observe loop. invoke returns a JOB
91
- * handle (the worker links the run LATER), so a client cannot observe by
92
- * run id from invoke's response. `observeHandle` resolves job→run using
93
- * the EXISTING `job.run_id` linkage (set by `insertRun`, src/db/index.ts:1240):
94
- * - run_id given → observe(run) directly.
95
- * - job_id, run not linked → coherent transitional snapshot
96
- * (run_id:null, status:'queued') — the client
97
- * keeps polling the SAME job handle, no extra
98
- * tool, no blocking (deadlock-class stays out).
99
- * - job_id, run linked → observe(job.run_id) — the real snapshot.
100
- * Uniform RunObservation shape throughout so the client's poll loop never
101
- * special-cases the job→run gap.
102
- */
103
- export declare function observeHandle(reader: MediationReader, h: RunHandle, sinceStepId?: number): RunObservation;
104
- export interface TransitInput {
105
- /** The operator's answer text (route's `input`). */
106
- input: string;
107
- /** End the interactive session (route's `done`); default false. */
108
- done?: boolean;
109
- /** Target by run (active interactive_waiting_operator escalation for it)… */
110
- run_id?: number;
111
- /** …or by explicit attention id (takes precedence when both given). */
112
- attention_id?: number;
113
- }
114
- export interface TransitResult {
115
- ok: boolean;
116
- /** Discovery/resume failure reason (mirrors the route's reason codes). */
117
- reason?: 'no_active_escalation' | 'wrong_kind' | 'no_step' | 'already_acked' | 'not_found' | 'not_waiting_operator' | 'run_not_found';
118
- /** Offending attention kind when reason === 'wrong_kind' (parity with app.ts:710). */
119
- kind?: string;
120
- attention_id?: number;
121
- step_id?: number;
122
- /** interactive_session.status after the existing resume (waiting_agent|done). */
123
- session_status?: string;
124
- acknowledged: boolean;
125
- /** Fresh snapshot — proves the run transitioned off paused (resume cleared __paused__:). */
126
- observation?: RunObservation;
127
- }
128
- export declare function transit(dal: Dal, t: TransitInput): TransitResult;
@@ -1,7 +0,0 @@
1
- export interface McpExecutableWarningOptions {
2
- env?: NodeJS.ProcessEnv;
3
- warn?: (message: string) => void;
4
- }
5
- export declare function executableOnPath(command: string, env?: NodeJS.ProcessEnv): boolean;
6
- export declare function formatMissingMcpExecutableWarning(command: string, toolName: string): string;
7
- export declare function warnIfMcpExecutableMissing(command: string, toolName: string, options?: McpExecutableWarningOptions): void;
@@ -1,63 +0,0 @@
1
- import { type DispatchDeps } from './dispatch.js';
2
- export interface JsonRpcRequest {
3
- jsonrpc: '2.0';
4
- id?: number | string | null;
5
- method: string;
6
- params?: unknown;
7
- }
8
- export interface JsonRpcSuccess {
9
- jsonrpc: '2.0';
10
- id: number | string | null;
11
- result: unknown;
12
- }
13
- export interface JsonRpcError {
14
- jsonrpc: '2.0';
15
- id: number | string | null;
16
- error: {
17
- code: number;
18
- message: string;
19
- data?: unknown;
20
- };
21
- }
22
- export type JsonRpcResponse = JsonRpcSuccess | JsonRpcError;
23
- export interface ServerIo {
24
- /** Sink for outbound JSON-RPC frames (typically `process.stdout`). */
25
- write(chunk: string): unknown;
26
- /** Optional sink for human-readable stderr diagnostics. */
27
- log?: (chunk: string) => void;
28
- }
29
- export interface ServerDeps {
30
- io: ServerIo;
31
- dispatch: DispatchDeps;
32
- }
33
- /**
34
- * Handle a single inbound message. Public for testability — the
35
- * `runServer` event loop just plumbs stdin/stdout into this.
36
- *
37
- * Returns:
38
- * - `{kind:'response', message: ...}` for request→response handling
39
- * - `{kind:'notification'}` when the inbound was a notification (id missing)
40
- * - `{kind:'exit'}` when the inbound was an `exit` notification — the
41
- * caller stops the loop. We pull this signal out as its own variant
42
- * rather than e.g. throwing because the spec calls for a clean exit
43
- * code (0 if `shutdown` was seen, 1 otherwise) and the cleanest way
44
- * to encode that is bubbling the intent up.
45
- */
46
- export type HandleOutcome = {
47
- kind: 'response';
48
- message: JsonRpcResponse;
49
- } | {
50
- kind: 'notification';
51
- } | {
52
- kind: 'exit';
53
- };
54
- export declare function handleMessage(raw: JsonRpcRequest, deps: ServerDeps): Promise<HandleOutcome>;
55
- /**
56
- * Run the stdio event loop until EOF or `exit`. Accepts a readable
57
- * stream (default `process.stdin`) so tests can plug in a `PassThrough`.
58
- *
59
- * Returns the integer exit code:
60
- * - 0 if `shutdown` was observed before exit (graceful)
61
- * - 1 if exit / EOF arrived without `shutdown` (per LSP-derived MCP convention)
62
- */
63
- export declare function runServer(deps: ServerDeps, stdin: NodeJS.ReadableStream): Promise<number>;
@@ -1,24 +0,0 @@
1
- /**
2
- * MCP tool catalog for AI-managed .lmctl teams.
3
- *
4
- * The managed workflow product is intentionally CLI-first for now; its
5
- * API is not exposed through MCP until that surface is explicitly designed.
6
- */
7
- export interface ToolDef {
8
- name: string;
9
- description: string;
10
- inputSchema: {
11
- type: 'object';
12
- properties: Record<string, {
13
- type: string;
14
- description?: string;
15
- items?: unknown;
16
- }>;
17
- required?: readonly string[];
18
- additionalProperties?: boolean;
19
- };
20
- local: true;
21
- }
22
- export declare const TOOLS: readonly ToolDef[];
23
- /** Total tool count for tests + tools/list assertions. */
24
- export declare const TOOL_COUNT: number;
@@ -1,271 +0,0 @@
1
- /**
2
- * Provider Adapter — unified interface for all provider-specific behavior.
3
- *
4
- * Consolidates discovery, session lifecycle, agent turns, and injection
5
- * capabilities into one contract per provider. Replaces the scattered
6
- * provider switches across session-seed, user-config, transport manager,
7
- * and tail-cmd.
8
- */
9
- import type { ProviderName, SessionSummary, SessionDetail, WatchPathInfo } from "./types.js";
10
- /**
11
- * Normalized progress event from a provider turn. Each transport wrapper is
12
- * responsible for translating its native event stream into this shape so that
13
- * downstream consumers (idle-timer, stderr printer, future heartbeat) only
14
- * need to know one format.
15
- */
16
- export interface ProgressEvent {
17
- /**
18
- * Coarse classification of what the provider is doing.
19
- *
20
- * `api_retry` is special — it indicates the provider's HTTP transport
21
- * is retrying upstream, which is the **absence** of progress, not the
22
- * presence. The idle timer in withTimeouts must NOT reset on these
23
- * events (task 63 finding 1). The heartbeat does observe them so the
24
- * user can see the retry cadence in the running… tail.
25
- */
26
- kind: "tool_use" | "tool_result" | "thinking" | "text" | "system" | "api_retry" | "other";
27
- /** Tool name when kind === "tool_use" / "tool_result" (e.g., "Bash"). */
28
- tool?: string;
29
- /** Short human-readable summary (e.g., "cargo build", "exit 0"). */
30
- summary?: string;
31
- /**
32
- * Correlation id linking a tool_use to its matching tool_result. Set
33
- * by classifiers when the underlying provider exposes a stable id
34
- * (`tool_use_id` for claude, `item.id` for codex). Used by the
35
- * progress printer to compute per-tool elapsed time on tool_result.
36
- */
37
- id?: string;
38
- /**
39
- * Wall-clock duration in ms, when the provider supplies it directly
40
- * (codex sets this from `item.durationMs` on commandExecution
41
- * completion). Optional. The printer prefers this over its own
42
- * Map-based correlation when both are available.
43
- */
44
- elapsedMs?: number;
45
- /**
46
- * Normalized tool_result status: "ok" | "error" | "exit ${number}".
47
- * Set by classifiers on tool_result events so the printer doesn't
48
- * have to parse summary strings to decide success vs failure.
49
- */
50
- status?: string;
51
- /**
52
- * The original block / message dict from the provider's wire event,
53
- * attached lossless for downstream consumers that want richer
54
- * structure than the flat kind/tool/summary fields capture (e.g.
55
- * `ThinkingBlock.signature`, `ServerToolUseBlock`,
56
- * `RateLimitEvent`). Populated today by the claude stream-json
57
- * classifier (per-block for content blocks, top-level message dict
58
- * for `result`/`system`); codex/ACP classifiers do not populate it.
59
- * Optional and advisory — classifiers MAY omit when the source is
60
- * trivial (heartbeats, bare text deltas, synthesized api_retry).
61
- */
62
- raw?: Record<string, unknown>;
63
- }
64
- export interface TurnOptions {
65
- sessionId: string;
66
- cwd: string;
67
- env?: NodeJS.ProcessEnv;
68
- profile?: string;
69
- requireResume?: boolean;
70
- onDelta?: (text: string) => void;
71
- /** Called for every classified progress event from the provider. */
72
- onProgress?: (event: ProgressEvent) => void;
73
- signal?: AbortSignal;
74
- /** Idle timeout in milliseconds. Default: 8 hours. 0 = no timeout.
75
- * When the timer fires, the turn resolves with status: "stalled"
76
- * instead of killing the child process. */
77
- timeoutMs?: number;
78
- /** Called when the idle timer fires (before resolving as stalled).
79
- * Use for logging/debug output. */
80
- onIdleWarning?: (elapsedMs: number) => void;
81
- /** User config overrides — adapter checks this before using defaults. */
82
- userConfig?: import("./config/types.js").UserConfig;
83
- /**
84
- * Override the spawned provider binary path. Used for troubleshooting
85
- * with custom builds (e.g. `~/research/studyclaude/cli-dev` for a
86
- * Claude Code dev build). When set, the transport spawns this exact
87
- * path instead of looking up `claude` / `codex` / etc. on PATH.
88
- * (Task 63 fix 3.)
89
- */
90
- progPath?: string;
91
- /**
92
- * Provider-specific model name (e.g. "claude-sonnet-4-6"). The
93
- * transport maps this through each provider's supported surface:
94
- * claude/gemini/qwen use `--model`, codex uses app-server
95
- * `-c model="..."` plus RPC `model` overrides, opencode uses ACP
96
- * `session/set_config_option`, and unsupported providers ignore
97
- * with provider-specific diagnostics.
98
- */
99
- model?: string;
100
- /** Provider-specific effort / variant override. Honored by OpenCode ACP; Kimi has no genuine per-turn effort override (see model-selection-lint.ts) so lint warns and ignores it there. */
101
- effort?: string;
102
- /**
103
- * The teamfile alias of the member being spawned. Kept for diagnostics
104
- * and old codex callers that only identify the literal "Lead" alias.
105
- */
106
- alias?: string;
107
- /**
108
- * Role-based Lead signal from teamfile resolution. Use this instead of
109
- * alias text when Lead-only provider wiring is required; teams may name
110
- * their leader something other than "Lead".
111
- */
112
- isLead?: boolean;
113
- /**
114
- * Permission mode for the turn — `"yolo"` (default) or `"plan"`.
115
- *
116
- * - `"yolo"`: append the provider's permission-bypass flag (the
117
- * historical hardcoded behavior — `--dangerously-skip-permissions`
118
- * for claude, `--approval-mode yolo` for qwen, `-y` for gemini,
119
- * `--yolo` for copilot; codex JSON-RPC sandbox is
120
- * `danger-full-access`).
121
- * - `"plan"`: substitute the provider's plan-mode flag instead
122
- * (`--permission-mode plan` for claude, `--approval-mode plan`
123
- * for qwen/gemini; codex JSON-RPC sandbox is `read-only`).
124
- *
125
- * Default is `"yolo"` so calls that omit the field preserve the
126
- * pre-existing argv/protocol shape exactly. See
127
- * `src/providers/yolo-contract.ts` for the per-provider table.
128
- *
129
- * Caveat (gemini): plan mode filters `write_file` by workspace path
130
- * only; an agent can still escape via `run_shell_command`. A tighter
131
- * sandbox for plan mode is a follow-up.
132
- */
133
- permissionMode?: import("./yolo-contract.js").PermissionMode;
134
- /**
135
- * Defer the end-of-turn shutdown while the session being run still has
136
- * outstanding dispatched work (live `agent_inflight` rows it is the
137
- * SENDER of). Honored by the stream-json transport (claude/qwen), whose
138
- * first-result stdin close is what orphans a session's
139
- * `run_in_background` dispatches when the host process exits
140
- * (BUG-chat-client-death-interrupts-receiver-live-session). Other
141
- * transports currently ignore it: codex/ACP hold persistent server
142
- * processes with different end-of-turn semantics and have not exhibited
143
- * this failure mode.
144
- */
145
- holdOpen?: import("./transports/hold-open.js").HoldOpenOptions;
146
- /**
147
- * Caller-held bundle session (batch bundle mode): when set, the
148
- * transport sends this turn through the ALREADY-OPEN provider process
149
- * instead of spawning a new one. Per-turn spawn options (model, env,
150
- * holdOpen, requireResume) were fixed at open and are ignored here;
151
- * the per-turn `expectedSession` check upstream still verifies the
152
- * returned sessionId. See src/providers/bundle.ts for the contract.
153
- */
154
- bundleSession?: import("./bundle.js").BundleSession;
155
- }
156
- export interface TurnResult {
157
- text: string;
158
- sessionId: string;
159
- durationMs: number;
160
- stopReason?: string;
161
- numTurns?: number;
162
- /** "ok" (default/omitted) = normal completion.
163
- * "stalled" = idle timeout fired — provider went silent for the
164
- * configured duration. The child process is still alive. The text
165
- * field contains whatever was produced before the stall.
166
- * "empty" = ACP transports only (see transport-wrappers.ts's
167
- * emptyTurnStatus): the provider's own protocol reported a normal
168
- * completion, but produced no text and no observed activity -- almost
169
- * always an upstream failure (rate limit, quota, auth) that the
170
- * provider's ACP layer swallowed instead of surfacing as an error.
171
- * Never set for non-ACP transports (stream-json, codex-app-server). */
172
- status?: "ok" | "stalled" | "empty";
173
- /** When status === "stalled": how long the provider was idle (ms). */
174
- stalledAfterMs?: number;
175
- /** Human-readable strings when this turn's provider silently dropped a
176
- * declared model=/effort= (task #232). Omitted when nothing was dropped.
177
- * Same convention as `SeedResult.warnings`. */
178
- warnings?: string[];
179
- }
180
- export interface SeedResult {
181
- success: boolean;
182
- error?: string;
183
- /** Non-fatal provider diagnostics that callers should surface to the operator. */
184
- warnings?: string[];
185
- /** Native session id when the provider reports it directly during seed. */
186
- sessionId?: string;
187
- }
188
- export interface SeedOptions {
189
- /** Provider-specific model name requested for the initial seed turn. */
190
- model?: string;
191
- /** Provider-specific effort / variant requested for the initial seed turn. */
192
- effort?: string;
193
- /** Optional provider seed prompt; defaults to the standard lmctl seed ACK prompt. */
194
- prompt?: string;
195
- }
196
- export interface ForkResult {
197
- success: boolean;
198
- error?: string;
199
- /** Native session ID of the forked session. */
200
- sessionId?: string;
201
- /** File path of the forked session (if applicable). */
202
- filePath?: string;
203
- }
204
- export interface ProviderCapabilities {
205
- canCreate: boolean;
206
- canResumeInteractive: boolean;
207
- canFork: boolean;
208
- /** "automatic" = lmctl can fork end-to-end; "manual" = print instructions */
209
- forkSupport: "automatic" | "manual";
210
- canStructuredTurn: boolean;
211
- canStreamDeltas: boolean;
212
- canCancel: boolean;
213
- }
214
- export interface InjectionInfo {
215
- /** How leader behavior can be shaped through public provider mechanisms. */
216
- leaderMode: "none" | "prompt-append" | "skill-file" | "custom-tool";
217
- /** Human-readable hint shown when creating a managed team with this leader. */
218
- leaderSetupHint?: string;
219
- }
220
- /**
221
- * Per-provider instructions for the user to MANUALLY create a
222
- * session when `lmctl seed` auto-seed fails.
223
- *
224
- * Lmctl can't anticipate every cause of seed failure (workspace
225
- * trust, expired auth, sandbox restriction, version drift in flag
226
- * names) but the recovery is always the same shape: launch the
227
- * provider interactively, send lmctl's explicit seed instruction
228
- * to commit a waiting session file, then update the teamfile with
229
- * the new sessionid.
230
- *
231
- * Adapters override the default to inject provider-specific flags
232
- * (e.g. gemini's `--skip-trust` for the workspace-trust gate).
233
- */
234
- export interface ManualSeedHint {
235
- /** Native command the user runs interactively to create a session.
236
- * Includes the `cd <sessiondir> && <binary> [flags]` shape. */
237
- launchCommand: string;
238
- /** One-line note on what to do INSIDE the launched session. */
239
- postLaunchNote: string;
240
- /** Filter to pass to `lmctl ls` for finding the freshly-created
241
- * session id. */
242
- lsCommand: string;
243
- }
244
- export interface ProviderAdapter {
245
- readonly name: ProviderName;
246
- readonly capabilities: ProviderCapabilities;
247
- readonly injection: InjectionInfo;
248
- discover(): Promise<SessionSummary[]>;
249
- load(sessionId: string): Promise<SessionDetail | null>;
250
- resolvePath(sessionId: string): Promise<string | null>;
251
- delete(sessionId: string): Promise<boolean>;
252
- getWatchPaths?(): WatchPathInfo[];
253
- seed(cwd: string, opts?: SeedOptions): Promise<SeedResult>;
254
- resumeCommand(sessionId: string, profile?: string): string;
255
- startCommand(profile?: string): string;
256
- /** Instructions for the user to manually seed this provider's
257
- * session in `sessiondir` when auto-seed fails. */
258
- manualSeedHint(sessiondir: string): ManualSeedHint;
259
- forkHint?(sessionId: string): string;
260
- fork?(sessionId: string, tag: string): Promise<ForkResult>;
261
- sendTurn(prompt: string, opts: TurnOptions): Promise<TurnResult>;
262
- /**
263
- * Open ONE provider process serving many turns (batch bundle
264
- * mode). Present only on bundle-capable adapters — Landing C1
265
- * implements the ACP providers (gemini/copilot/opencode/kimi/hermes);
266
- * stream-json/codex/dsh follow. The lifecycle contract (per-turn
267
- * boundary, cancellation, hold-open, unexpected exit, idempotent
268
- * bounded close, session identity) is in `src/providers/bundle.ts`.
269
- */
270
- openSession?(opts: import("./bundle.js").BundleSessionOpenOptions): Promise<import("./bundle.js").BundleSession>;
271
- }
@@ -1,18 +0,0 @@
1
- import { BaseProviderAdapter } from "../base-adapter.js";
2
- import type { SeedOptions, SeedResult } from "../adapter.js";
3
- export declare function createAgyAdapter(opts?: {
4
- agyDir?: string;
5
- }): AgyAdapter;
6
- declare class AgyAdapter extends BaseProviderAdapter {
7
- constructor(opts?: {
8
- agyDir?: string;
9
- });
10
- protected seedArgsFor(opts?: SeedOptions): string[];
11
- seed(cwd: string, opts?: SeedOptions): Promise<SeedResult>;
12
- manualSeedHint(sessiondir: string): {
13
- launchCommand: string;
14
- postLaunchNote: string;
15
- lsCommand: string;
16
- };
17
- }
18
- export {};
@@ -1,20 +0,0 @@
1
- import { BaseProviderAdapter } from "../base-adapter.js";
2
- import type { SeedOptions } from "../adapter.js";
3
- import type { BundleSession, BundleSessionOpenOptions } from "../bundle.js";
4
- export declare function createClaudeAdapter(opts?: {
5
- claudeDir?: string;
6
- }): ClaudeAdapter;
7
- declare class ClaudeAdapter extends BaseProviderAdapter {
8
- private readonly claudeDir;
9
- constructor(opts?: {
10
- claudeDir?: string;
11
- });
12
- /**
13
- * Bundle support (batch redesign item 2): one stream-json process, many
14
- * turns. The identity check's session-file root follows this adapter's
15
- * provider home (custom claudeDir ⇒ custom projects dir).
16
- */
17
- openSession(opts: BundleSessionOpenOptions): Promise<BundleSession>;
18
- protected seedArgsFor(opts?: SeedOptions): string[];
19
- }
20
- export {};
@@ -1,22 +0,0 @@
1
- import { BaseProviderAdapter } from "../base-adapter.js";
2
- import type { SeedOptions, TurnOptions } from "../adapter.js";
3
- import type { BundleSession, BundleSessionOpenOptions } from "../bundle.js";
4
- export declare function createCodexAdapter(opts?: {
5
- codexDir?: string;
6
- codeDir?: string;
7
- }): CodexAdapter;
8
- declare class CodexAdapter extends BaseProviderAdapter {
9
- constructor(opts?: {
10
- codexDir?: string;
11
- codeDir?: string;
12
- });
13
- /**
14
- * Bundle support (batch redesign item 2): one app-server process, many
15
- * `turn/start`s on the strictly-resumed thread. The bare-member default
16
- * model applies at open (same rule as turnOptsFor for one-shot turns).
17
- */
18
- openSession(opts: BundleSessionOpenOptions): Promise<BundleSession>;
19
- protected seedArgsFor(opts?: SeedOptions): string[];
20
- protected turnOptsFor(opts: TurnOptions): TurnOptions;
21
- }
22
- export {};
@@ -1,16 +0,0 @@
1
- import { BaseProviderAdapter } from "../base-adapter.js";
2
- import type { SeedOptions, SeedResult } from "../adapter.js";
3
- import type { BundleSession, BundleSessionOpenOptions } from "../bundle.js";
4
- export declare function createCopilotAdapter(opts?: {
5
- copilotDir?: string;
6
- }): CopilotAdapter;
7
- declare class CopilotAdapter extends BaseProviderAdapter {
8
- private readonly copilotDir?;
9
- constructor(opts?: {
10
- copilotDir?: string;
11
- });
12
- /** Bundle support (batch redesign item 2): one ACP process, many turns. */
13
- openSession(opts: BundleSessionOpenOptions): Promise<BundleSession>;
14
- seed(cwd: string, opts?: SeedOptions): Promise<SeedResult>;
15
- }
16
- export {};
@@ -1,89 +0,0 @@
1
- /**
2
- * dsh (DeepSeek Harness) provider adapter.
3
- *
4
- * dsh's headless profile is one-shot-only (no session resume — proven
5
- * three independent ways in `backlog/DESIGN-add-dsh-provider.md`). The
6
- * only real continuity path is the `web` profile's internal HTTP RPC
7
- * surface: `session.create` with a caller-supplied id, then repeated
8
- * `session.prompt` calls against that same id, genuinely carry context
9
- * forward (proven end-to-end). This adapter drives that RPC surface
10
- * through a managed sidecar (`dsh-sidecar.ts`) rather than spawning a new
11
- * `dsh` process per turn the way argv-templated providers (agy, claude,
12
- * codex, qwen) do — there is no equivalent one-shot-with-resume-flag
13
- * shape for dsh to model those on.
14
- */
15
- import { BaseProviderAdapter } from "../base-adapter.js";
16
- import type { SeedOptions, SeedResult } from "../adapter.js";
17
- import type { BundleSession, BundleSessionOpenOptions } from "../bundle.js";
18
- export declare function createDshAdapter(opts?: {
19
- dshHome?: string;
20
- }): DshAdapter;
21
- interface DshRecord {
22
- type?: string;
23
- seq?: number;
24
- time?: number;
25
- data?: Record<string, unknown>;
26
- }
27
- declare class DshAdapter extends BaseProviderAdapter {
28
- private readonly dshProvider;
29
- constructor(opts?: {
30
- dshHome?: string;
31
- });
32
- manualSeedHint(sessiondir: string): {
33
- launchCommand: string;
34
- postLaunchNote: string;
35
- lsCommand: string;
36
- };
37
- /**
38
- * Overridden entirely rather than relying on BaseProviderAdapter's
39
- * default (spawn `binary` with `seedArgs` as a one-shot process) — dsh
40
- * has no such mode with continuity. Generates the session id lmctl will
41
- * use for every future turn, creates it via RPC, and sends the seed
42
- * prompt through the exact same path a real turn uses.
43
- */
44
- seed(cwd: string, opts?: SeedOptions): Promise<SeedResult>;
45
- private dshPromptTurn;
46
- /**
47
- * Bundle support (batch redesign item 2): hold the shared sidecar across
48
- * turns — the per-turn `shutdownDshSidecar` in dshPromptTurn is deferred
49
- * to close(). Turn completion stays the seq-scoped transcript poll
50
- * (promptAndWait), which is per-turn safe by construction: each turn
51
- * waits for a turn/end NEWER than the seq captured before its prompt.
52
- *
53
- * Cancellation is TERMINAL for dsh bundles (the adapter advertises
54
- * canCancel: false — the RPC surface has no cancel verb): aborting a
55
- * turn rejects it, shuts the sidecar down, and closes the bundle.
56
- */
57
- openSession(opts: BundleSessionOpenOptions): Promise<BundleSession>;
58
- /** Send `prompt`, poll the session file until a NEW turn/end record
59
- * appears (by seq, so an earlier turn's completion can't be mistaken
60
- * for this one's), and return the newest assistant/message text. */
61
- private promptAndWait;
62
- }
63
- interface TurnEndReason {
64
- kind?: string;
65
- error?: {
66
- message?: string;
67
- code?: string;
68
- };
69
- }
70
- /**
71
- * dsh's own `turn/end` record carries a real, actionable error (e.g.
72
- * `{code:"MISSING_CREDENTIAL", message:"...store DEEPSEEK_API_KEY..."}`)
73
- * on a failed turn -- surface it instead of the bare reason kind, which
74
- * gave no hint the actual cause was a missing DEEPSEEK_API_KEY (real
75
- * incident: math.lmctl spent 4 seed attempts chasing a model-name red
76
- * herring before finding the real cause by reading raw session bytes).
77
- */
78
- declare function turnEndErrorMessage(reason: TurnEndReason | undefined): string;
79
- declare function maxTurnEndSeq(filePath: string): Promise<number>;
80
- declare function readRecordsSafe(filePath: string): Promise<DshRecord[]>;
81
- declare function assistantText(record: DshRecord): string;
82
- /** Test seam for the pure record helpers (F1/F4 regression tests). */
83
- export declare const _internals: {
84
- assistantText: typeof assistantText;
85
- readRecordsSafe: typeof readRecordsSafe;
86
- maxTurnEndSeq: typeof maxTurnEndSeq;
87
- turnEndErrorMessage: typeof turnEndErrorMessage;
88
- };
89
- export {};