@love-moon/conductor-cli 0.7.6 → 0.8.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 CHANGED
@@ -1,5 +1,47 @@
1
1
  # @love-moon/conductor-cli
2
2
 
3
+ ## 0.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 959dd1d: Add project-configured worker and reviewer task groups, task-group discovery in
8
+ the SDK and `conductor task group`, and a lightweight daemon protocol for
9
+ refreshing the project agent registry.
10
+ - fe76139: Add `conductor task create` for creating app tasks with title, prompt, backend,
11
+ project resolution, and optional parent task-card grouping. App tasks now
12
+ require an online compatible daemon, and grouping results are exposed to
13
+ callers so partial success is visible without retrying task creation.
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies [959dd1d]
18
+ - Updated dependencies [fe76139]
19
+ - @love-moon/conductor-sdk@0.8.0
20
+ - @love-moon/ai-sdk@0.8.0
21
+
22
+ ## 0.7.7
23
+
24
+ ### Patch Changes
25
+
26
+ - 400f3a7: Report a terminal task status when a stop request finds no active process, so a
27
+ task whose Fire already died converges instead of sitting in `killing` forever.
28
+
29
+ Drop queued terminal status events before an in-place restart reuses a working
30
+ directory. The durable upstream outbox lives inside that directory, so an
31
+ undelivered `KILLED` from the previous run was flushed on startup and killed the
32
+ task that had just finished resuming.
33
+
34
+ - 67498dc: Report a Fire that dies inside its tmux session instead of leaving the task
35
+ hanging. In tmux mode the daemon's child is the short-lived `tmux new-session`
36
+ client, not the Fire, so an abnormal death (crash, OOM, SIGKILL) went unreported
37
+ and the task sat at `running` until reconcile relabelled it as a user stop. The
38
+ Fire now records its own exit code into its log under a per-launch nonce, and the
39
+ liveness reaper classifies the death from that marker and publishes a terminal
40
+ status with the real cause.
41
+ - Updated dependencies [400f3a7]
42
+ - @love-moon/conductor-sdk@0.7.7
43
+ - @love-moon/ai-sdk@0.7.7
44
+
3
45
  ## 0.7.6
4
46
 
5
47
  ### Patch Changes
@@ -5,7 +5,10 @@
5
5
  *
6
6
  * Subcommands:
7
7
  * list [--project ...] [--issue <id>] [--status ...]
8
+ * create --title <title> [--prompt <prompt>] [--backend <backend>]
9
+ * [--parent-task-id <id>] [--project ...]
8
10
  * show <id>
11
+ * group [<id>]
9
12
  * send <id> [<message>] [--stdin] [--from-file FILE] [--metadata-json '{...}']
10
13
  * insert <id> [<message>] [--stdin] [--from-file FILE] [--target-reply-to <msg-id>]
11
14
  * messages <id> [--limit N] [--before <msg-id>]
@@ -63,6 +66,7 @@ function taskAsObject(task) {
63
66
  sessionId: task.sessionId,
64
67
  createdAt: task.createdAt,
65
68
  updatedAt: task.updatedAt,
69
+ grouping: task.grouping ?? undefined,
66
70
  };
67
71
  }
68
72
 
@@ -243,6 +247,54 @@ async function handleList(argv, deps) {
243
247
  return EXIT.OK;
244
248
  }
245
249
 
