jinzd-ai-cli 0.4.3 → 0.4.4

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.
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  EnvLoader,
4
4
  schemaToJsonSchema
5
- } from "./chunk-AQ4O6SVK.js";
5
+ } from "./chunk-FUPDFYHI.js";
6
6
  import {
7
7
  APP_NAME,
8
8
  CONFIG_DIR_NAME,
@@ -15,7 +15,7 @@ import {
15
15
  MCP_TOOL_PREFIX,
16
16
  PLUGINS_DIR_NAME,
17
17
  VERSION
18
- } from "./chunk-3LKIHGAR.js";
18
+ } from "./chunk-QAYMV7WE.js";
19
19
 
20
20
  // src/config/config-manager.ts
21
21
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
@@ -6,7 +6,7 @@ import {
6
6
  SUBAGENT_DEFAULT_MAX_ROUNDS,
7
7
  SUBAGENT_MAX_ROUNDS_LIMIT,
8
8
  runTestsTool
9
- } from "./chunk-3LKIHGAR.js";
9
+ } from "./chunk-QAYMV7WE.js";
10
10
 
11
11
  // src/tools/builtin/bash.ts
12
12
  import { execSync } from "child_process";
@@ -6,7 +6,7 @@ import { platform } from "os";
6
6
  import chalk from "chalk";
7
7
 
8
8
  // src/core/constants.ts
9
- var VERSION = "0.4.3";
9
+ var VERSION = "0.4.4";
10
10
  var APP_NAME = "ai-cli";
11
11
  var CONFIG_DIR_NAME = ".aicli";
12
12
  var CONFIG_FILE_NAME = "config.json";
@@ -8,7 +8,7 @@ import { platform } from "os";
8
8
  import chalk from "chalk";
9
9
 
10
10
  // src/core/constants.ts
11
- var VERSION = "0.4.3";
11
+ var VERSION = "0.4.4";
12
12
  var APP_NAME = "ai-cli";
13
13
  var CONFIG_DIR_NAME = ".aicli";
14
14
  var CONFIG_FILE_NAME = "config.json";
@@ -381,7 +381,7 @@ ${content}`);
381
381
  }
382
382
  }
383
383
  async function runTaskMode(config, providers, configManager, topic) {
384
- const { TaskOrchestrator } = await import("./task-orchestrator-7NTCIVCF.js");
384
+ const { TaskOrchestrator } = await import("./task-orchestrator-XUMAUKLC.js");
385
385
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
386
386
  let interrupted = false;
387
387
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  saveDevState,
24
24
  sessionHasMeaningfulContent,
25
25
  setupProxy
26
- } from "./chunk-VC6DFUFP.js";
26
+ } from "./chunk-DGH7SQCZ.js";
27
27
  import {
28
28
  ToolRegistry,
29
29
  askUserContext,
@@ -38,7 +38,7 @@ import {
38
38
  theme,
39
39
  truncateOutput,
40
40
  undoStack
41
- } from "./chunk-AQ4O6SVK.js";
41
+ } from "./chunk-FUPDFYHI.js";
42
42
  import {
43
43
  AGENTIC_BEHAVIOR_GUIDELINE,
44
44
  AUTHOR,
@@ -58,7 +58,7 @@ import {
58
58
  REPO_URL,
59
59
  SKILLS_DIR_NAME,
60
60
  VERSION
61
- } from "./chunk-3LKIHGAR.js";
61
+ } from "./chunk-QAYMV7WE.js";
62
62
 
63
63
  // src/index.ts
64
64
  import { program } from "commander";
@@ -1914,7 +1914,7 @@ ${hint}` : "")
1914
1914
  description: "Run project tests and show structured report",
1915
1915
  usage: "/test [command|filter]",
1916
1916
  async execute(args, _ctx) {
1917
- const { executeTests } = await import("./run-tests-W2RQN33S.js");
1917
+ const { executeTests } = await import("./run-tests-KPWEEJKA.js");
1918
1918
  const argStr = args.join(" ").trim();
1919
1919
  let testArgs = {};
1920
1920
  if (argStr) {
@@ -5524,7 +5524,7 @@ program.command("web").description("Start Web UI server with browser-based chat
5524
5524
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
5525
5525
  process.exit(1);
5526
5526
  }
5527
- const { startWebServer } = await import("./server-WPLQ2AII.js");
5527
+ const { startWebServer } = await import("./server-USQZD3PU.js");
5528
5528
  await startWebServer({ port, host: options.host });
5529
5529
  });
5530
5530
  program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | migrate <name>)").action(async (action, username) => {
@@ -5757,7 +5757,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
5757
5757
  }),
5758
5758
  config.get("customProviders")
5759
5759
  );
