-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparse-args.ts
More file actions
344 lines (315 loc) · 11 KB
/
Copy pathparse-args.ts
File metadata and controls
344 lines (315 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
// CLI argv parser — minimal, dependency-free, designed for the flag set in
// docs/DEVELOPMENT_PLAN.md §5.
// Returns a strongly-typed shape. Unknown flags are collected into `unknown` for
// graceful "did you mean..." errors.
import type { Effort, Mode } from '@deepcode/core';
export interface ParsedArgs {
// Action triggers (mutually exclusive — first match wins)
showHelp: boolean;
showVersion: boolean;
doctor: boolean;
upgrade: boolean;
// Mode of execution
prompt?: string; // -p / --print, one-shot
resume: boolean; // --resume (interactive picker)
resumeId?: string; // --resume <sessionId>
continue: boolean;
forkSession: boolean;
// Session shaping
mode?: Mode;
model?: string;
effort?: Effort;
maxTurns?: number;
bare: boolean;
/** `-C` / `--cd <dir>`: chdir to this directory before running (Codex parity). */
cwd?: string;
// System prompt overrides
systemPrompt?: string;
appendSystemPrompt?: string;
appendSystemPromptFile?: string;
// Tool allow/deny lists
allowedTools?: string[];
disallowedTools?: string[];
// Output (headless mode)
outputFormat: 'text' | 'json' | 'stream-json';
jsonSchema?: string;
includePartialMessages: boolean;
verbose: boolean;
/** `--json` — machine-readable output for subcommands (plugins/skills list). */
json: boolean;
// Settings overrides
settingsFile?: string;
agentsDir?: string;
mcpConfig?: string;
pluginDir?: string;
pluginUrl?: string;
noPlugins: boolean;
strict: boolean;
// Diagnostics
unknownFlags: string[];
// Positional args (rarely used)
positional: string[];
}
const VALID_MODES: Mode[] = [
'default',
'acceptEdits',
'plan',
'auto',
'dontAsk',
'bypassPermissions',
];
const VALID_EFFORTS: Effort[] = ['low', 'medium', 'high', 'xhigh', 'max'];
/**
* Resolve the effective effort level from all precedence layers.
* Order (high → low): cli flag → DEEPCODE_EFFORT_LEVEL env → settings → default.
* Spec: docs/DEVELOPMENT_PLAN.md §3.13c.
*
* Returns `'medium'` if nothing produces a valid value.
*/
export function resolveEffort(args: {
cliFlag?: string;
envVar?: string;
settingsLevel?: string;
}): Effort {
const candidates: Array<string | undefined> = [
args.cliFlag,
args.envVar?.trim(),
args.settingsLevel,
];
for (const c of candidates) {
if (c && (VALID_EFFORTS as string[]).includes(c)) {
return c as Effort;
}
}
return 'medium';
}
export function parseArgs(argv: string[]): ParsedArgs {
const out: ParsedArgs = {
showHelp: false,
showVersion: false,
doctor: false,
upgrade: false,
resume: false,
continue: false,
forkSession: false,
bare: false,
outputFormat: 'text',
includePartialMessages: false,
verbose: false,
json: false,
noPlugins: false,
strict: false,
unknownFlags: [],
positional: [],
};
for (let i = 0; i < argv.length; i++) {
const a = argv[i]!;
const next = (): string | undefined => argv[++i];
switch (true) {
case a === '-h' || a === '--help':
out.showHelp = true;
break;
case a === '-v' || a === '--version':
out.showVersion = true;
break;
case a === 'doctor':
out.doctor = true;
break;
case a === 'upgrade':
out.upgrade = true;
break;
case a === '-p' || a === '--print':
out.prompt = next();
break;
case a === '--resume' || a === '-r': {
const maybeId = argv[i + 1];
if (maybeId && !maybeId.startsWith('-')) {
out.resumeId = maybeId;
i++;
}
out.resume = true;
break;
}
case a === '--continue' || a === '-c':
out.continue = true;
break;
case a === '--fork-session':
out.forkSession = true;
break;
case a === '--mode': {
const v = next();
if (v && (VALID_MODES as string[]).includes(v)) out.mode = v as Mode;
else out.unknownFlags.push(`--mode ${v ?? ''}`);
break;
}
// Claude Code alias for --mode: set out.mode directly so it's actually
// wired through cli.ts (which only forwards args.mode). Last flag wins if
// both --mode and --permission-mode are given.
case a === '--permission-mode': {
const v = next();
if (v && (VALID_MODES as string[]).includes(v)) out.mode = v as Mode;
else out.unknownFlags.push(`--permission-mode ${v ?? ''}`);
break;
}
case a === '--model':
out.model = next();
break;
case a === '--effort': {
const v = next();
if (v && (VALID_EFFORTS as string[]).includes(v)) out.effort = v as Effort;
else out.unknownFlags.push(`--effort ${v ?? ''}`);
break;
}
case a === '--max-turns': {
const v = next();
const n = v ? Number.parseInt(v, 10) : NaN;
if (Number.isFinite(n) && n > 0) out.maxTurns = n;
else out.unknownFlags.push(`--max-turns ${v ?? ''}`);
break;
}
case a === '--bare':
out.bare = true;
break;
case a === '-C' || a === '--cd':
out.cwd = next();
break;
case a === '--system-prompt':
out.systemPrompt = next();
break;
case a === '--append-system-prompt':
out.appendSystemPrompt = next();
break;
case a === '--append-system-prompt-file':
out.appendSystemPromptFile = next();
break;
case a === '--allowedTools': {
const v = next();
if (v)
out.allowedTools = v
.split(',')
.map((s) => s.trim())
.filter(Boolean);
break;
}
case a === '--disallowedTools': {
const v = next();
if (v)
out.disallowedTools = v
.split(',')
.map((s) => s.trim())
.filter(Boolean);
break;
}
case a === '--output-format': {
const v = next();
if (v === 'text' || v === 'json' || v === 'stream-json') out.outputFormat = v;
else out.unknownFlags.push(`--output-format ${v ?? ''}`);
break;
}
case a === '--json-schema':
out.jsonSchema = next();
break;
case a === '--include-partial-messages':
out.includePartialMessages = true;
break;
case a === '--json':
out.json = true;
break;
case a === '--verbose':
out.verbose = true;
break;
case a === '--settings':
out.settingsFile = next();
break;
case a === '--agents':
out.agentsDir = next();
break;
case a === '--mcp-config':
out.mcpConfig = next();
break;
case a === '--plugin-dir':
out.pluginDir = next();
break;
case a === '--plugin-url':
out.pluginUrl = next();
break;
case a === '--no-plugins':
out.noPlugins = true;
break;
case a === '--strict':
out.strict = true;
break;
case a.startsWith('--'):
out.unknownFlags.push(a);
break;
case a.startsWith('-'):
out.unknownFlags.push(a);
break;
default:
out.positional.push(a);
break;
}
}
return out;
}
export function helpText(version: string): string {
return `DeepCode v${version} — DeepSeek-powered AI coding agent (Claude Code parity)
USAGE
deepcode Interactive REPL
deepcode -p "<prompt>" Headless one-shot
deepcode --resume, -r [<id>] Resume a session (picker if no id)
deepcode --continue, -c Continue most recent session here
deepcode --resume <id> --fork-session Resume into a new session (keep original)
deepcode doctor Diagnostic checks
deepcode upgrade Self-update (CLI; Mac client auto-updates)
deepcode setup-token [<token>] Store a long-lived DeepSeek auth token (CI)
deepcode cron <cmd> Scheduled tasks: install/uninstall/list/status
deepcode scheduler run Run due scheduled jobs (invoked by launchd)
deepcode mcp serve Expose DeepCode tools as an MCP server (stdio)
deepcode app-server Run the experimental lifecycle server (JSONL stdio)
deepcode trust [--plan-only] Trust this directory's project config (hooks/MCP/...)
deepcode plugins list [--json] List installed plugins
deepcode plugins install <spec> Install a plugin (gh:owner/repo | name@npm | ./path)
deepcode plugins uninstall <name> Remove an installed plugin
deepcode skills list [--json] List available skills
deepcode completion <shell> Print a bash/zsh/fish shell-completion script
MODE
--mode <name> default / acceptEdits / plan / auto / dontAsk / bypassPermissions
--permission-mode <name> Alias for --mode (Claude Code parity)
--bare No plugins / MCP / skills — just kernel + tools
WORKING DIRECTORY
-C, --cd <dir> Change to <dir> before running (default: current dir)
MODEL & EFFORT
--model <id> deepseek-chat | deepseek-reasoner
--effort <tier> low | medium | high | xhigh | max
--max-turns <n> Cap agent loop turns
SYSTEM PROMPT
--system-prompt "<text>" Replace default system prompt
--append-system-prompt "<text>" Append to default
--append-system-prompt-file <path> Append from a file
TOOLS
--allowedTools "Tool,..." Whitelist
--disallowedTools "Tool,..." Blacklist
HEADLESS / CI (-p mode only)
--output-format text|json|stream-json Default text. json = single object at exit; stream-json = NDJSON events.
--json-schema <path> Constrain final output to a JSON schema
--include-partial-messages Stream partial deltas
--verbose Print LLM/tool call traces
Exit codes (headless): 0 ok · 1 generic · 2 bad-input · 3 api/auth · 4 max-turns · 5 aborted
OVERRIDES
--settings <path> Override settings.json discovery
--agents <dir> Override sub-agents dir
--mcp-config <path> Override MCP server config
--plugin-dir <dir> Temporarily mount a plugin dir
--plugin-url <gh:user/repo> Temporarily mount a remote plugin
--no-plugins Disable all plugins for this run
--strict Strict mode: only official-marketplace plugins, no hooks
DIAGNOSTICS
-h, --help Show this
-v, --version Show version
Configuration: ~/.deepcode/settings.json · <project>/.deepcode/settings.json · <project>/.deepcode/settings.local.json
Credentials: macOS Keychain (service=deepcode) · ~/.deepcode/credentials.json (chmod 600)
Sessions: ~/.deepcode/sessions/
Docs: https://github.com/oratis/deepcode#docs
`;
}