@lazyingart/agintiflow 0.20.63 → 0.20.64

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.20.63",
3
+ "version": "0.20.64",
4
4
  "type": "module",
5
5
  "description": "Low-cost, project-aware Web and CLI agents with DeepSeek/Venice/OpenAI routing, visible tool calls, durable sessions, scouts, AAPS, SCS, and guarded local execution.",
6
6
  "license": "Apache-2.0",
@@ -15,7 +15,7 @@ import {
15
15
  formatWorkspaceChange,
16
16
  stripMarkdown,
17
17
  } from "../src/interactive-cli.js";
18
- import { parseArgs } from "../src/cli.js";
18
+ import { parseArgs, parseResumeCommandArgs, splitResumeCommandArgv } from "../src/cli.js";
19
19
  import { dockerPolicyTimeoutMs, dockerUserCommand } from "../src/docker-sandbox.js";
20
20
  import { formatBehaviorContractForPrompt } from "../src/behavior-contract.js";
21
21
 
@@ -286,6 +286,48 @@ try {
286
286
  if (scsAutoArgs.enableScs !== "auto" || scsAutoArgs.goal !== "fix this project") {
287
287
  throw new Error("--scs auto should consume auto and preserve the task");
288
288
  }
289
+ const resumeAfterOptions = parseResumeCommandArgs([
290
+ "web-agent-smoke",
291
+ "--provider",
292
+ "deepseek",
293
+ "--routing",
294
+ "smart",
295
+ "--sandbox-mode",
296
+ "host",
297
+ "--scout-count",
298
+ "3",
299
+ ]);
300
+ const resumeAfterParsed = parseArgs(resumeAfterOptions.optionArgv);
301
+ if (
302
+ resumeAfterOptions.sessionId !== "web-agent-smoke" ||
303
+ resumeAfterOptions.prompt ||
304
+ resumeAfterParsed.provider !== "deepseek" ||
305
+ resumeAfterParsed.routingMode !== "smart" ||
306
+ resumeAfterParsed.sandboxMode !== "host" ||
307
+ resumeAfterParsed.parallelScoutCount !== 3
308
+ ) {
309
+ throw new Error("resume subcommand options after the session id should remain options, not prompt text");
310
+ }
311
+ const resumePromptAfterDash = parseResumeCommandArgs(["web-agent-smoke", "--provider", "mock", "--", "--provider should be prompt"]);
312
+ if (
313
+ resumePromptAfterDash.sessionId !== "web-agent-smoke" ||
314
+ resumePromptAfterDash.prompt !== "--provider should be prompt" ||
315
+ parseArgs(resumePromptAfterDash.optionArgv).provider !== "mock"
316
+ ) {
317
+ throw new Error("resume subcommand should preserve explicit prompt text after --");
318
+ }
319
+ const leadingResume = splitResumeCommandArgv(["--provider", "mock", "--routing", "manual", "resume", "latest"]);
320
+ if (
321
+ !leadingResume ||
322
+ leadingResume.resumeArgv.join(" ") !== "latest" ||
323
+ parseArgs(leadingResume.leadingOptionArgv).provider !== "mock" ||
324
+ parseArgs(leadingResume.leadingOptionArgv).routingMode !== "manual"
325
+ ) {
326
+ throw new Error("leading global options before resume should still invoke the resume subcommand");
327
+ }
328
+ if (splitResumeCommandArgv(["--provider", "mock", "resume", "a normal task"]) !== null) {
329
+ throw new Error("leading global options should not turn an ordinary resume-themed prompt into the resume subcommand");
330
+ }
289
331
 
290
332
  await runCli(["init"], "");
291
333
  const instructions = await fs.readFile(path.join(tempRoot, "AGINTI.md"), "utf8");
@@ -420,6 +462,7 @@ try {
420
462
  "skills-command",
421
463
  "review-command",
422
464
  "scs-command-toggle",
465
+ "resume-command-options",
423
466
  "slash-prefix-autoselect",
424
467
  "slash-prefix-canonical-history",
425
468
  "instructions-chat-edit",
package/src/cli.js CHANGED
@@ -65,6 +65,205 @@ function readOptionalScsMode(argv, index) {
65
65
  return { mode: value, consumed: true };
66
66
  }
67
67
 
68
+ const CLI_VALUE_OPTIONS = new Set([
69
+ "--port",
70
+ "--host",
71
+ "--language",
72
+ "--lang",
73
+ "-L",
74
+ "--start-url",
75
+ "--resume",
76
+ "--session-id",
77
+ "--provider",
78
+ "--model",
79
+ "--route-provider",
80
+ "--route-model",
81
+ "--main-provider",
82
+ "--main-model",
83
+ "--spare-provider",
84
+ "--spare-model",
85
+ "--spare-reasoning",
86
+ "--wrapper-model",
87
+ "--wrapper-reasoning",
88
+ "--aux-provider",
89
+ "--auxiliary-provider",
90
+ "--aux-model",
91
+ "--auxiliary-model",
92
+ "--routing",
93
+ "--cwd",
94
+ "--sandbox-mode",
95
+ "--package-install-policy",
96
+ "--max-steps",
97
+ "--scout-count",
98
+ "--wrapper",
99
+ "--preferred-wrapper",
100
+ "--profile",
101
+ "--task-profile",
102
+ ]);
103
+
104
+ const CLI_FLAG_OPTIONS = new Set([
105
+ "--web",
106
+ "--chat",
107
+ "--interactive",
108
+ "--no-auto-update",
109
+ "--auto-update",
110
+ "--enable-scs",
111
+ "--disable-scs",
112
+ "--no-scs",
113
+ "--approve-package-installs",
114
+ "--latex",
115
+ "--image",
116
+ "--image-gen",
117
+ "--image-generation",
118
+ "--allow-shell",
119
+ "--no-shell",
120
+ "--allow-destructive",
121
+ "--trusted-host-shell",
122
+ "--allow-file-tools",
123
+ "--no-file-tools",
124
+ "--allow-auxiliary-tools",
125
+ "--allow-auxiliary",
126
+ "--no-auxiliary-tools",
127
+ "--no-auxiliary",
128
+ "--web-search",
129
+ "--no-web-search",
130
+ "--parallel-scouts",
131
+ "--no-parallel-scouts",
132
+ "--allow-wrappers",
133
+ "--docker-sandbox",
134
+ "--headless",
135
+ "--list-routes",
136
+ "--list-models",
137
+ "--models",
138
+ "--list-wrappers",
139
+ "--list-profiles",
140
+ "--list-skills",
141
+ "--sandbox-status",
142
+ "--sandbox-preflight",
143
+ "--scs",
144
+ ]);
145
+
146
+ function collectCliOption(argv, index) {
147
+ const arg = argv[index];
148
+ if (arg === "--scs" || arg === "--enable-scs") {
149
+ const { consumed } = readOptionalScsMode(argv, index);
150
+ return { recognized: true, args: consumed ? [arg, argv[index + 1]] : [arg], nextIndex: index + (consumed ? 2 : 1) };
151
+ }
152
+ if (arg === "--language" || arg === "--lang" || arg === "-L") {
153
+ const first = readOption(argv, index);
154
+ const second = argv[index + 2] && !String(argv[index + 2]).startsWith("--") ? argv[index + 2] : "";
155
+ if (["cn", "zh"].includes(String(first || "").toLowerCase()) && ["s", "t"].includes(String(second || "").toLowerCase())) {
156
+ return { recognized: true, args: [arg, first, second], nextIndex: index + 3 };
157
+ }
158
+ return first
159
+ ? { recognized: true, args: [arg, first], nextIndex: index + 2 }
160
+ : { recognized: true, args: [arg], nextIndex: index + 1 };
161
+ }
162
+ if (CLI_VALUE_OPTIONS.has(arg)) {
163
+ const value = readOption(argv, index);
164
+ return value
165
+ ? { recognized: true, args: [arg, value], nextIndex: index + 2 }
166
+ : { recognized: true, args: [arg], nextIndex: index + 1 };
167
+ }
168
+ if (CLI_FLAG_OPTIONS.has(arg)) {
169
+ return { recognized: true, args: [arg], nextIndex: index + 1 };
170
+ }
171
+ return { recognized: false, args: [], nextIndex: index };
172
+ }
173
+
174
+ function looksLikeResumeSessionSelector(value) {
175
+ if (!value) return true;
176
+ const normalized = String(value);
177
+ return (
178
+ normalized === "latest" ||
179
+ normalized.startsWith("web-agent-") ||
180
+ normalized.startsWith("round") ||
181
+ normalized.startsWith("session-") ||
182
+ normalized.startsWith("aginti-")
183
+ );
184
+ }
185
+
186
+ function looksLikeResumeInvocation(resumeArgv = []) {
187
+ for (let index = 0; index < resumeArgv.length;) {
188
+ const arg = resumeArgv[index];
189
+ if (arg === "--" || looksLikeResumeSessionSelector(arg)) return looksLikeResumeSessionSelector(arg);
190
+ if (arg === "--all-sessions") {
191
+ index += 1;
192
+ continue;
193
+ }
194
+ const collected = collectCliOption(resumeArgv, index);
195
+ if (collected.recognized) {
196
+ index = collected.nextIndex;
197
+ continue;
198
+ }
199
+ return looksLikeResumeSessionSelector(arg);
200
+ }
201
+ return true;
202
+ }
203
+
204
+ export function splitResumeCommandArgv(argv = []) {
205
+ if (argv[0] === "resume") {
206
+ return { leadingOptionArgv: [], resumeArgv: argv.slice(1) };
207
+ }
208
+
209
+ const leadingOptionArgv = [];
210
+ let index = 0;
211
+ while (index < argv.length) {
212
+ if (argv[index] === "resume") {
213
+ const resumeArgv = argv.slice(index + 1);
214
+ return looksLikeResumeInvocation(resumeArgv) ? { leadingOptionArgv, resumeArgv } : null;
215
+ }
216
+ const collected = collectCliOption(argv, index);
217
+ if (!collected.recognized) return null;
218
+ leadingOptionArgv.push(...collected.args);
219
+ index = collected.nextIndex;
220
+ }
221
+ return null;
222
+ }
223
+
224
+ export function parseResumeCommandArgs(resumeArgv = [], leadingOptionArgv = []) {
225
+ const optionArgv = [...leadingOptionArgv];
226
+ const positional = [];
227
+ const promptParts = [];
228
+ let allSessions = false;
229
+ let promptMode = false;
230
+
231
+ for (let index = 0; index < resumeArgv.length;) {
232
+ const arg = resumeArgv[index];
233
+ if (promptMode) {
234
+ promptParts.push(arg);
235
+ index += 1;
236
+ continue;
237
+ }
238
+ if (arg === "--") {
239
+ promptMode = true;
240
+ index += 1;
241
+ continue;
242
+ }
243
+ if (arg === "--all-sessions") {
244
+ allSessions = true;
245
+ index += 1;
246
+ continue;
247
+ }
248
+ const collected = collectCliOption(resumeArgv, index);
249
+ if (collected.recognized) {
250
+ optionArgv.push(...collected.args);
251
+ index = collected.nextIndex;
252
+ continue;
253
+ }
254
+ if (positional.length === 0) positional.push(arg);
255
+ else promptParts.push(arg);
256
+ index += 1;
257
+ }
258
+
259
+ return {
260
+ allSessions,
261
+ optionArgv,
262
+ sessionId: positional[0] || "",
263
+ prompt: promptParts.join(" ").trim(),
264
+ };
265
+ }
266
+
68
267
  export function parseArgs(argv) {
69
268
  const result = {
70
269
  goal: "",
@@ -1114,6 +1313,7 @@ export async function main(argv = process.argv.slice(2)) {
1114
1313
  const stripped = stripLeadingGlobalOptions(argv);
1115
1314
  const commandArgv = stripped.argv;
1116
1315
  const commandCwd = stripped.options.commandCwd || process.cwd();
1316
+ const resumeCommand = splitResumeCommandArgv(commandArgv);
1117
1317
 
1118
1318
  if (commandArgv[0] === "aaps") {
1119
1319
  try {
@@ -1254,27 +1454,25 @@ export async function main(argv = process.argv.slice(2)) {
1254
1454
  return;
1255
1455
  }
1256
1456
 
1257
- if (commandArgv[0] === "resume") {
1258
- const resumeArgv = commandArgv.slice(1);
1259
- const allSessions = resumeArgv.includes("--all-sessions");
1260
- const positional = resumeArgv.filter((arg) => arg !== "--all-sessions");
1261
- let sessionId = positional[0] || "";
1262
- const prompt = positional.slice(1).join(" ").trim();
1457
+ if (resumeCommand) {
1458
+ const resumeOptions = parseResumeCommandArgs(resumeCommand.resumeArgv, resumeCommand.leadingOptionArgv);
1459
+ let sessionId = resumeOptions.sessionId;
1460
+ const prompt = resumeOptions.prompt;
1263
1461
  try {
1264
- sessionId = await resolveResumeSessionId(sessionId, { allSessions });
1462
+ sessionId = await resolveResumeSessionId(sessionId, { allSessions: resumeOptions.allSessions });
1265
1463
  } catch (error) {
1266
1464
  console.error(error instanceof Error ? error.message : String(error));
1267
1465
  process.exit(1);
1268
1466
  }
1269
1467
  if (!sessionId) return;
1270
1468
  if (!prompt) {
1271
- await startInteractiveCli(agentDefaults({ ...parseArgs([]), resume: sessionId, commandCwd }), {
1469
+ await startInteractiveCli(agentDefaults({ ...parseArgs(resumeOptions.optionArgv), resume: sessionId, commandCwd }), {
1272
1470
  packageDir,
1273
1471
  packageVersion: packageJson.version,
1274
1472
  });
1275
1473
  return;
1276
1474
  }
1277
- const resumeArgs = agentDefaults({ ...parseArgs([prompt]), resume: sessionId, goal: prompt, commandCwd });
1475
+ const resumeArgs = agentDefaults({ ...parseArgs([...resumeOptions.optionArgv, prompt]), resume: sessionId, goal: prompt, commandCwd });
1278
1476
  if (!(await ensureDeepSeekKeyForOneShot(resumeArgs))) process.exit(1);
1279
1477
  const config = loadConfig(resumeArgs, { packageDir });
1280
1478
  await runAgent(config);