@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,23 +0,0 @@
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 {};
package/dist/cli/mcp.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { CliIo } from './common.js';
2
- export declare function runMcp(args: string[], io?: CliIo, stdin?: NodeJS.ReadableStream): Promise<number>;
@@ -1,21 +0,0 @@
1
- import { type CliIo } from './common.js';
2
- import { type CatalogSnapshot } from '../providers/pricing.js';
3
- export declare const MODEL_PROVIDERS: readonly ["codex", "agy", "claude", "kimi"];
4
- type ModelProvider = string;
5
- interface ModelList {
6
- available: boolean;
7
- models: string[];
8
- reason?: string;
9
- }
10
- interface ModelDeps {
11
- loadSnapshot?: () => Promise<CatalogSnapshot>;
12
- selections?: Array<{
13
- provider: string;
14
- models?: string[];
15
- }>;
16
- loadModels?: (provider: ModelProvider, snapshot: CatalogSnapshot) => ModelList | Promise<ModelList>;
17
- }
18
- /** Shared inventory for deterministic target matching; never sends a prompt. */
19
- export declare function knownModelNames(provider: string): Promise<string[]>;
20
- export declare function runModel(args: string[], io: CliIo, deps?: ModelDeps): Promise<number>;
21
- export {};
@@ -1,50 +0,0 @@
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;
@@ -1,42 +0,0 @@
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 { loadModelSuggestions } from '../providers/model-suggestions.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
- initConfigPath?: string;
35
- loadModels?: typeof loadModelSuggestions;
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[];
@@ -1,20 +0,0 @@
1
- import type { loadModelSuggestions } from '../providers/model-suggestions.js';
2
- import type { CliIo } from './common.js';
3
- /** Test seams — fetch for --from URLs, model suggestions + editor for the wizard. */
4
- export interface PlanDeps {
5
- fetchFn?: typeof fetch;
6
- loadModels?: typeof loadModelSuggestions;
7
- editFile?: (path: string) => void;
8
- /** Overrides stdin TTY detection (wizard auto-trigger). */
9
- stdinIsTTY?: boolean;
10
- /** Test seam: defaults to ~/.lmctl/init.toml (getDefaultInitConfigPath()). */
11
- initConfigPath?: string;
12
- }
13
- export declare function runPlan(args: string[], io?: CliIo, deps?: PlanDeps): Promise<number>;
14
- /** Reads a `--from`-style source: a local file, a directory holding exactly
15
- * one .lmctl file, or an https:// URL (https-only, redirect-pinned).
16
- * Exported for reuse by quickrun/hello, which fetch the same kinds of
17
- * sources (a teamfile template, or a per-provider example) via the same
18
- * rules -- no local http://, https-only redirects, one candidate file per
19
- * directory. */
20
- export declare function readPlanSource(source: string, fetchFn: typeof fetch, cwd: string): Promise<string>;
@@ -1,122 +0,0 @@
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
- /**
98
- * Real incident, 2026-09-29: kimi's ACP layer reported a clean
99
- * completion (no RPC error) with zero text and zero observed
100
- * activity for a turn that in fact hit a 403 quota-exhausted
101
- * failure -- "status=ok" is not allowed to mean this. ACP
102
- * transports only (see transport-wrappers.ts's emptyTurnStatus);
103
- * never set for stream-json/codex-app-server providers.
104
- */
105
- status: 'empty';
106
- receipt: string;
107
- prompt: string;
108
- wroteDelta: boolean;
109
- durationMs?: number;
110
- warnings?: string[];
111
- } | {
112
- status: 'error';
113
- receipt: string;
114
- prompt: string;
115
- wroteDelta: boolean;
116
- durationMs?: number;
117
- error: string;
118
- };
119
- export declare function deliverLane(input: DeliverLaneInput): Promise<DeliverLaneResult>;
120
- export declare function renderQueuedChatPrompt(newPrompt: string, options?: {
121
- newMessageFrom?: string;
122
- }): string;
@@ -1,14 +0,0 @@
1
- import { type CliIo } from './common.js';
2
- import { runTerminal } from './terminal.js';
3
- import { runScriptEngine } from '../script/adapter.js';
4
- export interface QuickrunDeps {
5
- fetchFn?: typeof fetch;
6
- cwd?: string;
7
- /** Test seam: defaults to ~/.lmctl/init.toml (getDefaultInitConfigPath()). */
8
- initConfigPath?: string;
9
- /** Test seam: defaults to the real runTerminal (a live provider TUI). */
10
- openTerminal?: typeof runTerminal;
11
- runScript?: typeof runScriptEngine;
12
- }
13
- /** Names resolve dynamically; the CLI has no compiled-in sample allowlist. */
14
- export declare function runQuickrun(args: string[], io?: CliIo, deps?: QuickrunDeps): Promise<number>;
@@ -1,2 +0,0 @@
1
- import { type CliIo } from './common.js';
2
- export declare function runRatelimit(args: string[], io: CliIo): Promise<number>;
@@ -1,7 +0,0 @@
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>;
@@ -1,82 +0,0 @@
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;
@@ -1,5 +0,0 @@
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>;
@@ -1,41 +0,0 @@
1
- import type { CliIo } from './common.js';
2
- export interface SaveScriptRequest {
3
- destPath: string;
4
- /** Resolved script name, e.g. "plan" (default) or "plan-minimal" (--script). */
5
- slug: string;
6
- /** File extension lmctl.com serves for this command's family, e.g. ".lms" or ".txt". */
7
- extension: string;
8
- force: boolean;
9
- }
10
- export interface ExtractSaveScriptResult {
11
- rest: string[];
12
- request?: SaveScriptRequest;
13
- error?: string;
14
- }
15
- /**
16
- * Strips --save-script <file>, --script <slug>, and (unless the command
17
- * already owns --force itself, e.g. `plan`) a bare --force from args.
18
- * --script only makes sense paired with --save-script.
19
- */
20
- export declare function extractSaveScriptFlags(args: string[], command: string, opts?: {
21
- ownsForce?: boolean;
22
- extension?: string;
23
- }): ExtractSaveScriptResult;
24
- /**
25
- * Fetches https://lmctl.com/lmscript/commands/<slug><extension> and writes
26
- * it to request.destPath. Verifies the full response BEFORE writing
27
- * anything -- a failed fetch, a 404, or an HTML page (offline/misconfigured
28
- * host fallback) never reaches the destination file, half-written or
29
- * otherwise.
30
- */
31
- export declare function performSaveScript(io: CliIo, request: SaveScriptRequest, fetchFn?: typeof fetch): Promise<number>;
32
- /**
33
- * Wraps a command's own run function with --save-script handling: strips
34
- * the flags, runs the command UNCHANGED with the remaining args, and -- only
35
- * if the command itself succeeded -- fetches and writes the script as an
36
- * additive side effect. A failed command is left alone; nothing is fetched.
37
- */
38
- export declare function runWithSaveScript(io: CliIo, command: string, args: string[], runCommand: (rest: string[]) => Promise<number>, opts?: {
39
- ownsForce?: boolean;
40
- extension?: string;
41
- }): Promise<number>;
@@ -1,6 +0,0 @@
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>;
@@ -1,2 +0,0 @@
1
- export declare function seedInProgress(teamfile: string, alias: string): boolean;
2
- export declare function beginSeedFlight(teamfile: string, alias: string): () => void;
@@ -1,25 +0,0 @@
1
- import type { Dal } from '../db/index.js';
2
- export type SelfIdentityInference = {
3
- ok: true;
4
- identity: string;
5
- } | {
6
- ok: false;
7
- reason: 'unset' | 'not-found';
8
- };
9
- export type ResolvedSelfIdentity = {
10
- ok: true;
11
- identity: string;
12
- source: 'session';
13
- } | {
14
- ok: false;
15
- reason: 'unset' | 'not-found';
16
- };
17
- export declare function manualInvocationMessage(command: string): string;
18
- export declare function unmatchedSelfSessionMessage(command: string): string;
19
- export declare function removedFromOptionMessage(command: string): string;
20
- export declare function extractSelfIdentityArg(args: string[], command: string): {
21
- args: string[];
22
- error?: string;
23
- };
24
- export declare function resolveSelfIdentity(env: NodeJS.ProcessEnv, dal: Pick<Dal, 'getRootTeam' | 'listRootTeams'>): ResolvedSelfIdentity;
25
- export declare function inferSelfIdentityFromEnv(env: NodeJS.ProcessEnv, dal: Pick<Dal, 'getRootTeam' | 'listRootTeams'>): SelfIdentityInference;
@@ -1,118 +0,0 @@
1
- /**
2
- * Session-idle availability override for delivery decisions.
3
- *
4
- * Operator (2026-07-22): *"also check the last update of session (from
5
- * sessionid), if it is been idle for 10 minute, then it is available (this
6
- * does not change terminal pid)."*
7
- *
8
- * THRESHOLD: 60 minutes, NOT the 10 initially requested. Do not "fix" this
9
- * back to 10 without re-running the numbers below.
10
- *
11
- * A misfire is not benign: the reclaim force-steals a lease from a LIVE holder
12
- * and starts a second turn on the same sessionid — the concurrent-resume abort
13
- * `b85c5a1` exists to prevent. So the threshold has to clear real turn
14
- * durations. Measured over completed chat turns, SPLIT BY OUTCOME — the split
15
- * is the whole point, an unsplit number is misleading in both directions:
16
- *
17
- * SELECT status, COUNT(*), SUM(CASE WHEN m>60 THEN 1 END), MAX(m)
18
- * FROM (SELECT status, (julianday(ended_at)-julianday(started_at))*1440 AS m
19
- * FROM tracked_invocation WHERE ended_at IS NOT NULL AND kind='chat')
20
- * GROUP BY status;
21
- *
22
- * status='done' n=2056 >60min: 0 longest: 51.8 min
23
- * status='error' n=1054 >60min: 191 longest: 2709 min (~45h)
24
- * status='busy' n=727 >60min: 0
25
- *
26
- * NO SUCCESSFULLY-COMPLETED CHAT TURN HAS EVER EXCEEDED 60 MINUTES. The longest
27
- * was 51.8 min, so 60min sits ~16% above the worst observed healthy turn. Every
28
- * one of the 191 turns past 60min ended in `error` — hung, aborted, abandoned:
29
- * exactly the population this feature exists to reclaim.
30
- *
31
- * Beware the unsplit figure: "5.0% of all turns exceed 60min" is arithmetically
32
- * true and materially misleading, because it counts already-failed turns as if
33
- * they were healthy ones at risk of a wrongful steal. Exposure among healthy
34
- * turns is zero in the observed record. (Turn DURATION is also only an upper
35
- * bound — the trigger needs a >60min GAP BETWEEN WRITES, and a turn making tool
36
- * calls keeps `modifiedAt` fresh.) 60min also still beats the 8h inflight TTL
37
- * by ~8x, which is the actual complaint being solved.
38
- *
39
- * Re-run the query rather than trusting these figures; if you retune, split by
40
- * status or the number will mislead you.
41
- * See `backlog/DESIGN-session-idle-availability-scope.md`.
42
- *
43
- * THE PROBLEM. An `in-flight` lease taken by `lmctl prompt`/relay delivery keeps
44
- * a receiver unreachable until the holder releases it or the 8h TTL expires.
45
- * A hung turn therefore blocks that receiver for hours. Holder-pid liveness
46
- * alone cannot detect this: the process is alive, it is just not progressing.
47
- *
48
- * THE SIGNAL. `SessionDetail.modifiedAt` — the provider's own session file
49
- * mtime, i.e. real conversation activity. Deliberately NOT the chat/terminal
50
- * heartbeat (`tracked_invocation.last_heartbeat_at`), which a timer in the
51
- * holder process refreshes every 30s whether the turn is working OR wedged.
52
- * The heartbeat distinguishes process-alive (already covered by the pid
53
- * check), not stuck-vs-working, so it cannot detect a hung turn at all.
54
- *
55
- * FAILS CLOSED, ALWAYS. Every failure path returns `false` = "not idle, keep
56
- * treating as busy". A false "available" lets two deliveries resume the same
57
- * held session and collide; a false "busy" only means the message waits
58
- * longer. Those costs are not symmetric, so the ambiguous cases (session not
59
- * found, ambiguous provider, read error, unresolvable member) all resolve to
60
- * busy. Same lesson as the reboot/pid-reuse work: never fail open on a
61
- * liveness question.
62
- *
63
- * SCOPE. This is an ADDITIVE override consulted only at the synchronous
64
- * chat delivery decision point (`chat-exec`) and only for the `in-flight`
65
- * busy reason. `terminal-held` is NEVER overridden at any idle duration — see
66
- * `isInflightButSessionIdle` below for why. It does not touch
67
- * `getReceiverBusyState`, the terminal lock, or any pid.
68
- */
69
- import type { Dal } from '../db/index.js';
70
- /**
71
- * Threshold override, matching the existing staleness-window convention in
72
- * this codebase (`LMCTL_INFLIGHT_TTL_MS`, `LMCTL_TERMINAL_LOCK_STALE_MS`):
73
- * ignore unset/blank/non-finite/non-positive values and fall back to the
74
- * 60-minute default.
75
- */
76
- export declare function sessionIdleTimeoutMsFromEnv(env?: NodeJS.ProcessEnv): number;
77
- /**
78
- * Has this receiver's underlying provider session been quiet for at least
79
- * `thresholdMs`?
80
- *
81
- * `true` ONLY when the session was found and its last activity is at or past
82
- * the threshold. Anything else — including every error — is `false`.
83
- */
84
- export declare function isReceiverIdleTimedOut(dal: Pick<Dal, 'getRootTeam' | 'listRootTeams'>, teamfile: string, alias: string, thresholdMs?: number): Promise<boolean>;
85
- /**
86
- * How long has this receiver's session been quiet, in ms? `null` when that
87
- * cannot be established for ANY reason — the fail-closed signal, and also what
88
- * the reclaim log reports so a steal can be judged after the fact.
89
- */
90
- export declare function sessionIdleMs(dal: Pick<Dal, 'getRootTeam' | 'listRootTeams'>, teamfile: string, alias: string): Promise<number | null>;
91
- /**
92
- * The delivery-side question, in one call: given the busy state we already
93
- * computed synchronously, may we deliver anyway because the session is idle?
94
- *
95
- * SCOPE — `in-flight` ONLY. Operator (2026-07-22): *"terminal-held is alway
96
- * regarded as busy, no matter how long idle is. session idle is only for
97
- * non-terminal session, that is through lmctl prompt."*
98
- *
99
- * `terminal-held` is NEVER overridden, at any idle duration. That case is a
100
- * human's interactive terminal — including a live codex/opencode TUI with a
101
- * persistent process attached — and declaring it available on a timestamp
102
- * would reintroduce exactly the concurrent-resume collision `b85c5a1`
103
- * ("Protect held sessions from stale lease steals") was written to prevent.
104
- * A quiet terminal is someone thinking, not an absent holder.
105
- *
106
- * `in-flight`, by contrast, is a lease taken by `lmctl prompt`/relay delivery:
107
- * bounded, ephemeral, non-interactive work. A live pid there with no session
108
- * file activity for the full window is most plausibly a hung turn, so it
109
- * is a reasonable reclaim target — the same spirit as the existing dead-pid
110
- * reclaim, adding long-idle-with-live-pid as a second trigger on the
111
- * chat-invoked path only.
112
- *
113
- * See `backlog/DESIGN-session-idle-availability-scope.md`.
114
- */
115
- export declare function isInflightButSessionIdle(dal: Pick<Dal, 'getRootTeam' | 'listRootTeams'>, busy: {
116
- busy: boolean;
117
- reason?: string;
118
- }, teamfile: string, alias: string, thresholdMs?: number): Promise<boolean>;
@@ -1,22 +0,0 @@
1
- import { type CliIo } from './common.js';
2
- /**
3
- * Path to the rolling intent log written by `status` (and, in future, by
4
- * other verbs that want a breadcrumb trail). Plain JSONL — one event per
5
- * line — so a troubleshooting bundle can ship it verbatim. Override via
6
- * `LMCTL_INTENT_LOG` for tests / non-default homes.
7
- */
8
- export declare function resolveIntentLogPath(): string;
9
- /**
10
- * Append a single intent record to the rolling log. Failures are
11
- * swallowed — the log is best-effort breadcrumbs, never load-bearing.
12
- */
13
- export declare function appendIntent(record: {
14
- verb: string;
15
- args: ReadonlyArray<string>;
16
- cwd?: string;
17
- ts?: string;
18
- }): void;
19
- export declare function runStatus(args: string[], io: CliIo): Promise<number>;
20
- export declare function formatDuration(ms: number): string;
21
- export declare function formatAge(iso: string): string;
22
- export declare function shortIdentity(identity: string): string;
@@ -1,18 +0,0 @@
1
- import type { ConversationMessage } from '../providers/types.js';
2
- import { type CliIo } from './common.js';
3
- export declare function runTail(args: string[], io?: CliIo): Promise<number>;
4
- /** Plain renderer (no chalk/ANSI per design R3). Indents continuation
5
- * lines so multi-line messages remain visually grouped. */
6
- export declare function renderMessage(msg: ConversationMessage): string;
7
- export declare function applyMaxBytes(output: string, maxBytes: number): string;
8
- /**
9
- * Same grammar as status.ts's parseStatusSince parser: a relative
10
- * duration (<n>s|m|h|d) or an absolute ISO8601
11
- * timestamp. Unlike status's version, `undefined` here means "no filter"
12
- * (tail's existing default is unchanged), not a default window.
13
- */
14
- export declare function parseTailSince(value: string | undefined): {
15
- date: Date | undefined;
16
- } | {
17
- error: string;
18
- };