yaml-flow 8.4.22 → 8.4.25
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/browser/asset-integrity.json +3 -3
- package/browser/board-livecards-localstorage.js +5 -5
- package/cli/bundled/board-live-cards-cli.mjs +1 -1
- package/examples/board/demo-shell-with-server.html +2 -2
- package/examples/board/doc.html +2 -2
- package/examples/board/server/board-server.js +4 -0
- package/examples/board/server/chat-flow/flow-steps.json +62 -3
- package/examples/board/test/server-http-test.js +25 -8
- package/examples/board-local/demo-shell-localstorage.html +3 -3
- package/lib/board-live-cards-node.d.cts +2 -2
- package/lib/board-live-cards-node.d.ts +2 -2
- package/lib/board-live-cards-server-runtime.cjs +3 -3
- package/lib/board-live-cards-server-runtime.d.cts +1 -1
- package/lib/board-live-cards-server-runtime.d.ts +1 -1
- package/lib/board-live-cards-server-runtime.js +3 -3
- package/lib/server-runtime/index.cjs +3 -3
- package/lib/server-runtime/index.d.cts +2 -2
- package/lib/server-runtime/index.d.ts +2 -2
- package/lib/server-runtime/index.js +3 -3
- package/lib/{types-D501gMQt.d.cts → types-BpfMamGs.d.cts} +2 -0
- package/lib/{types-1L1D33mr.d.ts → types-DwPRb-PY.d.ts} +2 -0
- package/package.json +1 -1
|
@@ -26,4 +26,4 @@ ${new Date().toISOString()}
|
|
|
26
26
|
`,"utf-8"),a},readAll(){return t()},readAfter(r){let a=t();if(!r)return{entries:a,newCursor:a.length>0?a[a.length-1].id:null};let n=a.findIndex(o=>o.id===r),s=n===-1?a:a.slice(n+1);return{entries:s,newCursor:s.length>0?s[s.length-1].id:r}},clear(){D.existsSync(e)&&D.truncateSync(e,0)}}}function Xo(e){if(e==null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e))return`[${e.map(Xo).join(",")}]`;let t=e;return`{${Object.keys(t).sort().map(r=>`${JSON.stringify(r)}:${Xo(t[r])}`).join(",")}}`}function q0(e){return ed("sha256").update(Xo(e)).digest("hex")}function D0(e){let t=Q.join(e,"board-journal.jsonl");return{readAllEntries(){if(!D.existsSync(t))return[];let r=D.readFileSync(t,"utf-8").trim();return r?r.split(`
|
|
27
27
|
`).filter(Boolean).map(a=>JSON.parse(a)):[]},appendEntry(r){D.appendFileSync(t,JSON.stringify(r)+`
|
|
28
28
|
`,"utf-8")},generateId(){return et()}}}function M0(e){return{tryAcquire(){try{if(!D.existsSync(e)){D.mkdirSync(Q.dirname(e),{recursive:!0});try{D.writeFileSync(e,"{}",{flag:"wx"})}catch{}}return(0,td.lockSync)(e,{retries:0})}catch{return null}}}}var F0={$schema:"http://json-schema.org/draft-07/schema#",$id:"https://nsreehari.github.io/boards/live-cards.schema.json",definitions:{bind_ref:{description:"A card data path reference, e.g. 'card_data.raw_quotes' or 'requires.upstream'",type:"string",pattern:"^(card_data|requires|fetched_sources|computed_values)(\\.|$)"},bind_or_literal:{description:"A literal value or a bind reference object",oneOf:[{type:"string"},{type:"number"},{type:"boolean"},{type:"array"},{type:"object",properties:{bind:{$ref:"#/definitions/bind_ref"}},required:["bind"]}]},compute_expr:{description:"A declarative JSON compute expression",type:"object",required:["fn"],properties:{fn:{type:"string",description:"Function name from the built-in vocabulary",enum:["sum","avg","min","max","count","first","last","add","sub","mul","div","round","abs","mod","gt","gte","lt","lte","eq","neq","if","and","or","not","concat","upper","lower","template","filter","pluck","map","sort","slice","flat","unique","group","get","default","now","diff_days","format_date"]},input:{description:"card_data.path, literal, array of inputs, or nested compute_expr",oneOf:[{type:"string"},{type:"number"},{type:"boolean"},{type:"array"},{$ref:"#/definitions/compute_expr"}]},field:{type:"string",description:"For pluck/sum/group \u2014 the object key to extract"},where:{$ref:"#/definitions/compute_expr",description:"For filter \u2014 predicate expression ($ = current item)"},cond:{$ref:"#/definitions/compute_expr",description:"For if \u2014 condition expression"},then:{description:"For if \u2014 value when cond is truthy"},else:{description:"For if \u2014 value when cond is falsy"},format:{type:"string",description:"For format_date \u2014 date format string"}}},meta:{type:"object",properties:{title:{type:"string"},tags:{type:"array",items:{type:"string"}}}},requires:{type:"array",items:{type:"string"},description:"IDs of upstream nodes this node depends on"},provides:{type:"array",items:{type:"object",required:["bindTo","ref"],properties:{bindTo:{type:"string",description:"Token name published downstream"},ref:{type:"string",description:"Path to read value from (card_data.*, requires.*, fetched_sources.*, computed_values.*)"}}},description:"Explicit bindings exposing computed or card_data values downstream as named tokens"},compute_step:{description:"A single ordered compute step: reads card_data.*/requires.*/computed_values.*, writes to computed_values[bindTo]",type:"object",required:["bindTo","expr"],properties:{bindTo:{type:"string",description:"Key in computed_values to write result"},expr:{type:"string",description:"JSONata expression evaluated against { card_data, requires, fetched_sources, computed_values }"}}},source_def:{description:"One source entry. The engine requires 'bindTo' (compute namespace key) and 'outputFile' (delivery signal path). bindTo and outputFile must be unique across all source_defs in a card. Every other property is yours \u2014 add whatever your task-executor needs: kind, url, headers, mailbox, channel, model, query, etc. The full object is passed verbatim as the --in JSON to the executor.",type:"object",required:["bindTo","outputFile"],additionalProperties:!0,properties:{bindTo:{type:"string",description:"Key under fetched_sources.* available in compute expressions"},outputFile:{type:"string",description:"Board-relative path the executor writes its JSON result to. Presence of this file signals delivery."},projections:{type:"object",description:"Named data projections from card_data or requires, evaluated before the executor is called. Each key is a ref name; each value is a JSONata expression rooted at card_data or requires. The resolved values are passed to the executor as _projections. fetched_sources, computed_values, and source_defs are not accessible here \u2014 sources run before those exist.",additionalProperties:{type:"string"}},optionalForCompletionGating:{type:"boolean",default:!1,description:"When true this source does not gate card completion. Default false when absent, so source_defs are completion-gating by default."},timeout:{type:"integer",minimum:0,default:12e4,description:"Executor/script timeout in ms. Default: 120 000 (2 min)."},script:{type:"string",description:"Legacy direct-run: shell command executed when no .task-executor is registered. stdout is captured as the result."}}},render_element:{type:"object",required:["kind"],properties:{id:{type:"string",description:"Optional element ID for targeted updates"},kind:{enum:["metric","table","editable-table","chart","form","filter","list","notes","todo","alert","narrative","badge","text","markdown","ref","custom","actions"]},label:{type:"string",description:"Heading above this element"},className:{type:"string",description:"Bootstrap grid class, e.g. 'col-12 col-md-6'"},visible:{type:"string",description:"card_data/requires/fetched_sources/computed_values path \u2014 element shown only if truthy"},data:{type:"object",properties:{bind:{$ref:"#/definitions/bind_ref",description:"card_data/requires/fetched_sources/computed_values path to read data from"},writeTo:{$ref:"#/definitions/bind_ref",description:"card_data path for user input (form, filter, todo, notes)"},columns:{type:"array",items:{type:"string"},description:"table: visible columns"},maxRows:{type:"integer",description:"table/list: max rows to display"},sortable:{type:"boolean",default:!0,description:"table: enable click-to-sort"},placeholder:{type:"string",description:"Empty-state message"},chartType:{enum:["bar","line","pie","doughnut"]},chartOptions:{type:"object",description:"Chart.js options passthrough"},fields:{type:"object",description:"JSON Schema for form/filter fields"},thresholds:{type:"object",properties:{green:{type:"string"},amber:{type:"string"}}},colorMap:{type:"object",description:"badge: value \u2192 Bootstrap color"},style:{enum:["heading","muted","default"],description:"text: display style"},upload:{type:"boolean",default:!0,description:"file-upload: show drop zone (false = read-only file list)"},accept:{type:"array",items:{type:"string"},description:"file-upload: allowed extensions"},multiple:{type:"boolean",default:!0,description:"file-upload: allow multiple files"},fileAttach:{type:"boolean",default:!1,description:"chat: enable inline file attachments"},fileAccept:{type:"array",items:{type:"string"},description:"chat: allowed attachment extensions"},buttons:{type:"array",description:"actions: button definitions",items:{type:"object",required:["id","label"],properties:{id:{type:"string"},label:{type:"string"},style:{type:"string",description:"Bootstrap button variant, e.g. 'success', 'outline-danger'"},size:{type:"string",default:"sm"},disabled:{oneOf:[{type:"boolean"},{type:"string",description:"card_data/requires/fetched_sources/computed_values path \u2014 truthy = disabled"}]}}}}}}}},view:{type:"object",required:["elements"],properties:{elements:{type:"array",minItems:1,items:{$ref:"#/definitions/render_element"}},layout:{type:"object",properties:{board:{type:"object",properties:{col:{type:"integer",minimum:1,maximum:12},order:{type:"integer"}}},canvas:{type:"object",properties:{x:{type:"number"},y:{type:"number"},w:{type:"number"},h:{type:"number"}}}}},features:{type:"object",properties:{chat:{type:"boolean",default:!1},notes:{type:"boolean",default:!1},refresh:{type:"boolean",default:!0}}}}}},title:"LiveCard",description:"A unified card node. Behavior depends on which sections are present (source_defs, compute, view, etc.)",type:"object",required:["id"],additionalProperties:!1,properties:{id:{type:"string"},requires:{$ref:"#/definitions/requires"},provides:{$ref:"#/definitions/provides"},meta:{$ref:"#/definitions/meta"},view:{$ref:"#/definitions/view"},card_data:{type:"object",description:"Authored card data and runtime metadata. Includes uploaded-file metadata maintained by host handlers and inference evaluation results.",properties:{files:{type:"array",description:"Optional uploaded-file metadata maintained by host handlers. Stored name is normalized and serial-prefixed (for example 001-my_file.pdf).",items:{type:"object",required:["name","stored_name"],properties:{name:{type:"string",minLength:1},stored_name:{type:"string",minLength:5,maxLength:32,pattern:"^[0-9]{3,}-[a-z0-9._-]+$"},size:{oneOf:[{type:"integer",minimum:0},{type:"null"}]},mime_type:{type:"string"},path:{type:"string",pattern:"^[^\\s]+/files/[0-9]{3,}-[a-z0-9._-]+$"},uploaded_at:{type:"string",format:"date-time"},chat:{type:"boolean",description:"Whether this file entry is associated with a chat interaction"}},additionalProperties:!1}}},additionalProperties:!0},source_defs:{type:"array",description:"Source entries. Each entry is passed verbatim to the board's .task-executor (registered via init --task-executor) as the --in JSON file. The executor fetches/generates the data and writes JSON to --out. If no executor is registered, the built-in executor runs the entry's 'cli' command directly. Sources gate completion by default. Set optionalForCompletionGating: true for enrichment-only source_defs that should not block task-completed.",items:{$ref:"#/definitions/source_def"}},compute:{type:"array",description:"Ordered array of compute steps. Each reads card_data.*/requires.*/fetched_sources.*/computed_values.* and writes to ephemeral computed_values[bindTo].",items:{$ref:"#/definitions/compute_step"}}}},V0=dv(n0()),z0=On(import.meta.url),U0=z0("./jsonata-sync.cjs"),wn=null,Fl=/\b(card_data|requires|fetched_sources|computed_values|source_defs)\b/g,K0=/^\s*(card_data|requires|fetched_sources|computed_values|source_defs)(\.|$)/;function L0(e){let t=new Set,r;for(Fl.lastIndex=0;(r=Fl.exec(e))!==null;)t.add(r[1]);return t}function gd(e){let t=K0.exec(e);return t?t[1]:null}function Vl(e,t,r,a){try{U0(e)}catch(s){let o=s instanceof Error?s.message:String(s);a.push(`${t}: invalid JSONata expression (${o})`);return}let n=L0(e);for(let s of n)r.has(s)||a.push(`${t}: disallowed namespace "${s}" in expression`)}function Yo(e,t,r){if(Array.isArray(e)){e.forEach((n,s)=>{Yo(n,`${t}/${s}`,r)});return}if(typeof e=="string"){let n=gd(e);if(!n)return;new Set(["card_data","requires","computed_values"]).has(n)||r.push(`${t}: disallowed namespace "${n}" in view reference`);return}if(!e||typeof e!="object")return;let a=e;for(let[n,s]of Object.entries(a))Yo(s,`${t}/${n}`,r)}function H0(){if(wn)return wn;let e=new V0.default({allErrors:!0});return(0,rd.default)(e),wn=e.compile(F0),wn}function B0(e){let t=H0(),r=t(e),a=(t.errors??[]).map(n=>`${n.instancePath||"/"}: ${n.message??"unknown error"}`);if(e&&typeof e=="object"&&!Array.isArray(e)){let n=e.source_defs;if(Array.isArray(n)){let s=new Set,o=new Set;n.forEach((u,i)=>{if(!u||typeof u!="object"||Array.isArray(u))return;let c=u;typeof c.bindTo=="string"&&c.bindTo&&(s.has(c.bindTo)&&a.push(`/source_defs/${i}/bindTo: bindTo "${c.bindTo}" must be unique across all source_defs`),s.add(c.bindTo)),typeof c.outputFile=="string"&&c.outputFile&&(o.has(c.outputFile)&&a.push(`/source_defs/${i}/outputFile: outputFile "${c.outputFile}" must be unique across all source_defs`),o.add(c.outputFile))})}}return!r||a.length>0?{ok:!1,errors:a}:{ok:!0,errors:[]}}function J0(e){let t=[];if(!e||typeof e!="object"||Array.isArray(e))return{ok:!0,errors:[]};let r=e,a=r.compute;Array.isArray(a)&&a.forEach((c,l)=>{if(!c||typeof c!="object"||Array.isArray(c))return;let d=c.expr;typeof d!="string"||d.trim().length===0||Vl(d,`/compute/${l}/expr`,new Set(["card_data","requires","fetched_sources","computed_values"]),t)});let n=new Set(["card_data","requires","fetched_sources","computed_values"]),s=r.provides;Array.isArray(s)&&s.forEach((c,l)=>{if(!c||typeof c!="object"||Array.isArray(c))return;let d=c.ref;if(typeof d!="string"||d.trim().length===0)return;let w=gd(d);w===null?t.push(`/provides/${l}/ref: path "${d}" must start with a valid namespace (${[...n].join(", ")})`):n.has(w)||t.push(`/provides/${l}/ref: disallowed namespace "${w}" in path "${d}" (valid: ${[...n].join(", ")})`)});let o=r.view;o&&typeof o=="object"&&!Array.isArray(o)&&Yo(o,"/view",t);let u=new Set(["card_data","requires"]),i=r.source_defs;return Array.isArray(i)&&i.forEach((c,l)=>{if(!c||typeof c!="object"||Array.isArray(c))return;let d=c.projections;if(!(!d||typeof d!="object"||Array.isArray(d)))for(let[w,$]of Object.entries(d))typeof $!="string"||$.trim().length===0||Vl($,`/source_defs/${l}/projections/${w}`,u,t)}),{ok:t.length===0,errors:t}}function G0(e){let t=B0(e);if(!t.ok)return t;let r=J0(e);return r.ok?{ok:!0,errors:[]}:{ok:!1,errors:r.errors}}var Ar={RUNNING:"running",COMPLETED:"completed",FAILED:"failed",INACTIVATED:"inactivated"};function bt(e){return e?Array.isArray(e.provides)?e.provides:[]:[]}function $a(e){return e?Array.isArray(e.requires)?e.requires:[]:[]}function W0(e){return e.tasks??{}}function zl(e){return e?e.status===Ar.FAILED||e.status===Ar.INACTIVATED:!1}function X0(e,t){return e.refreshStrategy??t?.refreshStrategy??"data-changed"}function Y0(e){return e.maxExecutions}function Q0(e,t){let r=new Set;for(let[a,n]of Object.entries(t))if(n.status===Ar.COMPLETED){let s=e.tasks[a];s&&bt(s).forEach(o=>r.add(o))}return Array.from(r)}function Z0(e,t){let r={};return e.forEach(a=>{let n=t[a];n&&bt(n).forEach(s=>{r[s]||(r[s]=[]),r[s].push(a)})}),r}function e_(e,t,r){let a=e.tasks[t]??In(),n={};if(r){let o=r.tasks[t],u=$a(o);for(let i of u)for(let[c,l]of Object.entries(r.tasks))if(bt(l).includes(i)){let d=e.tasks[c];d?.lastDataHash&&(n[i]=d.lastDataHash);break}}let s={...a,status:"running",startedAt:new Date().toISOString(),lastUpdated:new Date().toISOString(),progress:0,error:void 0,startConsumedHashes:n};return{...e,tasks:{...e.tasks,[t]:s},lastUpdated:new Date().toISOString()}}function t_(e,t,r,a,n,s){let o=e.tasks[r]??In(),u=t.tasks[r];if(!u)throw new Error(`Task "${r}" not found in graph`);let i;a&&u.on&&u.on[a]?i=u.on[a]:i=bt(u);let c=o.startConsumedHashes?{...o.startConsumedHashes}:{...o.lastConsumedHashes};if(!o.startConsumedHashes){let w=u.requires??[];for(let $ of w)for(let[h,v]of Object.entries(t.tasks))if(bt(v).includes($)){let m=e.tasks[h];m?.lastDataHash&&(c[$]=m.lastDataHash);break}}let l={...o,status:"completed",completedAt:new Date().toISOString(),lastUpdated:new Date().toISOString(),executionCount:o.executionCount+1,lastEpoch:o.executionCount+1,lastDataHash:n,data:s,lastConsumedHashes:c,error:void 0},d=[...new Set([...e.availableOutputs,...i])];return{...e,tasks:{...e.tasks,[r]:l},availableOutputs:d,lastUpdated:new Date().toISOString()}}function r_(e,t,r,a){let n=e.tasks[r]??In(),s=t.tasks[r];if(s?.retry){let i=n.retryCount+1;if(i<=s.retry.max_attempts){let c={...n,status:"not-started",retryCount:i,lastUpdated:new Date().toISOString(),error:a};return{...e,tasks:{...e.tasks,[r]:c},lastUpdated:new Date().toISOString()}}}let o={...n,status:"failed",failedAt:new Date().toISOString(),lastUpdated:new Date().toISOString(),error:a,executionCount:n.executionCount+1},u=e.availableOutputs;if(s?.on_failure&&s.on_failure.length>0&&(u=[...new Set([...e.availableOutputs,...s.on_failure])]),s?.circuit_breaker&&o.executionCount>=s.circuit_breaker.max_executions){let i=s.circuit_breaker.on_break;u=[...new Set([...u,...i])]}return{...e,tasks:{...e.tasks,[r]:o},availableOutputs:u,lastUpdated:new Date().toISOString()}}function a_(e,t,r,a){let n=e.tasks[t]??In(),s={...n,progress:typeof a=="number"?a:n.progress,messages:[...n.messages??[],...r?[{message:r,timestamp:new Date().toISOString(),status:n.status}]:[]],lastUpdated:new Date().toISOString()};return{...e,tasks:{...e.tasks,[t]:s},lastUpdated:new Date().toISOString()}}function n_(e,t){let r=e.tasks[t];if(!r)return e;let a={...r,status:"not-started",startedAt:void 0,completedAt:void 0,failedAt:void 0,error:void 0,data:void 0,progress:null,lastUpdated:new Date().toISOString()};return{...e,tasks:{...e.tasks,[t]:a},lastUpdated:new Date().toISOString()}}function In(){return{status:"not-started",executionCount:0,retryCount:0,lastEpoch:0,messages:[],progress:null}}function vd(e,t){let r=`live-${Date.now()}`,a={};for(let s of Object.keys(e.tasks))a[s]=_d();let n={status:"running",tasks:a,availableOutputs:[],stuckDetection:{is_stuck:!1,stuck_description:null,outputs_unresolvable:[],tasks_blocked:[]},lastUpdated:new Date().toISOString(),executionId:r,executionConfig:{executionMode:e.settings.execution_mode??"eligibility-mode",conflictStrategy:e.settings.conflict_strategy??"alphabetical",completionStrategy:e.settings.completion}};return{config:e,state:n}}function s_(e,t){let{config:r,state:a}=e;if("executionId"in t&&t.executionId&&t.executionId!==a.executionId)return e;switch(t.type){case"task-started":return{config:r,state:e_(a,t.taskName,r)};case"task-completed":return{config:r,state:t_(a,r,t.taskName,t.result,t.dataHash,t.data)};case"task-failed":return{config:r,state:r_(a,r,t.taskName,t.error)};case"task-progress":return{config:r,state:a_(a,t.taskName,t.message,t.progress)};case"task-restart":return{config:r,state:n_(a,t.taskName)};case"inject-tokens":return{config:r,state:{...a,availableOutputs:[...new Set([...a.availableOutputs,...t.tokens])],lastUpdated:new Date().toISOString()}};case"agent-action":return{config:r,state:p_(a,t.action)};case"task-upsert":return i_(e,t.taskName,t.taskConfig);case"task-removal":return u_(e,t.taskName);case"node-requires-add":return c_(e,t.nodeName,t.tokens);case"node-requires-remove":return l_(e,t.nodeName,t.tokens);case"node-provides-add":return d_(e,t.nodeName,t.tokens);case"node-provides-remove":return f_(e,t.nodeName,t.tokens);default:return e}}function o_(e,t){return t.reduce((r,a)=>s_(r,a),e)}function i_(e,t,r){let a=!!e.config.tasks[t];return{config:{...e.config,tasks:{...e.config.tasks,[t]:r}},state:{...e.state,tasks:{...e.state.tasks,[t]:a?e.state.tasks[t]:_d()},lastUpdated:new Date().toISOString()}}}function u_(e,t){if(!e.config.tasks[t])return e;let{[t]:r,...a}=e.config.tasks,{[t]:n,...s}=e.state.tasks;return{config:{...e.config,tasks:a},state:{...e.state,tasks:s,lastUpdated:new Date().toISOString()}}}function c_(e,t,r){let a=e.config.tasks[t];if(!a)return e;let n=$a(a),s=r.filter(o=>!n.includes(o));return s.length===0?e:{config:{...e.config,tasks:{...e.config.tasks,[t]:{...a,requires:[...n,...s]}}},state:e.state}}function l_(e,t,r){let a=e.config.tasks[t];if(!a)return e;let n=$a(a),s=n.filter(o=>!r.includes(o));return s.length===n.length?e:{config:{...e.config,tasks:{...e.config.tasks,[t]:{...a,requires:s}}},state:e.state}}function d_(e,t,r){let a=e.config.tasks[t];if(!a)return e;let n=bt(a),s=r.filter(o=>!n.includes(o));return s.length===0?e:{config:{...e.config,tasks:{...e.config.tasks,[t]:{...a,provides:[...n,...s]}}},state:e.state}}function f_(e,t,r){let a=e.config.tasks[t];if(!a)return e;let n=bt(a),s=n.filter(o=>!r.includes(o));return s.length===n.length?e:{config:{...e.config,tasks:{...e.config.tasks,[t]:{...a,provides:s}}},state:e.state}}function Qo(e){return{version:1,config:e.config,state:e.state,snapshotAt:new Date().toISOString()}}function Ho(e){if(!e||typeof e!="object")throw new Error("Invalid snapshot: expected an object");let t=e;if(!t.config||typeof t.config!="object")throw new Error('Invalid snapshot: missing or invalid "config"');if(!t.state||typeof t.state!="object")throw new Error('Invalid snapshot: missing or invalid "state"');let r=t.config,a=t.state;if(!r.settings||typeof r.settings!="object")throw new Error("Invalid snapshot: config.settings missing");if(!r.tasks||typeof r.tasks!="object")throw new Error("Invalid snapshot: config.tasks missing");if(!a.tasks||typeof a.tasks!="object")throw new Error("Invalid snapshot: state.tasks missing");if(!Array.isArray(a.availableOutputs))throw new Error("Invalid snapshot: state.availableOutputs must be an array");return{config:r,state:a}}function _d(){return{status:"not-started",executionCount:0,retryCount:0,lastEpoch:0,messages:[],progress:null}}function p_(e,t){let r=new Date().toISOString();switch(t){case"stop":return{...e,status:"stopped",lastUpdated:r};case"pause":return{...e,status:"paused",lastUpdated:r};case"resume":return{...e,status:"running",lastUpdated:r};default:return e}}function Zo(e){let{config:t,state:r}=e,a=W0(t);if(Object.keys(a).length===0)return{eligible:[],pending:[],unresolved:[],blocked:[],conflicts:{}};let n=h_(a),s=Q0(t,r.tasks),o=new Set([...s,...r.availableOutputs]),u=[],i=[],c=[],l=[];for(let[w,$]of Object.entries(a)){let h=r.tasks[w],v=X0($,t.settings),m=v!=="once";if(h?.status===Ar.RUNNING||zl(h))continue;let f=Y0($);if(f!==void 0&&h&&h.executionCount>=f||$.circuit_breaker&&h&&h.executionCount>=$.circuit_breaker.max_executions||!m&&h?.status===Ar.COMPLETED)continue;if(m&&h?.status===Ar.COMPLETED){let y=$a($),p=!1;switch(v){case"data-changed":{y.length>0&&y.some(E=>{for(let[j,R]of Object.entries(a))if(bt(R).includes(E)){let C=r.tasks[j];if(!C)continue;let q=h.lastConsumedHashes?.[E];return C.lastDataHash==null?C.executionCount>h.lastEpoch:C.lastDataHash!==q}return!1})||(p=!0);break}case"epoch-changed":{y.length>0&&y.some(E=>{for(let[j,R]of Object.entries(a))if(bt(R).includes(E)){let C=r.tasks[j];if(C&&C.executionCount>h.lastEpoch)return!0}return!1})||(p=!0);break}case"time-based":{let E=$.refreshInterval??0;if(E<=0){p=!0;break}let j=h.completedAt;if(!j){p=!0;break}(Date.now()-Date.parse(j))/1e3<E&&(p=!0);break}case"manual":p=!0;break}if(p)continue}let k=$a($);if(k.length===0){u.push(w);continue}let g=[],S=[],_=[];for(let y of k){if(o.has(y))continue;let p=n[y]||[];p.length===0?g.push(y):p.every(E=>zl(r.tasks[E]))?_.push({token:y,failedProducer:p[0]}):S.push(y)}g.length>0?c.push({taskName:w,missingTokens:g}):_.length>0?l.push({taskName:w,failedTokens:_.map(y=>y.token),failedProducers:[...new Set(_.map(y=>y.failedProducer))]}):S.length>0?i.push({taskName:w,waitingOn:S}):u.push(w)}let d={};if(u.length>1){let w=Z0(u,a);for(let[$,h]of Object.entries(w))h.length>1&&(d[$]=h)}return{eligible:u,pending:i,unresolved:c,blocked:l,conflicts:d}}function h_(e){let t={};for(let[r,a]of Object.entries(e)){for(let n of bt(a))t[n]||(t[n]=[]),t[n].push(r);if(a.on)for(let n of Object.values(a.on))for(let s of n)t[s]||(t[s]=[]),t[s].includes(r)||t[s].push(r);if(a.on_failure)for(let n of a.on_failure)t[n]||(t[n]=[]),t[n].includes(r)||t[n].push(r)}return t}var Ul=class{buffer=[];append(e){this.buffer.push(e)}drain(){let e=this.buffer;return this.buffer=[],e}get size(){return this.buffer.length}};function Bo(e){let t=ei(e);return m_(t)}function ei(e){if(e==null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e))return"["+e.map(ei).join(",")+"]";let t=e;return"{"+Object.keys(t).sort().map(r=>JSON.stringify(r)+":"+ei(t[r])).join(",")+"}"}function m_(e){let t=0xcbf29ce484222325n,r=0x100000001b3n,a=0xffffffffffffffffn;for(let n=0;n<e.length;n++)t^=BigInt(e.charCodeAt(n)),t=t*r&a;return t.toString(16).padStart(16,"0")}function y_(e){if(typeof Buffer<"u")return Buffer.from(e,"utf8").toString("base64url");if(typeof btoa=="function"){let t=new TextEncoder().encode(e),r="";for(let a of t)r+=String.fromCharCode(a);return btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}throw new Error("No base64 encoder available in this runtime")}function g_(e){if(typeof Buffer<"u")return Buffer.from(e,"base64url").toString("utf8");if(typeof atob=="function"){let t=e.replace(/-/g,"+").replace(/_/g,"/"),r=t+"=".repeat((4-t.length%4)%4),a=atob(r),n=new Uint8Array(a.length);for(let s=0;s<a.length;s++)n[s]=a.charCodeAt(s);return new TextDecoder().decode(n)}throw new Error("No base64 decoder available in this runtime")}function Kl(e){let t=JSON.stringify({t:e,n:Date.now().toString(36)+Math.random().toString(36).slice(2,6)});return y_(t)}function v_(e){try{let t=JSON.parse(g_(e));return typeof t?.t=="string"?{taskName:t.t}:null}catch{return null}}function __(e,t,r){let{handlers:a,onNodeRemoved:n,onDrain:s}=t,o=new Ul,u="state"in e&&"config"in e?e:vd(e),i=!1,c=new Set,l=new Map(Object.entries(a)),d=new Ul,w=!1,$=!1;function h(){if(!i){if(w){$=!0;return}w=!0;try{do $=!1,v();while($)}finally{w=!1}}}function v(){let g=d.drain(),S=o.drain(),_=[...g,...S];if(_.length>0&&(u=o_(u,_),n)){for(let p of _)if(p.type==="task-removal")try{n(p.taskName)}catch(E){console.warn("[reactive] onNodeRemoved failed:",E instanceof Error?E.message:String(E))}}let y=Zo(u);_.length>0&&s?.(_,u,y);for(let p of y.eligible)k(p);for(let p of _)if(p.type==="task-progress"){let{taskName:E,update:j}=p;if(!u.config.tasks[E])continue;let R=u.state.tasks[E];if(!R||R.status!=="running")continue;let C=Kl(E),q=f(E,C,j).catch(F=>{i||(d.append({type:"task-failed",taskName:E,error:F.message??String(F),timestamp:new Date().toISOString()}),h())}).finally(()=>{c.delete(q)});c.add(q)}}function m(g){let S=u.config.tasks[g].requires??[],_=new Map;for(let[p,E]of Object.entries(u.config.tasks))for(let j of E.provides??[])_.set(j,p);let y={};for(let p of S){let E=_.get(p);E?y[p]=u.state.tasks[E]?.data:y[p]=void 0}return y}async function f(g,S,_){let y=u.config.tasks[g],p=y.taskHandlers??[],E=m(g);for(let j of p){let R=l.get(j);if(!R)throw new Error(`Handler '${j}' not found in registry (task '${g}')`);let C={nodeId:g,state:E,taskState:u.state.tasks[g],config:y,callbackToken:S,update:_};if(await R(C)==="task-initiate-failure")throw new Error(`Handler '${j}' returned task-initiate-failure (task '${g}')`)}}function k(g){let S=u.config.tasks[g]?.taskHandlers;if(!S||S.length===0)return;d.append({type:"task-started",taskName:g,timestamp:new Date().toISOString()}),h();let _=Kl(g),y=f(g,_).catch(p=>{i||(d.append({type:"task-failed",taskName:g,error:p.message??String(p),timestamp:new Date().toISOString()}),h())}).finally(()=>{c.delete(y)});c.add(y)}return{push(g){i||(g.type==="task-completed"&&g.data&&!g.dataHash&&(g={...g,dataHash:Bo(g.data)}),o.append(g),h())},pushAll(g){if(!i){for(let S of g)S.type==="task-completed"&&S.data&&!S.dataHash?o.append({...S,dataHash:Bo(S.data)}):o.append(S);h()}},resolveCallback(g,S,_){if(i)return;let y=v_(g);if(!y)return;let{taskName:p}=y;if(u.config.tasks[p]){if(_&&_.length>0)o.append({type:"task-failed",taskName:p,error:_.join("; "),timestamp:new Date().toISOString()});else{let E=S&&Object.keys(S).length>0?Bo(S):void 0;o.append({type:"task-completed",taskName:p,data:S,dataHash:E,timestamp:new Date().toISOString()})}h()}},addNode(g,S){i||(o.append({type:"task-upsert",taskName:g,taskConfig:S,timestamp:new Date().toISOString()}),h())},removeNode(g){i||(o.append({type:"task-removal",taskName:g,timestamp:new Date().toISOString()}),h())},addRequires(g,S){i||(o.append({type:"node-requires-add",nodeName:g,tokens:S,timestamp:new Date().toISOString()}),h())},removeRequires(g,S){i||(o.append({type:"node-requires-remove",nodeName:g,tokens:S,timestamp:new Date().toISOString()}),h())},addProvides(g,S){i||(o.append({type:"node-provides-add",nodeName:g,tokens:S,timestamp:new Date().toISOString()}),h())},removeProvides(g,S){i||(o.append({type:"node-provides-remove",nodeName:g,tokens:S,timestamp:new Date().toISOString()}),h())},registerHandler(g,S){l.set(g,S)},unregisterHandler(g){l.delete(g)},retrigger(g){i||u.config.tasks[g]&&(o.append({type:"task-restart",taskName:g,timestamp:new Date().toISOString()}),h())},retriggerAll(g){if(!i){for(let S of g)u.config.tasks[S]&&o.append({type:"task-restart",taskName:S,timestamp:new Date().toISOString()});h()}},snapshot(){return Qo(u)},getState(){return u},getSchedule(){return Zo(u)},async waitForHandlers(){c.size>0&&await Promise.allSettled([...c])},async dispose(g){g?.wait&&c.size>0&&await Promise.allSettled([...c]),i=!0}}}var $_=On(import.meta.url),Cn=$_("./jsonata-sync.cjs"),$d=Cn;function Ll(e,t){if(!t||!e)return;let r=t.split("."),a=e;for(let n=0;n<r.length;n++){if(a==null)return;a=a[r[n]]}return a}function wd(e,t,r){let a=t.split("."),n=e;for(let s=0;s<a.length-1;s++)(n[a[s]]==null||typeof n[a[s]]!="object")&&(n[a[s]]={}),n=n[a[s]];n[a[a.length-1]]=r}async function w_(e,t){if(!e?.compute?.length)return e;e.card_data||(e.card_data={}),e.computed_values={},e._sourcesData=t?.sourcesData??{};let r=e.requires??{},a={card_data:e.card_data,requires:r,expects_data:r,fetched_sources:e._sourcesData,data:e.computed_values,computed_values:e.computed_values};for(let n of e.compute)try{let s=await Cn(n.expr).evaluate(a);wd(e.computed_values,n.bindTo,s),a.computed_values=e.computed_values}catch{}return e}function b_(e,t){if(!e?.compute?.length)return{ok:!0,node:e};e.card_data||(e.card_data={}),e.computed_values={},e._sourcesData=t?.sourcesData??{};let r=e.requires??{},a={card_data:e.card_data,requires:r,expects_data:r,fetched_sources:e._sourcesData,data:e.computed_values,computed_values:e.computed_values},n=[];for(let s of e.compute)try{let o=$d(s.expr).evaluate(a);wd(e.computed_values,s.bindTo,o),a.computed_values=e.computed_values}catch(o){let u=o instanceof Error?o.message:String(o);n.push({bindTo:s.bindTo,error:u})}return n.length>0?{ok:!0,node:e,errors:n}:{ok:!0,node:e}}async function S_(e,t,r){let a={...r??{},card_data:t.card_data??{},requires:t.requires??{},fetched_sources:t._sourcesData??{},computed_values:t.computed_values??{}};return Cn(e).evaluate(a)}function k_(e,t){return t.startsWith("fetched_sources.")?Ll(e._sourcesData??{},t.slice(16)):Ll(e,t)}var Hl=new Set(["metric","table","editable-table","chart","form","filter","list","notes","todo","alert","narrative","badge","text","markdown","ref","custom","actions"]),E_=new Set(["id","meta","requires","provides","view","card_data","compute","source_defs"]);function P_(e){let t=[];if(!e||typeof e!="object"||Array.isArray(e))return{ok:!1,errors:["Node must be a non-null object"]};let r=e;(typeof r.id!="string"||!r.id)&&t.push("id: required, must be a non-empty string");for(let a of Object.keys(r))E_.has(a)||t.push(`Unknown top-level key: "${a}"`);if((r.card_data==null||typeof r.card_data!="object"||Array.isArray(r.card_data))&&t.push("card_data: required, must be an object"),r.meta!=null)if(typeof r.meta!="object"||Array.isArray(r.meta))t.push("meta: must be an object");else{let a=r.meta;a.title!=null&&typeof a.title!="string"&&t.push("meta.title: must be a string"),a.tags!=null&&!Array.isArray(a.tags)&&t.push("meta.tags: must be an array")}if(r.requires!=null&&!Array.isArray(r.requires)&&t.push("requires: must be an array of strings"),r.provides!=null&&(Array.isArray(r.provides)?r.provides.forEach((a,n)=>{if(!a||typeof a!="object"||Array.isArray(a))t.push(`provides[${n}]: must be an object with bindTo and ref`);else{let s=a;(typeof s.bindTo!="string"||!s.bindTo)&&t.push(`provides[${n}]: missing required "bindTo" string`),(typeof s.ref!="string"||!s.ref)&&t.push(`provides[${n}]: missing required "ref" string`)}}):t.push("provides: must be an array of { bindTo, ref } bindings")),r.compute!=null&&(Array.isArray(r.compute)?r.compute.forEach((a,n)=>{if(!a||typeof a!="object"||Array.isArray(a))t.push(`compute[${n}]: must be a compute step object`);else{let s=a;(typeof s.bindTo!="string"||!s.bindTo)&&t.push(`compute[${n}]: missing required "bindTo" property`),(typeof s.expr!="string"||!s.expr)&&t.push(`compute[${n}]: missing required "expr" string (JSONata expression)`)}}):t.push("compute: must be an array of compute steps")),r.source_defs!=null)if(!Array.isArray(r.source_defs))t.push("source_defs: must be an array");else{let a=new Set,n=new Set;r.source_defs.forEach((s,o)=>{if(!s||typeof s!="object"||Array.isArray(s))t.push(`source_defs[${o}]: must be an object`);else{let u=s;typeof u.bindTo!="string"||!u.bindTo?t.push(`source_defs[${o}]: missing required "bindTo" property`):(a.has(u.bindTo)&&t.push(`source_defs[${o}]: bindTo "${u.bindTo}" is not unique across source_defs`),a.add(u.bindTo)),typeof u.outputFile!="string"||!u.outputFile?t.push(`source_defs[${o}]: missing required "outputFile" property`):(n.has(u.outputFile)&&t.push(`source_defs[${o}]: outputFile "${u.outputFile}" is not unique across source_defs`),n.add(u.outputFile)),u.optionalForCompletionGating!=null&&typeof u.optionalForCompletionGating!="boolean"&&t.push(`source_defs[${o}]: optionalForCompletionGating must be a boolean`)}})}if(r.view!=null)if(typeof r.view!="object"||Array.isArray(r.view))t.push("view: must be an object");else{let a=r.view;!Array.isArray(a.elements)||a.elements.length===0?t.push("view.elements: required, must be a non-empty array"):a.elements.forEach((n,s)=>{if(!n||typeof n!="object"){t.push(`view.elements[${s}]: must be an object`);return}!n.kind||typeof n.kind!="string"?t.push(`view.elements[${s}].kind: required, must be a string`):Hl.has(n.kind)||t.push(`view.elements[${s}].kind: unknown kind "${n.kind}". Valid: ${[...Hl].join(", ")}`),n.data!=null&&(typeof n.data!="object"||Array.isArray(n.data))&&t.push(`view.elements[${s}].data: must be an object`)}),a.layout!=null&&(typeof a.layout!="object"||Array.isArray(a.layout))&&t.push("view.layout: must be an object"),a.features!=null&&(typeof a.features!="object"||Array.isArray(a.features))&&t.push("view.features: must be an object")}return{ok:t.length===0,errors:t}}async function j_(e,t){if(!e||e.length===0)return[];let r={card_data:t.card_data??{},requires:t.requires??{}};return Promise.all(e.map(async a=>{let n={};if(a.projections&&typeof a.projections=="object"&&!Array.isArray(a.projections)){for(let[s,o]of Object.entries(a.projections))if(typeof o=="string"&&o.trim().length>0)try{n[s]=await Cn(o).evaluate(r)}catch{n[s]=void 0}}return{...a,_projections:n}}))}function O_(e,t){if(!e||e.length===0)return[];let r={card_data:t.card_data??{},requires:t.requires??{}};return e.map(a=>{let n={};if(a.projections&&typeof a.projections=="object"&&!Array.isArray(a.projections)){for(let[s,o]of Object.entries(a.projections))if(typeof o=="string"&&o.trim().length>0)try{n[s]=$d(o).evaluate(r)}catch{n[s]=void 0}}return{...a,_projections:n}})}var qr={run:w_,runSync:b_,eval:S_,resolve:k_,validate:P_,enrichSources:j_,enrichSourcesSync:O_};function N_(e){return JSON.stringify(e)}function T_(e){let t;try{t=JSON.parse(e)}catch{throw new Error(`parseExecutionRef: invalid JSON \u2014 ${e}`)}if(typeof t!="object"||t===null||typeof t.howToRun!="string"||typeof t.whatToRun!="string")throw new Error(`parseExecutionRef: missing required fields howToRun/whatToRun \u2014 ${e}`);return t}function bd(e,t){function r(){return e.readIndex()??{}}function a(n,s,o){let u=String(s||"").split(".").filter(Boolean);if(u.length===0)return o&&typeof o=="object"&&!Array.isArray(o)?o:{value:o};let i={...n},c=i;for(let l=0;l<u.length-1;l++){let d=u[l],w=c[d],$=w&&typeof w=="object"&&!Array.isArray(w)?{...w}:{};c[d]=$,c=$}return c[u[u.length-1]]=o,i}return{readCard(n){let s=r()[n];return!s||!e.cardExists(s.key)?null:e.readCard(s.key)},readCardKey(n){return r()[n]?.key??null},readAllCards(){let n=[];for(let[s,o]of Object.entries(r())){if(!e.cardExists(o.key))continue;let u=e.readCard(o.key);u?n.push(u):t?.(`[card-store] could not read card "${s}" at key "${o.key}"`)}return n},readChecksumIndex(){let n={};for(let[s,o]of Object.entries(r()))n[s]=o.checksum;return n},changedSince(n){let s=r(),o=[];for(let[u,i]of Object.entries(s))n[u]!==i.checksum&&o.push(u);for(let u of Object.keys(n))s[u]||o.push(u);return o},validateUpsert(n,s){let o=r(),u=o[n],i=Object.entries(o).find(([,c])=>c.key===s);return u&&u.key!==s?{ok:!1,error:`Card id "${n}" is already mapped to key "${u.key}", cannot remap to "${s}"`}:i&&i[0]!==n?{ok:!1,error:`Key "${s}" is already mapped to card id "${i[0]}", cannot remap to "${n}"`}:{ok:!0}},writeCard(n,s,o){let u=r(),i=o??u[n]?.key??e.defaultCardKey(n),c=e.writeCard(i,s);u[n]={key:i,checksum:c,updatedAt:new Date().toISOString()},e.writeIndex(u)},patchCard(n,s,o){let u=r(),i=u[n];if(!i||!e.cardExists(i.key))throw new Error(`card "${n}" not found`);let c=e.readCard(i.key);if(!c||typeof c!="object"||Array.isArray(c))throw new Error(`card "${n}" is not patchable`);let l=a(c,s,o),d=e.writeCard(i.key,l);u[n]={key:i.key,checksum:d,updatedAt:new Date().toISOString()},e.writeIndex(u)},removeCard(n){let s=r(),o=s[n];o&&(e.removeCard(o.key),delete s[n],e.writeIndex(s))},readIndex(){return r()}}}function Jo(e,t){return{readSourceData(r,a){let n=e.read(`${r}/${a}`);if(n==null)return null;let s=n.trim();if(!s)return null;try{return JSON.parse(s)}catch{return s}},ingestSourceDataStaged(r,a,n,s){let o=t(n);e.write(`${r}/.staged/${s}/${a}`,o)},commitSourceData(r,a,n){let s=`${r}/.staged/${n}/${a}`,o=e.read(s);return o==null?!1:(e.write(`${r}/${a}`,o),e.remove(s),!0)},hasSource(r,a){return e.exists(`${r}/${a}`)},listSources(r){return e.listKeys(`${r}/`).filter(a=>!a.includes("/.staged/")).map(a=>a.slice(`${r}/`.length))}}}function R_(e){function t(r){let a=e.readAllEntries();if(!r)return a;let n=a.findIndex(s=>s.id===r);return n===-1?a:a.slice(n+1)}return{readEntriesAfterCursor(r){let a=t(r);return a.length===0?{events:[],newCursor:r}:{events:a.map(n=>n.event),newCursor:a[a.length-1].id}},pendingCount(r){return t(r).length},appendEvent(r){e.appendEntry({id:e.generateId(),event:r})}}}function x_(e,t){return{appendEntries(r,a){if(!r||a.length===0)return;let n=e.read(r)??[];e.write(r,[...n,...a])},dispatchEntriesForJournalId(r,a){if(!r)return;let n=e.read(r);if(!(!n||n.length===0)){for(let s of n)try{a(s)}catch(o){let u=o instanceof Error?o.message:String(o);try{t(s,u)}catch{}}e.delete(r)}}}}var Sd="v1",wa="board/graph",kd="board/lastJournalProcessedId";function Bl(e){return`cards/${e}/runtime`}function I_(e){return{readRuntime(t){return e.read(Bl(t))??{_sources:{}}},writeRuntime(t,r){e.write(Bl(t),r)}}}function C_(e,t){let r={...e};for(let a of t.deleteKeys)delete r[a];return{...r,...t.shallowMerge}}function A_(e){return{readSnapshot(t){return e.readValues(t)},commitSnapshot(t,r){if(r.schemaVersion!==Sd)throw new Error(`Unsupported snapshot schema version: ${r.schemaVersion}`);let a=e.readValues(t);if(a.version!==r.expectedVersion)return{ok:!1,reason:"version-mismatch",currentVersion:a.version};let n=C_(a.values,r);return{ok:!0,newVersion:e.writeValues(t,n,r.deleteKeys)}}}}function ii(e){function t(r){let a=e.read(r);return a==null?null:typeof a=="string"?a:JSON.stringify(a)}return{readTaskExecutorRef(){let r=t("task-executor");if(r?.trim())return T_(r.trim())},writeTaskExecutorRef(r){e.write("task-executor",N_(r))},readChatHandlerFlow(){return e.read("chat-handler-flow")},writeChatHandlerFlow(r){e.write("chat-handler-flow",r)},readCardStoreRef(){return t("card-store-ref")},writeCardStoreRef(r){e.write("card-store-ref",r)},readOutputsStoreRef(){return t("outputs-store-ref")},writeOutputsStoreRef(r){e.write("outputs-store-ref",r)},readScratchStoreRef(){return t("scratch-store-ref")},writeScratchStoreRef(r){e.write("scratch-store-ref",r)},readArchiveStoreRef(){return t("archive-store-ref")},writeArchiveStoreRef(r){e.write("archive-store-ref",r)},readChatStoreRef(){return t("chat-store-ref")},writeChatStoreRef(r){e.write("chat-store-ref",r)},readArtifactsStoreRef(){return t("artifacts-store-ref")},writeArtifactsStoreRef(r){e.write("artifacts-store-ref",r)}}}function q_(e){return{writeComputedValues(t,r){e.write(`cards/${t}/computed_values`,r)},readComputedValues(t){return e.read(`cards/${t}/computed_values`)},readAllComputedValues(){let t={};for(let r of e.listKeys("cards/")){let a=r.match(/^cards\/([^/]+)\/computed_values$/);a&&(t[a[1]]=e.read(r))}return t},writeDataObjects(t){for(let[r,a]of Object.entries(t))r&&e.write(`data-objects/${r}`,a)},readDataObject(t){return e.read(`data-objects/${t}`)},readAllDataObjects(){let t={};for(let r of e.listKeys("data-objects/"))t[r.slice(13)]=e.read(r);return t},writeStatusSnapshot(t){e.write("status",t)},readStatusSnapshot(){return e.read("status")}}}function Jl(e){return e?{lastRequestedToken:e.lastRequestedToken,lastCompletedToken:e.lastCompletedToken,lastCompletionStatus:e.lastCompletionStatus??(e.lastCompletedToken?"success":"not-started"),queueRequestedToken:e.queueRequestedToken}:{lastCompletionStatus:"not-started"}}function D_(e){return e?.lastRequestedToken?e.lastCompletedToken!==e.lastRequestedToken:!1}function Gl(e,t){return e?.lastRequestedToken?D_(e)?"in-flight":!e.lastCompletedToken||e.lastCompletedToken<t?"dispatch":"idle":"dispatch"}function M_(e,t){return{...e,lastCompletedToken:t,lastCompletionStatus:"success"}}function Wl(e,t){return{...e,lastCompletedToken:t,lastCompletionStatus:"failure"}}function Go(e,t){let r=t.state.tasks,a=t.config.tasks,n=Object.keys(r),s=Zo(t),o={completed:0,failed:0,in_progress:0,pending:0,blocked:0,unresolved:0},u=new Map;for(let h of s.pending)u.set(h.taskName,h.waitingOn);for(let h of s.unresolved)u.set(h.taskName,h.missingTokens);for(let h of s.blocked)u.set(h.taskName,h.failedTokens);let i=new Map;for(let[h,v]of Object.entries(a))for(let m of v.requires??[]){let f=i.get(m)??[];f.push(h),i.set(m,f)}let c=n.sort().map(h=>{let v=r[h],m=a[h]??{requires:[],provides:[]};v.status==="completed"?o.completed+=1:v.status==="failed"?o.failed+=1:v.status==="in-progress"&&(o.in_progress+=1);let f=m.requires??[],k=m.provides??[],g=Object.keys(v.data??{}).sort(),S=f.filter(R=>t.state.availableOutputs.includes(R)),_=f.filter(R=>!t.state.availableOutputs.includes(R)),y=u.get(h)??_,p=new Set;for(let R of k)for(let C of i.get(R)??[])C!==h&&p.add(C);let E=v.failedAt,j=v.error?{message:v.error,code:"TASK_FAILED",at:E,source:"task-runtime"}:void 0;return{name:h,status:v.status,error:j,requires:f,requires_satisfied:S,requires_missing:_,provides_declared:k,provides_runtime:g,blocked_by:y,unblocks:Array.from(p).sort(),runtime:{attempt_count:v.executionCount??0,restart_count:v.retryCount??0,in_progress_since:v.status==="in-progress"?v.startedAt??null:null,last_transition_at:v.lastUpdated??null,last_completed_at:v.completedAt??null,last_restarted_at:v.startedAt??null,status_age_ms:v.lastUpdated?0:null}}});o.pending=s.pending.length,o.blocked=s.blocked.length,o.unresolved=s.unresolved.length;let l=c.map(h=>({name:h.name,fanOut:h.unblocks.length})).sort((h,v)=>v.fanOut-h.fanOut||h.name.localeCompare(v.name)),d=l.length>0?l[0]:{name:null,fanOut:0},w=new Set;for(let h of Object.values(a))for(let v of h.requires??[])w.add(v);let $=0;for(let[h,v]of Object.entries(a)){let m=(v.requires??[]).length===0,f=(v.provides??[]).some(k=>(i.get(k)??[]).some(g=>g!==h));m&&!f&&($+=1)}return{schema_version:"v1",meta:{board:{path:e}},summary:{card_count:n.length,completed:o.completed,eligible:s.eligible.length,pending:o.pending,blocked:o.blocked,unresolved:o.unresolved,failed:o.failed,in_progress:o.in_progress,orphan_cards:$,topology:{edge_count:Array.from(w).length,max_fan_out_card:d.name,max_fan_out:d.fanOut}},cards:c}}function F_(){return new Date().toISOString()}function V_(e,t,r,a,n,s,o){return async u=>{let i=[],c=r.cardStore.readCard(u.nodeId);if(!c)return"task-initiate-failure";let l=c.id,d=c.card_data??{},w=c.source_defs??[],$=w.filter(M=>M.optionalForCompletionGating!==!0),h=r.cardRuntimeStore.readRuntime(l),v=!1,m=()=>{v&&(r.cardRuntimeStore.writeRuntime(l,h),v=!1)},f=M=>Jl(h._sources[M]),k=(M,U)=>{h._sources[M]=Jl(U),v=!0},g=u.taskState?.executionCount??0;if(h._lastExecutionCount!==g&&(h._sources={},h._lastExecutionCount=g,v=!0),u.update){let M=u.update,U=M.outputFile;if(U){let G=f(U);if(M.failure){let re=M.rqt??G.lastRequestedToken??G.queueRequestedToken;re&&k(U,Wl(G,re))}else{let re=M.rqt;if(!G.lastCompletedToken||re>G.lastCompletedToken){let W=typeof M.deliveryToken=="string"?M.deliveryToken:void 0,T=!1;W&&(T=r.fetchedSourcesStore.commitSourceData(l,U,W)),T?k(U,M_(G,re)):k(U,Wl(G,re))}}m()}}let S={};for(let M of w)if(M.outputFile){let U=r.fetchedSourcesStore.readSourceData(l,M.outputFile);U!==null&&(S[M.bindTo]=U)}let _={};for(let[M,U]of Object.entries(u.state??{}))if(U!==null&&typeof U=="object"&&!Array.isArray(U)){let G=U[M];_[M]=G!==void 0?G:U}else _[M]=U;let y={id:l,card_data:{...d},requires:_,source_defs:w,compute:c.compute};y._sourcesData=S,c.compute&&qr.runSync(y,{sourcesData:S}),(s??r.outputStore.writeComputedValues.bind(r.outputStore))(l,y.computed_values??{});let p={...c},E=qr.enrichSourcesSync(Array.isArray(c.source_defs)?c.source_defs:void 0,{card_data:c.card_data,requires:_}),j=e.value;p.source_defs=Array.isArray(E)?E.map(M=>({...M,boardDir:typeof M.boardDir=="string"&&M.boardDir?M.boardDir:j})):E;let R=F_(),C=u.update?void 0:R,q=$.filter(M=>{let U=M.outputFile;if(typeof U!="string"||!U)return!0;let G=f(U);C&&(G={...G,queueRequestedToken:C},k(U,G));let re=G.queueRequestedToken??G.lastRequestedToken??R,W=Gl(G,re);return W==="in-flight"?!1:W==="dispatch"});if(m(),q.length>0){let M=!1,U=R;for(let G of q){let re=G.outputFile;if(typeof re!="string"||!re)continue;let W=f(re),T=W.queueRequestedToken??R;k(re,{...W,lastRequestedToken:T}),U=T,M=!0}return M&&m(),M&&(i.push({taskKind:"source-fetch",payload:{boardRef:ze(e),enrichedCard:p,callbackToken:u.callbackToken,rqt:U}}),r.executionRequestStore.appendEntries(t,i)),"task-initiated"}if($.some(M=>{let U=M.outputFile;if(typeof U!="string"||!U)return!1;let G=f(U),re=G.queueRequestedToken??G.lastRequestedToken??R;return Gl(G,re)==="in-flight"}))return"task-initiated";let F=c.provides??[],L={};for(let{bindTo:M,ref:U}of F)L[M]=qr.resolve(y,U);return(o??r.outputStore.writeDataObjects.bind(r.outputStore))(L),w.filter(M=>{if(M.optionalForCompletionGating!==!0)return!1;let U=f(M.outputFile);return!U.lastRequestedToken||!U.lastCompletedToken?!0:U.lastCompletedToken<=U.lastRequestedToken}).length>0&&i.push({taskKind:"source-fetch",payload:{boardRef:ze(e),enrichedCard:p,callbackToken:u.callbackToken,rqt:R}}),a(u.nodeId,L),i.length>0&&r.executionRequestStore.appendEntries(t,i),"task-initiated"}}var z_={settings:{completion:"manual",refreshStrategy:"data-changed"},tasks:{}};function U_(e){return{[wa]:e.graph,[kd]:e.lastDrainedJournalId}}function K_(e){let t=e[wa],r=e[kd];if(!t||typeof t!="object")throw new Error(`State snapshot is missing required key: ${wa}`);return{graph:t,lastDrainedJournalId:typeof r=="string"?r:""}}function L_(e){let t=e.requires,r=e.provides?.map(a=>a.bindTo)??[];return{requires:t&&t.length>0?t:void 0,provides:r,taskHandlers:["card-handler"],description:e.meta?.title??e.id}}function H_(e){function t(s){return{status:"success",data:s}}function r(s){return{status:"fail",error:s}}function a(s){return{status:"error",error:s instanceof Error?s.message:String(s)}}function n(s){if(Array.isArray(s))return s;if(s&&typeof s=="object"){let o=s;return Array.isArray(o.files)?o.files:[s]}return null}return{get(s){try{let o=s.params?.id;if(o){let u=e.readCard(o);return u?t({cards:[u]}):r(`card "${o}" not found`)}return t({cards:e.readAllCards()})}catch(o){return a(o)}},set(s){try{let o=s.body;if(o==null)return r("set requires a body (card object or array of cards)");let u=Array.isArray(o)?o:[o];for(let i of u){if(typeof i.id!="string")return r("each card must have a string `id` field");e.writeCard(i.id,i)}return t({count:u.length})}catch(o){return a(o)}},del(s){try{let o=s.body?.ids??[],u=s.params?.id,i=u?[...o,u]:o;if(i.length===0)return r("del requires body.ids (string[]) or params.id");for(let c of i)e.removeCard(c);return t({count:i.length})}catch(o){return a(o)}},patch(s){try{let o=s.params?.id,u=s.params?.path;if(!o)return r("patch requires params.id");if(!u)return r("patch requires params.path");let i=s.body,c=i&&Object.prototype.hasOwnProperty.call(i,"value")?i.value:s.body;return e.patchCard(o,u,c),t({count:1})}catch(o){return a(o)}},appendFiles(s){try{let o=s.params?.id;if(!o)return r("appendFiles requires params.id");let u=e.readCard(o);if(!u)return r(`card "${o}" not found`);let i=n(s.body);if(!i||i.length===0)return r("appendFiles requires a file metadata object, array, or body.files array");let c=u.card_data&&typeof u.card_data=="object"&&!Array.isArray(u.card_data)?u.card_data:{},l=Array.isArray(c.files)?c.files:[],d=[...l,...i],w=i.map((h,v)=>({idx:l.length+v,entry:h})),$=this.patch({params:{id:o,path:"card_data.files"},body:{value:d}});return $.status!=="success"?$:t({files_added:w})}catch(o){return a(o)}}}}function pe(e){return e!==void 0?{status:"success",data:e}:{status:"success"}}function ne(e){return{status:"fail",error:e}}function me(e){return{status:"error",error:e instanceof Error?e.message:String(e)}}function B_(e){let t=new TextEncoder().encode(e),r=Array.from(t,a=>String.fromCharCode(a)).join("");return btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function Ed(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),r=t+"=".repeat((4-t.length%4)%4),a=atob(r),n=Uint8Array.from(a,s=>s.charCodeAt(0));return new TextDecoder().decode(n)}function bn(e){try{let t=JSON.parse(Ed(e));return typeof t?.t=="string"?{taskName:t.t}:null}catch{return null}}function J_(e){return B_(JSON.stringify(e))}function Xl(e){try{let t=JSON.parse(Ed(e));return typeof t?.cbk=="string"&&typeof t?.cid=="string"&&typeof t?.b=="string"&&typeof t?.d=="string"?t:null}catch{return null}}function He(){return new Date().toISOString()}function Wo(e,t){let r=t.onWarn??(()=>{}),a=ze(e);function n(z){if(z.length!==0)try{let b=t.publishBoardChangeNotifications?.(z);b&&typeof b.catch=="function"&&b.catch(N=>r(`[board-live-cards-public] publishBoardChangeNotifications failed: ${N instanceof Error?N.message:String(N)}`))}catch(b){r(`[board-live-cards-public] publishBoardChangeNotifications failed: ${b instanceof Error?b.message:String(b)}`)}}function s(){let z=u().readCardStoreRef();if(!z)throw new Error(`Board at ${e.value} has no card store configured. Run: init --base-ref <ref> --store-ref <b64-ref>`);let b=t.kvStorageForRef(z);return{readIndex(){return b.read("_index")},writeIndex(N){b.write("_index",N)},readCard(N){return b.read(N)},writeCard(N,x){return b.write(N,x),t.hashFn(x)},removeCard(N){b.delete(N)},cardExists(N){return b.read(N)!==null},defaultCardKey(N){return N}}}let o={readValues(z){let b=t.kvStorage("state-snapshot"),N=b.listKeys().sort();if(N.length===0)return{version:null,values:{}};let x={};for(let K of N)x[K]=b.read(K);return{version:t.hashFn(x),values:x}},writeValues(z,b,N){let x=t.kvStorage("state-snapshot");for(let K of N)x.delete(K);for(let[K,J]of Object.entries(b))x.write(K,J);return t.hashFn(b)}},u=()=>ii(t.kvStorage("config")),i=()=>A_(o),c=()=>R_(t.journalAdapter()),l=()=>bd(s(),r),d=()=>{let z=u().readOutputsStoreRef();if(!z)throw new Error(`Board at ${e.value} has no outputs store configured. Run: init --outputs-store-ref <b64-ref>`);return q_(t.kvStorageForRef(z))},w=()=>{let z=u().readArchiveStoreRef();return z?t.archiveFactoryForRef(z):t.archiveFactory()};function $(){return!!i().readSnapshot(e.value).values[wa]}function h(){let z=i().readSnapshot(e.value);if(!z.values[wa])throw new Error(`Board not initialized at ${e.value}`);return K_(z.values)}function v(z,b){let N=i().commitSnapshot(e.value,{schemaVersion:Sd,expectedVersion:b,commitId:t.genId(),committedAt:He(),deleteKeys:[],shallowMerge:U_(z)});if(!N.ok)throw new Error(`Snapshot commit failed (version mismatch): expected=${b??"null"} current=${N.currentVersion??"null"}`)}function m(z){c().appendEvent(z)}async function f(){let z=(Y,se)=>{let je=Y.payload,kt=(je?.enrichedCard??{}).id??je?.cardId??"unknown";m({type:"task-failed",taskName:kt,error:se,timestamp:He()})},b=x_(t.kvStorage("execution-requests"),z),N=I_(t.kvStorage("card-runtime")),x=Jo(t.blobStorage("sources"),Y=>t.resolveBlob(Y)),K=new Map,J={readRuntime(Y){return K.get(Y)??N.readRuntime(Y)},writeRuntime(Y,se){K.set(Y,se)}},ae=[],le=new Map,Se={readSourceData(Y,se){let je=`${Y}/${se}`;return le.has(je)?le.get(je):x.readSourceData(Y,se)},ingestSourceDataStaged(Y,se,je,kt){x.ingestSourceDataStaged(Y,se,je,kt)},commitSourceData(Y,se,je){let kt=`${Y}/.staged/${je}/${se}`,it=t.blobStorage("sources").read(kt);if(it==null)return!1;let ka=`${Y}/${se}`,fr=it.trim();try{le.set(ka,JSON.parse(fr))}catch{le.set(ka,fr)}return ae.push({cardId:Y,outputFile:se,deliveryToken:je}),!0},hasSource(Y,se){let je=`${Y}/${se}`;return le.has(je)?!0:x.hasSource(Y,se)},listSources(Y){let se=x.listSources(Y),je=new Set;for(let it of le.keys())it.startsWith(`${Y}/`)&&je.add(it.slice(`${Y}/`.length));let kt=new Set([...se,...je]);return Array.from(kt)}},Ee={cardStore:l(),cardRuntimeStore:J,fetchedSourcesStore:Se,outputStore:d(),executionRequestStore:b},Ie=h(),Pe=Ho(Ie.graph),{events:Ze,newCursor:qe}=c().readEntriesAfterCursor(Ie.lastDrainedJournalId),ot=[],St=[],Jt=[],lr=new Map,Dr=new Set,An=(Y,se)=>{ot.push({type:"task-completed",taskName:Y,data:se,timestamp:He()});try{w().stream("exec-history").append({taskName:Y,status:"completed",completedAt:He()})}catch{}},ui=(Y,se)=>{m({type:"task-failed",taskName:Y,error:se,timestamp:He()});try{w().stream("exec-history").append({taskName:Y,status:"failed",error:se,completedAt:He()})}catch{}},ba=__(Pe,{handlers:{"card-handler":V_(e,qe,Ee,An,ui,(Y,se)=>{St.push({cardId:Y,values:se})},Y=>{Jt.push(Y)})},onNodeRemoved:Y=>{lr.delete(Y),K.delete(Y),Dr.add(Y)}});for(ot=Ze;ot.length>0;){let Y=ot;ot=[];for(let se of Y)if(se.type==="task-restart"){let je=Ee.cardStore.readCard(se.taskName);je&&lr.set(se.taskName,je)}ba.pushAll(Y),await ba.waitForHandlers()}let ci=ba.getState();await ba.dispose({wait:!0});let jd=i().readSnapshot(e.value).version;v({lastDrainedJournalId:qe,graph:Qo(ci)},jd);for(let{cardId:Y,values:se}of St)Ee.outputStore.writeComputedValues(Y,se);for(let Y of Jt)Ee.outputStore.writeDataObjects(Y);for(let[Y,se]of K)N.writeRuntime(Y,se);for(let{cardId:Y,outputFile:se,deliveryToken:je}of ae)x.commitSourceData(Y,se,je);let Sa;try{Sa=Go(a,ci),Ee.outputStore.writeStatusSnapshot(Sa)}catch(Y){r(`[board-live-cards-public] status publish failed: ${Y instanceof Error?Y.message:String(Y)}`)}let dr=[];for(let{cardId:Y,values:se}of St)dr.push({kind:"computed_values",cardId:Y,values:se});for(let Y of Jt)for(let[se,je]of Object.entries(Y))se&&dr.push({kind:"data_object",key:se,payload:je});for(let[Y,se]of lr)dr.push({kind:"card_refreshed",cardId:Y,card:se});for(let Y of Dr)dr.push({kind:"card_removed",cardId:Y});Sa!==void 0&&dr.push({kind:"status",status:Sa}),n(dr);let Od=u().readTaskExecutorRef()??{howToRun:"built-in",whatToRun:ze({kind:"built-in",value:"source-cli-task-executor"})};b.dispatchEntriesForJournalId(qe,Y=>{if(Y.taskKind!=="source-fetch"){r(`[process-accumulated-events] unknown taskKind "${Y.taskKind}" \u2014 skipping`);return}let se=Y.payload,je=se.enrichedCard?.id??"unknown",kt=se.enrichedCard?.source_defs??[];for(let it of kt){if(!it.outputFile){r(`[dispatch] source "${it.bindTo}" has no outputFile \u2014 skipping`);continue}let ka=J_({cbk:se.callbackToken,rg:e.value,br:ze(e),cid:je,b:it.bindTo,d:it.outputFile,cs:void 0,rqt:se.rqt});t.dispatchExecution(Od,{source_def:it,base_ref:ze(e),callback:{token:ka,via:t.selfRef}}).catch(fr=>ui(je,fr instanceof Error?fr.message:String(fr)))}})}async function k(){try{let z=()=>{let N=h(),{events:x}=c().readEntriesAfterCursor(N.lastDrainedJournalId);x.length<=0||(k(),t.requestProcessAccumulated?.())},b=await i0(t.lock,f,z);return pe({ran:b!==!1})}catch(z){return me(z)}}function g(){k(),t.requestProcessAccumulated?.()}function S(z){try{let b=z.params?.cardStoreRef;if(!b)return ne("init requires params.cardStoreRef \u2014 create a card store with card-store-cli and pass its ref here");if(!$()){let Ee=vd(z_);v({lastDrainedJournalId:"",graph:Qo(Ee)},null)}let N=z.params?.outputsStoreRef;if(!N)return ne("init requires params.outputsStoreRef \u2014 pass the outputs store ref here");let x=z.params?.scratchStoreRef,K=z.params?.archiveStoreRef,J=z.params?.chatStoreRef,ae=z.params?.artifactsStoreRef,le=u();le.writeCardStoreRef(b),le.writeOutputsStoreRef(N),x&&le.writeScratchStoreRef(x),K&&le.writeArchiveStoreRef(K),J&&le.writeChatStoreRef(J),ae&&le.writeArtifactsStoreRef(ae);let Se=z.body??{};Se["task-executor-ref"]&&le.writeTaskExecutorRef(Se["task-executor-ref"]),Object.prototype.hasOwnProperty.call(Se,"chat-handler-flow")&&le.writeChatHandlerFlow(Se["chat-handler-flow"]);try{d().writeStatusSnapshot(Go(a,Ho(h().graph)))}catch{}return pe()}catch(b){return me(b)}}function _(z){try{let b=d().readStatusSnapshot();if(!b){b=Go(a,Ho(h().graph));try{d().writeStatusSnapshot(b)}catch{}}return pe(b)}catch(b){return me(b)}}function y(z){try{let b=z.params?.id;return b?(m({type:"task-removal",taskName:b,timestamp:He()}),g(),pe()):ne("removeCard requires params.id")}catch(b){return me(b)}}function p(z){try{let b=z.params?.cardId;if(!b)return ne("addCardFiles requires params.cardId");let N=H_(l()).appendFiles({params:{id:b},body:z.body});if(N.status!=="success")return N;let x=E({params:{cardId:b}});return x.status!=="success"?x:pe({cardId:b,files_added:N.data.files_added,notified:!0})}catch(b){return me(b)}}function E(z){try{let b=z.params?.cardId;if(!b)return ne("cardRefreshedNotify requires params.cardId");let N=l().readCard(b);return N?(n([{kind:"card_refreshed",cardId:b,card:N}]),pe({cardId:b,notified:!0})):ne(`Card "${b}" not found in board at ${e.value}`)}catch(b){return me(b)}}function j(z){try{let b=z.params?.id;return b?(m({type:"task-restart",taskName:b,timestamp:He()}),g(),pe()):ne("retrigger requires params.id")}catch(b){return me(b)}}async function R(z){return k()}function C(z){try{let b=z.params?.cardId,N=z.params?.all,x=!!z.params?.restart;if(!b&&!N)return ne("upsertCard requires --card-id <id> or --all");let K=N?l().readAllCards().map(J=>J.id):[b];for(let J of K)if(!l().readCard(J))return ne(`Card "${J}" not found in board at ${e.value}`);for(let J of K){let ae=l().readCard(J),le=L_(ae),Se=t.hashFn(le),Ee=t.kvStorage("card-upsert"),Ie=Ee.read(J),Pe=Ie?.taskConfigHash!==Se;if(!(!Pe&&!x)){if(Pe){let Ze=Ie?.blobRef??l().readCardKey(J)??J;m({type:"task-upsert",taskName:J,taskConfig:le,timestamp:He()}),Ee.write(J,{blobRef:Ze,taskConfigHash:Se,updatedAt:He()})}x&&m({type:"task-restart",taskName:J,timestamp:He()})}}return g(),pe()}catch(b){return me(b)}}function q(z){try{let b=z.params?.token;if(!b)return ne("taskFailed requires params.token");let N=z.params?.error??"unknown error",x=bn(b);if(!x)return ne("Invalid callback token");m({type:"task-failed",taskName:x.taskName,error:N,timestamp:He()});try{w().stream("exec-history").append({taskName:x.taskName,status:"failed",error:N,completedAt:He()})}catch{}return g(),pe()}catch(b){return me(b)}}function F(z){try{let b=z.params?.token;if(!b)return ne("taskProgress requires params.token");let N=(z.body??{}).update??{},x=bn(b);return x?(m({type:"task-progress",taskName:x.taskName,update:N,timestamp:He()}),g(),pe()):ne("Invalid callback token")}catch(b){return me(b)}}function L(z){try{let b=z.params?.token,N=z.params?.ref;if(!b)return ne("sourceDataFetched requires params.token");if(!N)return ne("sourceDataFetched requires params.ref");let x=Xl(b);if(!x)return ne("Invalid source token");let{cbk:K,cid:J,b:ae,d:le,cs:Se,rqt:Ee}=x,Ie=Jo(t.blobStorage("sources"),ot=>t.resolveBlob(ot)),Pe=t.genId();Ie.ingestSourceDataStaged(J,le,ht(N),Pe);let Ze=bn(K);if(!Ze)return ne("Invalid callback token embedded in source token");let qe=He();return m({type:"task-progress",taskName:Ze.taskName,update:{bindTo:ae,outputFile:le,fetchedAt:qe,deliveryToken:Pe,sourceChecksum:Se,rqt:Ee},timestamp:qe}),g(),pe()}catch(b){return me(b)}}function M(z){try{let b=z.params?.token,N=z.params?.reason??"unknown";if(!b)return ne("sourceDataFetchFailure requires params.token");let x=Xl(b);if(!x)return ne("Invalid source token");let{cbk:K,b:J,d:ae,cs:le,rqt:Se}=x,Ee=bn(K);return Ee?(m({type:"task-progress",taskName:Ee.taskName,update:{bindTo:J,outputFile:ae,failure:!0,reason:N,sourceChecksum:le,rqt:Se},timestamp:He()}),g(),pe()):ne("Invalid callback token embedded in source token")}catch(b){return me(b)}}function U(z){try{let b=u().readCardStoreRef();return b?pe({storeRef:b}):ne(`Board at ${e.value} has no card store configured`)}catch(b){return me(b)}}function G(z){try{let b=u().readOutputsStoreRef();return b?pe({storeRef:b}):ne(`Board at ${e.value} has no outputs store configured`)}catch(b){return me(b)}}function re(z){try{let b=u().readScratchStoreRef();return pe({storeRef:b})}catch(b){return me(b)}}function W(z){try{let b=u().readArchiveStoreRef();return pe({storeRef:b})}catch(b){return me(b)}}function T(z){try{let b=u().readChatStoreRef();return pe({storeRef:b})}catch(b){return me(b)}}function A(z){try{let b=u().readArtifactsStoreRef();return pe({storeRef:b})}catch(b){return me(b)}}function V(z){try{let b=z.params?.key;if(!b)return ne("getConfig requires params.key");let N=u(),x;switch(b){case"task-executor":x=N.readTaskExecutorRef()??null;break;case"chat-handler-flow":x=N.readChatHandlerFlow()??null;break;case"card-store-ref":x=N.readCardStoreRef();break;case"outputs-store-ref":x=N.readOutputsStoreRef();break;case"scratch-store-ref":x=N.readScratchStoreRef();break;case"archive-store-ref":x=N.readArchiveStoreRef();break;case"chat-store-ref":x=N.readChatStoreRef();break;case"artifacts-store-ref":x=N.readArtifactsStoreRef();break;default:return ne(`getConfig: unknown key "${b}"`)}return pe({value:x})}catch(b){return me(b)}}function P(z){try{let b=z.params?.key;if(!b)return ne("getOutputsDataObject requires params.key");let N=d().readDataObject(b);return pe(N)}catch(b){return me(b)}}function O(z){try{return pe(d().readAllDataObjects())}catch(b){return me(b)}}function I(z){try{let b=z.params?.key;if(!b)return ne("getOutputsComputedValues requires params.key");let N=d().readComputedValues(b);return pe(N)}catch(b){return me(b)}}function B(z){try{return pe(d().readAllComputedValues())}catch(b){return me(b)}}function ee(){return Jo(t.blobStorage("sources"),z=>t.resolveBlob(z))}function ie(z){let b=t.blobStorage("sources").keyRef?.(z);return b?ze(b):z}function te(z){try{let b=z.params?.key;if(!b)return ne("getOutputsFetchedSources requires params.key");let N=ee().listSources(b),x={};for(let K of N)x[K]=ie(`${b}/${K}`);return pe(x)}catch(b){return me(b)}}function xe(z){try{let b=ee(),N=new Set;for(let K of t.blobStorage("sources").listKeys()){let J=K.indexOf("/");J>0&&!K.includes("/.staged/")&&N.add(K.slice(0,J))}let x={};for(let K of N){let J=b.listSources(K);if(J.length>0){x[K]={};for(let ae of J)x[K][ae]=ie(`${K}/${ae}`)}}return pe(x)}catch(b){return me(b)}}return{init:S,status:_,getCardStoreRef:U,getOutputsStoreRef:G,getScratchStoreRef:re,getArchiveStoreRef:W,getChatStoreRef:T,getArtifactsStoreRef:A,getConfig:V,getOutputsDataObject:P,getAllOutputsDataObjects:O,getOutputsComputedValues:I,getAllOutputsComputedValues:B,getOutputsFetchedSources:te,getAllOutputsFetchedSources:xe,removeCard:y,addCardFiles:p,cardRefreshedNotify:E,retrigger:j,processAccumulatedEvents:R,upsertCard:C,taskFailed:q,taskProgress:F,sourceDataFetched:L,sourceDataFetchFailure:M}}function ur(e,t){let r=()=>ii(t.kvStorage("config"));function a(){let _=r().readCardStoreRef();if(!_)throw new Error(`Board at ${e.value} has no card store configured. Run: init --base-ref <ref> --store-ref <b64-ref>`);let y=t.kvStorageForRef(_);return{readIndex(){return y.read("_index")},writeIndex(p){y.write("_index",p)},readCard(p){return y.read(p)},writeCard(p,E){return y.write(p,E),t.hashFn(E)},removeCard(p){y.delete(p)},cardExists(p){return y.read(p)!==null},defaultCardKey(p){return p}}}let n=()=>bd(a(),t.onWarn??(()=>{})),s=()=>{let _=r().readScratchStoreRef();return _?t.scratchStorageForRef(_):t.scratchStorage()};function o(_,y){let p=t.validateSchema(y),E=[],j=r().readTaskExecutorRef();if(j&&Array.isArray(y.source_defs))for(let C of y.source_defs){let q=typeof C.bindTo=="string"?C.bindTo:"(unknown)";try{let F;try{F=t.invokeExecutorSync(j,"validate-source-def",[],{timeout:t.executorTimeouts?.validationMs??1e4,input:JSON.stringify(C)})}catch(M){let U=M;if(F=typeof U?.stdout=="string"?U.stdout:"",!F.trim()){E.push(`source "${q}": executor validate-source-def failed \u2014 ${M instanceof Error?M.message:String(M)}`);continue}}let L=JSON.parse(F.trim());if(!L.ok&&Array.isArray(L.errors))for(let M of L.errors)E.push(`source "${q}": ${M}`)}catch(F){E.push(`source "${q}": executor validate-source-def failed \u2014 ${F instanceof Error?F.message:String(F)}`)}}let R=[...p.errors,...E];return pe({cardId:_,isValid:R.length===0,issues:R})}function u(_,y){let p=r().readTaskExecutorRef();if(!p)throw new Error("No task-executor registered for this board");let E=typeof _.bindTo=="string"?_.bindTo:"source",j=s(),R={..._,boardDir:e.value,_projections:y},C=j.create(JSON.stringify(R,null,2),`probe-in-${E}`,".json"),q=j.getUniqueKey(`probe-out-${E}`,".json"),F=j.getUniqueKey(`probe-err-${E}`,".txt"),L=ze(j.keyRef(C)),M=ze(j.keyRef(q)),U=ze(j.keyRef(F)),G=null;try{if(t.invokeExecutorSync(p,"run-source-fetch",["--in-ref",L,"--out-ref",M,"--err-ref",U],{timeout:_.timeout??t.executorTimeouts?.probeMs??6e4}),G=j.read(q),G===null)throw new Error("Executor produced no output file")}catch(re){let W=j.read(F)?.trim()??(re instanceof Error?re.message:String(re));throw new Error(`Probe failed: ${W}`)}finally{try{j.remove(C)}catch{}try{j.remove(F)}catch{}}return{bindTo:E,result:G}}function i(_,y,p){let E;try{E=u(_,y)}catch(j){return ne(j instanceof Error?j.message:String(j))}if(p){let j=ht(p);t.absoluteBlob.write(j.value,E.result)}return pe({bindTo:E.bindTo,resultSizeBytes:E.result.length})}function c(_,y){let p=_.params?.sourceIdx,E=_.params?.outRef;if(p===void 0)return ne(`${y} requires params.sourceIdx`);if(!_.body||typeof _.body!="object"||Array.isArray(_.body))return ne(`${y} requires card JSON object in body`);let j=_.body,R=j["card-content"]??j,C=j["mock-projections"]??{},q=R.source_defs??[];if(p<0||p>=q.length)return ne(`sourceIdx ${p} out of range (card has ${q.length} source(s))`);let F=q[p],L=typeof F.bindTo=="string"?F.bindTo:"source";return{src:F,bindTo:L,outRef:E,mockProjections:C}}function l(_){try{let y=_.params?.cardId,p=_.params?.all;if(!y&&!p)return ne("validateCard requires --card-id <id> or --all");let E=p?n().readAllCards().map(R=>R.id):[y],j=[];for(let R of E){let C=n().readCard(R);if(!C){j.push({cardId:R,isValid:!1,issues:[`Card "${R}" not found`]});continue}let q=o(R,C);if(q.status!=="success")return q;j.push(q.data)}return pe(j)}catch(y){return me(y)}}function d(_){try{if(!_.body||typeof _.body!="object"||Array.isArray(_.body))return ne("validateCardPreflight requires card JSON object in body");let y=_.body,p=y["card-content"]??y,E=typeof p.id=="string"?p.id:"(unknown)",j=o(E,p),R=r().readTaskExecutorRef();if(R)try{let C=t.invokeExecutorSync(R,"validate-card-preflight",[],{timeout:t.executorTimeouts?.validationMs??1e4,input:JSON.stringify(p)}),q=JSON.parse(C.trim());if(!q.ok&&Array.isArray(q.errors)&&q.errors.length>0){let F=[...j.status==="success"?j.data.issues:[],...q.errors];return pe({cardId:E,isValid:!1,issues:F})}}catch{}return j}catch(y){return me(y)}}function w(_){try{let y=_.params?.cardId,p=_.params?.sourceIdx,E=_.params?.outRef;if(!y)return ne("probeSource requires params.cardId");if(p===void 0)return ne("probeSource requires params.sourceIdx");let j=(_.body??{})["mock-projections"]??{},R=n().readCard(y);if(!R)return ne(`Card "${y}" not found`);let C=R.source_defs??[];return p<0||p>=C.length?ne(`sourceIdx ${p} out of range (card has ${C.length} source(s))`):i(C[p],j,E)}catch(y){return me(y)}}function $(_){try{let y=_.params?.outRef,p=_.body;if(!p)return ne('probeTmpSource requires body with "source-def" and "mock-projections"');let E=p["source-def"],j=p["mock-projections"]??{};return E?i(E,j,y):ne('probeTmpSource body requires "source-def"')}catch(y){return me(y)}}function h(_){try{let y=c(_,"probeSourcePreflight");if("status"in y)return y;let p=r().readTaskExecutorRef();if(!p)return ne("No task-executor registered for this board");try{let E={...y.src,_projections:y.mockProjections},j=t.invokeExecutorSync(p,"probe-source-preflight",[],{timeout:y.src.timeout??t.executorTimeouts?.preflightMs??6e4,input:JSON.stringify(E)}),R=JSON.parse(j.trim());return R.ok?pe({bindTo:y.bindTo,reachable:R.reachable,latencyMs:R.latencyMs,note:R.note}):ne(R.error??"Preflight probe failed")}catch{return ne("Executor does not support probe-source-preflight")}}catch(y){return me(y)}}function v(_){try{let y=c(_,"runSourcePreflight");if("status"in y)return y;let p=r().readTaskExecutorRef();if(p)try{let C={...y.src,_projections:y.mockProjections},q=t.invokeExecutorSync(p,"run-source-preflight",[],{timeout:y.src.timeout??t.executorTimeouts?.preflightMs??6e4,input:JSON.stringify(C)}),F=JSON.parse(q.trim());return F.ok?pe({bindTo:F.bindTo??y.bindTo,reachable:F.reachable,latencyMs:F.latencyMs,kind:F.kind,resultValue:F.resultValue,note:F.note}):ne(F.error??"Source preflight failed")}catch{}let E=Date.now(),j=u(y.src,y.mockProjections);if(y.outRef){let C=ht(y.outRef);t.absoluteBlob.write(C.value,j.result)}let R=j.result;try{R=JSON.parse(j.result)}catch{}return pe({bindTo:j.bindTo,reachable:!0,latencyMs:Date.now()-E,resultValue:R,note:"Actual fetch preflight passed"})}catch(y){return me(y)}}function m(_){try{let y=r().readTaskExecutorRef();if(!y)return ne("No task-executor registered for this board");let p=t.invokeExecutorSync(y,"describe-capabilities",[],{timeout:t.executorTimeouts?.describeMs??1e4});return pe(JSON.parse(p.trim()))}catch(y){return me(y)}}function f(_){try{let y=_.body;if(!y||!Array.isArray(y.ops))return ne("updatesInCardStore requires body.ops array");let p=y.ops,E=n();for(let j of p){let R=j.op,C=j.id;if(!C)return ne('op is missing "id"');if(R==="update"){let q=j["card-content"];if(!q)return ne(`update op for "${C}" is missing "card-content"`);E.writeCard(C,q)}else return ne(`Unknown op type: "${R??"(none)"}"`)}return pe()}catch(y){return me(y)}}function k(_){try{let y=_.body;if(!y||!Array.isArray(y.ids))return ne("readFromCardStore requires body.ids array");let p=y.ids,E=n(),j=p.map(R=>({id:R,"card-content":E.readCard(R)}));return pe({cards:j})}catch(y){return me(y)}}function g(_){try{if(!_.body||typeof _.body!="object"||Array.isArray(_.body))return ne("evalCardCompute requires a JSON object in body");let y=_.body,p=y["card-content"]??y,E=typeof p.id=="string"?p.id:"(unknown)",j=y["mock-fetched-sources"]??{},R=y["mock-requires"]??{},C=p.compute;if(!C||!Array.isArray(C)||C.length===0)return pe({cardId:E,ok:!0,computed_values:{},errors:[]});let q={id:E,card_data:p.card_data??{},requires:R,source_defs:p.source_defs,compute:C},F=qr.runSync(q,{sourcesData:j}),L=F.node.computed_values??{},M=F.errors??[];return pe({cardId:E,ok:M.length===0,computed_values:L,errors:M})}catch(y){return me(y)}}function S(_){try{if(!_.body||typeof _.body!="object"||Array.isArray(_.body))return ne("simulateCardCycle requires a JSON object in body");let y=_.body,p=y["card-content"]??y,E=typeof p.id=="string"?p.id:"(unknown)",j=y["mock-fetched-sources"]??{},R=y["mock-requires"]??{},C=o(E,p),q=C.status==="success"?{isValid:C.data.isValid,issues:C.data.issues}:{isValid:!1,issues:[C.status==="fail"?C.error:"internal error"]},F=p.source_defs??[],L=p.card_data??{},M=[],U=[];if(F.length>0){M=qr.enrichSourcesSync(F,{card_data:L,requires:R});for(let O of M){let I=O.projections,B=O._projections;if(I&&B){for(let ee of Object.keys(I))if(B[ee]===void 0){let ie=typeof O.bindTo=="string"?O.bindTo:"(unknown)";U.push({bindTo:ie,key:ee,error:`Projection "${ee}" resolved to undefined`})}}}}let G=[],re=y["task-executor-ref"],W=(re?.howToRun&&re?.whatToRun?re:void 0)??r().readTaskExecutorRef();for(let O=0;O<M.length;O++){let I=M[O],B=typeof I.bindTo=="string"?I.bindTo:`source_${O}`;if(!W){G.push({bindTo:B,skipped:!0,error:"No task executor configured"});continue}try{let ee={...I},ie=t.invokeExecutorSync(W,"run-source-preflight",[],{timeout:I.timeout??t.executorTimeouts?.preflightMs??6e4,input:JSON.stringify(ee)}),te=JSON.parse(ie.trim());G.push({bindTo:B,reachable:te.reachable,latencyMs:te.latencyMs,error:te.ok?void 0:te.error})}catch{G.push({bindTo:B,skipped:!0,error:"Executor does not support run-source-preflight"})}}let T=p.compute,A={},V=[];if(T&&Array.isArray(T)&&T.length>0){let O={id:E,card_data:L,requires:R,source_defs:p.source_defs,compute:T},I=qr.runSync(O,{sourcesData:j});A=I.node.computed_values??{},V=I.errors??[]}let P=q.isValid&&U.length===0&&V.length===0&&G.every(O=>O.reachable!==!1);return pe({cardId:E,ok:P,validation:q,source_probes:G,projection_errors:U,computed_values:A,compute_errors:V})}catch(y){return me(y)}}return{validateCard:l,validateCardPreflight:d,probeSource:w,probeTmpSource:$,probeSourcePreflight:h,runSourcePreflight:v,evalCardCompute:g,simulateCardCycle:S,describeTaskExecutorCapabilities:m,updatesInCardStore:f,readFromCardStore:k}}var G_=".board.lock";function W_(e,t){return typeof e=="string"?{cliDir:e,opts:t}:{cliDir:void 0,opts:e}}function X_(e,t){return typeof e=="string"?{cliDir:e,opts:t}:{cliDir:void 0,opts:e}}function Pd(e){if(e)return e;let t=dd(import.meta.url),r=[t,xt(t,"..","cli","node"),xt(t,"..","..","cli","node")];for(let a of r)try{return hd(a),a}catch{}throw new Error(`createFsBoardPlatformAdapter: could not resolve a public CLI directory from module dir ${t}`)}function _a(e,t,r){let{cliDir:a,opts:n}=W_(t,r),s=Pd(a),o=e.value,u={meta:"board-live-cards",howToRun:"local-node",whatToRun:!n?.suppressSpawn&&hd(s)?ze({kind:"yaml-flow-cli",value:"board-live-cards-cli.js"}):"",...n?.notifyChannel?{extra:{notifyChannel:n.notifyChannel}}:{}};return{kvStorage:i=>Ml(xt(o,`.${i}`)),blobStorage:i=>va(i?xt(o,i):o),scratchStorage:()=>Ko(xt(o,".tmp")),scratchStorageForRef:i=>Ko(ht(i).value),archiveFactory:()=>Lo(xt(o,"archive")),archiveFactoryForRef:i=>Lo(ht(i).value),journalAdapter:()=>D0(o),lock:M0(xt(o,G_)),selfRef:u,async dispatchExecution(i,c){if(n?.suppressSpawn)return{dispatched:!1};try{let l=c.source_def?.bindTo??Il().slice(0,8),d=Ko(xt(o,".tmp")),w=d.create(JSON.stringify(c,null,2),`exec-in-${l}`,".json"),$=d.getUniqueKey(`exec-out-${l}`,".json"),h=d.getUniqueKey(`exec-err-${l}`,".txt"),v=ze(d.keyRef(w)),m=ze(d.keyRef($)),f=ze(d.keyRef(h));return O0(i,{subcommand:"run-source-fetch",inRef:v,outRef:m,errRef:f},s),{dispatched:!0}}catch(l){let d=l instanceof Error?l.message:String(l);try{let w=Lo(xt(o,"archive")),$=new Date().toISOString().replace(/[:.]/g,"-"),h=c.source_def?.bindTo??"unknown";w.blob("exec-failures").write(`${$}-${h}.json`,JSON.stringify({error:d,args:c,ref:i,at:new Date().toISOString()},null,2))}catch{}return{dispatched:!1,error:d}}},resolveBlob(i){let c=u0(i.value)?yd().read(i.value):va(o).read(i.value);if(c===null)throw new Error(`resolveBlob: blob not found: ::${i.kind}::${i.value}`);return c},hashFn:q0,genId:()=>c0(`${Date.now()}-${Math.random()}`).slice(0,32),kvStorageForRef:i=>Ml(ht(i).value),requestProcessAccumulated(){n?.suppressSpawn||p0(s,e,n?.notifyChannel)},publishBoardChangeNotifications(i){if(!n?.notifyChannel||i.length===0)return;let c=i.map(l=>({id:Il(),ts:new Date().toISOString(),boardRef:ze(e),notification:l}));m0(n.notifyChannel,c,n.onWarn)},onWarn:n?.onWarn}}function cr(e,t,r){let{cliDir:a,opts:n}=X_(t,r),s=Pd(a),o=_a(e,s,n),u=y0();return{...o,invokeExecutorSync(i,c,l,d){let{command:w,baseArgs:$}=P0(i,s),h=i.extra?["--extra",Buffer.from(JSON.stringify(i.extra)).toString("base64")]:[];return u.executeSync(w,[...$,c,...l,...h],{timeout:d?.timeout??3e4,encoding:"utf-8",input:d?.input})},validateSchema(i){let c=G0(i);return{ok:c.errors.length===0,errors:c.errors}},absoluteBlob:yd()}}function Yl(e){try{let t=JSON.parse(Buffer.from(e,"base64url").toString());return typeof t.br=="string"?t.br:null}catch{return null}}var pt=dd(import.meta.url);function Ae(e,t,r){let a=e.indexOf(t),n=a!==-1?e[a+1]:void 0;if(!n)throw new Error(`Missing ${t}
|
|
29
|
-
Usage: ${r}`);return n}function Ge(e,t){let r=e.indexOf(t);return r!==-1?e[r+1]:void 0}function $e(e){console.log(JSON.stringify(e,null,2))}async function Rt(){if(process.stdin.isTTY)return;let e=[];for await(let r of process.stdin)e.push(Buffer.isBuffer(r)?r:Buffer.from(r));let t=Buffer.concat(e).toString("utf-8").trim();if(t)return JSON.parse(t)}function Y_(e){return String(e||"").replace(/[^a-zA-Z0-9_-]/g,"_")||"unknown-card"}function Q_(e,t,r,a){if(!e)throw new Error("get-attachment-content requires --base-ref <ref>");let n=_a(e,pt,{onWarn:console.warn,notifyChannel:t}),s=ii(n.kvStorage("config")),o=s.readCardStoreRef();if(!o)throw new Error(`Board at ${e.value} has no card store configured`);let u=n.kvStorageForRef(o).read(r);if(!u)throw new Error(`Card "${r}" not found in board at ${e.value}`);let i=u.card_data&&typeof u.card_data=="object"&&!Array.isArray(u.card_data)?u.card_data:{},c=Array.isArray(i.files)?i.files:[],l=a===void 0?0:Number(a);if(!Number.isInteger(l)||l<0)throw new Error("get-attachment-content requires --file-idx to be a non-negative integer");if(l>=c.length)throw new Error(`attachment index ${l} is out of range for card "${r}"`);let d=c[l];if(!d||typeof d!="object"||Array.isArray(d))throw new Error(`attachment index ${l} for card "${r}" is not an object`);let w=d.stored_name;if(typeof w!="string"||!w)throw new Error(`attachment index ${l} for card "${r}" has no stored_name`);let $=`${Y_(r)}/${w}`,h=s.readArtifactsStoreRef()
|
|
29
|
+
Usage: ${r}`);return n}function Ge(e,t){let r=e.indexOf(t);return r!==-1?e[r+1]:void 0}function $e(e){console.log(JSON.stringify(e,null,2))}async function Rt(){if(process.stdin.isTTY)return;let e=[];for await(let r of process.stdin)e.push(Buffer.isBuffer(r)?r:Buffer.from(r));let t=Buffer.concat(e).toString("utf-8").trim();if(t)return JSON.parse(t)}function Y_(e){return String(e||"").replace(/[^a-zA-Z0-9_-]/g,"_")||"unknown-card"}function Q_(e,t,r,a){if(!e)throw new Error("get-attachment-content requires --base-ref <ref>");let n=_a(e,pt,{onWarn:console.warn,notifyChannel:t}),s=ii(n.kvStorage("config")),o=s.readCardStoreRef();if(!o)throw new Error(`Board at ${e.value} has no card store configured`);let u=n.kvStorageForRef(o).read(r);if(!u)throw new Error(`Card "${r}" not found in board at ${e.value}`);let i=u.card_data&&typeof u.card_data=="object"&&!Array.isArray(u.card_data)?u.card_data:{},c=Array.isArray(i.files)?i.files:[],l=a===void 0?0:Number(a);if(!Number.isInteger(l)||l<0)throw new Error("get-attachment-content requires --file-idx to be a non-negative integer");if(l>=c.length)throw new Error(`attachment index ${l} is out of range for card "${r}"`);let d=c[l];if(!d||typeof d!="object"||Array.isArray(d))throw new Error(`attachment index ${l} for card "${r}" is not an object`);let w=d.stored_name;if(typeof w!="string"||!w)throw new Error(`attachment index ${l} for card "${r}" has no stored_name`);let $=`${Y_(r)}/${w}`,h=s.readArtifactsStoreRef();if(!h)throw new Error(`Board at ${e.value} has no artifacts store configured`);let v=va(ht(h).value).readBytes;if(!v)throw new Error("configured artifacts store does not support byte reads");let m=v($);if(m===null)throw new Error(`attachment content not found for key "${$}"`);return m}async function Z_(e){let t=e[0],r=e.slice(1);if(t==="help"||t==="--help"||t==="-h"){console.log("board-live-cards \u2014 see board-live-cards-cli-PARAMS.md for command reference");return}let a=Ge(r,"--base-ref"),n=Ge(r,"--notify-channel"),s=a?ht(a):void 0;if(t==="source-data-fetched"){let i=Ae(r,"--token","source-data-fetched --token <token> --ref <sourcefile>"),c=Ae(r,"--ref","source-data-fetched --token <token> --ref <sourcefile>"),l=Yl(i);if(!l)throw new Error("source-data-fetched: could not decode board ref from token \u2014 is this a valid source token?");let d=ht(l),w=Wo(d,_a(d,pt,{onWarn:console.warn,notifyChannel:n}));$e(w.sourceDataFetched({params:{token:i,ref:c}}));return}if(t==="source-data-fetch-failure"){let i=Ae(r,"--token","source-data-fetch-failure --token <token> [--reason <message>]"),c=Yl(i);if(!c)throw new Error("source-data-fetch-failure: could not decode board ref from token \u2014 is this a valid source token?");let l=ht(c),d=Wo(l,_a(l,pt,{onWarn:console.warn,notifyChannel:n})),w={token:i},$=Ge(r,"--reason");$&&(w.reason=$),$e(d.sourceDataFetchFailure({params:w}));return}if(t==="validate-card-preflight"){let i=s??{kind:"fs-path",value:Ht(".")},c=ur(i,cr(i,pt,{onWarn:console.warn})),l=await Rt();$e(c.validateCardPreflight({body:l}));return}if(t==="probe-source-preflight"){let i=Ae(r,"--source-idx","probe-source-preflight --source-idx <n>"),c=Ge(r,"--out-ref"),l=s??{kind:"fs-path",value:Ht(".")},d=ur(l,cr(l,pt,{onWarn:console.warn})),w=await Rt(),$={sourceIdx:parseInt(i,10)};c&&($.outRef=c),$e(d.probeSourcePreflight({params:$,body:w}));return}if(t==="run-source-preflight"){let i=Ae(r,"--source-idx","run-source-preflight --source-idx <n>"),c=Ge(r,"--out-ref"),l=s??{kind:"fs-path",value:Ht(".")},d=ur(l,cr(l,pt,{onWarn:console.warn})),w=await Rt(),$={sourceIdx:parseInt(i,10)};c&&($.outRef=c),$e(d.runSourcePreflight({params:$,body:w}));return}if(t==="eval-card-compute"){let i=s??{kind:"fs-path",value:Ht(".")},c=ur(i,cr(i,pt,{onWarn:console.warn})),l=await Rt();$e(c.evalCardCompute({body:l}));return}if(t==="simulate-card-cycle"){let i=s??{kind:"fs-path",value:Ht(".")},c=ur(i,cr(i,pt,{onWarn:console.warn})),l=await Rt();$e(c.simulateCardCycle({body:l}));return}if(t==="probe-tmp-source"){let i=Ae(r,"--out-ref","probe-tmp-source --out-ref <ref>"),c=s??{kind:"fs-path",value:Ht(".")},l=ur(c,cr(c,pt,{onWarn:console.warn})),d=await Rt();$e(l.probeTmpSource({params:{outRef:i},body:d}));return}if(!s)throw new Error(`--base-ref is required for command "${t??"(none)"}"`);let o=()=>Wo(s,_a(s,pt,{onWarn:console.warn,notifyChannel:n})),u=()=>ur(s,cr(s,pt,{onWarn:console.warn}));switch(t){case"init":{let i=Ae(r,"--card-store-ref","init --base-ref <ref> --card-store-ref <b64-ref> --outputs-store-ref <b64-ref>"),c=Ae(r,"--outputs-store-ref","init --base-ref <ref> --card-store-ref <b64-ref> --outputs-store-ref <b64-ref>"),l=Ge(r,"--scratch-store-ref"),d=Ge(r,"--archive-store-ref"),w=Ge(r,"--artifacts-store-ref"),$=await Rt();$e(o().init({params:{cardStoreRef:i,outputsStoreRef:c,...l?{scratchStoreRef:l}:{},...d?{archiveStoreRef:d}:{},...w?{artifactsStoreRef:w}:{}},body:$}));return}case"status":{$e(o().status({}));return}case"get-card-store-ref":{$e(o().getCardStoreRef({}));return}case"get-outputs-store-ref":{$e(o().getOutputsStoreRef({}));return}case"get-scratch-store-ref":{$e(o().getScratchStoreRef({}));return}case"get-archive-store-ref":{$e(o().getArchiveStoreRef({}));return}case"get-chat-store-ref":{$e(o().getChatStoreRef({}));return}case"get-artifacts-store-ref":{$e(o().getArtifactsStoreRef({}));return}case"get-outputs":{let i=Ae(r,"--type","get-outputs --base-ref <ref> --type <data-object|computed-values> [--key <key>] [--all]"),c=r.includes("--all");if(i==="data-object")if(c)$e(o().getAllOutputsDataObjects({}));else{let l=Ae(r,"--key","get-outputs --type data-object --base-ref <ref> --key <datakey>");$e(o().getOutputsDataObject({params:{key:l}}))}else if(i==="computed-values")if(c)$e(o().getAllOutputsComputedValues({}));else{let l=Ae(r,"--key","get-outputs --type computed-values --base-ref <ref> --key <card-id>");$e(o().getOutputsComputedValues({params:{key:l}}))}else if(i==="fetched_sources")if(c)$e(o().getAllOutputsFetchedSources({}));else{let l=Ae(r,"--key","get-outputs --type fetched_sources --base-ref <ref> --key <card-id>");$e(o().getOutputsFetchedSources({params:{key:l}}))}else throw new Error(`get-outputs: unknown --type "${i}", expected data-object | computed-values | fetched_sources`);return}case"remove-card":{let i=Ae(r,"--id","remove-card --base-ref <ref> --id <card-id>");$e(o().removeCard({params:{id:i}}));return}case"add-card-files":{let i=Ae(r,"--card-id","add-card-files --base-ref <ref> --card-id <card-id> [--value-json <json>]"),c=Ge(r,"--value-json"),l=c?JSON.parse(c):await Rt();$e(o().addCardFiles({params:{cardId:i},body:l}));return}case"get-attachment-content":{let i=Ae(r,"--card-id","get-attachment-content --base-ref <ref> --card-id <card-id> [--file-idx <n>]"),c=Ge(r,"--file-idx");process.stdout.write(Buffer.from(Q_(s,n,i,c)));return}case"card-refreshed-notify":{let i=Ae(r,"--card-id","card-refreshed-notify --base-ref <ref> --card-id <card-id>");$e(o().cardRefreshedNotify({params:{cardId:i}}));return}case"retrigger":{let i=Ae(r,"--id","retrigger --base-ref <ref> --id <card-id>");$e(o().retrigger({params:{id:i}}));return}case"process-accumulated-events":{$e(await o().processAccumulatedEvents({}));return}case"upsert-card":{let i=Ge(r,"--card-id"),c=r.includes("--all"),l=r.includes("--restart");if(!i&&!c)throw new Error("upsert-card requires --card-id <id> or --all");let d={};i&&(d.cardId=i),c&&(d.all=!0),l&&(d.restart=!0),$e(o().upsertCard({params:d}));return}case"task-failed":{let i={token:Ae(r,"--token","task-failed --base-ref <ref> --token <token> [--error <message>]")},c=Ge(r,"--error");c&&(i.error=c),$e(o().taskFailed({params:i}));return}case"task-progress":{let i=Ae(r,"--token","task-progress --base-ref <ref> --token <token> [--update <json>]"),c=Ge(r,"--update"),l=c?JSON.parse(c):{};$e(o().taskProgress({params:{token:i},body:{update:l}}));return}case"validate-card":{let i=Ge(r,"--card-id"),c=r.includes("--all");if(!i&&!c)throw new Error("validate-card requires --card-id <id> or --all");let l={};i&&(l.cardId=i),c&&(l.all=!0),$e(u().validateCard({params:l}));return}case"probe-source":{let i=Ae(r,"--card-id","probe-source --base-ref <ref> --card-id <id> --source-idx <n> --out-ref <ref>"),c=Ae(r,"--source-idx","probe-source --base-ref <ref> --card-id <id> --source-idx <n> --out-ref <ref>"),l=Ge(r,"--out-ref"),d=await Rt(),w={cardId:i,sourceIdx:parseInt(c,10)};l&&(w.outRef=l),$e(u().probeSource({params:w,body:d}));return}case"describe-task-executor-capabilities":{$e(u().describeTaskExecutorCapabilities({}));return}default:throw new Error(`Unknown command: ${t??"(none)"}`)}}var e$=process.argv[1]&&Ht(process.argv[1])===Ht(new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"));e$&&Z_(process.argv.slice(2)).catch(e=>{let t=e instanceof Error?e.message:String(e);console.error(t),process.exit(1)});export{Z_ as cli};
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
20
20
|
<script src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script>
|
|
21
21
|
<script src="https://cdn.jsdelivr.net/npm/leader-line/leader-line.min.js"></script>
|
|
22
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.
|
|
23
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.
|
|
22
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.25/browser/live-cards.js"></script>
|
|
23
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.25/browser/board-livecards-client.js"></script>
|
|
24
24
|
</head>
|
|
25
25
|
<body class="bg-light">
|
|
26
26
|
<div class="container-fluid py-3">
|
package/examples/board/doc.html
CHANGED
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
38
38
|
<script src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script>
|
|
39
39
|
<script src="https://cdn.jsdelivr.net/npm/leader-line/leader-line.min.js"></script>
|
|
40
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.
|
|
41
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.
|
|
40
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.25/browser/live-cards.js"></script>
|
|
41
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.25/browser/board-livecards-client.js"></script>
|
|
42
42
|
</head>
|
|
43
43
|
<body class="bg-light">
|
|
44
44
|
<div class="container-fluid py-3">
|
|
@@ -305,6 +305,7 @@ function buildBoardContextConfig(label, boardDir, taskExecPath, chatHandlerFlow,
|
|
|
305
305
|
|
|
306
306
|
const artifactsRef = parseRef(serializeRef({ kind: 'fs-path', value: runtimeCardsDir }));
|
|
307
307
|
const artifactsAdapter = createFsBoardPlatformAdapter(artifactsRef, { suppressSpawn: true });
|
|
308
|
+
const artifactsStoreRef = serializeRef({ kind: 'fs-path', value: runtimeCardsDir });
|
|
308
309
|
const cardStoreRef = serializeRef({ kind: 'fs-path', value: runtimeCardStoreDir });
|
|
309
310
|
const scratchStoreRef = serializeRef({ kind: 'fs-path', value: scratchDir });
|
|
310
311
|
const archiveStoreRef = serializeRef({ kind: 'fs-path', value: archiveDir });
|
|
@@ -316,6 +317,7 @@ function buildBoardContextConfig(label, boardDir, taskExecPath, chatHandlerFlow,
|
|
|
316
317
|
baseRef,
|
|
317
318
|
cardStoreRef,
|
|
318
319
|
outputsStoreRef: serializeRef({ kind: 'fs-path', value: runtimeOutDir }),
|
|
320
|
+
artifactsStoreRef,
|
|
319
321
|
scratchStoreRef,
|
|
320
322
|
archiveStoreRef,
|
|
321
323
|
notifyRef: { kind: 'named-pipe', value: namedPipePath(notifyChannel) },
|
|
@@ -422,6 +424,7 @@ const runtime = createMultiBoardServerRuntime({
|
|
|
422
424
|
});
|
|
423
425
|
const baseExecutionExtra = {
|
|
424
426
|
boardSetupRoot: boardRoot,
|
|
427
|
+
boardBaseRef: serializeRef({ kind: 'fs-path', value: boardDir }),
|
|
425
428
|
boardRuntimeDir: 'runtime',
|
|
426
429
|
runtimeStatusDir: 'runtime-out',
|
|
427
430
|
cardsDir: 'cards',
|
|
@@ -452,6 +455,7 @@ const runtime = createMultiBoardServerRuntime({
|
|
|
452
455
|
serverUrl: `http://127.0.0.1:${PORT}`,
|
|
453
456
|
executionExtra: {
|
|
454
457
|
boardSetupRoot: boardRoot,
|
|
458
|
+
boardBaseRef: serializeRef({ kind: 'fs-path', value: boardDir }),
|
|
455
459
|
boardRuntimeDir: 'runtime',
|
|
456
460
|
runtimeStatusDir: 'runtime-out',
|
|
457
461
|
cardsDir: 'cards',
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"open_turn": {
|
|
40
40
|
"description": "Resolve the current user turn from flow-provided chat messages and parse any chat envelope options",
|
|
41
|
-
"produces_data": ["boardId", "cardId", "boardSetupRoot", "boardRuntimeDir", "runtimeStatusDir", "cardsDir", "projectRoot", "chatFlowRoot", "chatMessages", "userText", "lastChatEntryId", "probe", "chatHandlerMode", "chatCopilotTimeoutMs"],
|
|
41
|
+
"produces_data": ["boardId", "cardId", "boardSetupRoot", "boardBaseRef", "boardRuntimeDir", "runtimeStatusDir", "cardsDir", "projectRoot", "chatFlowRoot", "chatMessages", "userText", "lastChatEntryId", "probe", "chatHandlerMode", "chatCopilotTimeoutMs", "probeAttachmentFileIdx"],
|
|
42
42
|
"input_validations": [
|
|
43
43
|
"$type(cardId) = \"string\" and $length(cardId) > 0",
|
|
44
44
|
"$type(chatMessages) = \"array\"",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"data.boardId = $type(expects_data.boardId) = \"string\" ? expects_data.boardId : \"\"",
|
|
52
52
|
"data.cardId = $type(expects_data.cardId) = \"string\" ? expects_data.cardId : \"\"",
|
|
53
53
|
"data.boardSetupRoot = $type(expects_data.boardSetupRoot) = \"string\" ? expects_data.boardSetupRoot : \"\"",
|
|
54
|
+
"data.boardBaseRef = $type(expects_data.boardBaseRef) = \"string\" ? expects_data.boardBaseRef : \"\"",
|
|
54
55
|
"data.boardRuntimeDir = ($type(expects_data.boardRuntimeDir) = \"string\" and $length(expects_data.boardRuntimeDir) > 0) ? expects_data.boardRuntimeDir : \"runtime\"",
|
|
55
56
|
"data.runtimeStatusDir = ($type(expects_data.runtimeStatusDir) = \"string\" and $length(expects_data.runtimeStatusDir) > 0) ? expects_data.runtimeStatusDir : \"runtime-out\"",
|
|
56
57
|
"data.cardsDir = ($type(expects_data.cardsDir) = \"string\" and $length(expects_data.cardsDir) > 0) ? expects_data.cardsDir : \"cards\"",
|
|
@@ -58,7 +59,9 @@
|
|
|
58
59
|
"data.chatFlowRoot = $type(expects_data.chatFlowRoot) = \"string\" ? expects_data.chatFlowRoot : \"\"",
|
|
59
60
|
"data.chatMessages = expects_data.chatMessages",
|
|
60
61
|
"data.lastChatEntryId = expects_data.lastChatEntryId",
|
|
61
|
-
"data.
|
|
62
|
+
"data._currentUserMessage = $filter(expects_data.chatMessages, function($message) { $message.id = expects_data.lastChatEntryId and $message.role = \"user\" })[0]",
|
|
63
|
+
"data._rawMessageText = $trim($string(data._currentUserMessage.text))",
|
|
64
|
+
"data.probeAttachmentFileIdx = ($type(data._currentUserMessage.files) = \"array\" and $count(data._currentUserMessage.files) > 0) ? 0 : null",
|
|
62
65
|
"data._marker = \"__probe__echo__probe__\"",
|
|
63
66
|
"data._markerLen = $length(data._marker)",
|
|
64
67
|
"data._isEchoProbe = $length(data._rawMessageText) >= (data._markerLen * 2) and $substring(data._rawMessageText, 0, data._markerLen) = data._marker and $substring(data._rawMessageText, $length(data._rawMessageText) - data._markerLen) = data._marker",
|
|
@@ -91,7 +94,25 @@
|
|
|
91
94
|
},
|
|
92
95
|
"transitions": {
|
|
93
96
|
"copilot": "copilot_assistant",
|
|
94
|
-
"probe": "
|
|
97
|
+
"probe": "select_probe_reply_source",
|
|
98
|
+
"failure": "cleanup_failure",
|
|
99
|
+
"error": "cleanup_failure"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"select_probe_reply_source": {
|
|
103
|
+
"description": "Use attached file content for probe replies when the current user message carries a file",
|
|
104
|
+
"expects_data": ["probeAttachmentFileIdx"],
|
|
105
|
+
"produces_data": ["probeReplySource"],
|
|
106
|
+
"handler": {
|
|
107
|
+
"type": "compute-jsonata",
|
|
108
|
+
"expr": [
|
|
109
|
+
"data.probeReplySource = $type(expects_data.probeAttachmentFileIdx) = \"number\" ? \"attachment\" : \"echo\"",
|
|
110
|
+
"result = data.probeReplySource"
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
"transitions": {
|
|
114
|
+
"attachment": "probe_attachment_reply",
|
|
115
|
+
"echo": "probe_assistant",
|
|
95
116
|
"failure": "cleanup_failure",
|
|
96
117
|
"error": "cleanup_failure"
|
|
97
118
|
}
|
|
@@ -117,6 +138,44 @@
|
|
|
117
138
|
"error": "cleanup_failure"
|
|
118
139
|
}
|
|
119
140
|
},
|
|
141
|
+
"probe_attachment_reply": {
|
|
142
|
+
"description": "Read the current probe attachment via board-live-cards-cli and use its content as the assistant reply",
|
|
143
|
+
"expects_data": ["boardBaseRef", "cardId", "probeAttachmentFileIdx"],
|
|
144
|
+
"produces_data": ["replyText"],
|
|
145
|
+
"input_validations": [
|
|
146
|
+
"$type(boardBaseRef) = \"string\" and $length(boardBaseRef) > 0",
|
|
147
|
+
"$type(cardId) = \"string\" and $length(cardId) > 0",
|
|
148
|
+
"$type(probeAttachmentFileIdx) = \"number\" and probeAttachmentFileIdx >= 0"
|
|
149
|
+
],
|
|
150
|
+
"handler": {
|
|
151
|
+
"type": "ref",
|
|
152
|
+
"howToRun": "local-node",
|
|
153
|
+
"whatToRun": {
|
|
154
|
+
"kind": "yaml-flow-cli",
|
|
155
|
+
"value": "board-live-cards-cli.js"
|
|
156
|
+
},
|
|
157
|
+
"meta": "chat-handler",
|
|
158
|
+
"argsMassaging": {
|
|
159
|
+
"cmdTemplate": [
|
|
160
|
+
"'get-attachment-content'",
|
|
161
|
+
"'--base-ref'",
|
|
162
|
+
"boardBaseRef",
|
|
163
|
+
"'--card-id'",
|
|
164
|
+
"cardId",
|
|
165
|
+
"'--file-idx'",
|
|
166
|
+
"$string(probeAttachmentFileIdx)"
|
|
167
|
+
]
|
|
168
|
+
},
|
|
169
|
+
"outputTransforms": {
|
|
170
|
+
"dataTemplate": "{ 'replyText': $string(output.data.stdout) }"
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"transitions": {
|
|
174
|
+
"success": "probe_in_progress",
|
|
175
|
+
"failure": "cleanup_failure",
|
|
176
|
+
"error": "cleanup_failure"
|
|
177
|
+
}
|
|
178
|
+
},
|
|
120
179
|
"copilot_assistant": {
|
|
121
180
|
"description": "Run the Copilot-backed assistant logic to generate the reply from the resolved chat history",
|
|
122
181
|
"expects_data": ["userText", "chatMessages", "boardId", "cardId", "boardSetupRoot", "boardRuntimeDir", "runtimeStatusDir", "cardsDir", "projectRoot", "chatFlowRoot", "chatCopilotTimeoutMs"],
|
|
@@ -50,6 +50,7 @@ const BOARD_DIR = path.resolve(__dirname, '..');
|
|
|
50
50
|
const SERVER_SCRIPT = path.resolve(BOARD_DIR, 'server', 'board-server.js');
|
|
51
51
|
const SSE_WORKER_SCRIPT = path.join(__dirname, 'sse-worker.js');
|
|
52
52
|
const CARD_PATTERN = 'cardT*';
|
|
53
|
+
const T2_FILE_CARD_ID = 'card-market-prices';
|
|
53
54
|
const CHAT_CARD_ID = 'card-portfolio';
|
|
54
55
|
|
|
55
56
|
function findFreePort() {
|
|
@@ -236,6 +237,7 @@ function deriveProbeLifecycleMilestones(events, opts) {
|
|
|
236
237
|
let prevMessageCount = Number(opts.beforeCount || 0);
|
|
237
238
|
let prevProcessing = Boolean(opts.beforeProcessing);
|
|
238
239
|
const prompt = String(opts.prompt || '');
|
|
240
|
+
const assistantText = opts.assistantText == null ? `Echo: ${prompt}` : String(opts.assistantText);
|
|
239
241
|
const inProgressText = String(opts.inProgressText || PROBE_IN_PROGRESS_TEXT);
|
|
240
242
|
|
|
241
243
|
for (const event of events) {
|
|
@@ -250,7 +252,7 @@ function deriveProbeLifecycleMilestones(events, opts) {
|
|
|
250
252
|
const text = String(message?.text || '');
|
|
251
253
|
if (role === 'user' && text.includes(prompt)) milestones.push('user');
|
|
252
254
|
else if (role === 'system' && text.trim().toLowerCase() === inProgressText) milestones.push('in-progress');
|
|
253
|
-
else if (role === 'assistant' && text.includes(
|
|
255
|
+
else if (role === 'assistant' && text.includes(assistantText)) milestones.push('assistant');
|
|
254
256
|
}
|
|
255
257
|
|
|
256
258
|
const processing = Boolean(event?.processing);
|
|
@@ -510,7 +512,7 @@ try {
|
|
|
510
512
|
console.log('\n=== T2: skipped (--skip-t2) ===');
|
|
511
513
|
} else {
|
|
512
514
|
console.log('\n=== T2: plain file upload -> card_data.files -> download ===');
|
|
513
|
-
const t2CardBefore = await httpGet(`${BASE}/cards/${
|
|
515
|
+
const t2CardBefore = await httpGet(`${BASE}/cards/${T2_FILE_CARD_ID}`);
|
|
514
516
|
assert(t2CardBefore.status === 200, `T2 pre card read returned ${t2CardBefore.status}`);
|
|
515
517
|
const t2FilesBefore = Array.isArray(t2CardBefore.data?.card_data?.files)
|
|
516
518
|
? t2CardBefore.data.card_data.files
|
|
@@ -520,7 +522,7 @@ try {
|
|
|
520
522
|
const t2UploadText = `plain-file-upload-${Date.now()}`;
|
|
521
523
|
const t2UploadName = 't2-upload.txt';
|
|
522
524
|
const t2UploadRes = await httpUploadChatFile(
|
|
523
|
-
`${BASE}/cards/${
|
|
525
|
+
`${BASE}/cards/${T2_FILE_CARD_ID}/files`,
|
|
524
526
|
t2UploadName,
|
|
525
527
|
t2UploadText,
|
|
526
528
|
);
|
|
@@ -529,7 +531,7 @@ try {
|
|
|
529
531
|
assert(t2UploadedFile && typeof t2UploadedFile === 'object', 'T2 upload response missing file metadata');
|
|
530
532
|
assert(String(t2UploadedFile?.name || '') === t2UploadName, 'T2 uploaded file name mismatch');
|
|
531
533
|
|
|
532
|
-
const t2CardAfter = await httpGet(`${BASE}/cards/${
|
|
534
|
+
const t2CardAfter = await httpGet(`${BASE}/cards/${T2_FILE_CARD_ID}`);
|
|
533
535
|
assert(t2CardAfter.status === 200, `T2 post card read returned ${t2CardAfter.status}`);
|
|
534
536
|
const t2FilesAfter = Array.isArray(t2CardAfter.data?.card_data?.files)
|
|
535
537
|
? t2CardAfter.data.card_data.files
|
|
@@ -540,7 +542,7 @@ try {
|
|
|
540
542
|
assert(t2FileIndex >= 0, 'T2 uploaded file metadata not found in card_data.files');
|
|
541
543
|
|
|
542
544
|
const t2DownloadRes = await httpGetRaw(
|
|
543
|
-
`${BASE}/cards/${
|
|
545
|
+
`${BASE}/cards/${T2_FILE_CARD_ID}/files/${t2FileIndex}?sn=${encodeURIComponent(String(t2UploadedFile?.stored_name || ''))}`,
|
|
544
546
|
);
|
|
545
547
|
assert(t2DownloadRes.status === 200, `T2 file download returned ${t2DownloadRes.status}`);
|
|
546
548
|
const t2DownloadedText = t2DownloadRes.body.toString('utf-8');
|
|
@@ -663,7 +665,7 @@ try {
|
|
|
663
665
|
const t2bUploadRes = await httpUploadChatFile(
|
|
664
666
|
`${BASE}/cards/${CHAT_CARD_ID}/files?inChat=true`,
|
|
665
667
|
'q1.txt',
|
|
666
|
-
'
|
|
668
|
+
'tokyo',
|
|
667
669
|
);
|
|
668
670
|
assert(t2bUploadRes.status === 200, `T3b file upload returned ${t2bUploadRes.status}`);
|
|
669
671
|
const uploadedFile = t2bUploadRes.data?.file;
|
|
@@ -677,6 +679,20 @@ try {
|
|
|
677
679
|
assert(!!t2bUploadSystem, 'T3b upload protocol missing system chat file');
|
|
678
680
|
assert(String(t2bUploadSystem?.text || '').toLowerCase().includes('file uploaded:'), 'T3b upload system message does not describe uploaded file');
|
|
679
681
|
|
|
682
|
+
const t2bCardAfterUpload = await httpGet(`${BASE}/cards/${CHAT_CARD_ID}`);
|
|
683
|
+
assert(t2bCardAfterUpload.status === 200, `T3b card read after upload returned ${t2bCardAfterUpload.status}`);
|
|
684
|
+
const t2bFilesAfterUpload = Array.isArray(t2bCardAfterUpload.data?.card_data?.files)
|
|
685
|
+
? t2bCardAfterUpload.data.card_data.files
|
|
686
|
+
: [];
|
|
687
|
+
const t2bFileIndex = t2bFilesAfterUpload.findIndex((f) => String(f?.stored_name || '') === String(uploadedFile?.stored_name || ''));
|
|
688
|
+
assert(t2bFileIndex >= 0, 'T3b uploaded file metadata not found in card_data.files');
|
|
689
|
+
|
|
690
|
+
const t2bDownloadRes = await httpGetRaw(
|
|
691
|
+
`${BASE}/cards/${CHAT_CARD_ID}/files/${t2bFileIndex}?sn=${encodeURIComponent(String(uploadedFile?.stored_name || ''))}`,
|
|
692
|
+
);
|
|
693
|
+
assert(t2bDownloadRes.status === 200, `T3b file download returned ${t2bDownloadRes.status}`);
|
|
694
|
+
assert(t2bDownloadRes.body.toString('utf-8') === 'tokyo', 'T3b downloaded content mismatch');
|
|
695
|
+
|
|
680
696
|
const t2bSendBaseline = t2bUploadMessages.length;
|
|
681
697
|
const t2bEventStart = NS.chatEvents.length;
|
|
682
698
|
|
|
@@ -695,6 +711,7 @@ try {
|
|
|
695
711
|
beforeCount: t2bSendBaseline,
|
|
696
712
|
beforeProcessing: false,
|
|
697
713
|
prompt: t2bPrompt,
|
|
714
|
+
assistantText: 'tokyo',
|
|
698
715
|
inProgressText: PROBE_IN_PROGRESS_TEXT,
|
|
699
716
|
});
|
|
700
717
|
}, 60_000, 'T3b ordered lifecycle');
|
|
@@ -714,8 +731,8 @@ try {
|
|
|
714
731
|
assert(!!t2bInProgress && typeof t2bInProgress.id === 'string', 'T3b missing in-progress system chat message');
|
|
715
732
|
assert(!!t2bAssistantMsg && typeof t2bAssistantMsg.id === 'string', 'T3b missing assistant chat message notification');
|
|
716
733
|
assert(Array.isArray(t2bUser?.files) && t2bUser.files.length === 1, 'T3b user chat message missing uploaded file metadata');
|
|
717
|
-
assert(String(t2bAssistantMsg?.text || '').
|
|
718
|
-
console.log('[T3b] ok: upload protocol and ordered probe lifecycle observed
|
|
734
|
+
assert(String(t2bAssistantMsg?.text || '').trim() === 'tokyo', 'T3b assistant attachment content mismatch');
|
|
735
|
+
console.log('[T3b] ok: upload protocol and ordered probe lifecycle observed with attachment-derived assistant reply');
|
|
719
736
|
}
|
|
720
737
|
}
|
|
721
738
|
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
<title>Example Board Demo (LocalStorage Runtime)</title>
|
|
7
7
|
<link rel="icon" type="image/svg+xml" href="../../browser/favicon.svg" />
|
|
8
8
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
|
9
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.
|
|
9
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.25/browser/compute-jsonata.js"></script>
|
|
10
10
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
11
11
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
12
12
|
<script src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script>
|
|
13
13
|
<script src="https://cdn.jsdelivr.net/npm/leader-line/leader-line.min.js"></script>
|
|
14
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.
|
|
15
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.
|
|
14
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.25/browser/live-cards.js"></script>
|
|
15
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.4.25/browser/board-livecards-localstorage.js"></script>
|
|
16
16
|
</head>
|
|
17
17
|
<body class="bg-light">
|
|
18
18
|
<div class="container-fluid py-3">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as ArtifactsStore } from './artifacts-store-lib-CVgtQrNZ.cjs';
|
|
2
2
|
export { c as createArtifactsStore, b as createCardFileMetadataStore, d as createFileArtifactsStore } from './artifacts-store-lib-CVgtQrNZ.cjs';
|
|
3
|
-
import { I as InvocationAdapter } from './types-
|
|
4
|
-
export { D as DescribeEnvelope } from './types-
|
|
3
|
+
import { I as InvocationAdapter } from './types-BpfMamGs.cjs';
|
|
4
|
+
export { D as DescribeEnvelope } from './types-BpfMamGs.cjs';
|
|
5
5
|
import { a as KindValueRef } from './storage-interface-B2WD9D5n.cjs';
|
|
6
6
|
export { p as parseRef, s as serializeRef } from './storage-interface-B2WD9D5n.cjs';
|
|
7
7
|
import { e as BoardNonCorePlatformAdapter, d as BoardPlatformAdapter } from './board-live-cards-public-B4RcYPC_.cjs';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as ArtifactsStore } from './artifacts-store-lib-D-k-E8Vy.js';
|
|
2
2
|
export { c as createArtifactsStore, b as createCardFileMetadataStore, d as createFileArtifactsStore } from './artifacts-store-lib-D-k-E8Vy.js';
|
|
3
|
-
import { I as InvocationAdapter } from './types-
|
|
4
|
-
export { D as DescribeEnvelope } from './types-
|
|
3
|
+
import { I as InvocationAdapter } from './types-DwPRb-PY.js';
|
|
4
|
+
export { D as DescribeEnvelope } from './types-DwPRb-PY.js';
|
|
5
5
|
import { a as KindValueRef } from './storage-interface-B2WD9D5n.js';
|
|
6
6
|
export { p as parseRef, s as serializeRef } from './storage-interface-B2WD9D5n.js';
|
|
7
7
|
import { e as BoardNonCorePlatformAdapter, d as BoardPlatformAdapter } from './board-live-cards-public-ydXuA4zh.js';
|