5760
- const { startHub } = await import("./hub-UQ2IWPJK.js");
5760
+ const { startHub } = await import("./hub-ZP7OZJMH.js");
5761
5761
  await startHub(
5762
5762
  {
5763
5763
  topic: topic ?? "",
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeTests,
3
3
  runTestsTool
4
- } from "./chunk-ROFUA4O3.js";
4
+ } from "./chunk-GGIRUPT6.js";
5
5
  export {
6
6
  executeTests,
7
7
  runTestsTool
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-3LKIHGAR.js";
5
+ } from "./chunk-QAYMV7WE.js";
6
6
  export {
7
7
  executeTests,
8
8
  runTestsTool
@@ -18,7 +18,7 @@ import {
18
18
  renderDiff,
19
19
  runHook,
20
20
  setupProxy
21
- } from "./chunk-VC6DFUFP.js";
21
+ } from "./chunk-DGH7SQCZ.js";
22
22
  import {
23
23
  AuthManager
24
24
  } from "./chunk-CPLT6CD3.js";
@@ -32,7 +32,7 @@ import {
32
32
  spawnAgentContext,
33
33
  truncateOutput,
34
34
  undoStack
35
- } from "./chunk-AQ4O6SVK.js";
35
+ } from "./chunk-FUPDFYHI.js";
36
36
  import {
37
37
  AGENTIC_BEHAVIOR_GUIDELINE,
38
38
  CONTEXT_FILE_CANDIDATES,
@@ -44,7 +44,7 @@ import {
44
44
  PLAN_MODE_SYSTEM_ADDON,
45
45
  SKILLS_DIR_NAME,
46
46
  VERSION
47
- } from "./chunk-3LKIHGAR.js";
47
+ } from "./chunk-QAYMV7WE.js";
48
48
 
49
49
  // src/web/server.ts
50
50
  import express from "express";
