@lmctl-ai/lmctl 0.1.341 → 0.2.2

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 (182) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/README.md +11 -51
  3. package/data/price-aliases.json +1 -0
  4. package/data/price-data.json +1 -1
  5. package/dist/cli/batch.d.ts +2 -0
  6. package/dist/cli/busy-evidence.d.ts +27 -0
  7. package/dist/cli/chat-cycle.d.ts +59 -0
  8. package/dist/cli/chat-exec.d.ts +83 -0
  9. package/dist/cli/chat-policy.d.ts +22 -0
  10. package/dist/cli/chat.d.ts +23 -0
  11. package/dist/cli/code-resolver.d.ts +8 -0
  12. package/dist/cli/common.d.ts +54 -0
  13. package/dist/cli/context.d.ts +12 -0
  14. package/dist/cli/cost.d.ts +2 -0
  15. package/dist/cli/export.d.ts +2 -0
  16. package/dist/cli/index.d.ts +3 -0
  17. package/dist/cli/index.js +1081 -1891
  18. package/dist/cli/infra.d.ts +78 -0
  19. package/dist/cli/ls.d.ts +2 -0
  20. package/dist/cli/mailbox-cli.d.ts +6 -0
  21. package/dist/cli/managed.d.ts +62 -0
  22. package/dist/cli/mcp-install.d.ts +23 -0
  23. package/dist/cli/mcp.d.ts +2 -0
  24. package/dist/cli/paths.d.ts +50 -0
  25. package/dist/cli/plan-wizard.d.ts +42 -0
  26. package/dist/cli/plan.d.ts +20 -0
  27. package/dist/cli/queue-delivery.d.ts +107 -0
  28. package/dist/cli/ratelimit.d.ts +3 -0
  29. package/dist/cli/remote-fetch.d.ts +7 -0
  30. package/dist/cli/run-queries.d.ts +82 -0
  31. package/dist/cli/running.d.ts +5 -0
  32. package/dist/cli/schema.sql +20 -1
  33. package/dist/cli/script.d.ts +6 -0
  34. package/dist/cli/script.js +2097 -0
  35. package/dist/cli/self-identity.d.ts +25 -0
  36. package/dist/cli/session-idle.d.ts +118 -0
  37. package/dist/cli/status.d.ts +22 -0
  38. package/dist/cli/tail.d.ts +18 -0
  39. package/dist/cli/target-resolver.d.ts +139 -0
  40. package/dist/cli/team-status.d.ts +91 -0
  41. package/dist/cli/teamfile-compat.d.ts +71 -0
  42. package/dist/cli/teamfile-store.d.ts +18 -0
  43. package/dist/cli/teamfile-template.d.ts +40 -0
  44. package/dist/cli/template-env.d.ts +25 -0
  45. package/dist/cli/terminal-lock.d.ts +25 -0
  46. package/dist/cli/terminal.d.ts +23 -0
  47. package/dist/cli/time-filter.d.ts +10 -0
  48. package/dist/cli/update-notifier.d.ts +11 -0
  49. package/dist/cli/version-util.d.ts +2 -0
  50. package/dist/config/seed_templates.d.ts +1 -0
  51. package/dist/db/backfill-event-log.d.ts +26 -0
  52. package/dist/db/delegation.d.ts +37 -0
  53. package/dist/db/escalation_vocab.d.ts +45 -0
  54. package/dist/db/event-log.d.ts +40 -0
  55. package/dist/db/index.d.ts +1213 -0
  56. package/dist/db/inflight-acquire.d.ts +70 -0
  57. package/dist/db/invocation-event-projections.d.ts +65 -0
  58. package/dist/db/ledger-identity.test.d.ts +1 -0
  59. package/dist/db/live-event-projections.d.ts +92 -0
  60. package/dist/db/migrate.d.ts +51 -0
  61. package/dist/db/open-readonly.d.ts +2 -0
  62. package/dist/db/process-liveness.d.ts +37 -0
  63. package/dist/db/sqlite.d.ts +47 -0
  64. package/dist/db/sqlite.test.d.ts +1 -0
  65. package/dist/db/terminal-lock.d.ts +14 -0
  66. package/dist/db/tracked-invocation-reconcile.d.ts +52 -0
  67. package/dist/db/tracked-invocation.d.ts +116 -0
  68. package/dist/mcp/dispatch.d.ts +45 -0
  69. package/dist/mcp/mediation.d.ts +128 -0
  70. package/dist/mcp/path-warning.d.ts +7 -0
  71. package/dist/mcp/server.d.ts +63 -0
  72. package/dist/mcp/tools.d.ts +24 -0
  73. package/dist/providers/adapter.d.ts +265 -0
  74. package/dist/providers/adapters/agy-adapter.d.ts +17 -0
  75. package/dist/providers/adapters/claude-adapter.d.ts +20 -0
  76. package/dist/providers/adapters/codex-adapter.d.ts +22 -0
  77. package/dist/providers/adapters/copilot-adapter.d.ts +16 -0
  78. package/dist/providers/adapters/dsh-adapter.d.ts +89 -0
  79. package/dist/providers/adapters/gemini-adapter.d.ts +44 -0
  80. package/dist/providers/adapters/hermes-adapter.d.ts +71 -0
  81. package/dist/providers/adapters/index.d.ts +35 -0
  82. package/dist/providers/adapters/kimi-adapter.d.ts +16 -0
  83. package/dist/providers/adapters/lmplayer-adapter.d.ts +14 -0
  84. package/dist/providers/adapters/opencode-adapter.d.ts +11 -0
  85. package/dist/providers/adapters/pi-adapter.d.ts +17 -0
  86. package/dist/providers/adapters/print-turn.d.ts +29 -0
  87. package/dist/providers/adapters/qwen-adapter.d.ts +11 -0
  88. package/dist/providers/agy.d.ts +32 -0
  89. package/dist/providers/base-adapter.d.ts +107 -0
  90. package/dist/providers/base.d.ts +12 -0
  91. package/dist/providers/binary-check.d.ts +102 -0
  92. package/dist/providers/bundle.d.ts +118 -0
  93. package/dist/providers/claude-mock.d.ts +90 -0
  94. package/dist/providers/claude.d.ts +21 -0
  95. package/dist/providers/codex-config.d.ts +15 -0
  96. package/dist/providers/codex.d.ts +25 -0
  97. package/dist/providers/config/model-selection-lint.d.ts +45 -0
  98. package/dist/providers/config/team-config.d.ts +183 -0
  99. package/dist/providers/config/types.d.ts +146 -0
  100. package/dist/providers/config/user-config.d.ts +88 -0
  101. package/dist/providers/copilot.d.ts +21 -0
  102. package/dist/providers/debug.d.ts +128 -0
  103. package/dist/providers/dsh-sidecar.d.ts +65 -0
  104. package/dist/providers/dsh-zstd.d.ts +27 -0
  105. package/dist/providers/dsh.d.ts +37 -0
  106. package/dist/providers/frontmatter.d.ts +46 -0
  107. package/dist/providers/gemini-session-reader.d.ts +151 -0
  108. package/dist/providers/gemini.d.ts +39 -0
  109. package/dist/providers/hermes.d.ts +90 -0
  110. package/dist/providers/index.d.ts +421 -0
  111. package/dist/providers/kimi.d.ts +37 -0
  112. package/dist/providers/model-catalog.d.ts +141 -0
  113. package/dist/providers/one-shot-timeout.d.ts +1 -0
  114. package/dist/providers/opencode-config.d.ts +62 -0
  115. package/dist/providers/opencode.d.ts +40 -0
  116. package/dist/providers/parsers/acp.d.ts +47 -0
  117. package/dist/providers/parsers/codex-app-server.d.ts +60 -0
  118. package/dist/providers/parsers/stream-json.d.ts +57 -0
  119. package/dist/providers/passive-readers/agy.d.ts +155 -0
  120. package/dist/providers/passive-readers/copilot.d.ts +173 -0
  121. package/dist/providers/passive-readers/dsh.d.ts +34 -0
  122. package/dist/providers/passive-readers/kimi.d.ts +44 -0
  123. package/dist/providers/passive-readers/opencode.d.ts +89 -0
  124. package/dist/providers/passive-readers/qwen.d.ts +151 -0
  125. package/dist/providers/passive-readers/shared.d.ts +138 -0
  126. package/dist/providers/passive-session-reader.d.ts +188 -0
  127. package/dist/providers/path-utils.d.ts +1 -0
  128. package/dist/providers/pi.d.ts +32 -0
  129. package/dist/providers/pricing.d.ts +107 -0
  130. package/dist/providers/qwen.d.ts +22 -0
  131. package/dist/providers/ratelimit-readings.d.ts +32 -0
  132. package/dist/providers/registry.d.ts +31 -0
  133. package/dist/providers/resume.d.ts +43 -0
  134. package/dist/providers/seed-instruction.d.ts +3 -0
  135. package/dist/providers/self-session-env.d.ts +21 -0
  136. package/dist/providers/session-limit.d.ts +9 -0
  137. package/dist/providers/strip-ansi.d.ts +5 -0
  138. package/dist/providers/transport-errors.d.ts +94 -0
  139. package/dist/providers/transport-lifecycle.d.ts +63 -0
  140. package/dist/providers/transport-wrappers.d.ts +110 -0
  141. package/dist/providers/transports/acp-profiles/config-option-step.d.ts +24 -0
  142. package/dist/providers/transports/acp-profiles/copilot.d.ts +12 -0
  143. package/dist/providers/transports/acp-profiles/gemini.d.ts +22 -0
  144. package/dist/providers/transports/acp-profiles/hermes.d.ts +27 -0
  145. package/dist/providers/transports/acp-profiles/index.d.ts +19 -0
  146. package/dist/providers/transports/acp-profiles/kimi.d.ts +24 -0
  147. package/dist/providers/transports/acp-profiles/opencode.d.ts +26 -0
  148. package/dist/providers/transports/acp-profiles/types.d.ts +258 -0
  149. package/dist/providers/transports/acp-rpc.d.ts +18 -0
  150. package/dist/providers/transports/acp.d.ts +215 -0
  151. package/dist/providers/transports/codex-app-server.d.ts +190 -0
  152. package/dist/providers/transports/hold-open.d.ts +120 -0
  153. package/dist/providers/transports/manager.d.ts +21 -0
  154. package/dist/providers/transports/stream-json.d.ts +162 -0
  155. package/dist/providers/transports/types.d.ts +56 -0
  156. package/dist/providers/types.d.ts +154 -0
  157. package/dist/providers/yolo-contract.d.ts +131 -0
  158. package/dist/script/adapter.d.ts +101 -0
  159. package/dist/script/batch-script.d.ts +7 -0
  160. package/dist/script/index.d.ts +3 -0
  161. package/dist/script/lmscript.d.ts +550 -0
  162. package/dist/shared/policy.d.ts +74 -0
  163. package/dist/shared-lib/db.d.ts +25 -0
  164. package/dist/shared-lib/passive-session-reader.d.ts +2 -0
  165. package/dist/shared-lib/provider-parse.d.ts +6 -0
  166. package/dist/templates/basedir.d.ts +52 -0
  167. package/dist/uri/lmctl_uri.d.ts +38 -0
  168. package/durable-memory/model_selection.md +108 -25
  169. package/examples/README.md +103 -0
  170. package/examples/anonymous-panel.lms +3 -0
  171. package/examples/batch-prompts.txt +9 -0
  172. package/examples/batchscript.lms +67 -0
  173. package/examples/n8n/agent-lib.lms +56 -0
  174. package/examples/n8n/git-lib.lms +93 -0
  175. package/examples/n8n/mock-support.db +0 -0
  176. package/examples/n8n/multi-agent-review.lms +107 -0
  177. package/examples/n8n/news-digest.lms +159 -0
  178. package/examples/n8n/rag-search.lms +163 -0
  179. package/examples/n8n/support-agent.lms +88 -0
  180. package/examples/n8n/ticket-triage.lms +156 -0
  181. package/package.json +13 -17
  182. package/dist/cli/side_effect_classifier.json +0 -19
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Thin adapter mounting lmt + lmauto as `lmctl` subcommands, gated behind
3
+ * `LMCTL_INFRA_CLI`. Off by default — see
4
+ * ~/repos/infraqa/lmctl-thin-merge-design.md (§2.2 "the seam") for the
5
+ * original design; this was P2 of that design's phasing.
6
+ *
7
+ * STATUS (2026-09-10, lmauto.lmctl): `lmt` (the target this adapter was built
8
+ * against) is now RETIRED — see ~/repos/tools/lmt/RETIRED.md. Its command
9
+ * surface was absorbed natively into `@lmctl-ai/lmbee` (the renamed
10
+ * `lmauto`), but lmbee does NOT export the `InfraLmtModule` contract this
11
+ * file expects (`INFRA_CLI_CONTRACT`/`createRuntime`/a raw-exit-code
12
+ * `dispatch(argv, runtime)`) — lmbee's own `dispatch(context, argv)` has a
13
+ * different signature and return shape (`Promise<{output, exitCode}>`,
14
+ * requires a `CliContext` built via `buildContext()`, not a bare
15
+ * `runtime`), and it has no concept of a frozen `INFRA_CLI_CONTRACT` version
16
+ * number at all (that was an lmt-specific, this-adapter-specific concept).
17
+ * Blindly swapping the import target from `@lmctl-ai/lmt` to
18
+ * `@lmctl-ai/lmbee` would NOT make this adapter work — it would still throw,
19
+ * just for a different reason (shape mismatch, not MODULE_NOT_FOUND), while
20
+ * looking superficially "fixed." `defaultLoadInfraModule` below has been
21
+ * changed to throw directly instead of importing a package that no longer
22
+ * has any plausible target, so the previously-accurate-but-now-stale
23
+ * "private repo, no CI credential" reasoning doesn't linger as a misleading
24
+ * TODO. Reviving `LMCTL_INFRA_CLI` needs a real design pass against lmbee's
25
+ * actual `dispatch()`/`buildContext()` shape (coordinate with lmauto.lmctl,
26
+ * lmbee's owner) — not a mechanical rename, and out of scope for this
27
+ * cleanup. Still safely inert either way: `runInfraCommand`'s catch below
28
+ * already handles the throw as the correct "not available" remediation
29
+ * case, and the feature stays off by default.
30
+ *
31
+ * lmauto's own P1 landed first (lmauto-cli-v0.2.21, verified against
32
+ * ~/repos/lmauto/src/cli/dispatch.ts): its `dispatch()` never throws for
33
+ * ordinary usage/validation misuse (every malformed argv returns
34
+ * `{output, exitCode: 1}`; only a genuine internal failure — DB/fs error —
35
+ * still propagates), and it now exports `COMMANDS` (its 16 routable verbs,
36
+ * as of the lmbee migration's Stage 2) + `PROCESS_ONLY_COMMANDS`
37
+ * (`whoami`/`migrate-home`/`serve`/`peers`/`tell`/`sites`/`exec`/`fleet`/the
38
+ * 6 cloud-service adapters, reachable only through lmbee's own bin, never
39
+ * through `dispatch()`). Neither changes anything HERE: `InfraLmtModule.
40
+ * dispatch`'s return shape below was lmt's own contract, one layer above
41
+ * lmauto's/lmbee's own — with lmt retired, that specific contract has no
42
+ * living implementation to target at all anymore, lmbee's own `dispatch()`
43
+ * shape included. Also confirmed with lmauto/lmbee directly: its DB
44
+ * resolution (`buildContext()`/`resolveLmautoDbPath()`) has no concept of
45
+ * lmctl's `--db` anywhere in the chain, so the `--db` firewall correctly
46
+ * lives only in `src/cli/index.ts` (already shipped), not here.
47
+ */
48
+ import type { CliIo } from './common.js';
49
+ /** Design §2.2: lmt's embedding contract version this lmctl build expects. */
50
+ export declare const INFRA_CLI_CONTRACT_EXPECTED = 1;
51
+ /**
52
+ * Flat command names + the `auto` namespace, per the design's §2.1
53
+ * command-surface mapping. This list is pinned by the design doc itself,
54
+ * not derived from lmt's export — so it can be wired into `COMMANDS` and
55
+ * collision-checked before lmt exports anything.
56
+ */
57
+ export declare const INFRA_FLAT_COMMANDS: readonly ["lmchat", "lmmail", "lmnote", "lmsheet", "lmtext", "lmsound", "login", "whoami", "exec", "tell", "peers", "site"];
58
+ export declare const INFRA_NAMESPACE_COMMAND = "auto";
59
+ export declare function infraCliEnabled(env?: NodeJS.ProcessEnv): boolean;
60
+ export declare function isInfraCommand(command: string): boolean;
61
+ interface InfraLmtModule {
62
+ INFRA_CLI_CONTRACT: number;
63
+ createRuntime: (...args: unknown[]) => unknown;
64
+ dispatch: (argv: string[], runtime: unknown) => Promise<number> | number;
65
+ }
66
+ /** Test seam — production always uses {@link defaultLoadInfraModule}. */
67
+ export type InfraModuleLoader = () => Promise<InfraLmtModule>;
68
+ /**
69
+ * Design §2.6 acceptance criteria, implemented ahead of the real module:
70
+ * - optional-absent → exit 1 + the exact remediation string (never throws
71
+ * up through the CLI dispatcher).
72
+ * - contract-version skew → refuse rather than dispatch into a mismatched
73
+ * manifest.
74
+ * - pass-through parity → argv forwarded verbatim (minus the `auto`
75
+ * prefix), no re-parsing here.
76
+ */
77
+ export declare function runInfraCommand(command: string, args: string[], io: CliIo, loadModule?: InfraModuleLoader): Promise<number>;
78
+ export {};
@@ -0,0 +1,2 @@
1
+ import { type CliIo } from './common.js';
2
+ export declare function runLs(args: string[], io?: CliIo): Promise<number>;
@@ -0,0 +1,6 @@
1
+ export interface AgentIdentity {
2
+ teamfile: string;
3
+ alias: string;
4
+ value: string;
5
+ }
6
+ export declare function splitCanonicalIdentity(identity: string): AgentIdentity;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * P3 (briefs/lmctl0-verbs-native-port-design.md §2.4 / §2.5) — managed
3
+ * mode shared helpers. Consumed by terminal/chat/tail/info/ls when the
4
+ * P0 classifier returns `{mode:'managed'}`. The §2.4 precedence is
5
+ * kind-keyed (verbatim from the design):
6
+ *
7
+ * • workflow_escalation → attention payload is context-only; resolve
8
+ * the agent via the latest `agent_call`
9
+ * session_event for the RUN (never via
10
+ * interactive_session; never via a
11
+ * payload.step_id == session_event.step_id
12
+ * join — see Dal.latestAgentCall doc-comment).
13
+ * • interactive_waiting_op → interactive_session is authoritative for
14
+ * the paused step + resumeInteractive.
15
+ * Agent identity still via latestAgentCall.
16
+ * • running (no attention) → latestAgentCall only.
17
+ * • none resolves → clear error (no DAL write).
18
+ *
19
+ * All helpers are read-only; spawn nothing. They take `Dal` so callers
20
+ * can inject a memory DAL in tests.
21
+ */
22
+ import type { Dal } from '../db/index.js';
23
+ export interface ManagedAgent {
24
+ /** Resolved provider for the agent session. */
25
+ provider: string;
26
+ /** Native session id (the provider's id). */
27
+ sessionid: string;
28
+ /** Working directory for the provider TUI. */
29
+ sessiondir: string;
30
+ /** Team-member alias the run's latest agent_call drove. */
31
+ alias: string;
32
+ /** Optional model override. */
33
+ model?: string;
34
+ }
35
+ /**
36
+ * Resolve a run-id to its agent provider session (§2.4 precedence). Uses
37
+ * `Dal.latestAgentCall` — RUN-keyed, ORDER BY id DESC — and falls back to
38
+ * the single-member team rule (§2.5) when no agent_call has been written
39
+ * yet. NEVER joins `session_event` by `payload.step_id`, NEVER consults
40
+ * `interactive_session`.
41
+ *
42
+ * `aliasOverride` (optional) — if provided, looks up that specific member
43
+ * (skipping latestAgentCall). Used by callers that surface `--alias A`
44
+ * alongside `--run <id>` per the §3 grammar / §2.5 disambiguation.
45
+ *
46
+ * Returns `{ok:<ManagedAgent>}` on success or `{err:<message>}` on any
47
+ * resolution failure (caller surfaces as a clear user-error).
48
+ */
49
+ export declare function resolveManagedAgent(dal: Dal, run_id: number, aliasOverride?: string): {
50
+ ok: ManagedAgent;
51
+ } | {
52
+ err: string;
53
+ };
54
+ /**
55
+ * Find the run's pending operator-answerable attention (if any).
56
+ * Returns the unacked `requires_user=1` attention row's `{kind, attention_id}`
57
+ * or null. Read-only.
58
+ */
59
+ export declare function pendingOperatorAttention(dal: Dal, run_id: number): {
60
+ kind: string;
61
+ attention_id: number;
62
+ } | null;
@@ -0,0 +1,23 @@
1
+ import type { CliIo } from './common.js';
2
+ import type { TeamConfig } from '../providers/config/team-config.js';
3
+ interface McpInstallFileOps {
4
+ existsSync(path: string): boolean;
5
+ mkdirSync(path: string, opts: {
6
+ recursive: true;
7
+ }): unknown;
8
+ readFileSync(path: string, encoding: 'utf8'): string;
9
+ writeFileSync(path: string, data: string, encoding: 'utf8'): unknown;
10
+ renameSync(oldPath: string, newPath: string): unknown;
11
+ unlinkSync(path: string): unknown;
12
+ }
13
+ export type CopilotMcpServerConfig = Record<string, unknown>;
14
+ export declare function _setMcpInstallTestHooksForTests(input: {
15
+ homeDir?: string;
16
+ fileOps?: Partial<McpInstallFileOps>;
17
+ } | null): void;
18
+ export declare function cleanupStaleMcpForTeam(io: CliIo, config: TeamConfig, teamfilePath: string): void;
19
+ export declare function copilotMcpConfigPath(homeDir?: string): string;
20
+ export declare function mergeCopilotMcpServers(path: string, desiredServers: Record<string, CopilotMcpServerConfig>): {
21
+ changed: boolean;
22
+ };
23
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { CliIo } from './common.js';
2
+ export declare function runMcp(args: string[], io?: CliIo, stdin?: NodeJS.ReadableStream): Promise<number>;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * ~/.lmctl root directory (or override via `LMCTL_HOME`).
3
+ *
4
+ * `LMCTL_HOME` is the absolute path TO `.lmctl` (i.e. the directory that
5
+ * contains `state.db`) — not the parent. Used by tests to redirect the entire
6
+ * state tree.
7
+ *
8
+ * Without an override we use `os.homedir()` + `.lmctl`. Note: on POSIX, libuv
9
+ * resolves `homedir` from /etc/passwd rather than `$HOME`, which is why we
10
+ * expose a dedicated env override instead of relying on `$HOME` for test
11
+ * isolation.
12
+ */
13
+ export declare function lmctlNextHome(): string;
14
+ /** The default DB path: ~/.lmctl/state.db (under `LMCTL_HOME`). */
15
+ export declare function defaultDbPath(): string;
16
+ /**
17
+ * Single source of truth for the state.db path.
18
+ *
19
+ * Priority order (highest first):
20
+ * 1. dbFlag arg (passed via top-level `--db PATH` flag)
21
+ * 2. process.env.LMCTL_DB
22
+ * 3. ~/.lmctl/state.db (under `LMCTL_HOME`)
23
+ *
24
+ * Parent directories are created on first DB open by migrate().
25
+ */
26
+ export declare function resolveDbPath(dbFlag?: string): string;
27
+ /**
28
+ * One-line human rendering of the resolved state location, shared by
29
+ * `lmctl status`'s footer and the stale-SELF-marker error so both name the DB
30
+ * the same way. When the path came from an explicit `--db`/`LMCTL_DB` override,
31
+ * the label says so.
32
+ */
33
+ export declare function describeStateLocation(dbPath: string): string;
34
+ /**
35
+ * Detect whether `dbPath` lives on a WSL `/mnt/c` Windows-mounted volume.
36
+ * WSL Windows-mount IO is ~5-10x slower than the native ext4 home volume,
37
+ * which surfaces as flaky locks + slow migrations. We emit a one-line
38
+ * stderr hint at startup so operators can move the DB if they hit it.
39
+ *
40
+ * Exposed for tests; production callers should use `warnIfSlowDbPath`.
41
+ */
42
+ export declare function isSlowWslMount(dbPath: string, plat?: NodeJS.Platform): boolean;
43
+ /**
44
+ * Print a one-line stderr warning if `dbPath` is on `/mnt/c`. No-op on
45
+ * non-Linux platforms and on non-`/mnt/c` paths. Idempotent — safe to call
46
+ * once at startup.
47
+ */
48
+ export declare function warnIfSlowDbPath(dbPath: string, stderr?: {
49
+ write: (chunk: string) => unknown;
50
+ }, plat?: NodeJS.Platform): void;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Interactive fallback for `lmctl plan`: a plain node:readline wizard (no new
3
+ * dependencies). Every question here has a flag equivalent on `runPlan`; this
4
+ * module only runs when config flags are absent and stdin is a TTY (or
5
+ * `--wizard` forced it). It returns the final teamfile text plus where to
6
+ * write it — plan.ts owns the actual write/lint/seed pipeline so the flags
7
+ * path and the wizard path behave identically after this point.
8
+ */
9
+ import { type ProviderBinaryCheck } from '../providers/binary-check.js';
10
+ import type { CliIo } from './common.js';
11
+ import { type MemberSpec } from './teamfile-template.js';
12
+ export interface PlanWizardInitial {
13
+ provider?: string;
14
+ model?: string;
15
+ pattern?: string;
16
+ members?: MemberSpec[];
17
+ seed?: boolean;
18
+ /** Explicit --output destination; skips the directory/name questions. */
19
+ output?: string;
20
+ }
21
+ export interface PlanWizardResult {
22
+ destPath: string;
23
+ text: string;
24
+ seed: boolean;
25
+ }
26
+ export interface PlanWizardOptions {
27
+ io: CliIo;
28
+ /** Line source for readline — real stdin in the CLI, a scripted stream in tests. */
29
+ input: NodeJS.ReadableStream;
30
+ cwd: string;
31
+ /** Preselected directory (positional arg); defaults to cwd. */
32
+ directory?: string;
33
+ initial?: PlanWizardInitial;
34
+ /** Test seam — defaults to probing PATH via checkProviderBinaries. */
35
+ checkProviders?: () => ProviderBinaryCheck[];
36
+ /** Test seam — defaults to spawning $EDITOR synchronously on the temp file. */
37
+ editFile?: (path: string) => void;
38
+ env?: NodeJS.ProcessEnv;
39
+ }
40
+ export declare function runPlanWizard(opts: PlanWizardOptions): Promise<PlanWizardResult | null>;
41
+ /** Members for reporting after a wizard run — re-parse so `$EDITOR` changes are reflected. */
42
+ export declare function wizardMembers(text: string): MemberSpec[];
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `lmctl plan` — flags-first, wizard-fallback teamfile generator.
3
+ *
4
+ * Every wizard question has a flag; the wizard fires only when no config
5
+ * flags are present AND stdin is a TTY (`--wizard` forces it,
6
+ * `--non-interactive` suppresses it with a missing-params error). Session
7
+ * ids are never generated here — seeding is `lmctl seed`'s job, chained via
8
+ * `--seed` (lint first, refuse to seed when lint fails).
9
+ */
10
+ import type { ProviderBinaryCheck } from '../providers/binary-check.js';
11
+ import type { CliIo } from './common.js';
12
+ /** Test seams — fetch for --from URLs, provider probe + editor for the wizard. */
13
+ export interface PlanDeps {
14
+ fetchFn?: typeof fetch;
15
+ checkProviders?: () => ProviderBinaryCheck[];
16
+ editFile?: (path: string) => void;
17
+ /** Overrides stdin TTY detection (wizard auto-trigger). */
18
+ stdinIsTTY?: boolean;
19
+ }
20
+ export declare function runPlan(args: string[], io?: CliIo, deps?: PlanDeps): Promise<number>;
@@ -0,0 +1,107 @@
1
+ import { chat as libraryChat, type ProgressEvent } from '../providers/index.js';
2
+ import type { BundleSession } from '../providers/bundle.js';
3
+ import type { CliIo } from './common.js';
4
+ import type { PermissionMode } from '../providers/yolo-contract.js';
5
+ /**
6
+ * Hold-open predicate for the receiver's provider turn
7
+ * (BUG-chat-client-death-interrupts-receiver-live-session).
8
+ *
9
+ * The stream-json transport closes the provider child's stdin on the first
10
+ * result event, which makes headless claude exit immediately — orphaning any
11
+ * `run_in_background` dispatches the receiver fired during its turn. The
12
+ * durable "this session still has outstanding dispatched work" signal is an
13
+ * `agent_inflight` row whose SENDER is the receiver's own identity, held by
14
+ * a live pid: every `lmctl prompt` the receiver dispatched acquires exactly
15
+ * such a lease (its sender attribution comes from LMCTL_SELF_SESSIONID in
16
+ * the provider spawn env) and releases it when the dispatched turn
17
+ * finalizes.
18
+ *
19
+ * Predicate scope, deliberately narrow:
20
+ * - DIRECT children only (rows where sender = the session being run),
21
+ * never the transitive subtree. This is sufficient by recursion, not an
22
+ * approximation (operator-confirmed 2026-07-26): a direct child that
23
+ * dispatched further work applies this same holdOpen check before ITS
24
+ * stdin closes, so it holds its own lease — the one we watch — until
25
+ * its children are done. The same fix at every level yields full
26
+ * subtree coverage through one-hop checks; walking deeper would be
27
+ * redundant, not more correct.
28
+ * - live local pid required (`isProcessAlive`): dead-pid and null-pid rows
29
+ * are orphans for the reclaim machinery, not outstanding work — waiting
30
+ * on a corpse would hold the turn open for nothing. agent_inflight has
31
+ * no host column; like the busy check, liveness is judged against the
32
+ * local host (pre-existing remote-holder ambiguity, unchanged here).
33
+ * - the lease for THIS delivery (receiver == the session being run) is
34
+ * excluded — without that guard a self-addressed chat would wait on its
35
+ * own lease until max-hold.
36
+ *
37
+ * Bounding (the "stuck row" question): the real bound is per-poll liveness —
38
+ * a holder that dies or gets reclaimed drops out on the next poll. maxHoldMs
39
+ * (= the agent_inflight TTL, 8h default) is last-resort insurance against a
40
+ * live-but-wedged holder; anything SHORTER would re-introduce the original
41
+ * bug by killing legitimately long dispatched work, and the adapter's idle
42
+ * timer (same 8h default, resolves 'stalled') backstops independently.
43
+ */
44
+ export declare function buildDispatchHoldOpen(io: CliIo, receiver: LaneIdentity, env: NodeJS.ProcessEnv): NonNullable<Parameters<typeof libraryChat>[0]['holdOpen']>;
45
+ export interface LaneIdentity {
46
+ teamfile: string;
47
+ alias: string;
48
+ }
49
+ export interface LaneDeliveryTarget extends LaneIdentity {
50
+ provider: string;
51
+ sessionId: string;
52
+ cwd: string;
53
+ model?: string;
54
+ effort?: string;
55
+ isLead?: boolean;
56
+ }
57
+ export interface DeliverLaneInput {
58
+ sender: LaneIdentity;
59
+ receiver: LaneDeliveryTarget;
60
+ newMessage: string;
61
+ newMessageFrom?: string;
62
+ io: CliIo;
63
+ permissionMode: PermissionMode;
64
+ env: NodeJS.ProcessEnv;
65
+ idleTimeoutMs?: number;
66
+ /** Multi-turn callers must never fall back to a fresh provider session. */
67
+ requireResume?: boolean;
68
+ /**
69
+ * Caller-held bundle provider session (batch bundle mode): the turn
70
+ * goes through the already-open provider process. When set, the
71
+ * `holdOpen` below is still built but ignored by the transport — the
72
+ * bundle's persistence IS the hold, and its close() runs the check once.
73
+ */
74
+ bundleSession?: BundleSession;
75
+ onDelta?: (chunk: string) => void;
76
+ onProgress?: (event: ProgressEvent) => void;
77
+ onPromptBuilt?: (prompt: string) => void | Promise<void>;
78
+ }
79
+ export type DeliverLaneResult = {
80
+ status: 'ok';
81
+ receipt: string;
82
+ prompt: string;
83
+ wroteDelta: boolean;
84
+ durationMs?: number;
85
+ /** Task #232: human-readable strings when the provider silently
86
+ * dropped a declared model=/effort=. Omitted when nothing was dropped. */
87
+ warnings?: string[];
88
+ } | {
89
+ status: 'stalled';
90
+ receipt: string;
91
+ prompt: string;
92
+ wroteDelta: boolean;
93
+ durationMs?: number;
94
+ stalledAfterMs?: number;
95
+ warnings?: string[];
96
+ } | {
97
+ status: 'error';
98
+ receipt: string;
99
+ prompt: string;
100
+ wroteDelta: boolean;
101
+ durationMs?: number;
102
+ error: string;
103
+ };
104
+ export declare function deliverLane(input: DeliverLaneInput): Promise<DeliverLaneResult>;
105
+ export declare function renderQueuedChatPrompt(newPrompt: string, options?: {
106
+ newMessageFrom?: string;
107
+ }): string;
@@ -0,0 +1,3 @@
1
+ import { type CliIo } from './common.js';
2
+ export { _setRatelimitFsDepsForTests, _setRatelimitRunnerForTests } from '../providers/ratelimit-readings.js';
3
+ export declare function runRatelimit(args: string[], io: CliIo): Promise<number>;
@@ -0,0 +1,7 @@
1
+ export declare function isHttpsUrl(value: string): boolean;
2
+ export declare function isUrlLike(value: string): boolean;
3
+ export declare function httpsOnlyError(value: string, noun: string): string | null;
4
+ export declare function fetchHttpsBytes(url: string, options: {
5
+ description: string;
6
+ timeoutMs?: number;
7
+ }): Promise<Buffer>;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * DAL-pure run/attention/escalation read queries shared by the surviving
3
+ * stateless commands (`prompt --run`, `ls --runs`, the MCP mediation core).
4
+ *
5
+ * Relocated verbatim from src/serve/data.ts when the daemon/HTTP surface
6
+ * (`serve`/`api`) moved to lmbee — these helpers import only db types and
7
+ * perform no I/O beyond `dal.query`.
8
+ */
9
+ import type { AttentionRow, Dal, RunRow } from '../db/index.js';
10
+ export declare function listRuns(dal: Dal, opts?: {
11
+ limit?: number;
12
+ }): RunRow[];
13
+ export declare function listAttentions(dal: Dal, opts?: {
14
+ unacked?: boolean;
15
+ }): AttentionRow[];
16
+ export interface EscalationRow {
17
+ attention_id: number;
18
+ /**
19
+ * Discriminator for the operator response contract. Interactive rows resume
20
+ * an `interactive_session`; workflow escalations are session-free DEF-1
21
+ * decisions and accept only a declared outcome token or `@abort`.
22
+ */
23
+ kind: string;
24
+ /**
25
+ * Attention severity tier. Historical attention values were error/warn/info-ish.
26
+ *
27
+ * project_issue #37 item 5: `"attn"` is the value used for the new
28
+ * `interactive_waiting_operator` (operator-pause) escalations. It is an
29
+ * intentional new tier — these are NOT errors and NOT warnings; they are
30
+ * operator-attention requests with no provenance baggage. UI/tooling that
31
+ * filters or color-codes by severity should branch on "attn" alongside the
32
+ * pre-existing error/warn/info-ish values.
33
+ */
34
+ severity: string | null;
35
+ created_at: string;
36
+ project_id: number | null;
37
+ project: string | null;
38
+ run_id: number | null;
39
+ workflow_name: string | null;
40
+ step_id: number | null;
41
+ state_name: string | null;
42
+ prompt: string | null;
43
+ /** Most recent interactive_session row status; null when no session linked. */
44
+ session_status: string | null;
45
+ /**
46
+ * ISO timestamp when the attention was acknowledged; null when still pending.
47
+ * Surfaced so operators using `escalations list --all` can distinguish acked
48
+ * from unacked history. project_issue #45.
49
+ */
50
+ acknowledged_at: string | null;
51
+ node_path: string[] | null;
52
+ expected_response: {
53
+ kind: string;
54
+ choices: string[] | null;
55
+ } | null;
56
+ transcript_tail: string[] | null;
57
+ paused_at: string | null;
58
+ created_run_inputs: Record<string, unknown> | null;
59
+ workflow_version_id: number | null;
60
+ /**
61
+ * Session-free workflow-escalation context copied from attention.payload.
62
+ * `workflow_escalation` has no interactive_session row, so the JOIN columns
63
+ * above are intentionally null for prompt/step details; SDKs and CLI clients
64
+ * must use these nullable fields to render the human prompt.
65
+ */
66
+ workflow_step: {
67
+ id: string;
68
+ name: string | null;
69
+ type: string | null;
70
+ } | null;
71
+ escalation_tier: string | null;
72
+ escalation_token: string | null;
73
+ escalation_reason: string | null;
74
+ declared_outcomes: string[] | null;
75
+ agent_output: string | null;
76
+ }
77
+ export declare function listEscalations(dal: Dal, opts?: {
78
+ project?: string;
79
+ all?: boolean;
80
+ since?: string;
81
+ }): EscalationRow[];
82
+ export declare function getEscalation(dal: Dal, attention_id: number): EscalationRow | null;
@@ -0,0 +1,5 @@
1
+ import { type CliIo } from './common.js';
2
+ /** Test-only seam: cap the number of `--watch` ticks so tests can exercise
3
+ * the loop without hanging on the SIGINT/SIGTERM shutdown. */
4
+ export declare function _setRunningWatchMaxTicksForTests(maxTicks: number | null): void;
5
+ export declare function runRunning(args: string[], io: CliIo): Promise<number>;
@@ -613,7 +613,13 @@ CREATE TABLE IF NOT EXISTS team_chat_log (
613
613
  status TEXT NOT NULL,
614
614
  error_detail TEXT,
615
615
  truncated INTEGER NOT NULL DEFAULT 0,
616
- created_at TEXT NOT NULL
616
+ created_at TEXT NOT NULL,
617
+ -- v61: batch-vs-individual framing ('batch' for rows belonging to a batch
618
+ -- run, NULL for individual chats). Distinct from
619
+ -- message_pending.message_type (request/response lane semantics).
620
+ -- Appended LAST so a fresh create and a v60->v61 ALTER-upgrade converge on
621
+ -- the same column order (migrate-v32's table_info parity check).
622
+ message_type TEXT CHECK(message_type IN ('batch'))
617
623
  );
618
624
  CREATE INDEX IF NOT EXISTS idx_team_chat_log_root_time
619
625
  ON team_chat_log(root_teamfile, created_at);
@@ -878,3 +884,16 @@ CREATE TABLE IF NOT EXISTS state_ledger_identity (
878
884
  instance_id TEXT NOT NULL,
879
885
  created_at TEXT NOT NULL
880
886
  );
887
+
888
+ -- v61: schema metadata kv. Holds min_reader_version -- the oldest build
889
+ -- schema version that may safely open this db (batch redesign Landing A,
890
+ -- item 0). migrate()'s skew check refuses a newer db only when
891
+ -- min_reader_version exceeds the binary's CURRENT_USER_VERSION; a db without
892
+ -- the marker defaults to its raw user_version (strict, pre-v61 behavior).
893
+ -- v61 is purely additive, so its floor is 60. Additive migrations keep/lower
894
+ -- the floor (INSERT OR IGNORE); breaking ones raise it to their own version.
895
+ CREATE TABLE IF NOT EXISTS schema_meta (
896
+ key TEXT PRIMARY KEY,
897
+ value TEXT NOT NULL
898
+ );
899
+ INSERT OR IGNORE INTO schema_meta (key, value) VALUES ('min_reader_version', '60');
@@ -0,0 +1,6 @@
1
+ import { type CliIo } from './common.js';
2
+ import { type FunctionDoc, type LMScript, type ScriptModule } from '../script/adapter.js';
3
+ export declare function formatFunctionDoc(doc: FunctionDoc): string;
4
+ export declare function formatModuleOverview(engine: LMScript, module: ScriptModule): string;
5
+ export declare function formatCategoryOverview(engine: LMScript): string;
6
+ export declare function runScript(args: string[], io?: CliIo): Promise<number>;