@adhd/dispatch-base-spec 0.1.5 → 0.1.6
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 +15 -0
- package/dag-v4.schema.json +1 -0
- package/index.js +1 -1
- package/index.mjs +2 -1
- package/lib/types.d.ts +47 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## 0.1.6 (2026-10-06)
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- **dispatch-orchestrator:** dag.session_id producer stamps every DispatchUnit (fa9d3079/03145a46) ([e8271d77](https://github.com/PseudoSky/adhd/commit/e8271d77))
|
|
6
|
+
- **dispatch-orchestrator:** thread session_id through DispatchUnit + fire (fa9d3079) ([e3d3aa26](https://github.com/PseudoSky/adhd/commit/e3d3aa26))
|
|
7
|
+
|
|
8
|
+
### 🩹 Fixes
|
|
9
|
+
|
|
10
|
+
- **dispatch-orchestrator,dispatch-cli:** make HITL reachable from dispatch ([57f53429](https://github.com/PseudoSky/adhd/commit/57f53429))
|
|
11
|
+
|
|
12
|
+
### ❤️ Thank You
|
|
13
|
+
|
|
14
|
+
- pseudosky
|
|
15
|
+
|
|
1
16
|
## 0.1.4 (2026-09-26)
|
|
2
17
|
|
|
3
18
|
### 🚀 Features
|
package/dag-v4.schema.json
CHANGED
package/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=new Set([`create`,`modify-signature`,`modify-body`,`add-export`,`remove-export`,`rename`]),t={function:new Set([`add-param`,`remove-param`,`rename-param`,`retype-param`,`change-param-optional`,`reorder-params`,`change-return`]),interface:new Set([`add-field`,`remove-field`,`rename-field`,`retype-field`,`change-field-optional`,`add-generic`,`remove-generic`,`constrain-generic`,`add-extends`,`remove-extends`]),type:new Set([`add-field`,`remove-field`,`retype-field`]),class:new Set([`add-field`,`remove-field`,`rename-field`,`retype-field`,`change-field-optional`,`add-param`,`add-generic`,`remove-generic`,`constrain-generic`,`add-extends`,`remove-extends`]),enum:new Set([`add-field`,`remove-field`,`rename-field`]),const:new Set([`add-var`,`remove-var`,`rename-var`,`change-default`]),config:new Set([`set-key`,`remove-key`,`rename-key`,`add-entry`,`remove-entry`,`update-entry`,`bump-version`,`update-checksum`]),env:new Set([`set-key`,`remove-key`,`rename-key`]),schema:new Set([`add-table`,`remove-table`,`add-column`,`remove-column`,`rename-column`,`retype-column`,`change-nullable`,`add-index`,`remove-index`]),manifest:new Set([`add-entry`,`remove-entry`,`bump-version`]),doc:new Set([`add-section`,`remove-section`,`rename-section`,`update-section`]),"structured-output":new Set([]),script:new Set(`add-param.remove-param.rename-param.retype-param.change-param-optional.reorder-params.change-return.add-field.remove-field.rename-field.retype-field.change-field-optional.add-generic.remove-generic.constrain-generic.add-extends.remove-extends.set-key.remove-key.rename-key.add-array-item.remove-array-item.add-var.remove-var.rename-var.change-default.add-section.remove-section.rename-section.update-section.add-table.remove-table.add-column.remove-column.rename-column.retype-column.change-nullable.add-index.remove-index.add-entry.remove-entry.update-entry.bump-version.update-checksum.add-export`.split(`.`))};function n(e,n){let r=t[e];return r?r.has(n):!1}var r=new Set([`pending`,`pending-surfaced`,`in_progress`,`complete`,`failed`,`skipped`]),i=new Set([`pending`,`in_progress`,`complete`,`failed`,`skipped`]),a=new Set([`automated`,`tool-call`,`generative`]),o=new Set([`anthropic`,`openai`,`deepseek`,`google`,`local`,`claudecli`,`teammate`]),s=new Set([`function`,`interface`,`type`,`class`,`enum`,`const`,`script`,`config`,`env`,`schema`,`manifest`,`doc`,`structured-output`]);function c(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function l(e){return typeof e==`string`}function u(e,t,n){return{path:e,message:t,value:n}}function d(e){let t=Object.keys(e),n=new Map,r=new Map;for(let e of t)n.set(e,0),r.set(e,[]);for(let i of t)for(let t of e[i]?.depends_on??[])e[t]&&(r.get(t)?.push(i),n.set(i,(n.get(i)??0)+1));let i=t.filter(e=>(n.get(e)??0)===0),a=new Set;for(;i.length>0;){let e=i.shift();if(e!==void 0){a.add(e);for(let t of r.get(e)??[]){let e=(n.get(t)??1)-1;n.set(t,e),e===0&&i.push(t)}}}return a.size===t.length?null:t.filter(e=>!a.has(e)).map(e=>({slug:e}))}function f(e,t){for(let n of e){if(!c(n))continue;let e=l(n.id)?n.id:`?`,r=n.provider;(!l(r)||!o.has(r))&&t.push(u(`dispatch_log[${e}].provider`,`invalid provider`,r));let i=n.turns;if(!Array.isArray(i)){t.push(u(`dispatch_log[${e}].turns`,`must be an array`,i));continue}for(let n=0;n<i.length;n++){let r=i[n],a=`dispatch_log[${e}].turns[${n}]`;if(!c(r)){t.push(u(a,`must be an object`,r));continue}(typeof r.turn!=`number`||!Number.isInteger(r.turn)||r.turn<1)&&t.push(u(`${a}.turn`,`must be a positive integer`,r.turn)),typeof r.input_tokens!=`number`&&t.push(u(`${a}.input_tokens`,`must be a number`,r.input_tokens)),typeof r.output_tokens!=`number`&&t.push(u(`${a}.output_tokens`,`must be a number`,r.output_tokens)),l(r.t)||t.push(u(`${a}.t`,`must be a string`,r.t));let o=r.model_calls;o!=null&&typeof o!=`number`&&t.push(u(`${a}.model_calls`,`must be a number or null if present`,o))}}}function p(e){let t=[];if(!c(e))return{valid:!1,errors:[u(``,`root must be an object`)]};for(let n of[`description`,`problem`,`approach`,`executor`]){let r=e[n];(!l(r)||r.trim()===``)&&t.push(u(n,`required string field missing/empty`,r))}typeof e.schema_version!=`number`&&t.push(u(`schema_version`,`must be a number`,e.schema_version));let r=e.plan_kind;r!==`brownfield`&&r!==`greenfield`&&t.push(u(`plan_kind`,`must be "brownfield" or "greenfield"`,r)),Array.isArray(e.phases)?e.phases.length===0&&t.push(u(`phases`,`must have at least one entry`)):t.push(u(`phases`,`must be an array`,e.phases));let i=e.terminal;!l(i)&&!Array.isArray(i)&&t.push(u(`terminal`,`must be a string or array`,i)),Array.isArray(e.dispatch_log)?f(e.dispatch_log,t):t.push(u(`dispatch_log`,`must be an array`,e.dispatch_log)),c(e.optimization)||t.push(u(`optimization`,`must be an object`,e.optimization)),c(e.providers)||t.push(u(`providers`,`must be an object`,e.providers)),c(e.effort_max_tokens)||t.push(u(`effort_max_tokens`,`must be an object`,e.effort_max_tokens));let o=e.milestones;if(!c(o))t.push(u(`milestones`,`must be an object`,o));else{let r=Object.keys(o);r.length===0&&t.push(u(`milestones`,`must have at least one entry`));let f=new Set(r);for(let e of r){let n=o[e];if(!c(n)){t.push(u(`milestones.${e}`,`must be an object`,n));continue}if((!l(n.description)||n.description.trim()===``)&&t.push(u(`milestones.${e}.description`,`required string`,n.description)),!Array.isArray(n.depends_on))t.push(u(`milestones.${e}.depends_on`,`must be an array`,n.depends_on));else for(let r of n.depends_on)l(r)?f.has(r)||t.push(u(`milestones.${e}.depends_on`,`unknown milestone "${r}"`)):t.push(u(`milestones.${e}.depends_on[]`,`must be a string`,r));let r=n.phase;(!l(r)||r.trim()===``)&&t.push(u(`milestones.${e}.phase`,`required string`,r)),(!l(n.authored_by)||n.authored_by.trim()===``)&&t.push(u(`milestones.${e}.authored_by`,`required string`,n.authored_by));let i=n.model;i!=null&&![`Haiku`,`Sonnet`,`Opus`].includes(i)&&t.push(u(`milestones.${e}.model`,`invalid model tier`,i));let a=n.effort;a!=null&&![`low`,`medium`,`high`,`xhigh`,`max`].includes(a)&&t.push(u(`milestones.${e}.effort`,`invalid effort tier`,a)),n.two_stage!==void 0&&typeof n.two_stage!=`boolean`&&t.push(u(`milestones.${e}.two_stage`,`must be a boolean`,n.two_stage)),Array.isArray(n.read_only)||t.push(u(`milestones.${e}.read_only`,`must be an array`,n.read_only))}let p=d(o);if(p)for(let{slug:e}of p)t.push(u(`milestones.${e}`,`dependency cycle detected`));if(l(i)&&!f.has(i))t.push(u(`terminal`,`unknown milestone "${i}"`));else if(Array.isArray(i))for(let e of i)f.has(e)||t.push(u(`terminal[]`,`unknown milestone "${e}"`));let m=e.operations,h=new Set;if(!Array.isArray(m)&&!c(m))t.push(u(`operations`,`must be an array or object`,m));else{let e=Array.isArray(m)?m:Object.values(m);for(let r of e){if(!c(r)){t.push(u(`operations[]`,`must be an object`,r));continue}let e=r.id;if(!l(e)){t.push(u(`operations[?]`,`missing/invalid id`,e));continue}let i=e;h.add(i);let o=r.milestone;l(o)?f.has(o)||t.push(u(`operations[${i}].milestone`,`unknown milestone "${o}"`)):t.push(u(`operations[${i}].milestone`,`required string`,o));let d=r.type;l(d)&&!a.has(d)&&t.push(u(`operations[${i}].type`,`invalid type`,d));let p=r.shape;if(c(p)){let e=p.kind;e!=null&&l(e)&&!s.has(e)&&t.push(u(`operations[${i}].shape.kind`,`invalid shape kind`,e));let r=p.ops;if(Array.isArray(r)&&l(e))for(let a=0;a<r.length;a++){let o=r[a];if(!c(o))continue;let s=o.op;l(s)&&!n(e,s)&&t.push(u(`operations[${i}].shape.ops[${a}]`,`op "${s}" not valid for kind "${e}"`))}}Array.isArray(r.depends_on)||t.push(u(`operations[${i}].depends_on`,`must be an array`,r.depends_on))}for(let n of e){if(!c(n))continue;let e=n.id;if(!l(e))continue;let r=n.depends_on;if(Array.isArray(r))for(let n of r)l(n)&&!h.has(n)&&t.push(u(`operations[${e}].depends_on`,`unknown operation "${n}"`))}}}return{valid:t.length===0,errors:t}}function m(e){let t=[];if(!c(e))return{valid:!1,errors:[u(``,`root must be an object`)]};for(let n of[`snapshot_at`,`description`])l(e[n])||t.push(u(n,`required string field missing`,e[n]));l(e.plan)||t.push(u(`plan`,`required string`,e.plan));let n=e.milestones;if(!c(n))t.push(u(`milestones`,`must be an object`,n));else{let a=Object.keys(n),o=new Set(a);for(let e of a){let i=n[e];if(!c(i)){t.push(u(`milestones.${e}`,`must be an object`,i));continue}let a=i.eligible,o=i.pending;a===!0&&o!=null&&t.push(u(`milestones.${e}`,`D-07 violation: eligible=true but pending not null`)),typeof a!=`boolean`&&t.push(u(`milestones.${e}.eligible`,`must be boolean`,a));let s=i.status;(!l(s)||!r.has(s))&&t.push(u(`milestones.${e}.status`,`invalid status`,s)),a===!0&&s===`complete`&&t.push(u(`milestones.${e}`,`D-07 violation: eligible=true but status is complete`));let d=i.wave;(typeof d!=`number`||!Number.isInteger(d)||d<0)&&t.push(u(`milestones.${e}.wave`,`must be non-negative integer`,d));let f=i.ki_estimate;f!=null&&typeof f!=`number`&&t.push(u(`milestones.${e}.ki_estimate`,`must be number|null`,f));for(let n of[`tokens_estimated`,`tokens_actual`]){let r=i[n];r!=null&&typeof r!=`number`&&t.push(u(`milestones.${e}.${n}`,`must be number|null`,r))}Array.isArray(i.artifacts)||t.push(u(`milestones.${e}.artifacts`,`must be an array`,i.artifacts)),typeof i.si_bytes!=`number`&&t.push(u(`milestones.${e}.si_bytes`,`must be a number`,i.si_bytes))}let s=e.operations;if(!Array.isArray(s))t.push(u(`operations`,`must be an array`,s));else for(let e of s){if(!c(e))continue;let n=l(e.id)?e.id:`?`,r=e.milestone;l(r)&&!o.has(r)&&t.push(u(`operations[${n}].milestone`,`unknown milestone "${r}"`));let a=e.status;(!l(a)||!i.has(a))&&t.push(u(`operations[${n}].status`,`invalid operation status`,a)),Array.isArray(e.dispatch_ids)||t.push(u(`operations[${n}].dispatch_ids`,`must be an array`,e.dispatch_ids)),typeof e.attempt_count!=`number`&&t.push(u(`operations[${n}].attempt_count`,`must be a number`,e.attempt_count)),Array.isArray(e.blast_radius)||t.push(u(`operations[${n}].blast_radius`,`must be an array`,e.blast_radius))}let d=e.open_questions;if(!Array.isArray(d))t.push(u(`open_questions`,`must be an array`,d));else for(let e of d){if(!c(e))continue;let n=e.blocking;(!l(n)||!o.has(n))&&t.push(u(`open_questions`,`unknown blocking milestone "${n}"`)),typeof e.surfaced!=`boolean`&&t.push(u(`open_questions[${e.id}]`,`surfaced must be boolean`,e.surfaced)),typeof e.answered!=`boolean`&&t.push(u(`open_questions[${e.id}]`,`answered must be boolean`,e.answered))}let f=e.dispatch_units;if(f!==void 0){if(!Array.isArray(f))t.push(u(`dispatch_units`,`must be an array if present`,f));else for(let e of f){if(!c(e))continue;let n=e.fits_context_window;typeof n!=`boolean`&&t.push(u(`dispatch_units[${e.id}]`,`fits_context_window must be boolean`,n));let r=e.milestones;if(Array.isArray(r))for(let n of r)l(n)&&!o.has(n)&&t.push(u(`dispatch_units[${e.id}].milestones`,`unknown milestone "${n}"`))}}c(e.pairwise_overlap)||t.push(u(`pairwise_overlap`,`must be an object`,e.pairwise_overlap))}return{valid:t.length===0,errors:t}}function h(e){let t=p(e);if(!t.valid)throw Error(`DagJson validation failed:\n${t.errors.map(e=>` ${e.path}: ${e.message}`).join(`
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=new Set([`create`,`modify-signature`,`modify-body`,`add-export`,`remove-export`,`rename`]),t={function:new Set([`add-param`,`remove-param`,`rename-param`,`retype-param`,`change-param-optional`,`reorder-params`,`change-return`]),interface:new Set([`add-field`,`remove-field`,`rename-field`,`retype-field`,`change-field-optional`,`add-generic`,`remove-generic`,`constrain-generic`,`add-extends`,`remove-extends`]),type:new Set([`add-field`,`remove-field`,`retype-field`]),class:new Set([`add-field`,`remove-field`,`rename-field`,`retype-field`,`change-field-optional`,`add-param`,`add-generic`,`remove-generic`,`constrain-generic`,`add-extends`,`remove-extends`]),enum:new Set([`add-field`,`remove-field`,`rename-field`]),const:new Set([`add-var`,`remove-var`,`rename-var`,`change-default`]),config:new Set([`set-key`,`remove-key`,`rename-key`,`add-entry`,`remove-entry`,`update-entry`,`bump-version`,`update-checksum`]),env:new Set([`set-key`,`remove-key`,`rename-key`]),schema:new Set([`add-table`,`remove-table`,`add-column`,`remove-column`,`rename-column`,`retype-column`,`change-nullable`,`add-index`,`remove-index`]),manifest:new Set([`add-entry`,`remove-entry`,`bump-version`]),doc:new Set([`add-section`,`remove-section`,`rename-section`,`update-section`]),"structured-output":new Set([]),script:new Set(`add-param.remove-param.rename-param.retype-param.change-param-optional.reorder-params.change-return.add-field.remove-field.rename-field.retype-field.change-field-optional.add-generic.remove-generic.constrain-generic.add-extends.remove-extends.set-key.remove-key.rename-key.add-array-item.remove-array-item.add-var.remove-var.rename-var.change-default.add-section.remove-section.rename-section.update-section.add-table.remove-table.add-column.remove-column.rename-column.retype-column.change-nullable.add-index.remove-index.add-entry.remove-entry.update-entry.bump-version.update-checksum.add-export`.split(`.`))};function n(e,n){let r=t[e];return r?r.has(n):!1}var r=new Set([`pending`,`pending-surfaced`,`in_progress`,`complete`,`failed`,`skipped`,`awaiting_input`]),i=new Set([`pending`,`in_progress`,`complete`,`failed`,`skipped`]),a=new Set([`automated`,`tool-call`,`generative`]),o=new Set([`anthropic`,`openai`,`deepseek`,`google`,`local`,`claudecli`,`teammate`]),s=new Set([`function`,`interface`,`type`,`class`,`enum`,`const`,`script`,`config`,`env`,`schema`,`manifest`,`doc`,`structured-output`]);function c(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function l(e){return typeof e==`string`}function u(e,t,n){return{path:e,message:t,value:n}}function d(e){let t=Object.keys(e),n=new Map,r=new Map;for(let e of t)n.set(e,0),r.set(e,[]);for(let i of t)for(let t of e[i]?.depends_on??[])e[t]&&(r.get(t)?.push(i),n.set(i,(n.get(i)??0)+1));let i=t.filter(e=>(n.get(e)??0)===0),a=new Set;for(;i.length>0;){let e=i.shift();if(e!==void 0){a.add(e);for(let t of r.get(e)??[]){let e=(n.get(t)??1)-1;n.set(t,e),e===0&&i.push(t)}}}return a.size===t.length?null:t.filter(e=>!a.has(e)).map(e=>({slug:e}))}function f(e,t){for(let n of e){if(!c(n))continue;let e=l(n.id)?n.id:`?`,r=n.provider;(!l(r)||!o.has(r))&&t.push(u(`dispatch_log[${e}].provider`,`invalid provider`,r));let i=n.turns;if(!Array.isArray(i)){t.push(u(`dispatch_log[${e}].turns`,`must be an array`,i));continue}for(let n=0;n<i.length;n++){let r=i[n],a=`dispatch_log[${e}].turns[${n}]`;if(!c(r)){t.push(u(a,`must be an object`,r));continue}(typeof r.turn!=`number`||!Number.isInteger(r.turn)||r.turn<1)&&t.push(u(`${a}.turn`,`must be a positive integer`,r.turn)),typeof r.input_tokens!=`number`&&t.push(u(`${a}.input_tokens`,`must be a number`,r.input_tokens)),typeof r.output_tokens!=`number`&&t.push(u(`${a}.output_tokens`,`must be a number`,r.output_tokens)),l(r.t)||t.push(u(`${a}.t`,`must be a string`,r.t));let o=r.model_calls;o!=null&&typeof o!=`number`&&t.push(u(`${a}.model_calls`,`must be a number or null if present`,o))}}}function p(e){let t=[];if(!c(e))return{valid:!1,errors:[u(``,`root must be an object`)]};for(let n of[`description`,`problem`,`approach`,`executor`]){let r=e[n];(!l(r)||r.trim()===``)&&t.push(u(n,`required string field missing/empty`,r))}typeof e.schema_version!=`number`&&t.push(u(`schema_version`,`must be a number`,e.schema_version));let r=e.plan_kind;r!==`brownfield`&&r!==`greenfield`&&t.push(u(`plan_kind`,`must be "brownfield" or "greenfield"`,r)),Array.isArray(e.phases)?e.phases.length===0&&t.push(u(`phases`,`must have at least one entry`)):t.push(u(`phases`,`must be an array`,e.phases));let i=e.terminal;!l(i)&&!Array.isArray(i)&&t.push(u(`terminal`,`must be a string or array`,i)),Array.isArray(e.dispatch_log)?f(e.dispatch_log,t):t.push(u(`dispatch_log`,`must be an array`,e.dispatch_log)),c(e.optimization)||t.push(u(`optimization`,`must be an object`,e.optimization)),c(e.providers)||t.push(u(`providers`,`must be an object`,e.providers)),c(e.effort_max_tokens)||t.push(u(`effort_max_tokens`,`must be an object`,e.effort_max_tokens));let o=e.milestones;if(!c(o))t.push(u(`milestones`,`must be an object`,o));else{let r=Object.keys(o);r.length===0&&t.push(u(`milestones`,`must have at least one entry`));let f=new Set(r);for(let e of r){let n=o[e];if(!c(n)){t.push(u(`milestones.${e}`,`must be an object`,n));continue}if((!l(n.description)||n.description.trim()===``)&&t.push(u(`milestones.${e}.description`,`required string`,n.description)),!Array.isArray(n.depends_on))t.push(u(`milestones.${e}.depends_on`,`must be an array`,n.depends_on));else for(let r of n.depends_on)l(r)?f.has(r)||t.push(u(`milestones.${e}.depends_on`,`unknown milestone "${r}"`)):t.push(u(`milestones.${e}.depends_on[]`,`must be a string`,r));let r=n.phase;(!l(r)||r.trim()===``)&&t.push(u(`milestones.${e}.phase`,`required string`,r)),(!l(n.authored_by)||n.authored_by.trim()===``)&&t.push(u(`milestones.${e}.authored_by`,`required string`,n.authored_by));let i=n.model;i!=null&&![`Haiku`,`Sonnet`,`Opus`].includes(i)&&t.push(u(`milestones.${e}.model`,`invalid model tier`,i));let a=n.effort;a!=null&&![`low`,`medium`,`high`,`xhigh`,`max`].includes(a)&&t.push(u(`milestones.${e}.effort`,`invalid effort tier`,a)),n.two_stage!==void 0&&typeof n.two_stage!=`boolean`&&t.push(u(`milestones.${e}.two_stage`,`must be a boolean`,n.two_stage)),Array.isArray(n.read_only)||t.push(u(`milestones.${e}.read_only`,`must be an array`,n.read_only))}let p=d(o);if(p)for(let{slug:e}of p)t.push(u(`milestones.${e}`,`dependency cycle detected`));if(l(i)&&!f.has(i))t.push(u(`terminal`,`unknown milestone "${i}"`));else if(Array.isArray(i))for(let e of i)f.has(e)||t.push(u(`terminal[]`,`unknown milestone "${e}"`));let m=e.operations,h=new Set;if(!Array.isArray(m)&&!c(m))t.push(u(`operations`,`must be an array or object`,m));else{let e=Array.isArray(m)?m:Object.values(m);for(let r of e){if(!c(r)){t.push(u(`operations[]`,`must be an object`,r));continue}let e=r.id;if(!l(e)){t.push(u(`operations[?]`,`missing/invalid id`,e));continue}let i=e;h.add(i);let o=r.milestone;l(o)?f.has(o)||t.push(u(`operations[${i}].milestone`,`unknown milestone "${o}"`)):t.push(u(`operations[${i}].milestone`,`required string`,o));let d=r.type;l(d)&&!a.has(d)&&t.push(u(`operations[${i}].type`,`invalid type`,d));let p=r.shape;if(c(p)){let e=p.kind;e!=null&&l(e)&&!s.has(e)&&t.push(u(`operations[${i}].shape.kind`,`invalid shape kind`,e));let r=p.ops;if(Array.isArray(r)&&l(e))for(let a=0;a<r.length;a++){let o=r[a];if(!c(o))continue;let s=o.op;l(s)&&!n(e,s)&&t.push(u(`operations[${i}].shape.ops[${a}]`,`op "${s}" not valid for kind "${e}"`))}}Array.isArray(r.depends_on)||t.push(u(`operations[${i}].depends_on`,`must be an array`,r.depends_on))}for(let n of e){if(!c(n))continue;let e=n.id;if(!l(e))continue;let r=n.depends_on;if(Array.isArray(r))for(let n of r)l(n)&&!h.has(n)&&t.push(u(`operations[${e}].depends_on`,`unknown operation "${n}"`))}}}return{valid:t.length===0,errors:t}}function m(e){let t=[];if(!c(e))return{valid:!1,errors:[u(``,`root must be an object`)]};for(let n of[`snapshot_at`,`description`])l(e[n])||t.push(u(n,`required string field missing`,e[n]));l(e.plan)||t.push(u(`plan`,`required string`,e.plan));let n=e.milestones;if(!c(n))t.push(u(`milestones`,`must be an object`,n));else{let a=Object.keys(n),o=new Set(a);for(let e of a){let i=n[e];if(!c(i)){t.push(u(`milestones.${e}`,`must be an object`,i));continue}let a=i.eligible,o=i.pending;a===!0&&o!=null&&t.push(u(`milestones.${e}`,`D-07 violation: eligible=true but pending not null`)),typeof a!=`boolean`&&t.push(u(`milestones.${e}.eligible`,`must be boolean`,a));let s=i.status;(!l(s)||!r.has(s))&&t.push(u(`milestones.${e}.status`,`invalid status`,s)),a===!0&&s===`complete`&&t.push(u(`milestones.${e}`,`D-07 violation: eligible=true but status is complete`));let d=i.wave;(typeof d!=`number`||!Number.isInteger(d)||d<0)&&t.push(u(`milestones.${e}.wave`,`must be non-negative integer`,d));let f=i.ki_estimate;f!=null&&typeof f!=`number`&&t.push(u(`milestones.${e}.ki_estimate`,`must be number|null`,f));for(let n of[`tokens_estimated`,`tokens_actual`]){let r=i[n];r!=null&&typeof r!=`number`&&t.push(u(`milestones.${e}.${n}`,`must be number|null`,r))}Array.isArray(i.artifacts)||t.push(u(`milestones.${e}.artifacts`,`must be an array`,i.artifacts)),typeof i.si_bytes!=`number`&&t.push(u(`milestones.${e}.si_bytes`,`must be a number`,i.si_bytes))}let s=e.operations;if(!Array.isArray(s))t.push(u(`operations`,`must be an array`,s));else for(let e of s){if(!c(e))continue;let n=l(e.id)?e.id:`?`,r=e.milestone;l(r)&&!o.has(r)&&t.push(u(`operations[${n}].milestone`,`unknown milestone "${r}"`));let a=e.status;(!l(a)||!i.has(a))&&t.push(u(`operations[${n}].status`,`invalid operation status`,a)),Array.isArray(e.dispatch_ids)||t.push(u(`operations[${n}].dispatch_ids`,`must be an array`,e.dispatch_ids)),typeof e.attempt_count!=`number`&&t.push(u(`operations[${n}].attempt_count`,`must be a number`,e.attempt_count)),Array.isArray(e.blast_radius)||t.push(u(`operations[${n}].blast_radius`,`must be an array`,e.blast_radius))}let d=e.open_questions;if(!Array.isArray(d))t.push(u(`open_questions`,`must be an array`,d));else for(let e of d){if(!c(e))continue;let n=e.blocking;(!l(n)||!o.has(n))&&t.push(u(`open_questions`,`unknown blocking milestone "${n}"`)),typeof e.surfaced!=`boolean`&&t.push(u(`open_questions[${e.id}]`,`surfaced must be boolean`,e.surfaced)),typeof e.answered!=`boolean`&&t.push(u(`open_questions[${e.id}]`,`answered must be boolean`,e.answered))}let f=e.dispatch_units;if(f!==void 0){if(!Array.isArray(f))t.push(u(`dispatch_units`,`must be an array if present`,f));else for(let e of f){if(!c(e))continue;let n=e.fits_context_window;typeof n!=`boolean`&&t.push(u(`dispatch_units[${e.id}]`,`fits_context_window must be boolean`,n));let r=e.milestones;if(Array.isArray(r))for(let n of r)l(n)&&!o.has(n)&&t.push(u(`dispatch_units[${e.id}].milestones`,`unknown milestone "${n}"`))}}c(e.pairwise_overlap)||t.push(u(`pairwise_overlap`,`must be an object`,e.pairwise_overlap))}return{valid:t.length===0,errors:t}}function h(e){let t=p(e);if(!t.valid)throw Error(`DagJson validation failed:\n${t.errors.map(e=>` ${e.path}: ${e.message}`).join(`
|
|
2
2
|
`)}`)}function g(e){let t=m(e);if(!t.valid)throw Error(`Snapshot validation failed:\n${t.errors.map(e=>` ${e.path}: ${e.message}`).join(`
|
|
3
3
|
`)}`)}var _=[{from:2,to:3,apply:e=>{!e.milestones&&e.nodes&&(e.milestones=e.nodes,delete e.nodes);let t=e.operations;t&&typeof t==`object`&&!Array.isArray(t)&&(e.operations=Object.values(t))}},{from:3,to:4,apply:e=>{(!e.providers||Object.keys(e.providers).length===0)&&(e.providers={Haiku:{type:`claudecli`,model_id:`claude-haiku-4-5`,env_secret:null,base_url:null,timeout_ms:6e4,retry_config:{retries:3,min_timeout:1e3,max_timeout:3e4,factor:2}},Sonnet:{type:`claudecli`,model_id:`claude-sonnet-4-5`,env_secret:null,base_url:null,timeout_ms:12e4,retry_config:{retries:3,min_timeout:1e3,max_timeout:3e4,factor:2}},Opus:{type:`claudecli`,model_id:`claude-opus-4-5`,env_secret:null,base_url:null,timeout_ms:3e5,retry_config:{retries:3,min_timeout:1e3,max_timeout:3e4,factor:2}}}),(!e.effort_max_tokens||Object.keys(e.effort_max_tokens).length===0)&&(e.effort_max_tokens={low:1024,medium:4096,high:8192,xhigh:16384,max:32768}),e.optimization||={sentinel_fanout:{enabled:!0,write_multiplier:1.25,read_multiplier:.1,hit_probability:.9},b_per_tier:{Haiku:8e3,Sonnet:15e3,Opus:27e3},context_window_per_tier:{Haiku:16e3,Sonnet:16e3,Opus:32e3},context_window_override:null,b_override:null};let t=[];Array.isArray(e.operations)?t=e.operations:e.operations&&typeof e.operations==`object`&&(t=Object.values(e.operations));for(let e of t)if(typeof e==`object`&&e){let t=e;t.type===void 0&&(t.type=`generative`),t.criteria===void 0&&(t.criteria=[]),t.tool===void 0&&(t.tool=null),t.args===void 0&&(t.args=null)}}}];function v(e,t,n){if(e===t)return;let r=e;for(let e of[..._].sort((e,t)=>e.from-t.from))if(e.from===r&&(e.apply(n),r=e.to,r===t)){n.schema_version=t;return}throw Error(`migrateDag: no path from v${e} to v${t}. Available: [${_.map(e=>`v${e.from}→v${e.to}`).join(`, `)}]`)}exports.VALID_OPS_BY_KIND=t,exports.WRITE_CLASS_ACTIONS=e,exports.assertValidDagJson=h,exports.assertValidSnapshot=g,exports.isValidOpForKind=n,exports.migrateDag=v,exports.validateDagJson=p,exports.validateSnapshot=m;
|
package/index.mjs
CHANGED
package/lib/types.d.ts
CHANGED
|
@@ -15,7 +15,16 @@ export type CodeKind = 'function' | 'interface' | 'type' | 'class' | 'enum' | 'c
|
|
|
15
15
|
export type ConfigKind = 'config' | 'env' | 'schema' | 'manifest';
|
|
16
16
|
export type ShapeKind = CodeKind | ConfigKind | 'doc' | 'structured-output';
|
|
17
17
|
export type KindFamily = 'code-config' | 'doc' | 'structured' | 'tool-call';
|
|
18
|
-
export type MilestoneStatus = 'pending' | 'pending-surfaced' | 'in_progress' | 'complete' | 'failed' | 'skipped'
|
|
18
|
+
export type MilestoneStatus = 'pending' | 'pending-surfaced' | 'in_progress' | 'complete' | 'failed' | 'skipped'
|
|
19
|
+
/**
|
|
20
|
+
* The milestone's dispatch fired a sessioned agent-mcp task that suspended
|
|
21
|
+
* for human input (HITL: `request_human_input` -> `awaiting_input`). The work
|
|
22
|
+
* is PAUSED, not failed — an operator resumes it with `task_resume` (using the
|
|
23
|
+
* `resumeToken` recorded on the dispatch_log entry's `suspension`). Distinct
|
|
24
|
+
* from `failed` so `dispatch-cli status` can surface a resumable suspension
|
|
25
|
+
* instead of a terminal failure (FEAT; backlog 03145a46).
|
|
26
|
+
*/
|
|
27
|
+
| 'awaiting_input';
|
|
19
28
|
export type DispatchUnitStatus = 'pending' | 'in_progress' | 'complete' | 'failed';
|
|
20
29
|
export type DispatchExecutionMode = 'model-dispatch' | 'guard-only';
|
|
21
30
|
export type OperationStatus = 'pending' | 'in_progress' | 'complete' | 'failed' | 'skipped';
|
|
@@ -171,6 +180,21 @@ export interface DispatchLogEntry {
|
|
|
171
180
|
turns: Turn[];
|
|
172
181
|
results: DispatchResult[];
|
|
173
182
|
notes: DispatchNote[];
|
|
183
|
+
/**
|
|
184
|
+
* Set when this entry's agent-mcp task suspended to `awaiting_input` (HITL —
|
|
185
|
+
* backlog 03145a46) instead of reaching a terminal status. Carries the
|
|
186
|
+
* suspended task's id and the opaque `resumeToken` `task_resume` requires, so
|
|
187
|
+
* `dispatch-cli status` (`statusCore`) can surface the suspension and an
|
|
188
|
+
* operator can release it. Absent for every non-suspended dispatch.
|
|
189
|
+
*
|
|
190
|
+
* NOTE — a suspended dispatch is NOT a failure: the milestone's derived status
|
|
191
|
+
* is `awaiting_input`, its guards are deliberately NOT run and no correction is
|
|
192
|
+
* injected (verification is meaningless until the task actually completes).
|
|
193
|
+
*/
|
|
194
|
+
suspension?: {
|
|
195
|
+
taskId: string;
|
|
196
|
+
resumeToken: string;
|
|
197
|
+
} | null;
|
|
174
198
|
}
|
|
175
199
|
export interface OperationDag {
|
|
176
200
|
id: string;
|
|
@@ -277,6 +301,20 @@ export interface DagJson {
|
|
|
277
301
|
terminal: string | string[];
|
|
278
302
|
assumed_baseline?: string[] | Record<string, unknown>;
|
|
279
303
|
cross_plan_deps?: CrossPlanDep[];
|
|
304
|
+
/**
|
|
305
|
+
* Optional top-level agent-mcp session stamped onto every `DispatchUnit` the
|
|
306
|
+
* orchestrator fires (FEAT-DISPATCH-SESSION-001 producer, backlog fa9d3079 /
|
|
307
|
+
* 03145a46). When set, the run's units fire as SESSIONED tasks in that
|
|
308
|
+
* agent-mcp session instead of cold ephemeral ones — which is what makes
|
|
309
|
+
* HITL (`request_human_input` -> awaiting_input) reachable from dispatch and
|
|
310
|
+
* lets consecutive units share conversational context.
|
|
311
|
+
*
|
|
312
|
+
* The caller supplies an existing session id (created via agent-mcp's
|
|
313
|
+
* `agent` tool). A per-unit `DispatchUnit.session_id`, when already set by
|
|
314
|
+
* the optimizer, wins over this default. `null`/omitted preserves the
|
|
315
|
+
* pre-existing ephemeral behavior exactly.
|
|
316
|
+
*/
|
|
317
|
+
session_id?: string | null;
|
|
280
318
|
optimization: OptimizationConfig;
|
|
281
319
|
providers: Record<string, ProviderConfig>;
|
|
282
320
|
effort_max_tokens: Record<string, number>;
|
|
@@ -338,6 +376,14 @@ export interface DispatchUnit {
|
|
|
338
376
|
sentinel_role: SentinelRole | null;
|
|
339
377
|
dispatch_log_id: string | null;
|
|
340
378
|
remote_task_id: string | null;
|
|
379
|
+
/**
|
|
380
|
+
* agent-mcp session this unit runs in (FEAT-DISPATCH-SESSION-001 / backlog
|
|
381
|
+
* fa9d3079). When set, `AgentMcpRunner.fire` forwards it to agent-mcp's
|
|
382
|
+
* `task` tool, so consecutive units sharing a session keep conversational
|
|
383
|
+
* context instead of each being a cold, session-less (ephemeral) task.
|
|
384
|
+
* `null`/omitted preserves the pre-existing ephemeral behavior exactly.
|
|
385
|
+
*/
|
|
386
|
+
session_id?: string | null;
|
|
341
387
|
result: string | null;
|
|
342
388
|
status: DispatchUnitStatus;
|
|
343
389
|
started_at: string | null;
|