@volter/supercode-orchestrator 0.4.19 → 0.4.21
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/board/cli.mjs +4 -4
- package/board/dispatch.mjs +7 -3
- package/package.json +1 -1
package/board/cli.mjs
CHANGED
|
@@ -40,7 +40,7 @@ supercode's own:
|
|
|
40
40
|
create … --machine M --subtask-of ARC --notify ADDRESS|--no-notify --no-start
|
|
41
41
|
With a pane lane and room, a card starts at once and answers "started" with its session; else it answers why it
|
|
42
42
|
waits, and its creator is told when it starts. A subtask is worked by its arc's session and never starts alone.
|
|
43
|
-
move <id> <machine|none> adopt <id> <session> close <id> serve (= daemon) list --machine M
|
|
43
|
+
move <id> <machine|none> adopt <id> <session> [--assignee P] close <id> serve (= daemon) list --machine M
|
|
44
44
|
notify-subscribe <id> --address sc:<machine>:<harness>:<id> [--role creator|worker|dependency]
|
|
45
45
|
Any verb … --at sc:<machine>:board:<home>: sent as mail to a board kept on another machine.
|
|
46
46
|
|
|
@@ -512,11 +512,11 @@ export async function runWorkflow(argv) {
|
|
|
512
512
|
const results = [];
|
|
513
513
|
for (const t of targets) {
|
|
514
514
|
if (verb === 'specify' && (args.title !== undefined || args.body !== undefined)) {
|
|
515
|
-
withBoard((b) => engine.specify(b, t, { title: args.title ?? null, body: args.body ?? null, author: args.author ?? callerName() }));
|
|
515
|
+
withBoard((b) => engine.specify(b, t, { title: args.title ?? null, body: args.body ?? null, author: args.author ?? callerAddress() ?? callerName() }));
|
|
516
516
|
results.push({ id: t, specified: true });
|
|
517
517
|
} else if (verb === 'decompose' && args.child?.length) {
|
|
518
518
|
const children = args.child.map((c) => { const [title, assignee] = c.split(/@(?=[^@]*$)/); return { title: title.trim(), assignee: assignee?.trim() || undefined }; });
|
|
519
|
-
results.push({ id: t, children: withBoard((b) => engine.decompose(b, t, children, { author: args.author ?? callerName() })) });
|
|
519
|
+
results.push({ id: t, children: withBoard((b) => engine.decompose(b, t, children, { author: args.author ?? callerAddress() ?? callerName() })) });
|
|
520
520
|
} else {
|
|
521
521
|
const session = withBoard((b) => startTriageSession(b, t, lanes, settings, verb));
|
|
522
522
|
results.push({ id: t, session: session.address, mode: session.mode });
|
|
@@ -693,7 +693,7 @@ export async function runWorkflow(argv) {
|
|
|
693
693
|
case 'adopt': {
|
|
694
694
|
need(2, 'a card id and a session');
|
|
695
695
|
const { settings } = await laneState(root);
|
|
696
|
-
const got = withBoard((b) => adoptSession(b, id, rest[1], { workspace: args.workspace ?? null, ttl: settings.ttl }));
|
|
696
|
+
const got = withBoard((b) => adoptSession(b, id, rest[1], { workspace: args.workspace ?? null, ttl: settings.ttl, assignee: args.assignee ?? null }));
|
|
697
697
|
say(args, `${id} is worked by ${got.address} (pane ${got.pane ?? '?'} in ${got.workspace ?? 'its card\'s directory'})`, { ok: true, ...got });
|
|
698
698
|
return 0;
|
|
699
699
|
}
|
package/board/dispatch.mjs
CHANGED
|
@@ -31,7 +31,7 @@ const WORKER = fileURLToPath(new URL('../bin/hermes-worker.mjs', import.meta.url
|
|
|
31
31
|
const MAIL_KINDS = {
|
|
32
32
|
creator: ['completed', 'blocked', 'gave_up', 'crashed', 'timed_out', 'status', 'archived', 'block_loop_detected', 'review_requested',
|
|
33
33
|
'changes_requested', 'session_started', 'session_resumed', 'session_replaced', 'session_adopted', 'session_lost', 'spawn_failed'],
|
|
34
|
-
worker: ['commented', 'assigned', 'machine_set', 'blocked', 'unblocked', 'completed', 'archived', 'changes_requested', 'linked', 'unlinked', 'promoted_manual', 'subtask_added'],
|
|
34
|
+
worker: ['commented', 'assigned', 'machine_set', 'blocked', 'unblocked', 'completed', 'archived', 'changes_requested', 'linked', 'unlinked', 'promoted_manual', 'subtask_added', 'session_adopted'],
|
|
35
35
|
// a card the session's own card depends on: it sees it change
|
|
36
36
|
dependency: ['completed', 'blocked', 'unblocked', 'archived', 'review_requested', 'changes_requested', 'commented'],
|
|
37
37
|
};
|
|
@@ -583,7 +583,7 @@ function resolveLocalWorkspace(board, task) {
|
|
|
583
583
|
* never as the session describes itself. From then on the board watches it, resumes it when lost, and tells it of
|
|
584
584
|
* its card. `who` is an address, a session id, or a `name@machine` the fleet lists.
|
|
585
585
|
*/
|
|
586
|
-
export function adoptSession(board, id, who, { workspace = null, ttl } = {}) {
|
|
586
|
+
export function adoptSession(board, id, who, { workspace = null, ttl, assignee = null } = {}) {
|
|
587
587
|
const fleet = observeFleet();
|
|
588
588
|
if (!fleet.ok) throw new Error(`supercode could not read the fleet: ${fleet.error}`);
|
|
589
589
|
const found = fleet.sessions.find((s) => s.address === who || s.address.endsWith(`:${who}`) || s.name === who);
|
|
@@ -603,6 +603,8 @@ export function adoptSession(board, id, who, { workspace = null, ttl } = {}) {
|
|
|
603
603
|
const was = lastSession(db, id);
|
|
604
604
|
if (was && was.session_id !== sessionId && sessionAlive(fleet, was)) throw new Error(`${id} already has a live session, ${was.address}`);
|
|
605
605
|
if (!task.machine) db.prepare('INSERT OR REPLACE INTO supercode_cards (task_id, machine, subtask_of) VALUES (?, ?, ?)').run(id, host, task.subtask_of);
|
|
606
|
+
// the lane that resumes it if it is lost, set in the same transaction (assigning first would let a tick start another)
|
|
607
|
+
if (assignee && assignee !== task.assignee) { db.prepare('UPDATE tasks SET assignee = ? WHERE id = ?').run(assignee, id); event(db, id, 'assigned', { assignee }); }
|
|
606
608
|
if (dir && !(task.workspace_kind === 'dir' && task.workspace_path)) {
|
|
607
609
|
db.prepare("UPDATE tasks SET workspace_kind = 'dir', workspace_path = ? WHERE id = ?").run(dir.replace(/^dir:/, ''), id);
|
|
608
610
|
}
|
|
@@ -632,7 +634,9 @@ function notice(kind, task, p, role) {
|
|
|
632
634
|
const verb = { session_started: 'started', session_resumed: 'resumed', session_replaced: 'could not resume the card\'s last session and started' }[kind];
|
|
633
635
|
return `▶ ${who}card ${tid} — ${title}: the board ${verb} session ${p.session_id} on ${p.machine} (pane ${p.pane}; ${p.address}).`;
|
|
634
636
|
}
|
|
635
|
-
case 'session_adopted': return
|
|
637
|
+
case 'session_adopted': return role === 'worker'
|
|
638
|
+
? `▶ card ${tid} — ${title} is running again, with you: carry it on from where it stands (\`supercode workflow show ${tid}\` reads it).`
|
|
639
|
+
: `▶ ${who}card ${tid} — ${title}: the board found session ${p.session_id} still live on ${p.machine} and kept it (${p.address}).`;
|
|
636
640
|
case 'session_lost': return `✖ ${who}card ${tid}: session ${p.session_id} is gone from ${p.machine}; the board resumes it, and replaces it from the card only when it cannot.`;
|
|
637
641
|
case 'spawn_failed': return `✖ ${who}card ${tid}: its session did not start: ${String(p.error ?? '').slice(0, 300)}`;
|
|
638
642
|
case 'completed': return `✔ ${who}card ${tid} done — ${title}${p.summary ? `\n${String(p.summary).slice(0, 300)}` : ''}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/supercode-orchestrator",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.21",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The orchestrator runtime over the Volter Harness ontology: one typed operational model whose folder is its serialization, read and written through the harness orchestration doors (docs/ORCHESTRATOR-IR.md)",
|
|
6
6
|
"exports": {
|