250
+ async function handleCreate(argv, deps) {
251
+ const apis = await buildApis(deps);
252
+ const project = await resolveProject(apis, {
253
+ env: deps.env,
254
+ cwd: deps.cwd,
255
+ project: argv.project,
256
+ });
257
+ const title = String(argv.title ?? "").trim();
258
+ if (!title) {
259
+ const err = new Error("--title must not be empty");
260
+ err.code = "ARGS";
261
+ throw err;
262
+ }
263
+
264
+ const body = {
265
+ projectId: project.id,
266
+ title,
267
+ taskType: "ai_task",
268
+ ...(argv.prompt !== undefined ? { initialContent: String(argv.prompt) } : {}),
269
+ ...(argv.backend ? { backendType: String(argv.backend) } : {}),
270
+ ...(argv.parentTaskId ? { parentTaskId: String(argv.parentTaskId) } : {}),
271
+ metadata: buildAuditMetadata(deps.env),
272
+ };
273
+ if (argv.dryRun) {
274
+ emitDryRun(
275
+ deps.stdout,
276
+ argv.json,
277
+ makeDryRunPayload("POST", `${buildBaseUrl(apis.config)}/api/tasks`, body),
278
+ );
279
+ return EXIT.OK;
280
+ }
281
+
282
+ const created = await apis.tasks.createTask(body);
283
+ const obj = taskAsObject(created);
284
+ if (argv.json) {
285
+ printJson(deps.stdout, obj);
286
+ return EXIT.OK;
287
+ }
288
+ printPretty(deps.stdout, `Created app task ${obj.id}: ${obj.title}`);
289
+ if (obj.grouping?.grouped === false) {
290
+ printPretty(
291
+ deps.stderr,
292
+ `Warning: ${obj.grouping.warning || `task was not grouped with ${obj.grouping.parentTaskId}`}. The task itself was created successfully.`,
293
+ );
294
+ }
295
+ return EXIT.OK;
296
+ }
297
+
246
298
  async function handleShow(argv, deps) {
247
299
  const apis = await buildApis(deps);
248
300
  const task = await apis.tasks.getTask(argv.id);
@@ -267,6 +319,45 @@ async function handleShow(argv, deps) {
267
319
  return EXIT.OK;
268
320
  }
269
321
 
322
+ async function handleGroup(argv, deps) {
323
+ const apis = await buildApis(deps);
324
+ const taskId =
325
+ (argv.id && String(argv.id).trim()) ||
326
+ (deps.env.CONDUCTOR_TASK_ID && String(deps.env.CONDUCTOR_TASK_ID).trim());
327
+ if (!taskId) {
328
+ const err = new Error(
329
+ "No task id: pass <id> or run inside a task (CONDUCTOR_TASK_ID)",
330
+ );
331
+ err.statusCode = 400;
332
+ throw err;
333
+ }
334
+ const group = await apis.tasks.getTaskGroup(taskId);
335
+ if (argv.json) {
336
+ printJson(deps.stdout, group);
337
+ return EXIT.OK;
338
+ }
339
+ if (!group.groupId) {
340
+ printPretty(deps.stdout, "(task is not in a group)");
341
+ return EXIT.OK;
342
+ }
343
+ printPretty(deps.stdout, `group ${group.groupId}`);
344
+ printPretty(
345
+ deps.stdout,
346
+ `${pad("ROLE", 10)} ${pad("TASK ID", 24)} ${pad("AGENT", 20)} STATUS`,
347
+ );
348
+ for (const member of group.members) {
349
+ const selfMark = member.isSelf ? " (you)" : "";
350
+ printPretty(
351
+ deps.stdout,
352
+ `${pad(member.role || "?", 10)} ${pad(member.taskId, 24)} ${pad(
353
+ member.agent || "-",
354
+ 20,
355
+ )} ${member.status || ""}${selfMark}`,
356
+ );
357
+ }
358
+ return EXIT.OK;
359
+ }
360
+
270
361
  async function handleSend(argv, deps) {
271
362
  const apis = await buildApis(deps);
272
363
  const content = readMessageInput({
@@ -485,6 +576,31 @@ export async function main(argvInput = hideBin(process.argv), deps = {}) {
485
576
  exitCode = await handleList(argv, { ...handlerDeps, configFile: argv.configFile });
486
577
  },
487
578
  )
579
+ .command(
580
+ "create",
581
+ "Create a new app task through the frontend task pipeline",
582
+ (cmd) => cmd
583
+ .option("title", {
584
+ type: "string",
585
+ demandOption: true,
586
+ describe: "Task title",
587
+ })
588
+ .option("prompt", {
589
+ type: "string",
590
+ describe: "Initial user prompt",
591
+ })
592
+ .option("backend", {
593
+ type: "string",
594
+ describe: "AI backend type, for example codex or claude",
595
+ })
596
+ .option("parent-task-id", {
597
+ type: "string",
598
+ describe: "Display the new task in the same task-card group as this task",
599
+ }),
600
+ async (argv) => {
601
+ exitCode = await handleCreate(argv, { ...handlerDeps, configFile: argv.configFile });
602
+ },
603
+ )
488
604
  .command(
489
605
  "show <id>",
490
606
  "Show one task's detail",
@@ -493,6 +609,14 @@ export async function main(argvInput = hideBin(process.argv), deps = {}) {
493
609
  exitCode = await handleShow(argv, { ...handlerDeps, configFile: argv.configFile });
494
610
  },
495
611
  )
612
+ .command(
613
+ "group [id]",
614
+ "Show the multi-agent group a task belongs to (defaults to $CONDUCTOR_TASK_ID)",
615
+ (cmd) => cmd.positional("id", { type: "string" }),
616
+ async (argv) => {
617
+ exitCode = await handleGroup(argv, { ...handlerDeps, configFile: argv.configFile });
618
+ },
619
+ )
496
620
  .command(
497
621
  "send <id> [message]",
498
622
  "Send a user message into a running task",
package/bin/conductor.js CHANGED
@@ -14,7 +14,7 @@
14
14
  * serve-ai - Start an OpenAI-compatible local AI server
15
15
  * project - Manage Conductor projects (list/show/create/...)
16
16
  * issue - Manage issues (list/show/create/update/start/done)
17
- * task - Manage tasks (list/show/send/messages/schedule)
17
+ * task - Manage tasks (create/list/show/send/messages/schedule)
18
18
  */
19
19
 
20
20
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -134,7 +134,7 @@ Subcommands:
134
134
  serve-ai Start an OpenAI-compatible local AI server
135
135
  project Manage Conductor projects (list/show/create/...)
136
136
  issue Manage issues (list/show/create/update/start/done)
137
- task Manage tasks (list/show/send/messages/schedule)
137
+ task Manage tasks (create/list/show/send/messages/schedule)
138
138
 
139
139
  Options:
140
140
  -h, --help Show this help message
@@ -156,6 +156,7 @@ Examples:
156
156
  conductor update
157
157
  conductor project list
158
158
  conductor issue create --title "Refactor module" --priority P2
159
+ conductor task create --title "Refactor module" --prompt "Extract the parser" --backend codex
159
160
  conductor task send <task-id> "please add a unit test"
160
161
  conductor task schedule create <task-id> "follow up" --delay 10m
161
162
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@love-moon/conductor-cli",
3
- "version": "0.7.6",
4
- "gitCommitId": "c939df2",
3
+ "version": "0.8.0",
4
+ "gitCommitId": "04d4f62",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/lovemoon-ai/conductor.git"
@@ -24,8 +24,8 @@
24
24
  "test": "node --test test/*.test.js"
25
25
  },
26
26
  "dependencies": {
27
- "@love-moon/ai-sdk": "0.7.6",
28
- "@love-moon/conductor-sdk": "0.7.6",
27
+ "@love-moon/ai-sdk": "0.8.0",
28
+ "@love-moon/conductor-sdk": "0.8.0",
29
29
  "@github/copilot-sdk": "^0.3.0",
30
30
  "chrome-launcher": "^1.2.1",
31
31
  "chrome-remote-interface": "^0.33.0",
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "optionalDependencies": {
40
40
  "@roamhq/wrtc": "^0.10.0",
41
- "@love-moon/chat-web": "0.7.6"
41
+ "@love-moon/chat-web": "0.8.0"
42
42
  },
43
43
  "pnpm": {
44
44
  "onlyBuiltDependencies": [