@lmctl-ai/lmctl 0.1.342 → 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.
- package/CHANGELOG.md +116 -0
- package/README.md +11 -51
- package/data/price-aliases.json +1 -0
- package/data/price-data.json +1 -1
- package/dist/cli/batch.d.ts +2 -0
- package/dist/cli/busy-evidence.d.ts +27 -0
- package/dist/cli/chat-cycle.d.ts +59 -0
- package/dist/cli/chat-exec.d.ts +83 -0
- package/dist/cli/chat-policy.d.ts +22 -0
- package/dist/cli/chat.d.ts +23 -0
- package/dist/cli/code-resolver.d.ts +8 -0
- package/dist/cli/common.d.ts +54 -0
- package/dist/cli/context.d.ts +12 -0
- package/dist/cli/cost.d.ts +2 -0
- package/dist/cli/export.d.ts +2 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +1062 -1400
- package/dist/cli/infra.d.ts +78 -0
- package/dist/cli/ls.d.ts +2 -0
- package/dist/cli/mailbox-cli.d.ts +6 -0
- package/dist/cli/managed.d.ts +62 -0
- package/dist/cli/mcp-install.d.ts +23 -0
- package/dist/cli/mcp.d.ts +2 -0
- package/dist/cli/paths.d.ts +50 -0
- package/dist/cli/plan-wizard.d.ts +42 -0
- package/dist/cli/plan.d.ts +20 -0
- package/dist/cli/queue-delivery.d.ts +107 -0
- package/dist/cli/ratelimit.d.ts +3 -0
- package/dist/cli/remote-fetch.d.ts +7 -0
- package/dist/cli/run-queries.d.ts +82 -0
- package/dist/cli/running.d.ts +5 -0
- package/dist/cli/schema.sql +20 -1
- package/dist/cli/script.d.ts +6 -0
- package/dist/cli/script.js +2097 -0
- package/dist/cli/self-identity.d.ts +25 -0
- package/dist/cli/session-idle.d.ts +118 -0
- package/dist/cli/status.d.ts +22 -0
- package/dist/cli/tail.d.ts +18 -0
- package/dist/cli/target-resolver.d.ts +139 -0
- package/dist/cli/team-status.d.ts +91 -0
- package/dist/cli/teamfile-compat.d.ts +71 -0
- package/dist/cli/teamfile-store.d.ts +18 -0
- package/dist/cli/teamfile-template.d.ts +40 -0
- package/dist/cli/template-env.d.ts +25 -0
- package/dist/cli/terminal-lock.d.ts +25 -0
- package/dist/cli/terminal.d.ts +23 -0
- package/dist/cli/time-filter.d.ts +10 -0
- package/dist/cli/update-notifier.d.ts +11 -0
- package/dist/cli/version-util.d.ts +2 -0
- package/dist/config/seed_templates.d.ts +1 -0
- package/dist/db/backfill-event-log.d.ts +26 -0
- package/dist/db/delegation.d.ts +37 -0
- package/dist/db/escalation_vocab.d.ts +45 -0
- package/dist/db/event-log.d.ts +40 -0
- package/dist/db/index.d.ts +1213 -0
- package/dist/db/inflight-acquire.d.ts +70 -0
- package/dist/db/invocation-event-projections.d.ts +65 -0
- package/dist/db/ledger-identity.test.d.ts +1 -0
- package/dist/db/live-event-projections.d.ts +92 -0
- package/dist/db/migrate.d.ts +51 -0
- package/dist/db/open-readonly.d.ts +2 -0
- package/dist/db/process-liveness.d.ts +37 -0
- package/dist/db/sqlite.d.ts +47 -0
- package/dist/db/sqlite.test.d.ts +1 -0
- package/dist/db/terminal-lock.d.ts +14 -0
- package/dist/db/tracked-invocation-reconcile.d.ts +52 -0
- package/dist/db/tracked-invocation.d.ts +116 -0
- package/dist/mcp/dispatch.d.ts +45 -0
- package/dist/mcp/mediation.d.ts +128 -0
- package/dist/mcp/path-warning.d.ts +7 -0
- package/dist/mcp/server.d.ts +63 -0
- package/dist/mcp/tools.d.ts +24 -0
- package/dist/providers/adapter.d.ts +265 -0
- package/dist/providers/adapters/agy-adapter.d.ts +17 -0
- package/dist/providers/adapters/claude-adapter.d.ts +20 -0
- package/dist/providers/adapters/codex-adapter.d.ts +22 -0
- package/dist/providers/adapters/copilot-adapter.d.ts +16 -0
- package/dist/providers/adapters/dsh-adapter.d.ts +89 -0
- package/dist/providers/adapters/gemini-adapter.d.ts +44 -0
- package/dist/providers/adapters/hermes-adapter.d.ts +71 -0
- package/dist/providers/adapters/index.d.ts +35 -0
- package/dist/providers/adapters/kimi-adapter.d.ts +16 -0
- package/dist/providers/adapters/lmplayer-adapter.d.ts +14 -0
- package/dist/providers/adapters/opencode-adapter.d.ts +11 -0
- package/dist/providers/adapters/pi-adapter.d.ts +17 -0
- package/dist/providers/adapters/print-turn.d.ts +29 -0
- package/dist/providers/adapters/qwen-adapter.d.ts +11 -0
- package/dist/providers/agy.d.ts +32 -0
- package/dist/providers/base-adapter.d.ts +107 -0
- package/dist/providers/base.d.ts +12 -0
- package/dist/providers/binary-check.d.ts +102 -0
- package/dist/providers/bundle.d.ts +118 -0
- package/dist/providers/claude-mock.d.ts +90 -0
- package/dist/providers/claude.d.ts +21 -0
- package/dist/providers/codex-config.d.ts +15 -0
- package/dist/providers/codex.d.ts +25 -0
- package/dist/providers/config/model-selection-lint.d.ts +45 -0
- package/dist/providers/config/team-config.d.ts +183 -0
- package/dist/providers/config/types.d.ts +146 -0
- package/dist/providers/config/user-config.d.ts +88 -0
- package/dist/providers/copilot.d.ts +21 -0
- package/dist/providers/debug.d.ts +128 -0
- package/dist/providers/dsh-sidecar.d.ts +65 -0
- package/dist/providers/dsh-zstd.d.ts +27 -0
- package/dist/providers/dsh.d.ts +37 -0
- package/dist/providers/frontmatter.d.ts +46 -0
- package/dist/providers/gemini-session-reader.d.ts +151 -0
- package/dist/providers/gemini.d.ts +39 -0
- package/dist/providers/hermes.d.ts +90 -0
- package/dist/providers/index.d.ts +421 -0
- package/dist/providers/kimi.d.ts +37 -0
- package/dist/providers/model-catalog.d.ts +141 -0
- package/dist/providers/one-shot-timeout.d.ts +1 -0
- package/dist/providers/opencode-config.d.ts +62 -0
- package/dist/providers/opencode.d.ts +40 -0
- package/dist/providers/parsers/acp.d.ts +47 -0
- package/dist/providers/parsers/codex-app-server.d.ts +60 -0
- package/dist/providers/parsers/stream-json.d.ts +57 -0
- package/dist/providers/passive-readers/agy.d.ts +155 -0
- package/dist/providers/passive-readers/copilot.d.ts +173 -0
- package/dist/providers/passive-readers/dsh.d.ts +34 -0
- package/dist/providers/passive-readers/kimi.d.ts +44 -0
- package/dist/providers/passive-readers/opencode.d.ts +89 -0
- package/dist/providers/passive-readers/qwen.d.ts +151 -0
- package/dist/providers/passive-readers/shared.d.ts +138 -0
- package/dist/providers/passive-session-reader.d.ts +188 -0
- package/dist/providers/path-utils.d.ts +1 -0
- package/dist/providers/pi.d.ts +32 -0
- package/dist/providers/pricing.d.ts +107 -0
- package/dist/providers/qwen.d.ts +22 -0
- package/dist/providers/ratelimit-readings.d.ts +32 -0
- package/dist/providers/registry.d.ts +31 -0
- package/dist/providers/resume.d.ts +43 -0
- package/dist/providers/seed-instruction.d.ts +3 -0
- package/dist/providers/self-session-env.d.ts +21 -0
- package/dist/providers/session-limit.d.ts +9 -0
- package/dist/providers/strip-ansi.d.ts +5 -0
- package/dist/providers/transport-errors.d.ts +94 -0
- package/dist/providers/transport-lifecycle.d.ts +63 -0
- package/dist/providers/transport-wrappers.d.ts +110 -0
- package/dist/providers/transports/acp-profiles/config-option-step.d.ts +24 -0
- package/dist/providers/transports/acp-profiles/copilot.d.ts +12 -0
- package/dist/providers/transports/acp-profiles/gemini.d.ts +22 -0
- package/dist/providers/transports/acp-profiles/hermes.d.ts +27 -0
- package/dist/providers/transports/acp-profiles/index.d.ts +19 -0
- package/dist/providers/transports/acp-profiles/kimi.d.ts +24 -0
- package/dist/providers/transports/acp-profiles/opencode.d.ts +26 -0
- package/dist/providers/transports/acp-profiles/types.d.ts +258 -0
- package/dist/providers/transports/acp-rpc.d.ts +18 -0
- package/dist/providers/transports/acp.d.ts +215 -0
- package/dist/providers/transports/codex-app-server.d.ts +190 -0
- package/dist/providers/transports/hold-open.d.ts +120 -0
- package/dist/providers/transports/manager.d.ts +21 -0
- package/dist/providers/transports/stream-json.d.ts +162 -0
- package/dist/providers/transports/types.d.ts +56 -0
- package/dist/providers/types.d.ts +154 -0
- package/dist/providers/yolo-contract.d.ts +131 -0
- package/dist/script/adapter.d.ts +101 -0
- package/dist/script/batch-script.d.ts +7 -0
- package/dist/script/index.d.ts +3 -0
- package/dist/script/lmscript.d.ts +550 -0
- package/dist/shared/policy.d.ts +74 -0
- package/dist/shared-lib/db.d.ts +25 -0
- package/dist/shared-lib/passive-session-reader.d.ts +2 -0
- package/dist/shared-lib/provider-parse.d.ts +6 -0
- package/dist/templates/basedir.d.ts +52 -0
- package/dist/uri/lmctl_uri.d.ts +38 -0
- package/durable-memory/model_selection.md +108 -25
- package/examples/README.md +103 -0
- package/examples/anonymous-panel.lms +3 -0
- package/examples/batch-prompts.txt +9 -0
- package/examples/batchscript.lms +67 -0
- package/examples/n8n/agent-lib.lms +56 -0
- package/examples/n8n/git-lib.lms +93 -0
- package/examples/n8n/mock-support.db +0 -0
- package/examples/n8n/multi-agent-review.lms +107 -0
- package/examples/n8n/news-digest.lms +159 -0
- package/examples/n8n/rag-search.lms +163 -0
- package/examples/n8n/support-agent.lms +88 -0
- package/examples/n8n/ticket-triage.lms +156 -0
- package/package.json +13 -17
- package/dist/cli/side_effect_classifier.json +0 -19
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
export type ProviderName = "claude" | "codex" | "gemini" | "copilot" | "opencode" | "lmplayer" | "qwen" | "agy" | "kimi" | "dsh" | "hermes" | "pi" | "ClaudeMock";
|
|
2
|
+
export interface SessionTokenUsage {
|
|
3
|
+
inputTokens?: number;
|
|
4
|
+
cachedInputTokens?: number;
|
|
5
|
+
cacheWriteInputTokens?: number;
|
|
6
|
+
outputTokens?: number;
|
|
7
|
+
reasoningOutputTokens?: number;
|
|
8
|
+
totalTokens?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface SessionSummary {
|
|
11
|
+
provider: ProviderName;
|
|
12
|
+
sessionId: string;
|
|
13
|
+
slug?: string;
|
|
14
|
+
cwd: string;
|
|
15
|
+
createdAt: Date;
|
|
16
|
+
modifiedAt: Date;
|
|
17
|
+
model?: string;
|
|
18
|
+
cliVersion?: string;
|
|
19
|
+
startCommand?: string;
|
|
20
|
+
firstUserMessage?: string;
|
|
21
|
+
lastUserMessage?: string;
|
|
22
|
+
messageCount: number;
|
|
23
|
+
filePath: string;
|
|
24
|
+
filePaths?: string[];
|
|
25
|
+
totalInputTokens?: number;
|
|
26
|
+
totalCachedInputTokens?: number;
|
|
27
|
+
totalCacheWriteInputTokens?: number;
|
|
28
|
+
totalOutputTokens?: number;
|
|
29
|
+
totalReasoningOutputTokens?: number;
|
|
30
|
+
lastInputTokens?: number;
|
|
31
|
+
lastTokenUsage?: SessionTokenUsage;
|
|
32
|
+
modelContextWindow?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface SessionDetail extends SessionSummary {
|
|
35
|
+
/** Native external prompt text, excluding injected context and internal rows.
|
|
36
|
+
* When present (even empty), authoritative over user-role transcript messages. */
|
|
37
|
+
userPrompts?: string[];
|
|
38
|
+
gitBranch?: string;
|
|
39
|
+
turnStatus?: "in_progress" | "complete" | "aborted";
|
|
40
|
+
messages: ConversationMessage[];
|
|
41
|
+
}
|
|
42
|
+
export type MessageRole = "user" | "assistant" | "system" | "tool_use" | "tool_result" | "thinking";
|
|
43
|
+
export interface ConversationMessage {
|
|
44
|
+
role: MessageRole;
|
|
45
|
+
timestamp: Date;
|
|
46
|
+
content: string;
|
|
47
|
+
toolName?: string;
|
|
48
|
+
toolInput?: string;
|
|
49
|
+
toolInputData?: Record<string, unknown>;
|
|
50
|
+
toolCallId?: string;
|
|
51
|
+
backgroundTaskId?: string;
|
|
52
|
+
toolDetailedContent?: string;
|
|
53
|
+
stopReason?: string;
|
|
54
|
+
model?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface WatchPathInfo {
|
|
57
|
+
directory: string;
|
|
58
|
+
filePattern: RegExp;
|
|
59
|
+
}
|
|
60
|
+
export interface WatchTarget {
|
|
61
|
+
provider: ProviderName;
|
|
62
|
+
directory: string;
|
|
63
|
+
recursive: boolean;
|
|
64
|
+
filePattern?: RegExp;
|
|
65
|
+
}
|
|
66
|
+
export interface SessionProvider {
|
|
67
|
+
name: ProviderName;
|
|
68
|
+
discoverSessions(): Promise<SessionSummary[]>;
|
|
69
|
+
loadSession(sessionId: string): Promise<SessionDetail | null>;
|
|
70
|
+
resolveSessionPath(sessionId: string): Promise<string | null>;
|
|
71
|
+
deleteSession(sessionId: string): Promise<boolean>;
|
|
72
|
+
getWatchPaths?(): WatchPathInfo[];
|
|
73
|
+
}
|
|
74
|
+
export interface DeleteOptions {
|
|
75
|
+
provider?: ProviderName;
|
|
76
|
+
force?: boolean;
|
|
77
|
+
json?: boolean;
|
|
78
|
+
}
|
|
79
|
+
export interface MutationResult {
|
|
80
|
+
success: boolean;
|
|
81
|
+
sessionId: string;
|
|
82
|
+
provider?: ProviderName;
|
|
83
|
+
filePath: string;
|
|
84
|
+
error?: string;
|
|
85
|
+
}
|
|
86
|
+
export interface ListOptions {
|
|
87
|
+
provider?: ProviderName;
|
|
88
|
+
workspace?: string;
|
|
89
|
+
limit?: number;
|
|
90
|
+
from?: string;
|
|
91
|
+
to?: string;
|
|
92
|
+
json?: boolean;
|
|
93
|
+
}
|
|
94
|
+
export interface ViewOptions {
|
|
95
|
+
provider?: ProviderName;
|
|
96
|
+
detailed?: boolean;
|
|
97
|
+
noTools?: boolean;
|
|
98
|
+
noThinking?: boolean;
|
|
99
|
+
toolDetails?: boolean;
|
|
100
|
+
json?: boolean;
|
|
101
|
+
}
|
|
102
|
+
export interface ExtractOptions {
|
|
103
|
+
provider?: ProviderName;
|
|
104
|
+
detailed?: boolean;
|
|
105
|
+
last?: number;
|
|
106
|
+
}
|
|
107
|
+
export interface DumpMessage {
|
|
108
|
+
role: "user" | "assistant";
|
|
109
|
+
content: string;
|
|
110
|
+
}
|
|
111
|
+
export interface DumpResult {
|
|
112
|
+
success: boolean;
|
|
113
|
+
messages: DumpMessage[];
|
|
114
|
+
error?: string;
|
|
115
|
+
}
|
|
116
|
+
export interface DumpOptions {
|
|
117
|
+
provider?: ProviderName;
|
|
118
|
+
format?: "text" | "bundle";
|
|
119
|
+
}
|
|
120
|
+
export type LoadMode = "patch" | "transplant";
|
|
121
|
+
export interface LoadOptions {
|
|
122
|
+
provider?: ProviderName;
|
|
123
|
+
force?: boolean;
|
|
124
|
+
dryRun?: boolean;
|
|
125
|
+
preserve?: boolean;
|
|
126
|
+
mode?: LoadMode;
|
|
127
|
+
}
|
|
128
|
+
export interface EditableEntry {
|
|
129
|
+
role: "user" | "assistant";
|
|
130
|
+
recordIndex: number;
|
|
131
|
+
contentPath: string;
|
|
132
|
+
identityKey: string;
|
|
133
|
+
content: string;
|
|
134
|
+
}
|
|
135
|
+
export interface SessionBundle {
|
|
136
|
+
schemaVersion: 2;
|
|
137
|
+
provider: ProviderName;
|
|
138
|
+
toolVersion: string;
|
|
139
|
+
source: {
|
|
140
|
+
sessionId: string;
|
|
141
|
+
cwd: string;
|
|
142
|
+
dumpedAt: string;
|
|
143
|
+
};
|
|
144
|
+
raw: {
|
|
145
|
+
type: "jsonl" | "json";
|
|
146
|
+
records: string[];
|
|
147
|
+
};
|
|
148
|
+
editable: EditableEntry[];
|
|
149
|
+
}
|
|
150
|
+
export interface BundleResult {
|
|
151
|
+
success: boolean;
|
|
152
|
+
bundle?: SessionBundle;
|
|
153
|
+
error?: string;
|
|
154
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YOLO contract — every provider transport spawns its CLI in
|
|
3
|
+
* full-auto / permission-bypass mode. Hardcoded; not user-configurable.
|
|
4
|
+
*
|
|
5
|
+
* Why this is non-negotiable: lmctl drives provider sessions
|
|
6
|
+
* non-interactively. If the provider asks for a tool-use permission,
|
|
7
|
+
* there is no human at the prompt and lmctl has no UI for forwarding
|
|
8
|
+
* the request. The session hangs until the per-tool internal timeout
|
|
9
|
+
* fires (could be 30+ minutes), with no recovery path.
|
|
10
|
+
*
|
|
11
|
+
* The opencode06 incident exposed this concretely: opencode was
|
|
12
|
+
* spawned without any permission-bypass flag, sent
|
|
13
|
+
* `session/request_permission` for its first bash tool call, lmctl
|
|
14
|
+
* silently dropped the request, opencode hung for 42+ minutes. See
|
|
15
|
+
* `commit 1cc1766` for the safety-net (reply with -32601) and this
|
|
16
|
+
* module for the upstream fix (force YOLO so the request is never
|
|
17
|
+
* sent in the first place).
|
|
18
|
+
*
|
|
19
|
+
* Users who want permission prompts should use the provider's CLI
|
|
20
|
+
* directly, not through lmctl. That's a deliberate scope boundary.
|
|
21
|
+
*
|
|
22
|
+
* ## Coverage
|
|
23
|
+
*
|
|
24
|
+
* Argv-based providers — flag must appear in the spawn argv:
|
|
25
|
+
* claude → --dangerously-skip-permissions (stream-json transport)
|
|
26
|
+
* qwen → --approval-mode yolo (stream-json transport)
|
|
27
|
+
* gemini → -y (acp transport)
|
|
28
|
+
* copilot → --yolo (acp transport)
|
|
29
|
+
* agy → --dangerously-skip-permissions (one-shot print transport)
|
|
30
|
+
* lmplayer → --dangerously-skip-permissions (one-shot run transport)
|
|
31
|
+
* opencode → --dangerously-skip-permissions (acp transport)
|
|
32
|
+
*
|
|
33
|
+
* pi (NOT argv-based): pi has no tool-permission prompts by design —
|
|
34
|
+
* there is no approval UI to hang on, so no bypass flag exists or is
|
|
35
|
+
* needed. Routed through PROTOCOL_LEVEL_YOLO like codex so
|
|
36
|
+
* assertYoloFlagPresent documents the stance at every spawn.
|
|
37
|
+
*
|
|
38
|
+
* Codex (NOT argv-based): the `codex app-server` JSON-RPC speaks YOLO
|
|
39
|
+
* via per-call `thread/start` / `thread/resume` params:
|
|
40
|
+
* approvalPolicy: "never"
|
|
41
|
+
* sandbox: "danger-full-access"
|
|
42
|
+
* These are asserted in `codex-app-server.ts` (see `sendCodexPrompt`),
|
|
43
|
+
* but are NOT covered by `assertYoloFlagPresent` here because the
|
|
44
|
+
* argv carries no flag — codex's YOLO is wire-protocol-level.
|
|
45
|
+
*/
|
|
46
|
+
/**
|
|
47
|
+
* Required YOLO flag(s) per argv-based provider. Each entry is a
|
|
48
|
+
* sequence of consecutive argv tokens (e.g. `["--approval-mode",
|
|
49
|
+
* "yolo"]`) that must appear in the spawn args for the contract to
|
|
50
|
+
* hold. Single-token entries (e.g. `["--yolo"]`) just check for the
|
|
51
|
+
* one token's presence.
|
|
52
|
+
*
|
|
53
|
+
* **Note: opencode is NOT here.** Opencode's ACP mode rejects every
|
|
54
|
+
* permission-bypass argv flag (verified empirically — `--dangerously-
|
|
55
|
+
* skip-permissions` is a `run`-subcommand-only flag, not recognized
|
|
56
|
+
* by `opencode acp`). Opencode's YOLO is satisfied via the
|
|
57
|
+
* `permission: "allow"` key in `<cwd>/.opencode/opencode.json`,
|
|
58
|
+
* written by `installOpencodeConfig` (see
|
|
59
|
+
* src/providers/opencode-config.ts). It belongs in the protocol-level
|
|
60
|
+
* set below, same shape as codex.
|
|
61
|
+
*/
|
|
62
|
+
export declare const YOLO_FLAGS: Record<string, string[]>;
|
|
63
|
+
/**
|
|
64
|
+
* lmctl-controlled permission mode for a single chat call.
|
|
65
|
+
*
|
|
66
|
+
* - `"yolo"` — full-auto / permission-bypass (the historical default;
|
|
67
|
+
* what every spawn does without `--permission-mode`).
|
|
68
|
+
* - `"plan"` — provider should refuse tool calls that would write
|
|
69
|
+
* to the workspace, rather than prompt or auto-approve.
|
|
70
|
+
*
|
|
71
|
+
* Plan mode is for research / exploration sessions where the agent
|
|
72
|
+
* should produce a plan only and never modify the workspace. See
|
|
73
|
+
* `PERMISSION_FLAGS` (below) for the per-provider argv substitution.
|
|
74
|
+
*
|
|
75
|
+
* IMPORTANT (gemini caveat): gemini's `--approval-mode plan` only
|
|
76
|
+
* filters `write_file` by workspace path — an agent can still escape
|
|
77
|
+
* via `run_shell_command` (e.g. `bash -c 'echo > /tmp/x'`). This is
|
|
78
|
+
* a known limitation in gemini-cli; a tighter sandbox for plan mode
|
|
79
|
+
* is tracked as a follow-up. For this layer, plan mode means
|
|
80
|
+
* "ask the provider for plan-mode behavior" — guarantees depend on
|
|
81
|
+
* the provider.
|
|
82
|
+
*/
|
|
83
|
+
export type PermissionMode = "plan" | "yolo";
|
|
84
|
+
/**
|
|
85
|
+
* Per-provider argv tokens for the two permission modes, for the
|
|
86
|
+
* providers whose permission selection is argv-based. The `yolo`
|
|
87
|
+
* column mirrors `YOLO_FLAGS` (preserved as the historical default);
|
|
88
|
+
* the `plan` column carries the substitution applied when the CLI
|
|
89
|
+
* receives `--permission-mode plan`.
|
|
90
|
+
*
|
|
91
|
+
* Verified against the actual provider CLIs:
|
|
92
|
+
*
|
|
93
|
+
* claude : --dangerously-skip-permissions vs --permission-mode plan
|
|
94
|
+
* qwen : --approval-mode yolo vs --approval-mode plan
|
|
95
|
+
* gemini : -y vs --approval-mode plan
|
|
96
|
+
*
|
|
97
|
+
* Codex and opencode are not here — they are protocol-/config-level
|
|
98
|
+
* (see `PROTOCOL_LEVEL_YOLO`). Codex's plan-mode substitution lives in
|
|
99
|
+
* the `sandbox: "danger-full-access"` → `sandbox: "read-only"` swap in
|
|
100
|
+
* codex-app-server.ts. Opencode plan mode is not yet wired and
|
|
101
|
+
* preserves the yolo (config-file) behavior.
|
|
102
|
+
*
|
|
103
|
+
* Copilot is not here — its CLI lacks a plan-mode flag in `--acp`
|
|
104
|
+
* mode (verified). Copilot in plan mode keeps `--yolo` so it doesn't
|
|
105
|
+
* hang on permission prompts; the limitation is documented in
|
|
106
|
+
* acp.ts.
|
|
107
|
+
*/
|
|
108
|
+
export declare const PERMISSION_FLAGS: Record<string, Record<PermissionMode, string[]>>;
|
|
109
|
+
/**
|
|
110
|
+
* Resolve the argv tokens for `provider` under `mode`. Falls back to
|
|
111
|
+
* the yolo token sequence when no plan-mode entry exists, so the
|
|
112
|
+
* assertion in `assertYoloFlagPresent` stays meaningful for providers
|
|
113
|
+
* that do not yet support plan mode.
|
|
114
|
+
*/
|
|
115
|
+
export declare function flagsForPermissionMode(provider: string, mode: PermissionMode): string[] | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* Defense-in-depth pre-flight: assert that the YOLO flag for
|
|
118
|
+
* `provider` is present in `args` immediately before `spawn()` is
|
|
119
|
+
* called. Throws `TransportConnectionError` (and emits an
|
|
120
|
+
* unconditional debug-log record) on missing flag — catches the
|
|
121
|
+
* regression class "future refactor accidentally dropped the YOLO
|
|
122
|
+
* flag from the spawn args."
|
|
123
|
+
*
|
|
124
|
+
* Unknown providers (not in `YOLO_FLAGS` or `PROTOCOL_LEVEL_YOLO`)
|
|
125
|
+
* are treated as a hard error — the contract is global; new providers
|
|
126
|
+
* must opt in explicitly.
|
|
127
|
+
*
|
|
128
|
+
* Codex short-circuits with success — its YOLO is in the JSON-RPC
|
|
129
|
+
* params and verified separately at the call site.
|
|
130
|
+
*/
|
|
131
|
+
export declare function assertYoloFlagPresent(provider: string, args: readonly string[], mode?: PermissionMode): void;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { LMScript, type FunctionDoc, type ScriptModule } from './lmscript.js';
|
|
2
|
+
import { type ResolvedMember } from '../cli/target-resolver.js';
|
|
3
|
+
import type { BundleSession } from '../providers/bundle.js';
|
|
4
|
+
import { type CliIo } from '../cli/common.js';
|
|
5
|
+
import { resolveSelfIdentity } from '../cli/self-identity.js';
|
|
6
|
+
import type { AgentInflightInput, TrackedInvocationFinishPatch } from '../db/index.js';
|
|
7
|
+
export { LMScript, LMScriptExit, type FunctionDoc, type ScriptModule } from './lmscript.js';
|
|
8
|
+
export interface BatchHandle {
|
|
9
|
+
kind?: 'team';
|
|
10
|
+
id: string;
|
|
11
|
+
teamfile: string;
|
|
12
|
+
alias: string;
|
|
13
|
+
batchfile: string;
|
|
14
|
+
member: ResolvedMember;
|
|
15
|
+
promptCount: number;
|
|
16
|
+
useBundle: boolean;
|
|
17
|
+
rootId: number | null;
|
|
18
|
+
rootFinish: TrackedInvocationFinishPatch;
|
|
19
|
+
heldLease?: {
|
|
20
|
+
row: AgentInflightInput;
|
|
21
|
+
leaseId: string;
|
|
22
|
+
};
|
|
23
|
+
bundleSession?: BundleSession;
|
|
24
|
+
heartbeatTimer?: {
|
|
25
|
+
stop: () => void;
|
|
26
|
+
};
|
|
27
|
+
closed: boolean;
|
|
28
|
+
env: NodeJS.ProcessEnv;
|
|
29
|
+
}
|
|
30
|
+
interface AgentBatchHandle {
|
|
31
|
+
kind: 'agent';
|
|
32
|
+
id: string;
|
|
33
|
+
member: Record<string, any>;
|
|
34
|
+
sourceMember: Record<string, any>;
|
|
35
|
+
options: Record<string, any>;
|
|
36
|
+
closed: boolean;
|
|
37
|
+
failed: boolean;
|
|
38
|
+
inFlight: boolean;
|
|
39
|
+
}
|
|
40
|
+
type ManagedBatchHandle = BatchHandle | AgentBatchHandle;
|
|
41
|
+
export declare class ResourceRegistry {
|
|
42
|
+
private batchHandles;
|
|
43
|
+
private loggedErrors;
|
|
44
|
+
registerBatch(handle: ManagedBatchHandle): void;
|
|
45
|
+
getBatch(id: string): ManagedBatchHandle | undefined;
|
|
46
|
+
getOpenBatches(): ManagedBatchHandle[];
|
|
47
|
+
recordError(msg: string): void;
|
|
48
|
+
getErrors(): string[];
|
|
49
|
+
hasErrors(): boolean;
|
|
50
|
+
forceCloseAll(io: CliIo): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
export declare function bundleAvailable(member: ResolvedMember): Promise<boolean>;
|
|
53
|
+
export declare function releaseBundleLease(io: CliIo, lease: {
|
|
54
|
+
row: AgentInflightInput;
|
|
55
|
+
leaseId: string;
|
|
56
|
+
}): Promise<void>;
|
|
57
|
+
export declare function resolveBundleSender(env: NodeJS.ProcessEnv, dal: Parameters<typeof resolveSelfIdentity>[1]): {
|
|
58
|
+
teamfile: string;
|
|
59
|
+
alias: string;
|
|
60
|
+
} | null;
|
|
61
|
+
export declare function startBatchRootInvocation(io: CliIo, input: {
|
|
62
|
+
member: ResolvedMember;
|
|
63
|
+
batchfile: string;
|
|
64
|
+
promptCount: number;
|
|
65
|
+
parentInvocationId: number | null;
|
|
66
|
+
}): Promise<number | null>;
|
|
67
|
+
export declare function finishBatchRootInvocationSync(io: CliIo, id: number, patch: TrackedInvocationFinishPatch, env?: NodeJS.ProcessEnv): void;
|
|
68
|
+
export declare function closeBatchHandle(handle: ManagedBatchHandle, io: CliIo, status?: 'done' | 'error' | 'cancelled', errorDetail?: string): Promise<void>;
|
|
69
|
+
export declare const LMCTL_FUNCTION_DOCS: FunctionDoc[];
|
|
70
|
+
export declare function registerLmctlDocs(engine: LMScript): void;
|
|
71
|
+
export interface BaseEngineOptions {
|
|
72
|
+
scriptArgs?: string[];
|
|
73
|
+
io?: CliIo;
|
|
74
|
+
env?: NodeJS.ProcessEnv;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Creates a bare, generic LMScript engine configured with the language and standard library.
|
|
78
|
+
* Free of lmctl-specific host functions or domain bindings.
|
|
79
|
+
* Suitable as a reusable substrate for any consumer (lmctl, lmbee, custom tools).
|
|
80
|
+
*/
|
|
81
|
+
export declare function createBaseScriptEngine(options?: BaseEngineOptions): LMScript;
|
|
82
|
+
/**
|
|
83
|
+
* Registers all lmctl host functions onto an LMScript engine instance.
|
|
84
|
+
*/
|
|
85
|
+
export declare function registerLmctlHostFunctions(engine: LMScript, io: CliIo, registry: ResourceRegistry, env?: NodeJS.ProcessEnv): void;
|
|
86
|
+
/**
|
|
87
|
+
* First-class ScriptModule defining the lmctl automation host extension.
|
|
88
|
+
*/
|
|
89
|
+
export declare const lmctlModule: ScriptModule;
|
|
90
|
+
/**
|
|
91
|
+
* Registers the lmctl module and its host function documentation onto any LMScript engine.
|
|
92
|
+
*/
|
|
93
|
+
export declare function registerLmctlModule(engine: LMScript, io: CliIo, registry?: ResourceRegistry, env?: NodeJS.ProcessEnv): LMScript;
|
|
94
|
+
/**
|
|
95
|
+
* Creates and configures an LMScript engine instance pre-wired with the lmctl module.
|
|
96
|
+
*/
|
|
97
|
+
export declare function createLmScriptEngine(io: CliIo, scriptArgs?: string[], registry?: ResourceRegistry, env?: NodeJS.ProcessEnv): LMScript;
|
|
98
|
+
/**
|
|
99
|
+
* Executes an LMScript script source with full lifecycle and signal guarantees.
|
|
100
|
+
*/
|
|
101
|
+
export declare function runScriptEngine(source: string, scriptArgs: string[], io?: CliIo, env?: NodeJS.ProcessEnv, scriptFile?: string): Promise<number>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-only comparison implementation of `lmctl batch`.
|
|
3
|
+
* The production command remains procedural and independent of LMScript.
|
|
4
|
+
* examples/batchscript.lms exposes this asset through `lmctl script`; an
|
|
5
|
+
* equality test and shared behavioral suites keep the comparison repeatable.
|
|
6
|
+
*/
|
|
7
|
+
export declare const BATCH_LMS = "# batchscript.lms - Test-only comparison with procedural lmctl batch\n# Arguments: [teamfile, alias, batchfile, flags...]\n\nif (includes(args, \"--help\") || includes(args, \"-h\")) {\n println(\"usage: lmctl batch <teamfile> <alias> <batchfile> [--legacy] [--single]\");\n lm_exit(0);\n}\n\nif (len(args) < 3) {\n lm_error(\"usage: lmctl batch <teamfile> <alias> <batchfile> [--legacy] [--single]\");\n lm_exit(1);\n}\n\nteamfile = args[0];\nalias = args[1];\nbatchfile = args[2];\nlegacy = false;\nsingle = false;\nfor (flag_index = 3; flag_index < len(args); flag_index = flag_index + 1) {\n if (args[flag_index] == \"--legacy\") {\n legacy = true;\n } else if (args[flag_index] == \"--single\") {\n single = true;\n } else {\n lm_error(\"batch: unexpected argument: \" + args[flag_index]);\n lm_exit(1);\n }\n}\n\n# 1. Read prompts\nprompts = lm_read_prompts(batchfile, single);\n\nif (len(prompts) == 0) {\n lm_error(\"batch: \" + batchfile + \": no prompts found\");\n lm_exit(1);\n}\n\n# 2. Open batch session\nhandle = lm_batch_open(teamfile, alias, batchfile, {\n promptCount: len(prompts),\n legacy: legacy,\n single: single\n});\n\nif (handle == null) {\n lm_exit(1);\n}\n\n# 3. Sequential prompt execution\nfor (i = 0; i < len(prompts); i = i + 1) {\n promptText = prompts[i];\n res = lm_batch_turn(handle, promptText, i + 1, len(prompts));\n\n # Output reply or partial reply on stall\n if (res.reply != null && len(res.reply) > 0) {\n print(res.reply);\n print(\"\"); # Blank line separator\n }\n\n if (res.status != \"ok\") {\n lm_batch_close(handle, \"error\", res.error);\n lm_exit(1);\n }\n}\n\nlm_batch_close(handle, \"done\");\nlm_exit(0);\n";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { LMScript, LMScriptExit, type FunctionDoc, type ScriptModule } from './lmscript.js';
|
|
2
|
+
export { createBaseScriptEngine, createLmScriptEngine, registerLmctlModule, lmctlModule, registerLmctlHostFunctions, registerLmctlDocs, LMCTL_FUNCTION_DOCS, runScriptEngine, ResourceRegistry, type BatchHandle, type BaseEngineOptions, } from './adapter.js';
|
|
3
|
+
export { BATCH_LMS } from './batch-script.js';
|