@@ -1440,7 +1440,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
1440
1440
  case "test": {
1441
1441
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
1442
1442
  try {
1443
- const { executeTests } = await import("./run-tests-W2RQN33S.js");
1443
+ const { executeTests } = await import("./run-tests-KPWEEJKA.js");
1444
1444
  const argStr = args.join(" ").trim();
1445
1445
  let testArgs = {};
1446
1446
  if (argStr) {
@@ -4,13 +4,15 @@ import {
4
4
  getDangerLevel,
5
5
  googleSearchContext,
6
6
  truncateOutput
7
- } from "./chunk-AQ4O6SVK.js";
7
+ } from "./chunk-FUPDFYHI.js";
8
8
  import {
9
9
  SUBAGENT_ALLOWED_TOOLS
10
- } from "./chunk-3LKIHGAR.js";
10
+ } from "./chunk-QAYMV7WE.js";
11
11
 
12
12
  // src/hub/task-orchestrator.ts
13
13
  import { createInterface } from "readline";
14
+ import { existsSync, readFileSync, writeFileSync, unlinkSync } from "fs";
15
+ import { join } from "path";
14
16
  import chalk from "chalk";
15
17
 
16
18
  // src/hub/task-executor.ts
@@ -172,6 +174,7 @@ var TaskToolExecutor = class {
172
174
  };
173
175
 
174
176
  // src/hub/task-orchestrator.ts
177
+ var TASK_STATE_FILE = ".aicli-task.json";
175
178
  var TaskOrchestrator = class {
176
179
  constructor(config, providers, configManager) {
177
180
  this.config = config;
@@ -183,7 +186,7 @@ var TaskOrchestrator = class {
183
186
  this.aborted = true;
184
187
  }
185
188
  /**
186
- * Run the full task mode workflow.
189
+ * Run the full task mode workflow, with resume support.
187
190
  */
188
191
  async run(goal) {
189
192
  const provider = this.providers.get(this.config.defaultProvider);
@@ -191,23 +194,85 @@ var TaskOrchestrator = class {
191
194
  console.error(chalk.red(` \u2717 Provider "${this.config.defaultProvider}" not available.`));
192
195
  return;
193
196
  }
194
- this.renderPhaseHeader("PLAN", "Architect is decomposing the goal into tasks...");
195
- const plan = await this.generatePlan(goal, provider);
196
- if (!plan || plan.tasks.length === 0) {
197
- console.log(chalk.red(" \u2717 Failed to generate a task plan."));
198
- return;
197
+ const saved = this.loadState();
198
+ let plan = null;
199
+ if (saved && saved.tasks.some((t) => t.status === "pending" || t.status === "failed")) {
200
+ const doneCount = saved.tasks.filter((t) => t.status === "done").length;
201
+ const totalCount = saved.tasks.length;
202
+ console.log();
203
+ console.log(chalk.bold.yellow(` \u26A1 Found saved task plan (${doneCount}/${totalCount} completed)`));
204
+ console.log(chalk.dim(` Goal: ${saved.goal}`));
205
+ console.log();
206
+ const resume = await this.askResume();
207
+ if (resume) {
208
+ plan = saved;
209
+ for (const t of plan.tasks) {
210
+ if (t.status === "failed") t.status = "pending";
211
+ }
212
+ this.renderPlan(plan);
213
+ }
199
214
  }
200
- this.renderPlan(plan);
201
- this.renderPhaseHeader("APPROVE", "Review the task plan");
202
- const approved = await this.waitForApproval(plan);
203
- if (!approved) {
204
- console.log(chalk.yellow(" \u26A0 Task plan rejected. Exiting."));
205
- return;
215
+ if (!plan) {
216
+ this.renderPhaseHeader("PLAN", "Architect is decomposing the goal into tasks...");
217
+ plan = await this.generatePlan(goal, provider);
218
+ if (!plan || plan.tasks.length === 0) {
219
+ console.log(chalk.red(" \u2717 Failed to generate a task plan."));
220
+ return;
221
+ }
222
+ this.renderPlan(plan);
223
+ this.renderPhaseHeader("APPROVE", "Review the task plan");
224
+ const approved = await this.waitForApproval(plan);
225
+ if (!approved) {
226
+ console.log(chalk.yellow(" \u26A0 Task plan rejected. Exiting."));
227
+ return;
228
+ }
206
229
  }
207
230
  this.renderPhaseHeader("EXECUTE", "Agents are executing tasks...");
208
231
  await this.executePlan(plan, provider);
209
232
  this.renderPhaseHeader("REVIEW", "Generating project summary...");
210
233
  await this.generateReview(plan, provider);
234
+ const allDone = plan.tasks.every((t) => t.status === "done");
235
+ if (allDone) {
236
+ this.deleteState();
237
+ }
238
+ }
239
+ // ── State Persistence ────────────────────────────────────────────
240
+ get stateFilePath() {
241
+ return join(process.cwd(), TASK_STATE_FILE);
242
+ }
243
+ saveState(plan) {
244
+ try {
245
+ writeFileSync(this.stateFilePath, JSON.stringify(plan, null, 2), "utf-8");
246
+ } catch {
247
+ }
248
+ }
249
+ loadState() {
250
+ try {
251
+ if (!existsSync(this.stateFilePath)) return null;
252
+ const raw = readFileSync(this.stateFilePath, "utf-8");
253
+ const parsed = JSON.parse(raw);
254
+ if (!parsed.goal || !Array.isArray(parsed.tasks)) return null;
255
+ return parsed;
256
+ } catch {
257
+ return null;
258
+ }
259
+ }
260
+ deleteState() {
261
+ try {
262
+ if (existsSync(this.stateFilePath)) unlinkSync(this.stateFilePath);
263
+ } catch {
264
+ }
265
+ }
266
+ async askResume() {
267
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
268
+ try {
269
+ const answer = await new Promise((resolve) => {
270
+ rl.question(chalk.green(" Resume from saved state? (y/n) > "), resolve);
271
+ });
272
+ return answer.trim().toLowerCase() === "y" || answer.trim().toLowerCase() === "yes";
273
+ } finally {
274
+ rl.close();
275
+ }
211
276
  }
212
277
  // ── Phase 1: Plan Generation ──────────────────────────────────────
213
278
  async generatePlan(goal, provider) {
@@ -319,9 +384,12 @@ Example:
319
384
  }
320
385
  // ── Phase 3: Task Execution ───────────────────────────────────────
321
386
  async executePlan(plan, provider) {
322
- const maxRoundsPerTask = this.config.maxToolRoundsPerTurn ?? 15;
387
+ const maxRoundsPerTask = this.config.maxToolRoundsPerTurn ?? 30;
323
388
  const roleMap = new Map(this.config.roles.map((r) => [r.id, r]));
324
- const completedIds = /* @__PURE__ */ new Set();
389
+ const completedIds = new Set(
390
+ plan.tasks.filter((t) => t.status === "done").map((t) => t.id)
391
+ );
392
+ this.saveState(plan);
325
393
  while (!this.aborted) {
326
394
  const nextTask = plan.tasks.find(
327
395
  (t) => t.status === "pending" && t.dependencies.every((d) => completedIds.has(d))
@@ -368,6 +436,7 @@ Example:
368
436
  if (result.success) {
369
437
  completedIds.add(nextTask.id);
370
438
  }
439
+ this.saveState(plan);
371
440
  this.renderTaskEnd(nextTask, result);
372
441
  if (this.aborted) {
373
442
  console.log(chalk.yellow("\n \u26A0 Execution interrupted by user."));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",