lark-remote 0.1.0
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 +52 -0
- package/LICENSE +21 -0
- package/README.en.md +162 -0
- package/README.md +161 -0
- package/dist/binder.d.ts +57 -0
- package/dist/binder.js +105 -0
- package/dist/bridge/index.d.ts +338 -0
- package/dist/bridge/index.js +1281 -0
- package/dist/bridge/queue-manager.d.ts +277 -0
- package/dist/bridge/queue-manager.js +729 -0
- package/dist/card/bash-card-session.d.ts +78 -0
- package/dist/card/bash-card-session.js +174 -0
- package/dist/card/bash-renderer.d.ts +24 -0
- package/dist/card/bash-renderer.js +187 -0
- package/dist/card/card-budget.d.ts +31 -0
- package/dist/card/card-budget.js +280 -0
- package/dist/card/card-session.d.ts +83 -0
- package/dist/card/card-session.js +185 -0
- package/dist/card/card-shared.d.ts +28 -0
- package/dist/card/card-shared.js +99 -0
- package/dist/card/collapsible.d.ts +26 -0
- package/dist/card/collapsible.js +87 -0
- package/dist/card/run-card-session.d.ts +78 -0
- package/dist/card/run-card-session.js +165 -0
- package/dist/card/run-renderer.d.ts +66 -0
- package/dist/card/run-renderer.js +841 -0
- package/dist/card/run-state.d.ts +103 -0
- package/dist/card/run-state.js +313 -0
- package/dist/card/text-truncate.d.ts +56 -0
- package/dist/card/text-truncate.js +184 -0
- package/dist/card/time.d.ts +1 -0
- package/dist/card/time.js +14 -0
- package/dist/card/tool-render.d.ts +25 -0
- package/dist/card/tool-render.js +176 -0
- package/dist/cli.d.ts +28 -0
- package/dist/cli.js +89 -0
- package/dist/common/guards.d.ts +37 -0
- package/dist/common/guards.js +65 -0
- package/dist/config/codex-config.d.ts +113 -0
- package/dist/config/codex-config.js +428 -0
- package/dist/config/dir.d.ts +17 -0
- package/dist/config/dir.js +81 -0
- package/dist/config/index.d.ts +219 -0
- package/dist/config/index.js +388 -0
- package/dist/config/kimi-config.d.ts +33 -0
- package/dist/config/kimi-config.js +111 -0
- package/dist/config/opencode-config.d.ts +20 -0
- package/dist/config/opencode-config.js +124 -0
- package/dist/config/pi-config.d.ts +49 -0
- package/dist/config/pi-config.js +151 -0
- package/dist/config/wizard.d.ts +12 -0
- package/dist/config/wizard.js +84 -0
- package/dist/connector/file-limits.d.ts +7 -0
- package/dist/connector/file-limits.js +8 -0
- package/dist/connector/index.d.ts +86 -0
- package/dist/connector/index.js +340 -0
- package/dist/error-classification.d.ts +15 -0
- package/dist/error-classification.js +24 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +580 -0
- package/dist/instance-lock.d.ts +30 -0
- package/dist/instance-lock.js +184 -0
- package/dist/logger/index.d.ts +57 -0
- package/dist/logger/index.js +178 -0
- package/dist/order/index.d.ts +27 -0
- package/dist/order/index.js +90 -0
- package/dist/persistence/atomic-write.d.ts +10 -0
- package/dist/persistence/atomic-write.js +65 -0
- package/dist/persistence/load-json-file.d.ts +9 -0
- package/dist/persistence/load-json-file.js +23 -0
- package/dist/restart.d.ts +24 -0
- package/dist/restart.js +73 -0
- package/dist/router/card-helpers.d.ts +28 -0
- package/dist/router/card-helpers.js +65 -0
- package/dist/router/config/claude.d.ts +14 -0
- package/dist/router/config/claude.js +72 -0
- package/dist/router/config/codex.d.ts +22 -0
- package/dist/router/config/codex.js +100 -0
- package/dist/router/config/common/render.d.ts +16 -0
- package/dist/router/config/common/render.js +158 -0
- package/dist/router/config/index.d.ts +18 -0
- package/dist/router/config/index.js +38 -0
- package/dist/router/config/kimi.d.ts +21 -0
- package/dist/router/config/kimi.js +63 -0
- package/dist/router/config/opencode.d.ts +12 -0
- package/dist/router/config/opencode.js +44 -0
- package/dist/router/config/pi.d.ts +12 -0
- package/dist/router/config/pi.js +50 -0
- package/dist/router/config/types.d.ts +43 -0
- package/dist/router/config/types.js +8 -0
- package/dist/router/index.d.ts +318 -0
- package/dist/router/index.js +2715 -0
- package/dist/router/order-exec-dispatch.d.ts +30 -0
- package/dist/router/order-exec-dispatch.js +48 -0
- package/dist/router/utils.d.ts +44 -0
- package/dist/router/utils.js +116 -0
- package/dist/runner/bash/index.d.ts +4 -0
- package/dist/runner/bash/index.js +5 -0
- package/dist/runner/bash/runner.d.ts +55 -0
- package/dist/runner/bash/runner.js +213 -0
- package/dist/runner/claude/index.d.ts +4 -0
- package/dist/runner/claude/index.js +5 -0
- package/dist/runner/claude/runner.d.ts +29 -0
- package/dist/runner/claude/runner.js +83 -0
- package/dist/runner/codex/argv.d.ts +33 -0
- package/dist/runner/codex/argv.js +40 -0
- package/dist/runner/codex/index.d.ts +1 -0
- package/dist/runner/codex/index.js +2 -0
- package/dist/runner/codex/jsonl.d.ts +37 -0
- package/dist/runner/codex/jsonl.js +221 -0
- package/dist/runner/codex/runner.d.ts +65 -0
- package/dist/runner/codex/runner.js +124 -0
- package/dist/runner/common/exec-translator.d.ts +73 -0
- package/dist/runner/common/exec-translator.js +105 -0
- package/dist/runner/common/jsonl-stream.d.ts +39 -0
- package/dist/runner/common/jsonl-stream.js +203 -0
- package/dist/runner/common/process-stopper.d.ts +28 -0
- package/dist/runner/common/process-stopper.js +79 -0
- package/dist/runner/common/runner-utils.d.ts +21 -0
- package/dist/runner/common/runner-utils.js +65 -0
- package/dist/runner/common/spawn-heartbeat.d.ts +33 -0
- package/dist/runner/common/spawn-heartbeat.js +51 -0
- package/dist/runner/common/spawning-runner.d.ts +321 -0
- package/dist/runner/common/spawning-runner.js +634 -0
- package/dist/runner/common/usage.d.ts +31 -0
- package/dist/runner/common/usage.js +29 -0
- package/dist/runner/index.d.ts +19 -0
- package/dist/runner/index.js +24 -0
- package/dist/runner/kimi/index.d.ts +1 -0
- package/dist/runner/kimi/index.js +2 -0
- package/dist/runner/kimi/jsonl.d.ts +28 -0
- package/dist/runner/kimi/jsonl.js +143 -0
- package/dist/runner/kimi/runner.d.ts +50 -0
- package/dist/runner/kimi/runner.js +105 -0
- package/dist/runner/opencode/argv.d.ts +32 -0
- package/dist/runner/opencode/argv.js +35 -0
- package/dist/runner/opencode/index.d.ts +1 -0
- package/dist/runner/opencode/index.js +2 -0
- package/dist/runner/opencode/jsonl.d.ts +68 -0
- package/dist/runner/opencode/jsonl.js +295 -0
- package/dist/runner/opencode/runner.d.ts +63 -0
- package/dist/runner/opencode/runner.js +93 -0
- package/dist/runner/pi/index.d.ts +1 -0
- package/dist/runner/pi/index.js +2 -0
- package/dist/runner/pi/jsonl.d.ts +128 -0
- package/dist/runner/pi/jsonl.js +249 -0
- package/dist/runner/pi/runner.d.ts +37 -0
- package/dist/runner/pi/runner.js +76 -0
- package/dist/runner/registry.d.ts +54 -0
- package/dist/runner/registry.js +75 -0
- package/dist/runner/resolve-agent-choices.d.ts +7 -0
- package/dist/runner/resolve-agent-choices.js +76 -0
- package/dist/runner/sync-agent-choices.d.ts +6 -0
- package/dist/runner/sync-agent-choices.js +73 -0
- package/dist/runner/types.d.ts +250 -0
- package/dist/runner/types.js +8 -0
- package/dist/session/claude/index.d.ts +1 -0
- package/dist/session/claude/index.js +2 -0
- package/dist/session/claude/session-reader.d.ts +34 -0
- package/dist/session/claude/session-reader.js +46 -0
- package/dist/session/claude/sessions.d.ts +53 -0
- package/dist/session/claude/sessions.js +528 -0
- package/dist/session/codex/index.d.ts +1 -0
- package/dist/session/codex/index.js +2 -0
- package/dist/session/codex/rollout-reader.d.ts +88 -0
- package/dist/session/codex/rollout-reader.js +473 -0
- package/dist/session/codex/sessions.d.ts +21 -0
- package/dist/session/codex/sessions.js +40 -0
- package/dist/session/common/catch-up.d.ts +12 -0
- package/dist/session/common/catch-up.js +31 -0
- package/dist/session/common/constants.d.ts +11 -0
- package/dist/session/common/constants.js +12 -0
- package/dist/session/common/content-blocks.d.ts +37 -0
- package/dist/session/common/content-blocks.js +68 -0
- package/dist/session/common/jsonl.d.ts +77 -0
- package/dist/session/common/jsonl.js +351 -0
- package/dist/session/common/usage-accumulator.d.ts +58 -0
- package/dist/session/common/usage-accumulator.js +72 -0
- package/dist/session/index.d.ts +7 -0
- package/dist/session/index.js +11 -0
- package/dist/session/kimi/index.d.ts +1 -0
- package/dist/session/kimi/index.js +2 -0
- package/dist/session/kimi/sessions.d.ts +81 -0
- package/dist/session/kimi/sessions.js +527 -0
- package/dist/session/opencode/index.d.ts +1 -0
- package/dist/session/opencode/index.js +2 -0
- package/dist/session/opencode/sessions.d.ts +81 -0
- package/dist/session/opencode/sessions.js +388 -0
- package/dist/session/pi/index.d.ts +1 -0
- package/dist/session/pi/index.js +2 -0
- package/dist/session/pi/sessions.d.ts +27 -0
- package/dist/session/pi/sessions.js +399 -0
- package/dist/session/registry.d.ts +12 -0
- package/dist/session/registry.js +20 -0
- package/dist/session/session-store.d.ts +86 -0
- package/dist/session/session-store.js +450 -0
- package/dist/startup-contact.d.ts +18 -0
- package/dist/startup-contact.js +51 -0
- package/dist/workspace/index.d.ts +19 -0
- package/dist/workspace/index.js +53 -0
- package/package.json +93 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured tool rendering for collapsible panels.
|
|
3
|
+
*
|
|
4
|
+
* Adapted to lark-remote's `ToolEntry` type (which uses `status: 'running' | 'ok' | 'error'`
|
|
5
|
+
* and stores `input` as an already-stringified value in some paths).
|
|
6
|
+
*
|
|
7
|
+
* Why this exists: the old renderer dumped `JSON.stringify(input, null, 2)`
|
|
8
|
+
* which is verbose and buries the useful signal (command, file path, pattern)
|
|
9
|
+
* under formatting noise. `toolHeaderText` produces a compact one-liner header
|
|
10
|
+
* like `✅ **Bash** — pwd` so collapsed panels stay informative.
|
|
11
|
+
*/
|
|
12
|
+
import type { ToolEntry } from './run-state.js';
|
|
13
|
+
/**
|
|
14
|
+
* One-line header for a tool call:
|
|
15
|
+
* `⏳ **Bash** — pwd`
|
|
16
|
+
* `✅ **Read** — /repo/a.ts`
|
|
17
|
+
* `❌ **Grep** — pattern in path`
|
|
18
|
+
*/
|
|
19
|
+
export declare function toolHeaderText(tool: ToolEntry): string;
|
|
20
|
+
/**
|
|
21
|
+
* Structured body markdown for a tool call. Renders input fields by tool name
|
|
22
|
+
* (Bash → command, Read/Edit/Write → file_path, etc.) and output in a code
|
|
23
|
+
* block. Falls back to a raw JSON dump for unknown tools.
|
|
24
|
+
*/
|
|
25
|
+
export declare function toolBodyMd(tool: ToolEntry): string;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured tool rendering for collapsible panels.
|
|
3
|
+
*
|
|
4
|
+
* Adapted to lark-remote's `ToolEntry` type (which uses `status: 'running' | 'ok' | 'error'`
|
|
5
|
+
* and stores `input` as an already-stringified value in some paths).
|
|
6
|
+
*
|
|
7
|
+
* Why this exists: the old renderer dumped `JSON.stringify(input, null, 2)`
|
|
8
|
+
* which is verbose and buries the useful signal (command, file path, pattern)
|
|
9
|
+
* under formatting noise. `toolHeaderText` produces a compact one-liner header
|
|
10
|
+
* like `✅ **Bash** — pwd` so collapsed panels stay informative.
|
|
11
|
+
*/
|
|
12
|
+
const HEADER_SUMMARY_MAX = 80;
|
|
13
|
+
const BODY_FIELD_MAX = 600;
|
|
14
|
+
const OUTPUT_MAX = 1200;
|
|
15
|
+
/**
|
|
16
|
+
* Cumulative cap on a tool's full body markdown (input + output + code fences
|
|
17
|
+
* + headers). Even with per-field caps, pathological tools (many input fields
|
|
18
|
+
* + maxed-out output) can stack to multi-KB bodies which, multiplied across
|
|
19
|
+
* panels, push the card past Feishu's per-element size limit. This is the last
|
|
20
|
+
* belt across the whole rendered body string.
|
|
21
|
+
*/
|
|
22
|
+
const BODY_TOTAL_MAX = 2500;
|
|
23
|
+
/**
|
|
24
|
+
* One-line header for a tool call:
|
|
25
|
+
* `⏳ **Bash** — pwd`
|
|
26
|
+
* `✅ **Read** — /repo/a.ts`
|
|
27
|
+
* `❌ **Grep** — pattern in path`
|
|
28
|
+
*/
|
|
29
|
+
export function toolHeaderText(tool) {
|
|
30
|
+
const icon = tool.status === 'ok' ? '✅' : tool.status === 'error' ? '❌' : '⏳';
|
|
31
|
+
// P3-6: use the cached parsed record when available (avoids per-render parse).
|
|
32
|
+
const input = tool.parsedInput !== undefined ? tool.parsedInput : tool.input;
|
|
33
|
+
const summary = summarizeInput(tool.name, input);
|
|
34
|
+
return summary ? `${icon} **${tool.name}** — ${summary}` : `${icon} **${tool.name}**`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Structured body markdown for a tool call. Renders input fields by tool name
|
|
38
|
+
* (Bash → command, Read/Edit/Write → file_path, etc.) and output in a code
|
|
39
|
+
* block. Falls back to a raw JSON dump for unknown tools.
|
|
40
|
+
*/
|
|
41
|
+
export function toolBodyMd(tool) {
|
|
42
|
+
const parts = [];
|
|
43
|
+
const inputMd = renderInput(tool);
|
|
44
|
+
if (inputMd)
|
|
45
|
+
parts.push(inputMd);
|
|
46
|
+
if (tool.output) {
|
|
47
|
+
const truncated = truncate(tool.output, OUTPUT_MAX);
|
|
48
|
+
if (tool.status === 'error') {
|
|
49
|
+
parts.push(`**Error**\n\`\`\`\n${truncated}\n\`\`\``);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
parts.push(`**Output**\n\`\`\`\n${truncated}\n\`\`\``);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (tool.status === 'running') {
|
|
56
|
+
parts.push('_运行中…_');
|
|
57
|
+
}
|
|
58
|
+
const body = parts.join('\n\n');
|
|
59
|
+
if (body.length <= BODY_TOTAL_MAX)
|
|
60
|
+
return body;
|
|
61
|
+
return `${body.slice(0, BODY_TOTAL_MAX)}…\n\n_(body 已截断,完整内容查日志)_`;
|
|
62
|
+
}
|
|
63
|
+
function summarizeInput(name, input) {
|
|
64
|
+
const rec = asRecord(input);
|
|
65
|
+
if (!rec)
|
|
66
|
+
return '';
|
|
67
|
+
const pick = (key, max = HEADER_SUMMARY_MAX) => {
|
|
68
|
+
const v = rec[key];
|
|
69
|
+
if (typeof v !== 'string')
|
|
70
|
+
return '';
|
|
71
|
+
const oneLine = v.replace(/\s+/g, ' ').trim();
|
|
72
|
+
return oneLine.length > max ? `${oneLine.slice(0, max)}…` : oneLine;
|
|
73
|
+
};
|
|
74
|
+
switch (name) {
|
|
75
|
+
case 'Bash':
|
|
76
|
+
case 'bash':
|
|
77
|
+
return pick('command');
|
|
78
|
+
case 'Read':
|
|
79
|
+
case 'Edit':
|
|
80
|
+
case 'Write':
|
|
81
|
+
case 'NotebookEdit':
|
|
82
|
+
case 'read':
|
|
83
|
+
case 'edit':
|
|
84
|
+
case 'write':
|
|
85
|
+
return pick('file_path') || pick('path');
|
|
86
|
+
case 'Grep':
|
|
87
|
+
case 'grep': {
|
|
88
|
+
const pat = pick('pattern', 40);
|
|
89
|
+
const p = pick('path', 30);
|
|
90
|
+
return p ? `${pat} in ${p}` : pat;
|
|
91
|
+
}
|
|
92
|
+
case 'Glob':
|
|
93
|
+
case 'find':
|
|
94
|
+
return pick('pattern');
|
|
95
|
+
case 'ls':
|
|
96
|
+
return pick('path');
|
|
97
|
+
case 'WebFetch':
|
|
98
|
+
return pick('url');
|
|
99
|
+
case 'WebSearch':
|
|
100
|
+
return pick('query', 60);
|
|
101
|
+
case 'Agent':
|
|
102
|
+
case 'Task':
|
|
103
|
+
return pick('description') || pick('subagent_type');
|
|
104
|
+
default:
|
|
105
|
+
return pick('command') || pick('file_path') || pick('path') || pick('query');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function renderInput(tool) {
|
|
109
|
+
// P3-6: use the cached parsed record when available (avoids per-render parse).
|
|
110
|
+
const input = tool.parsedInput !== undefined ? tool.parsedInput : tool.input;
|
|
111
|
+
const rec = asRecord(input);
|
|
112
|
+
if (!rec)
|
|
113
|
+
return '';
|
|
114
|
+
const str = (k) => (typeof rec[k] === 'string' ? rec[k] : '');
|
|
115
|
+
switch (tool.name) {
|
|
116
|
+
case 'Bash':
|
|
117
|
+
case 'bash': {
|
|
118
|
+
const cmd = str('command');
|
|
119
|
+
return cmd ? `**Command**\n\`\`\`bash\n${truncate(cmd, BODY_FIELD_MAX)}\n\`\`\`` : '';
|
|
120
|
+
}
|
|
121
|
+
case 'Read':
|
|
122
|
+
case 'Edit':
|
|
123
|
+
case 'Write':
|
|
124
|
+
case 'NotebookEdit':
|
|
125
|
+
case 'read':
|
|
126
|
+
case 'edit':
|
|
127
|
+
case 'write': {
|
|
128
|
+
const fp = str('file_path') || str('path');
|
|
129
|
+
return fp ? `**File** \`${fp}\`` : '';
|
|
130
|
+
}
|
|
131
|
+
case 'Grep':
|
|
132
|
+
case 'grep': {
|
|
133
|
+
const lines = [];
|
|
134
|
+
if (str('pattern'))
|
|
135
|
+
lines.push(`**Pattern** \`${str('pattern')}\``);
|
|
136
|
+
if (str('path'))
|
|
137
|
+
lines.push(`**Path** \`${str('path')}\``);
|
|
138
|
+
return lines.join('\n');
|
|
139
|
+
}
|
|
140
|
+
case 'Glob':
|
|
141
|
+
case 'find': {
|
|
142
|
+
const p = str('pattern');
|
|
143
|
+
return p ? `**Pattern** \`${truncate(p, BODY_FIELD_MAX)}\`` : '';
|
|
144
|
+
}
|
|
145
|
+
case 'ls': {
|
|
146
|
+
const p = str('path');
|
|
147
|
+
return p ? `**Path** \`${p}\`` : '';
|
|
148
|
+
}
|
|
149
|
+
case 'WebFetch':
|
|
150
|
+
return str('url') ? `**URL** ${str('url')}` : '';
|
|
151
|
+
case 'WebSearch':
|
|
152
|
+
return str('query') ? `**Query** \`${truncate(str('query'), BODY_FIELD_MAX)}\`` : '';
|
|
153
|
+
default:
|
|
154
|
+
return '';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function asRecord(input) {
|
|
158
|
+
if (!input)
|
|
159
|
+
return null;
|
|
160
|
+
if (typeof input === 'object')
|
|
161
|
+
return input;
|
|
162
|
+
if (typeof input === 'string') {
|
|
163
|
+
try {
|
|
164
|
+
const p = JSON.parse(input);
|
|
165
|
+
return p && typeof p === 'object' ? p : null;
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
function truncate(s, max) {
|
|
174
|
+
return s.length > max ? `${s.slice(0, max)}…` : s;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=tool-render.js.map
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
type RuntimeChoice = 'bun' | 'node';
|
|
3
|
+
interface BunProbe {
|
|
4
|
+
error: boolean;
|
|
5
|
+
status: number | null;
|
|
6
|
+
}
|
|
7
|
+
/** Prefer bun unless we are already under bun or bun is not usable. */
|
|
8
|
+
export declare function decideRuntime(isBun: boolean, probe: BunProbe): RuntimeChoice;
|
|
9
|
+
interface ChildLike {
|
|
10
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
11
|
+
on(event: 'exit', listener: (code: number | null, signal: NodeJS.Signals | null) => void): this;
|
|
12
|
+
kill(signal?: NodeJS.Signals): boolean;
|
|
13
|
+
}
|
|
14
|
+
interface BootstrapDeps {
|
|
15
|
+
entry: string;
|
|
16
|
+
args: string[];
|
|
17
|
+
isBun: boolean;
|
|
18
|
+
probe: BunProbe;
|
|
19
|
+
platform?: string;
|
|
20
|
+
importEntry: () => Promise<unknown>;
|
|
21
|
+
spawnBun: (entry: string, args: string[]) => ChildLike;
|
|
22
|
+
onSignal: (signal: NodeJS.Signals, handler: () => void) => void;
|
|
23
|
+
offSignal: (signal: NodeJS.Signals, handler: () => void) => void;
|
|
24
|
+
killSelf: (signal: NodeJS.Signals) => void;
|
|
25
|
+
exit: (code: number) => void;
|
|
26
|
+
}
|
|
27
|
+
export declare function bootstrap(deps: BootstrapDeps): Promise<void>;
|
|
28
|
+
export {};
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
6
|
+
const entryUrl = new URL('./index.js', import.meta.url);
|
|
7
|
+
const entry = fileURLToPath(entryUrl);
|
|
8
|
+
/** Prefer bun unless we are already under bun or bun is not usable. */
|
|
9
|
+
export function decideRuntime(isBun, probe) {
|
|
10
|
+
if (!isBun && !probe.error && probe.status === 0)
|
|
11
|
+
return 'bun';
|
|
12
|
+
return 'node';
|
|
13
|
+
}
|
|
14
|
+
/** Check whether `bun` is present and runs `--version` successfully. */
|
|
15
|
+
function probeBun() {
|
|
16
|
+
try {
|
|
17
|
+
const res = spawnSync('bun', ['--version'], { stdio: 'ignore' });
|
|
18
|
+
return { error: res.error !== undefined, status: res.status };
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return { error: true, status: null };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export async function bootstrap(deps) {
|
|
25
|
+
const { entry, args, isBun, probe, platform = process.platform, importEntry, spawnBun, onSignal, offSignal, killSelf, exit, } = deps;
|
|
26
|
+
if (decideRuntime(isBun, probe) === 'node') {
|
|
27
|
+
await importEntry();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const child = spawnBun(entry, args);
|
|
31
|
+
const signals = platform === 'win32' ? ['SIGINT', 'SIGTERM', 'SIGBREAK'] : ['SIGINT', 'SIGTERM', 'SIGHUP'];
|
|
32
|
+
const forwarders = new Map();
|
|
33
|
+
for (const sig of signals) {
|
|
34
|
+
const forwarder = () => child.kill(sig);
|
|
35
|
+
forwarders.set(sig, forwarder);
|
|
36
|
+
onSignal(sig, forwarder);
|
|
37
|
+
}
|
|
38
|
+
child.on('error', () => {
|
|
39
|
+
for (const [sig, forwarder] of forwarders)
|
|
40
|
+
offSignal(sig, forwarder);
|
|
41
|
+
void importEntry().catch(() => exit(1));
|
|
42
|
+
});
|
|
43
|
+
child.on('exit', (code, signal) => {
|
|
44
|
+
if (signal) {
|
|
45
|
+
for (const [sig, forwarder] of forwarders)
|
|
46
|
+
offSignal(sig, forwarder);
|
|
47
|
+
try {
|
|
48
|
+
killSelf(signal);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
exit(code ?? 1);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function isDirectEntry() {
|
|
60
|
+
const argv1 = process.argv[1];
|
|
61
|
+
if (!argv1)
|
|
62
|
+
return false;
|
|
63
|
+
const candidates = [];
|
|
64
|
+
try {
|
|
65
|
+
candidates.push(fs.realpathSync(argv1));
|
|
66
|
+
}
|
|
67
|
+
catch { }
|
|
68
|
+
candidates.push(path.resolve(argv1));
|
|
69
|
+
return candidates.some((p) => pathToFileURL(p).href === import.meta.url);
|
|
70
|
+
}
|
|
71
|
+
function main() {
|
|
72
|
+
const deps = {
|
|
73
|
+
entry,
|
|
74
|
+
args: process.argv.slice(2),
|
|
75
|
+
isBun: process.isBun ?? false,
|
|
76
|
+
probe: probeBun(),
|
|
77
|
+
importEntry: () => import(entryUrl.href),
|
|
78
|
+
spawnBun: (e, a) => spawn('bun', [e, ...a], { stdio: 'inherit' }),
|
|
79
|
+
onSignal: (sig, handler) => process.on(sig, handler),
|
|
80
|
+
offSignal: (sig, handler) => process.off(sig, handler),
|
|
81
|
+
killSelf: (sig) => process.kill(process.pid, sig),
|
|
82
|
+
exit: (code) => process.exit(code),
|
|
83
|
+
};
|
|
84
|
+
void bootstrap(deps).catch(() => process.exit(1));
|
|
85
|
+
}
|
|
86
|
+
if (isDirectEntry()) {
|
|
87
|
+
main();
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type guards and safe value extractors for untyped (usually JSON-parsed)
|
|
3
|
+
* data coming from external sources such as LSP messages, API responses,
|
|
4
|
+
* or child-process stdout.
|
|
5
|
+
*
|
|
6
|
+
* Every function is intentionally tiny and side-effect-free so it can be
|
|
7
|
+
* inlined by the bundler and reasoned about at a glance.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Returns `true` when `v` is a non-null object (including arrays).
|
|
11
|
+
* Used as a prerequisite before accessing string-keyed properties.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isRecord(v: unknown): v is Record<string, unknown>;
|
|
14
|
+
/**
|
|
15
|
+
* Narrows `v` to `Record<string, unknown>` when it is a non-null object,
|
|
16
|
+
* otherwise returns `undefined`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function recordValue(v: unknown): Record<string, unknown> | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Returns the string value when `v` is a `string`, otherwise `undefined`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function stringValue(v: unknown): string | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Returns the number value when `v` is a `number`, otherwise `undefined`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function numberValue(v: unknown): number | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Extracts a human-readable error message from an opaque error object.
|
|
29
|
+
*
|
|
30
|
+
* Priority:
|
|
31
|
+
* 1. `raw.message` (string)
|
|
32
|
+
* 2. `raw.error.message` (string, when `raw.error` is a record)
|
|
33
|
+
* 3. `raw.error.data.message` (string, AI SDK wraps provider errors as {error:{data:{message}}})
|
|
34
|
+
* 4. `raw.error` itself (when it is a string)
|
|
35
|
+
* 5. `fallback`
|
|
36
|
+
*/
|
|
37
|
+
export declare function extractErrorMessage(raw: Record<string, unknown>, fallback: string): string;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type guards and safe value extractors for untyped (usually JSON-parsed)
|
|
3
|
+
* data coming from external sources such as LSP messages, API responses,
|
|
4
|
+
* or child-process stdout.
|
|
5
|
+
*
|
|
6
|
+
* Every function is intentionally tiny and side-effect-free so it can be
|
|
7
|
+
* inlined by the bundler and reasoned about at a glance.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Returns `true` when `v` is a non-null object (including arrays).
|
|
11
|
+
* Used as a prerequisite before accessing string-keyed properties.
|
|
12
|
+
*/
|
|
13
|
+
export function isRecord(v) {
|
|
14
|
+
return typeof v === 'object' && v !== null;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Narrows `v` to `Record<string, unknown>` when it is a non-null object,
|
|
18
|
+
* otherwise returns `undefined`.
|
|
19
|
+
*/
|
|
20
|
+
export function recordValue(v) {
|
|
21
|
+
return isRecord(v) ? v : undefined;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns the string value when `v` is a `string`, otherwise `undefined`.
|
|
25
|
+
*/
|
|
26
|
+
export function stringValue(v) {
|
|
27
|
+
return typeof v === 'string' ? v : undefined;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Returns the number value when `v` is a `number`, otherwise `undefined`.
|
|
31
|
+
*/
|
|
32
|
+
export function numberValue(v) {
|
|
33
|
+
return typeof v === 'number' ? v : undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Extracts a human-readable error message from an opaque error object.
|
|
37
|
+
*
|
|
38
|
+
* Priority:
|
|
39
|
+
* 1. `raw.message` (string)
|
|
40
|
+
* 2. `raw.error.message` (string, when `raw.error` is a record)
|
|
41
|
+
* 3. `raw.error.data.message` (string, AI SDK wraps provider errors as {error:{data:{message}}})
|
|
42
|
+
* 4. `raw.error` itself (when it is a string)
|
|
43
|
+
* 5. `fallback`
|
|
44
|
+
*/
|
|
45
|
+
export function extractErrorMessage(raw, fallback) {
|
|
46
|
+
const msg = stringValue(raw.message);
|
|
47
|
+
if (msg !== undefined)
|
|
48
|
+
return msg;
|
|
49
|
+
const err = raw.error;
|
|
50
|
+
if (isRecord(err)) {
|
|
51
|
+
const subMsg = stringValue(err.message);
|
|
52
|
+
if (subMsg !== undefined)
|
|
53
|
+
return subMsg;
|
|
54
|
+
const data = recordValue(err.data);
|
|
55
|
+
if (data) {
|
|
56
|
+
const dataMsg = stringValue(data.message);
|
|
57
|
+
if (dataMsg !== undefined)
|
|
58
|
+
return dataMsg;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (typeof err === 'string')
|
|
62
|
+
return err;
|
|
63
|
+
return fallback;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=guards.js.map
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex config loader
|
|
3
|
+
*
|
|
4
|
+
* Reads model_provider and model from ~/.codex/config.toml,
|
|
5
|
+
* provides dynamic dropdown options for /config card.
|
|
6
|
+
*
|
|
7
|
+
* Model filtering strategy:
|
|
8
|
+
* - catalog 模式(config.toml 声明 model_catalog_json):模型列表/档位来自活动目录
|
|
9
|
+
* - 非 catalog 模式:openai 用 bundled 全量;anthropic 仅在用户显式配置时存在
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Resolve codex home directory.
|
|
13
|
+
* Priority: explicit codexHome param > $CODEX_HOME env > ~/.codex
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveCodexHome(codexHome?: string): string;
|
|
16
|
+
/** loadCodexConfig() return type */
|
|
17
|
+
interface CodexConfigResult {
|
|
18
|
+
/** current selected model */
|
|
19
|
+
currentModel: string;
|
|
20
|
+
/** current selected model_provider */
|
|
21
|
+
currentProvider: string;
|
|
22
|
+
/** provider name list */
|
|
23
|
+
providerNames: string[];
|
|
24
|
+
/** provider -> env_key mapping (e.g., openai -> OPENAI_API_KEY) */
|
|
25
|
+
providerEnvKeys: Record<string, string>;
|
|
26
|
+
/** provider -> model list mapping.
|
|
27
|
+
* - custom provider: model from config.toml
|
|
28
|
+
* - openai: all bundled models
|
|
29
|
+
* - anthropic: bundled models with 'claude-*' prefix */
|
|
30
|
+
providerModels: Record<string, string[]>;
|
|
31
|
+
/** Get available model list by provider */
|
|
32
|
+
modelOptions: (provider?: string) => string[];
|
|
33
|
+
}
|
|
34
|
+
/** Enhanced bundled model info interface */
|
|
35
|
+
export interface BundledModelInfo {
|
|
36
|
+
/** model slug (e.g., gpt-5.6-sol) */
|
|
37
|
+
slug: string;
|
|
38
|
+
/** display name (e.g., GPT-5.6-Sol) */
|
|
39
|
+
displayName: string;
|
|
40
|
+
/** priority, lower number = first in list */
|
|
41
|
+
priority: number;
|
|
42
|
+
/** supported reasoning effort levels */
|
|
43
|
+
supportedReasoningLevels: string[];
|
|
44
|
+
/** default reasoning effort;未声明时为 undefined(codex 语义:不传 effort) */
|
|
45
|
+
defaultReasoningLevel: string | undefined;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Catalog mode = config.toml **声明了** model_catalog_json(键存在即算,不要求文件存在)。
|
|
49
|
+
* 依据:codex 运行时对"已配置但文件缺失/不可解析"的目录是硬错误
|
|
50
|
+
* (core/src/config/mod.rs load_model_catalog ?),绝不会回退内置目录;因此键存在即
|
|
51
|
+
* catalog 模式,文件缺失自然落入 `codex debug models` 失败路径 → 模型列表回退
|
|
52
|
+
* [currentModel](P1-1)。
|
|
53
|
+
*/
|
|
54
|
+
export declare function isCodexCatalogMode(codexHome?: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* 单一解析器:把 `codex debug models`(活动目录)或 `--bundled`(内置目录)的原始 JSON
|
|
57
|
+
* 输出解析为模型列表(P2-4 去重)。过滤/排序镜像 codex:
|
|
58
|
+
* - show_in_picker = visibility == List(openai_models.rs ModelPreset::from);
|
|
59
|
+
* - API 模式(lark 用 API key 认证)下 codex filter_by_auth 过滤 supported_in_api=false;
|
|
60
|
+
* - 按 priority 升序(build_available_models)。
|
|
61
|
+
* 档位按目录声明**原样透传**(含 custom/none,P2-5),不按标准枚举过滤、不虚构兜底:
|
|
62
|
+
* 未声明档位 → 空列表(codex with_model 语义:len=0 时用声明 default,都没有则不发
|
|
63
|
+
* effort;P1)。空串档位/空串 default 被过滤(P3-9:codex ReasoningEffort::from_str
|
|
64
|
+
* 对 "" 硬错误)。supported_in_api===true 过滤等价于 codex 的 chatgpt_mode ||
|
|
65
|
+
* supported_in_api:本项目以 API-key 模式运行 codex,chatgpt_mode 恒 false(P3-3)。
|
|
66
|
+
*/
|
|
67
|
+
export declare function parseCodexModelsOutput(stdout: string): BundledModelInfo[];
|
|
68
|
+
/**
|
|
69
|
+
* 统一目录入口:catalog 模式(model_catalog_json 已声明,含声明退化 '')跑
|
|
70
|
+
* `debug models`(无 --bundled),否则(未声明或 config.toml 解析失败)跑
|
|
71
|
+
* `debug models --bundled`。注(P3-4):codex 无参 `debug models` 在
|
|
72
|
+
* uses_codex_backend()/has_command_auth() 时会请求远端 /models(models-manager
|
|
73
|
+
* manager.rs / models_endpoint.rs);本项目以 API-key 模式运行(无 ChatGPT/命令
|
|
74
|
+
* 认证),结果与 bundled 一致,故非 catalog 用 --bundled(已文档化)。
|
|
75
|
+
* 缓存:键含 binary/home/mode/models.json mtime:size + config.toml mtime:size
|
|
76
|
+
* (P3-4/P3-15/P3-5);成功结果 TTL 1h,失败/空结果短 TTL 负缓存;stat 异常时
|
|
77
|
+
* 指纹为空(P1-1/P3-10)。
|
|
78
|
+
*/
|
|
79
|
+
export declare function getCodexCatalogModels(binary: string, codexHome?: string): BundledModelInfo[];
|
|
80
|
+
/**
|
|
81
|
+
* Test utility: clear the catalog cache. Tests that exercise the bundled
|
|
82
|
+
* command path (`--bundled`) directly use `invalidateCodexBundledTestCache`
|
|
83
|
+
* from `codex-bundled-test-helpers.ts`.
|
|
84
|
+
*/
|
|
85
|
+
export declare function invalidateCodexBundledCache(): void;
|
|
86
|
+
/**
|
|
87
|
+
* Get supported reasoning effort options for a model.
|
|
88
|
+
* @param codexHome 可选 codex 配置目录覆盖(与 loadCodexConfig 的 codexHome 对齐,
|
|
89
|
+
* 与 loadCodexConfig 的 codexHome 对齐);省略时走 $CODEX_HOME → ~/.codex。
|
|
90
|
+
*/
|
|
91
|
+
export declare function getReasoningEffortOptions(model: string, binary?: string, codexHome?: string): readonly string[];
|
|
92
|
+
/**
|
|
93
|
+
* Get default reasoning effort for a model.
|
|
94
|
+
* 未声明/未知模型 → undefined(codex 语义:ModelPreset.default_reasoning_effort
|
|
95
|
+
* unwrap_or(ReasoningEffort::None),即不传 effort;P3-12)。
|
|
96
|
+
*/
|
|
97
|
+
export declare function getDefaultReasoningEffort(model: string, binary?: string, codexHome?: string): string | undefined;
|
|
98
|
+
interface LoadCodexConfigOpts {
|
|
99
|
+
/** Explicit codex home override. Default: $CODEX_HOME -> ~/.codex */
|
|
100
|
+
codexHome?: string;
|
|
101
|
+
/** codex binary path, for `debug models --bundled`. Default: 'codex' */
|
|
102
|
+
binary?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Read codex config.toml, extract provider and model info
|
|
106
|
+
*
|
|
107
|
+
* Model filtering strategy:
|
|
108
|
+
* - Custom provider: model from config.toml (single model)
|
|
109
|
+
* - openai: all bundled models
|
|
110
|
+
* - anthropic: bundled models with 'claude-*' prefix
|
|
111
|
+
*/
|
|
112
|
+
export declare function loadCodexConfig(opts?: LoadCodexConfigOpts): CodexConfigResult;
|
|
113
|
+
export {};
|