@volter/supercode-orchestrator 0.4.77 → 0.4.78

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.
@@ -490,8 +490,8 @@ const ACTIONS = {
490
490
  cardField(ctx, 'every', interval == null ? null : String(interval));
491
491
  cardField(ctx, 'next_run_at', interval == null ? null : now());
492
492
  },
493
- card_event(ctx, { name, payload = {} }) {
494
- const result = fire(ctx.db, ctx.board, ctx.entry, ctx.id, name, { roles: ['platform'], payload, extra: ctx.scope });
493
+ card_event(ctx, { name, payload = {}, as = ['platform'] }) {
494
+ const result = fire(ctx.db, ctx.board, ctx.entry, ctx.id, name, { roles: [].concat(as), payload, extra: { lanes: lanesIn(ctx.entry) } });
495
495
  ctx.effects.push(...result.effects);
496
496
  },
497
497
  record(ctx, args, scope) {
@@ -762,12 +762,21 @@ function settleRelations(db, board, entry, id, effects) {
762
762
  const row = one(db, 'SELECT blocked_by FROM supercode_cards WHERE task_id = ?', id);
763
763
  const blocks = json(row?.blocked_by, []) ?? [];
764
764
  for (const block of blocks) {
765
+ if (!json(one(db, 'SELECT blocked_by FROM supercode_cards WHERE task_id = ?', id)?.blocked_by, []).some((b) => b.id === block.id)) continue;
765
766
  const dependency = block.kind === 'card' ? one(db, 'SELECT * FROM tasks WHERE id = ?', block.id) : null;
766
767
  const status = dependency ? statusOf(db, dependency) : null;
767
768
  const answer = block.kind === 'message' ? answerTo(block.id) : null;
768
769
  const policy = entry.workflow.relations.blocked_by;
769
770
  const name = answer ? policy.answered : status === 'done' ? policy.completed : status === 'cancelled' ? policy.cancelled : null;
770
771
  if (name) effects.push(...fire(db, board, entry, id, name, { roles: ['platform'], payload: { on: block.id, reason: answer ? `reply ${answer}` : `${block.id} ${status}` } }).effects);
772
+ else if (policy.aged && policy.age_seconds != null) {
773
+ const seconds = Number(evaluate(String(policy.age_seconds), { params: entry.params }));
774
+ if (seconds > 0 && now() - Number(block.notified_at ?? block.since ?? now()) >= seconds) {
775
+ const current = json(one(db, 'SELECT blocked_by FROM supercode_cards WHERE task_id = ?', id)?.blocked_by, []);
776
+ run(db, 'UPDATE supercode_cards SET blocked_by = ? WHERE task_id = ?', JSON.stringify(current.map((b) => b.id === block.id ? { ...b, notified_at: now() } : b)), id);
777
+ effects.push(...fire(db, board, entry, id, policy.aged, { roles: ['platform'], payload: { on: block.id, reason: block.reason } }).effects);
778
+ }
779
+ }
771
780
  }
772
781
  }
773
782
 
package/board/ztrack.mjs CHANGED
@@ -228,6 +228,11 @@ class ZtrackBoard {
228
228
  for (const [id, value] of Object.entries(current)) {
229
229
  const old = previous[id];
230
230
  if (old?.hash === value.hash) continue;
231
+ let entry; try { entry = workflowFor(this.root); } catch {}
232
+ if (old && entry?.workflow.verbs?.document_changed) {
233
+ const change = fire(this.mem, this.board(), entry, id, 'document_changed', { roles: ['platform'], payload: { previous_status: old.status, by, source: 'document' } });
234
+ for (const effect of change.effects) this.mem.prepare('INSERT INTO supercode_effects (effect) VALUES (?)').run(JSON.stringify(effect));
235
+ }
231
236
  const kind = !old ? 'created' : old.status !== value.status ? 'status' : old.assignee !== value.assignee ? 'assigned' : 'specified';
232
237
  event(this.mem, id, kind, { by, source: 'document', status: value.status, assignee: value.assignee, author: by });
233
238
  if (!old && value.parent) event(this.mem, value.parent, 'subtask_added', { by, subtask: id, title: this.mem.prepare('SELECT title FROM tasks WHERE id = ?').get(id).title });
@@ -318,6 +323,10 @@ class ZtrackBoard {
318
323
  else if (row.kind === 'completed') { name = 'complete'; words.summary = payload.summary ?? task.result; }
319
324
  else if (row.kind === 'blocked' || row.kind === 'dependency_wait') { name = 'block'; words.on = payload.on ?? payload.parent ?? null; words.hermes = true; }
320
325
  else if (row.kind === 'archived' && statusOf(this.mem, task) !== 'done') name = 'cancel';
326
+ if (row.kind === 'unblocked' && entry.workflow.verbs?.hermes_unpause) {
327
+ const resumed = fire(this.mem, this.board(), entry, task.id, 'hermes_unpause', { roles, payload: { hermes: true, reason: 'unblocked in Hermes' } });
328
+ for (const effect of resumed.effects) this.mem.prepare('INSERT INTO supercode_effects (effect) VALUES (?)').run(JSON.stringify(effect));
329
+ }
321
330
  if (name) {
322
331
  const result = fire(this.mem, this.board(), entry, task.id, name, { roles, payload: words });
323
332
  for (const effect of result.effects) this.mem.prepare('INSERT INTO supercode_effects (effect) VALUES (?)').run(JSON.stringify(effect));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-orchestrator",
3
- "version": "0.4.77",
3
+ "version": "0.4.78",
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": {