@north-light/crouter 0.3.322 → 0.3.324
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/bin/progress-painter.mjs +89 -0
- package/bin/runtime-selector.mjs +79 -9
- package/dist/api/client.d.ts +6 -2
- package/dist/api/client.js +2 -2
- package/dist/api/dto/broker-ops.d.ts +9 -0
- package/dist/api/dto/canvas.d.ts +23 -1
- package/dist/api/dto/nodes.d.ts +8 -0
- package/dist/api/node-transport.js +1 -1
- package/dist/api/routes.d.ts +2 -0
- package/dist/api/routes.js +1 -1
- package/dist/clients/attach/chrome/canvas-panels.js +1 -1
- package/dist/clients/attach/overlays/graph.d.ts +6 -5
- package/dist/clients/attach/overlays/graph.js +1 -1
- package/dist/clients/attach/viewer.js +536 -536
- package/dist/commands/node/create.js +3 -3
- package/dist/commands/sys/panels/plugins-panel.js +1 -1
- package/dist/commands/sys/panels/provider-panel.d.ts +4 -0
- package/dist/commands/sys/panels/provider-panel.js +1 -1
- package/dist/commands/sys/setup-core.js +7 -4
- package/dist/commands/sys/setup-wizard.d.ts +1 -1
- package/dist/commands/sys/setup-wizard.js +1 -1
- package/dist/core/canvas/canvas.d.ts +24 -0
- package/dist/core/canvas/canvas.js +29 -15
- package/dist/core/canvas/migrations.js +35 -32
- package/dist/core/canvas/nav-model.d.ts +1 -1
- package/dist/core/canvas/nav-model.js +1 -1
- package/dist/core/canvas/nav-render.d.ts +31 -25
- package/dist/core/canvas/nav-render.js +1 -1
- package/dist/core/canvas/render-source.d.ts +6 -16
- package/dist/core/canvas/render-source.js +9 -9
- package/dist/core/canvas/types.d.ts +16 -0
- package/dist/core/provider-credential.d.ts +6 -0
- package/dist/core/provider-credential.js +1 -0
- package/dist/core/runtime/boot-root.d.ts +2 -0
- package/dist/core/runtime/boot-root.js +5 -1
- package/dist/core/runtime/broker/daemon-ops.d.ts +2 -1
- package/dist/core/runtime/broker/daemon-ops.js +1 -1
- package/dist/core/runtime/front-door-login.d.ts +2 -0
- package/dist/core/runtime/front-door-login.js +1 -0
- package/dist/core/runtime/front-door.js +7 -5
- package/dist/core/runtime/nerd-font.d.ts +19 -1
- package/dist/core/runtime/nerd-font.js +2 -2
- package/dist/core/runtime/progress-bar.d.ts +13 -0
- package/dist/core/runtime/progress-bar.js +2 -0
- package/dist/core/runtime/provider-credential-gate.d.ts +4 -0
- package/dist/core/runtime/provider-credential-gate.js +2 -0
- package/dist/core/runtime/spawn-env.d.ts +7 -0
- package/dist/core/runtime/spawn-env.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/canvas.js +4 -4
- package/dist/daemon/api/map.d.ts +15 -1
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/fleet.js +1 -1
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/package.json +1 -1
- package/runtime.lock.json +5 -5
- package/scripts/install-runtime.mjs +7 -3
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)}
|
|
1
|
+
var Y=Object.defineProperty;var f=(t,e)=>Y(t,"name",{value:e,configurable:!0});import{existsSync as b,readFileSync as _,readdirSync as B,statSync as U,openSync as W,readSync as H,closeSync as Z}from"node:fs";import{join as T}from"node:path";import{RemoteCanvasSource as x}from"./remote-canvas-source.js";import{fullName as $}from"./labels.js";import{jobDir as q,contextDir as K,reportsDir as R}from"./paths.js";import{readNodeRecap as Q}from"./node-recap.js";import{parseFrontmatterGeneric as X}from"../frontmatter.js";import{isFrozenRow as v,resolveNodeVisual as C,faultSummary as P}from"./status-glyph.js";import{parseCard as L}from"../../shared/generated-context.js";function j(t){return t===void 0||t===0?"0k":`${Math.floor(t/1e3)}k`}f(j,"fmtCtx");function I(t,e,n,i,c,a){if(t===void 0)return`${n}${i}? <missing meta: ${e}>`;const s=t.fault??null,r=C(t.status,{hanging:s,frozen:v(t)}).glyph,o=c?"0k":j(t.telemetry_tokens_in??void 0),u=a[e]??0,m=u>0?` \u2691${u}`:"",d=s!==null?` \xB7 ${P(s)}`:"";return`${n}${i}${r} ${$(t)} [${t.kind}/${t.mode}] ctx ${o}${m}${d}`}f(I,"nodeLineFromSource");async function z(t,e,n,i,c,a,s,r,o){if(a.has(n))return;a.add(n);const u=c?"\u2514\u2500 ":"\u251C\u2500 ";s.push(I(e.get(n),n,i,u,r,o));const m=i+(c?" ":"\u2502 ");let d;try{d=await t.subscriptionsOf(n)}catch(l){s.push(`${m}\u26A0 children unavailable: ${l instanceof Error?l.message:String(l)}`);return}for(let l=0;l<d.length;l++){const h=d[l],S=l===d.length-1;if(a.has(h.node_id)){const N=S?"\u2514\u2500 ":"\u251C\u2500 ";s.push(`${m}${N}\u21BA <cycle: ${h.node_id}>`);continue}await z(t,e,h.node_id,m,S,a,s,r,o)}}f(z,"walkTreeFromSource");async function tt(t,e,n,i,c){const a=t instanceof x,s=new Map((n??await t.listNodes()).map(p=>[p.node_id,p])),r=s.get(e);if(r===void 0)return`? <missing node: ${e}>`;let o=i,u=c??null;if(o===void 0)try{o=await t.ticketCountsForView(e)}catch(p){o={},u=p instanceof Error?p.message:String(p)}const m=a?"0k":j(r.telemetry_tokens_in??void 0),d=o[e]??0,l=d>0?` \u2691${d}`:"",h=r.fault??null,S=C(r.status,{hanging:h,frozen:v(r)}).glyph,N=h!==null?` \xB7 ${P(h)}`:"",g=[];g.push(`${S} ${$(r)} [${r.kind}/${r.mode}] ctx ${m}${l}${N}`);const V=new Set([e]);let y;try{y=await t.subscriptionsOf(e)}catch(p){g.push(`\u26A0 children unavailable: ${p instanceof Error?p.message:String(p)}`),y=[]}for(let p=0;p<y.length;p++){const G=y[p],J=p===y.length-1;await z(t,s,G.node_id,"",J,V,g,a,o)}return u!==null&&g.push(`Tickets: unavailable (${u}).`),g.join(`
|
|
2
|
+
`)}f(tt,"renderTreeFromSource");async function Nt(t,e,n,i){const c=e??await t.listNodes();if(c.length===0)return"(canvas is empty)";const a=c.filter(r=>r.parent===null&&(r.status==="active"||r.status==="idle"));if(a.length===0)return"(no live roots)";const s=[];for(const r of a)s.push(await tt(t,r.node_id,c,n,i));return s.join(`
|
|
3
3
|
|
|
4
|
-
`)}
|
|
5
|
-
`);let
|
|
6
|
-
`);break}}const
|
|
7
|
-
`);return{head:
|
|
8
|
-
`)},"slice"),
|
|
9
|
-
`);
|
|
10
|
-
`)}catch{return!1}for(const n of e){if(n===""||n.indexOf('"role":"assistant"')===-1&&n.indexOf('"role": "assistant"')===-1)continue;let
|
|
4
|
+
`)}f(Nt,"renderForestFromSource");const M=4096;function et(t){try{const e=T(K(t),"initial-prompt.md");if(!b(e))return;const n=_(e,"utf8").trim();return n===""?void 0:n.length>M?n.slice(0,M):n}catch{return}}f(et,"readGoalText");const E=1024;function nt(t){const e=t.match(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(\d{3})?$/);if(e!==null)return`${e[1]}-${e[2]}-${e[3]}T${e[4]}:${e[5]}:${e[6]}.${e[7]??"000"}Z`}f(nt,"reportStampToIso");function it(t){let e;try{for(const l of B(R(t)))l.endsWith(".md")&&(e===void 0||l>e)&&(e=l)}catch{return}if(e===void 0)return;let n;try{n=_(T(R(t),e),"utf8")}catch{return}const{data:i,body:c}=X(n),a=e.replace(/\.md$/,""),s=typeof i?.kind=="string"?i.kind:a.split("-").pop()??"report",r=typeof i?.ts=="string"?i.ts:nt(a.split("-")[0]??"")??"",o=c.split(`
|
|
5
|
+
`);let u="",m=c;for(let l=0;l<o.length;l++){const h=(o[l]??"").trim();if(h!==""){u=h.startsWith("#")?h.replace(/^#+\s*/,"").trim():h,m=o.slice(l+1).join(`
|
|
6
|
+
`);break}}const d=m.replace(/\s+/g," ").trim();return{kind:s,ts:r,heading:u,body:d.length>E?d.slice(0,E):d}}f(it,"readNewestReport");const rt=1<<20,st=1<<20,ot=4<<20;function w(t,e,n){if(t==null||t==="")return null;try{if(!b(t))return null;const i=U(t).size;if(i<=e+n){const a=_(t,"utf8").split(`
|
|
7
|
+
`);return{head:a,tail:a}}const c=W(t,"r");try{const a=f((o,u)=>{if(u<=0)return[];const m=Buffer.allocUnsafe(u),d=H(c,m,0,u,o);return m.subarray(0,d).toString("utf8").split(`
|
|
8
|
+
`)},"slice"),s=a(0,e),r=a(i-n,n);return s.length>0&&s.pop(),r.length>0&&r.shift(),{head:s,tail:r}}finally{Z(c)}}catch{return null}}f(w,"readSessionWindow");const O=8192,k=2048;function at(t){const e=w(t,rt,st);if(e===null)return{};const n=[];let i=0;for(const s of e.head){if(s===""||s.indexOf('"role":"user"')===-1&&s.indexOf('"role": "user"')===-1)continue;let r;try{r=JSON.parse(s)}catch{continue}if(r.type!=="message"||r.message?.role!=="user")continue;const o=A(r.message.content);if(o===""||L({role:"user",content:o})!==null)continue;const u=o.length>k?o.slice(0,k):o;if(n.push(u),i+=u.length+1,i>=O)break}let c;if(n.length>0){const s=n.join(`
|
|
9
|
+
`);c=s.length>O?s.slice(0,O):s}let a;for(let s=e.tail.length-1;s>=0;s--){const r=e.tail[s];if(r===""||r.indexOf('"role":"assistant"')===-1&&r.indexOf('"role": "assistant"')===-1)continue;let o;try{o=JSON.parse(r)}catch{continue}if(o.type!=="message"||o.message?.role!=="assistant")continue;const u=A(o.message.content);if(u!==""){a=u.length>k?u.slice(0,k):u;break}}return{prompts:c,lastAssistant:a}}f(at,"readSessionParts");const D=120,F=4096;function ct(t){const e=w(t,0,ot);if(e===null)return[];const n=[];for(const i of e.tail){if(i==="")continue;const c=i.indexOf('"role":"user"')!==-1||i.indexOf('"role": "user"')!==-1,a=!c&&(i.indexOf('"role":"assistant"')!==-1||i.indexOf('"role": "assistant"')!==-1);if(!c&&!a)continue;let s;try{s=JSON.parse(i)}catch{continue}if(s.type!=="message")continue;const r=s.message?.role;if(r!=="user"&&r!=="assistant")continue;const o=A(s.message?.content);o!==""&&L({role:r,content:o})===null&&n.push({role:r,text:o.length>F?o.slice(0,F):o})}return n.length>D?n.slice(n.length-D):n}f(ct,"readTranscript");function bt(t){if(t==null||t==="")return!1;let e;try{if(!b(t))return!1;e=_(t,"utf8").split(`
|
|
10
|
+
`)}catch{return!1}for(const n of e){if(n===""||n.indexOf('"role":"assistant"')===-1&&n.indexOf('"role": "assistant"')===-1)continue;let i;try{i=JSON.parse(n)}catch{continue}if(!(i.type!=="message"||i.message?.role!=="assistant")&&ut(i.message.content))return!0}return!1}f(bt,"nodeHasAssistantMessage");function ut(t){if(typeof t=="string")return t.trim()!=="";if(!Array.isArray(t))return!1;for(const e of t){if(e===null||typeof e!="object")continue;const n=e,i=(n.type??"").toLowerCase();if(i==="text"){if(typeof n.text=="string"&&n.text.trim()!=="")return!0}else if(i==="thinking"){if(typeof n.thinking=="string"&&n.thinking.trim()!=="")return!0}else return!0}return!1}f(ut,"assistantContentIsSubstantive");function A(t){if(typeof t=="string")return t.trim();if(!Array.isArray(t))return"";const e=[];for(const n of t)if(n!==null&&typeof n=="object"){const i=n;i.type==="text"&&typeof i.text=="string"&&e.push(i.text)}return e.join(" ").trim()}f(A,"extractUserText");function ft(t,e,n=!1){if(!n&&e!==null&&e!==void 0){const c=Date.parse(e);if(!Number.isNaN(c))return c}const i=Date.parse(t);return Number.isNaN(i)?0:i}f(ft,"sessionMtime");function lt(t){if(t.status!=="active")return!1;try{const e=JSON.parse(_(T(q(t.node_id),"attach.json"),"utf8"));return typeof e.viewers=="number"&&e.viewers>0}catch{return!1}}f(lt,"hasLiveBrokerViewer");function dt(t,e,n){const i=t.status==="active"||t.status==="idle",c=t.fault??null;return{node_id:t.node_id,name:$(t),handle:t.name,description:t.description,status:t.status,frozen_at:t.frozen_at??null,terminal_reason:t.terminal_reason??null,kind:t.kind,mode:t.mode,ctx_tokens:n?0:t.telemetry_tokens_in??0,asks:0,cwd:t.cwd,profile_id:t.profile_id,created:t.created,lifecycle:t.lifecycle,finalized:t.final_report!=null,mtimeMs:ft(t.created,t.telemetry_updated_at,n),streaming:c===null&&i&&t.streaming===!0,hanging:c,viewed:n?!1:e.has(t.node_id)||lt(t),srcRow:t}}f(dt,"dashboardRowFromNodeRow");async function Tt(t,e,n,i){const c=t instanceof x,a=i??await t.ticketCountsForView(e).catch(()=>({})),s=new Map((n??await t.listNodes()).map(o=>[o.node_id,o]));return[e,...await t.view(e)].flatMap(o=>{const u=s.get(o);return u===void 0?[]:[{node_id:o,name:$(u),handle:u.name,description:u.description,status:u.status,frozen_at:u.frozen_at??null,terminal_reason:u.terminal_reason??null,kind:u.kind,mode:u.mode,ctx_tokens:c?0:u.telemetry_tokens_in??0,asks:a[o]??0,cwd:u.cwd,profile_id:u.profile_id,created:u.created}]})}f(Tt,"dashboardRowsFromSource");async function Ot(t,e=new Set,n=!1,i){const c=t instanceof x,a=c?new Set:e;return(i??await t.listNodes(n?{status:["active","idle"]}:void 0)).map(r=>dt(r,a,c))}f(Ot,"dashboardRowsAllFromSource");async function At(t,e,n){const i=e.filter(a=>a.enriched!==!0);if(i.length===0)return;const c=n??{};for(const a of i)a.asks=c[a.node_id]??0,a.enriched=!0}f(At,"enrichRowsFromSource");async function Rt(t,e){if(e.previewLoaded===!0)return e;const n=t instanceof x;if(e.goal=n?void 0:et(e.node_id),!n){const i=await t.getNode(e.node_id),{prompts:c,lastAssistant:a}=at(i?.pi_session_file);e.prompts=c,e.lastAssistant=a,e.recap=Q(e.node_id),e.report=it(e.node_id)}return e.previewLoaded=!0,e}f(Rt,"loadPreviewFromSource");async function vt(t,e){if(e.transcriptLoaded===!0)return e;if(t instanceof x)return e.transcript=[],e.transcriptLoaded=!0,e;const n=await t.getNode(e.node_id);return e.transcript=ct(n?.pi_session_file),e.transcriptLoaded=!0,e}f(vt,"loadTranscriptFromSource");export{dt as dashboardRowFromNodeRow,Ot as dashboardRowsAllFromSource,Tt as dashboardRowsFromSource,At as enrichRowsFromSource,j as fmtCtx,Rt as loadPreviewFromSource,vt as loadTranscriptFromSource,bt as nodeHasAssistantMessage,et as readGoalText,it as readNewestReport,at as readSessionParts,ct as readTranscript,Nt as renderForestFromSource,tt as renderTreeFromSource,ft as sessionMtime};
|
|
@@ -294,6 +294,14 @@ export interface NodeRuntime {
|
|
|
294
294
|
outcome_detail_json?: string | null;
|
|
295
295
|
/** Absolute wall-clock spawn deadline, or null when unbounded. */
|
|
296
296
|
deadline_at?: string | null;
|
|
297
|
+
/** Cumulative input tokens reported by the broker telemetry producer. */
|
|
298
|
+
telemetry_tokens_in?: number | null;
|
|
299
|
+
/** Latest live context-window token gauge reported by the broker. */
|
|
300
|
+
telemetry_context_tokens?: number | null;
|
|
301
|
+
/** Latest tool summary reported by the broker. */
|
|
302
|
+
telemetry_last_activity?: string | null;
|
|
303
|
+
/** Timestamp of the latest broker telemetry update. */
|
|
304
|
+
telemetry_updated_at?: string | null;
|
|
297
305
|
/** OS pid of the live broker process, recorded on boot (stophook session_start).
|
|
298
306
|
* The daemon's authoritative liveness signal — every node is a detached broker,
|
|
299
307
|
* so `isPidAlive(pi_pid)` is the sole liveness check. Cleared to null by
|
|
@@ -381,6 +389,14 @@ export interface NodeRow {
|
|
|
381
389
|
outcome_revision?: number;
|
|
382
390
|
outcome_detail_json?: string | null;
|
|
383
391
|
deadline_at?: string | null;
|
|
392
|
+
/** Cumulative input tokens reported by the broker telemetry producer. */
|
|
393
|
+
telemetry_tokens_in?: number | null;
|
|
394
|
+
/** Latest live context-window token gauge reported by the broker. */
|
|
395
|
+
telemetry_context_tokens?: number | null;
|
|
396
|
+
/** Latest tool summary reported by the broker. */
|
|
397
|
+
telemetry_last_activity?: string | null;
|
|
398
|
+
/** Timestamp of the latest broker telemetry update. */
|
|
399
|
+
telemetry_updated_at?: string | null;
|
|
384
400
|
pi_pid: number | null;
|
|
385
401
|
/** See `NodeRuntime.pi_pid_identity`. */
|
|
386
402
|
pi_pid_identity: string | null;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ModelRegistry, ModelRuntime } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
/** Whether the provider has a credential crouter can use. This is the same
|
|
3
|
+
* configured predicate shown by the setup Providers panel. */
|
|
4
|
+
export declare function isProviderCredentialConfigured(providerId: string, registry: ModelRegistry): boolean;
|
|
5
|
+
/** Whether any provider in the setup catalog has a usable configured credential. */
|
|
6
|
+
export declare function hasProviderCredential(runtime: ModelRuntime, registry: ModelRegistry): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var i=Object.defineProperty;var t=(e,r)=>i(e,"name",{value:r,configurable:!0});import{isManagedProvider as n,readSubscriptionPool as d}from"./subscription-state.js";function a(e,r){return r.getProviderAuthStatus(e).configured||n(e)&&d(e).length>0}t(a,"isProviderCredentialConfigured");function g(e,r){return[...new Set([...e.getProviders().map(o=>o.id),...r.getAll().map(o=>o.provider)])].some(o=>a(o,r))}t(g,"hasProviderCredential");export{g as hasProviderCredential,a as isProviderCredentialConfigured};
|
|
@@ -11,6 +11,8 @@ export interface BootRootOpts {
|
|
|
11
11
|
* spawner to inherit from, so this is the front door's only source of profile
|
|
12
12
|
* identity. */
|
|
13
13
|
profile?: string | null;
|
|
14
|
+
/** Profile already selected by the front door before its credential gate. */
|
|
15
|
+
selectedProfileId?: string;
|
|
14
16
|
/** `crtr --pick-profile`: force the startup profile chooser to open even when
|
|
15
17
|
* a per-cwd default is pinned, so the user can re-pin or unpin it. Without
|
|
16
18
|
* this a pinned default auto-picks silently (that is what "default" means). */
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
var l=Object.defineProperty;var
|
|
1
|
+
var l=Object.defineProperty;var s=(e,r)=>l(e,"name",{value:r,configurable:!0});import{spawn as p}from"node:child_process";import{inTmux as u,currentTmux as _,viewerSplitEnv as T}from"./placement-tmux.js";import{selectProfileForCwd as x}from"../profiles/select.js";import{cliClient as m}from"../../commands/api-client.js";import{mark as i}from"../timing.js";async function P(e){if(!u()){const t=process.stderr.isTTY?n=>`\x1B[1;33m${n}\x1B[0m`:n=>n;process.stderr.write(`
|
|
2
|
+
${t("crtr must be started from inside a tmux session.")}
|
|
3
|
+
${t("Start tmux first, e.g. tmux new -s work \u2014 then run crtr there.")}
|
|
4
|
+
|
|
5
|
+
`),process.exit(1)}const r=e.kind;i("boot_root.start");const f=e.selectedProfileId??await x(e.cwd,e.profile,e.pickProfile??!1);i("boot_root.profile_resolved");const d=(await m().createNode({...r!==void 0?{kind:r}:{},mode:"base",prompt:e.prompt,profile:f,cwd:e.cwd,...e.name!==void 0?{name:e.name}:r!==void 0?{name:r}:{},root:!0,prefer_warm:!0})).node_id;i("boot_root.node_created",{node:d});const o=_();if(o!==null)try{await m().registerFocus({node_id:d,pane:o.pane,session:o.session,window:o.window})}catch{}const a={...process.env,...T(),CRTR_ATTACH_WAIT_MS:"30000",...e.prompt!==void 0&&e.prompt!==""?{CRTR_ATTACH_INITIAL_WHIP:"1"}:{}};o!==null&&(a.CRTR_ATTACH_BORROWED_PANE=o.pane),i("boot_root.viewer_spawn");const c=p("crtr",["surface","attach","to",d],{stdio:"inherit",env:a}),w=await new Promise(t=>{c.once("exit",n=>t(n??0)),c.once("error",()=>t(1))});process.exit(w)}s(P,"bootRoot");export{P as bootRoot};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BrokerExtensionStateDTO, BrokerGeneratedNameRequest, BrokerGeneratedNameResultDTO, BrokerModelCommitRequest, BrokerModelCommitResultDTO, BrokerParkActivityResultDTO, BrokerParkCompleteRequest, BrokerPersonaAckRequest, BrokerPersonaAckResultDTO, BrokerSessionBoundRequest, BrokerSessionBoundResultDTO, BrokerSettleDirective, BrokerSettleRequest } from '../../../api/dto/broker-ops.js';
|
|
1
|
+
import type { BrokerExtensionStateDTO, BrokerGeneratedNameRequest, BrokerGeneratedNameResultDTO, BrokerModelCommitRequest, BrokerModelCommitResultDTO, BrokerParkActivityResultDTO, BrokerParkCompleteRequest, BrokerPersonaAckRequest, BrokerPersonaAckResultDTO, BrokerSessionBoundRequest, BrokerSessionBoundResultDTO, BrokerSettleDirective, BrokerSettleRequest, BrokerTelemetryRequest } from '../../../api/dto/broker-ops.js';
|
|
2
2
|
import type { AcknowledgeMailResultDTO, ClaimMailResultDTO, MailReceiptDTO } from '../../../api/dto/mail.js';
|
|
3
3
|
import type { BrokerFaultInputDTO, BrokerFaultRequest, BrokerFaultResultDTO, BrokerProviderRetryRequest, BrokerProviderRetryResultDTO, BrokerTurnRequest, BrokerTurnResultDTO, RecoveryStateDTO } from '../../../api/dto/recovery.js';
|
|
4
4
|
import type { RelaunchRootResultDTO } from '../../../api/dto/lifecycle.js';
|
|
@@ -9,6 +9,7 @@ type BrokerInput<T> = T extends unknown ? Omit<T, 'expected_execution_id'> : nev
|
|
|
9
9
|
export declare function settleBroker(nodeId: string, request: BrokerInput<BrokerSettleRequest>): Promise<BrokerSettleDirective>;
|
|
10
10
|
export declare function completeBrokerPark(nodeId: string, request: BrokerInput<BrokerParkCompleteRequest>): Promise<BrokerSettleDirective>;
|
|
11
11
|
export declare function recordBrokerParkActivity(nodeId: string): Promise<BrokerParkActivityResultDTO>;
|
|
12
|
+
export declare function recordBrokerTelemetry(nodeId: string, request: Omit<BrokerTelemetryRequest, 'expected_execution_id'>): Promise<void>;
|
|
12
13
|
export declare function claimBrokerMail(nodeId: string, channel: 'wake' | 'passive'): Promise<ClaimMailResultDTO>;
|
|
13
14
|
export declare function acknowledgeBrokerMail(nodeId: string, deliveries: MailReceiptDTO[]): Promise<AcknowledgeMailResultDTO>;
|
|
14
15
|
export declare function recordBrokerTurn(nodeId: string, request: Omit<BrokerTurnRequest, 'expected_execution_id'>): Promise<BrokerTurnResultDTO>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var c=Object.defineProperty;var o=(e,r)=>c(e,"name",{value:r,configurable:!0});import{localClient as u}from"../../../api/node-transport.js";import{ApiError as d}from"../../../api/errors.js";import{envExecutionId as a}from"../../../shared/env.js";function t(){return u({autostart:!1})}o(t,"daemonClient");function n(){const e=a();if(e===void 0||e==="")throw new Error("broker launch is missing CRTR_EXECUTION_ID");return e}o(n,"brokerExecutionId");function f(e,r){return t().bindBrokerSession(e,{...r,executionId:n()})}o(f,"bindBrokerSession");function m(e,r){return t().settleBroker(e,{...r,expected_execution_id:n()})}o(m,"settleBroker");function B(e,r){return t().completeBrokerPark(e,{...r,expected_execution_id:n()})}o(B,"completeBrokerPark");function _(e){return t().recordBrokerParkActivity(e,{expected_execution_id:n()})}o(_,"recordBrokerParkActivity");function s(e,r){return t().claimNodeMail(e,{execution_id:n(),channel:r})}o(
|
|
1
|
+
var c=Object.defineProperty;var o=(e,r)=>c(e,"name",{value:r,configurable:!0});import{localClient as u}from"../../../api/node-transport.js";import{ApiError as d}from"../../../api/errors.js";import{envExecutionId as a}from"../../../shared/env.js";function t(){return u({autostart:!1})}o(t,"daemonClient");function n(){const e=a();if(e===void 0||e==="")throw new Error("broker launch is missing CRTR_EXECUTION_ID");return e}o(n,"brokerExecutionId");function f(e,r){return t().bindBrokerSession(e,{...r,executionId:n()})}o(f,"bindBrokerSession");function m(e,r){return t().settleBroker(e,{...r,expected_execution_id:n()})}o(m,"settleBroker");function B(e,r){return t().completeBrokerPark(e,{...r,expected_execution_id:n()})}o(B,"completeBrokerPark");function _(e){return t().recordBrokerParkActivity(e,{expected_execution_id:n()})}o(_,"recordBrokerParkActivity");function s(e,r){return t().recordBrokerTelemetry(e,{...r,expected_execution_id:n()})}o(s,"recordBrokerTelemetry");function y(e,r){return t().claimNodeMail(e,{execution_id:n(),channel:r})}o(y,"claimBrokerMail");function v(e,r){return t().acknowledgeNodeMail(e,{execution_id:n(),deliveries:r})}o(v,"acknowledgeBrokerMail");function E(e,r){return t().recordBrokerTurn(e,{...r,expected_execution_id:n()})}o(E,"recordBrokerTurn");function R(e,r){return t().mutateBrokerProviderRetry(e,{...r,expected_execution_id:n()})}o(R,"mutateBrokerProviderRetry");function h(e,r){return t().mutateBrokerFault(e,{...r,expected_execution_id:n()})}o(h,"mutateBrokerFault");function N(e){return t().getBrokerRecovery(e,n())}o(N,"brokerRecovery");function b(e,r){return t().recordNodeFault(e,r)}o(b,"recordNodeFault");function P(e,r={}){return t().clearNodeFault(e,{...r.link===void 0?{}:{link:r.link},...r.preserveEpisode===void 0?{}:{preserve_episode:r.preserveEpisode}}).then(i=>i.cleared)}o(P,"clearNodeFault");function w(e,r){return t().commitBrokerModel(e,{...r,expected_execution_id:n()})}o(w,"commitBrokerModel");function F(e){return t().brokerExtensionState(e)}o(F,"brokerExtensionState");function M(e,r){return t().commitBrokerGeneratedName(e,{...r,expected_execution_id:n()})}o(M,"commitBrokerGeneratedName");function T(e,r){return t().commitBrokerPersonaAck(e,{...r,expected_execution_id:n()})}o(T,"commitBrokerPersonaAck");async function A(e,r){try{await t().pushReport(e,r)}catch(i){if(r.tier==="final"&&i instanceof d&&i.code==="already_finalized")return;throw i}}o(A,"publishBrokerReport");function I(e){return t().relaunchRoot(e)}o(I,"relaunchBrokerRoot");export{v as acknowledgeBrokerMail,f as bindBrokerSession,n as brokerExecutionId,F as brokerExtensionState,N as brokerRecovery,y as claimBrokerMail,P as clearNodeFault,M as commitBrokerGeneratedName,w as commitBrokerModel,T as commitBrokerPersonaAck,B as completeBrokerPark,h as mutateBrokerFault,R as mutateBrokerProviderRetry,A as publishBrokerReport,_ as recordBrokerParkActivity,s as recordBrokerTelemetry,E as recordBrokerTurn,b as recordNodeFault,I as relaunchBrokerRoot,m as settleBroker};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var m=Object.defineProperty;var r=(a,t)=>m(a,"name",{value:t,configurable:!0});import{CredentialSynchronizationError as d,LoginDialogComponent as l,OAuthSelectorComponent as p}from"@earendil-works/pi-coding-agent";import{execFile as f}from"node:child_process";import{join as g}from"node:path";import{setAuthCredential as w}from"../auth-file.js";import{dialogAuthInteraction as y}from"../auth-interaction.js";import{commitManagedLogin as I,isManagedProvider as L,readSubscriptionPool as b}from"../subscription-state.js";import{runSetupSettingsProcess as A}from"../../commands/sys/setup-settings-runner.js";import{buildProviderCatalog as P}from"../../commands/sys/panels/provider-panel.js";function x(a){const t=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",i=process.platform==="win32"?["/c","start","",a]:[a];f(t,i,{timeout:5e3},()=>{})}r(x,"openBrowser");class C{static{r(this,"FrontDoorLogin")}tui;runtime;agentDir;finish;component;dialog;settled=!1;constructor(t,i,s,o,c){this.tui=t,this.runtime=i,this.agentDir=s,this.finish=c,this.component=new p("login",o,n=>this.startLogin(o.find(u=>u.id===n)),()=>this.complete(!1))}get focused(){return this.component.focused}set focused(t){this.component.focused=t}handleInput(t){this.component.handleInput?.(t)}invalidate(){this.tui.requestRender()}render(t){return this.component.render(t)}dispose(){this.settled||this.dialog?.handleInput("\x1B")}complete(t){this.settled||(this.settled=!0,this.finish(t))}startLogin(t){if(!t){this.complete(!1);return}const i=new l(this.tui,t.id,e=>this.complete(e),t.name);this.dialog=i,this.component=i,this.tui.setFocus(this),this.tui.requestRender();const s=y(i,{openBrowser:x,onChange:r(()=>this.tui.requestRender(),"onChange"),isActive:r(()=>!this.settled&&!i.signal.aborted,"isActive")}),o=r(()=>{i.signal.aborted||this.complete(!1)},"fail");if(t.authType==="api_key"){i.showPrompt(`Enter API key for ${t.name}:`,"sk-...").then(async e=>{if(!e.trim()||this.settled){this.complete(!1);return}await w(t.id,{type:"api_key",key:e.trim()},g(this.agentDir,"auth.json")),this.complete(!0)}).catch(o);return}const c=this.runtime.getProvider(t.id)?.auth.oauth;if(!c){this.complete(!1);return}const n=t.id;if(!L(n)){this.runtime.login(n,"oauth",s).then(()=>this.complete(!0)).catch(e=>{if(e instanceof d){this.complete(!0);return}o()});return}const u=Math.max(0,...b(n).map(e=>e.lastRateLimitedAt));c.login(s).then(async e=>{if(this.settled||i.signal.aborted)return;const h=typeof e.accountId=="string"&&e.accountId.trim()?e.accountId.trim():void 0;await I(n,void 0,{access:e.access,refresh:e.refresh,expires:e.expires,...h?{accountId:h}:{},lastRateLimitedAt:u,autoLabel:!0}),this.complete(!0)}).catch(o)}}async function E(){return await A(({tui:t,agentDir:i,runtime:s,registry:o},c)=>new C(t,s,i,P(s,o).map(({providerId:n,name:u,authType:e})=>({id:n,name:u,authType:e})),c.submit))===!0}r(E,"runFrontDoorLogin");export{E as runFrontDoorLogin};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
1
|
+
var E=Object.defineProperty;var p=(r,i)=>E(r,"name",{value:i,configurable:!0});import{existsSync as w,statSync as F}from"node:fs";import{homedir as v}from"node:os";import{join as I,resolve as m}from"node:path";import{SUBTREE_NAMES as _}from"../../build-root.js";import{FRONT_DOOR_ENV as N}from"./front-door-env.js";function g(r){try{return w(r)&&F(r).isDirectory()}catch{return!1}}p(g,"isDir");const A=new Set(["--name","--kind","--profile","--pick-profile","--continue","-c","--resume","-r"]),h=I(v(),".crouter","setup-completed.json");async function C(){let r=!1;const i=p(()=>{r=!0},"onSigint");process.once("SIGINT",i);try{const{runSetup:e}=await import("../../commands/sys/setup-wizard.js"),t=await e();if(r){const c=new Error("Interrupted");throw c.name="AbortError",c}const[{atomicWriteJson:a},{crtrVersion:f}]=await Promise.all([import("../fs-utils.js"),import("../../shared/crtr-version.js")]);a(h,{packageVersion:f(),completedAt:new Date().toISOString(),outcome:t})}finally{process.removeListener("SIGINT",i)}}p(C,"runFirstSetup");function L(r){let i=process.cwd(),e,t,a,f=!1,c;const l=[];for(let n=0;n<r.length;n++){const o=r[n];o==="--name"?e=r[++n]:o==="--kind"?t=r[++n]:o==="--profile"?a=r[++n]:o==="--pick-profile"?f=!0:o==="--continue"||o==="-c"?c="continue":o==="--resume"||o==="-r"?c="pick":o.startsWith("--")||l.push(o)}l.length>0&&g(m(l[0]))&&(i=m(l.shift()));const d=l.length>0?l.join(" "):void 0;return{cwd:i,prompt:d,name:e,kind:t,profile:a,pickProfile:f,resume:c}}p(L,"parseRootArgs");import{FRONT_DOOR_ENV as Y}from"./front-door-env.js";async function B(r){const i=r.slice(2),e=i[0];if(process.env[N]||e==="-h"||e==="--help"||e==="--version"||e==="-v"||e!==void 0&&_.includes(e))return!1;if(e!==void 0){const s=/\s/.test(e),u=!e.startsWith("-")&&g(m(e)),T=A.has(e);if(!s&&!u&&!T)return!1;if(u){const{buildRoot:y}=await import("../../build-root.js");if((await y()).subtrees.some(D=>D.name===e))return!1}}const t=L(i);if(t.profile!==void 0){const{resolveProfileOperand:s}=await import("../profiles/manifest.js");t.profile=s(t.profile).profileId}const a=process.stdin.isTTY&&process.stdout.isTTY;let f=!1;a&&!w(h)&&(await C(),f=!0);const{selectProfileForCwd:c,selectProfileForCwdReadOnly:l}=await import("../profiles/select.js");f&&t.profile===void 0&&process.stdout.write(`
|
|
2
|
+
Choose a profile
|
|
3
|
+
`);const d=t.profile??(a?await c(t.cwd,void 0,t.pickProfile):l(t.cwd)),{exitForMissingProviderCredential:n,hasConfiguredProviderCredential:o}=await import("./provider-credential-gate.js");if(!await o(d)){a||n();const{runFrontDoorLogin:s}=await import("./front-door-login.js");await s()||n()}const[{bootRoot:R},{resumeRoot:P},{rendererWarning:k,missingPackageWarning:S,piAgentDir:O}]=await Promise.all([import("./boot-root.js"),import("./resume-root.js"),import("./package-health.js")]);try{const s=S(O());s!==null&&process.stderr.write(`
|
|
4
|
+
${s}
|
|
3
5
|
|
|
4
|
-
`);const
|
|
5
|
-
${
|
|
6
|
+
`);const u=k();u!==null&&process.stderr.write(`
|
|
7
|
+
${u}
|
|
6
8
|
|
|
7
|
-
`)}catch{}return
|
|
9
|
+
`)}catch{}return t.resume!==void 0&&await P(t.cwd,t.resume==="pick")==="aborted"||await R({...t,selectedProfileId:d}),!0}p(B,"maybeBootRoot");export{Y as FRONT_DOOR_ENV,B as maybeBootRoot};
|
|
@@ -10,8 +10,26 @@ export declare function detectNerdFont(platform?: NodeJS.Platform, home?: string
|
|
|
10
10
|
/** Download the upstream symbols-only patch into the user's font dir. Works on
|
|
11
11
|
* every Linux regardless of package manager — Debian/Ubuntu and Fedora ship no
|
|
12
12
|
* Nerd Font package, so there is nothing native to install there. Needs no
|
|
13
|
-
* sudo: it writes to `~/.local/share/fonts`.
|
|
13
|
+
* sudo: it writes to `~/.local/share/fonts`.
|
|
14
|
+
*
|
|
15
|
+
* curl runs with its progress meter on (no `-s`) because this is the one
|
|
16
|
+
* install step with a real download percentage: setup captures that stderr
|
|
17
|
+
* and drives the step's progress bar from it (`parseCurlPercent`). */
|
|
14
18
|
export declare const NERD_FONT_MANUAL_LINUX_COMMAND: string;
|
|
19
|
+
/** Reads percent complete out of curl's default progress meter as its stderr
|
|
20
|
+
* arrives. Rows are separated by `\r` and look like
|
|
21
|
+
* `100 1234k 100 1234k 0 0 987k 0 --:--:-- …`; the leading
|
|
22
|
+
* column is the percentage of the whole transfer, and the header rows
|
|
23
|
+
* (` % Total % Received …`) start with `%` so they never match.
|
|
24
|
+
*
|
|
25
|
+
* Stateful because curl's writes split rows anywhere: the tail of a chunk is
|
|
26
|
+
* held back until its row is terminated. Reading a half-row instead lands on
|
|
27
|
+
* a different column and reports a number that was never true — in practice
|
|
28
|
+
* the completed download's own summary row parsed as 0%.
|
|
29
|
+
*
|
|
30
|
+
* Returns the percentage of the last complete row in this chunk, or null when
|
|
31
|
+
* the chunk completed no row. */
|
|
32
|
+
export declare function createCurlPercentReader(): (chunk: string) => number | null;
|
|
15
33
|
export interface NerdFontInstallCommand {
|
|
16
34
|
command: string | null;
|
|
17
35
|
hint: string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
`))if(
|
|
1
|
+
var d=Object.defineProperty;var e=(n,t)=>d(n,"name",{value:t,configurable:!0});import{spawnSync as u}from"node:child_process";import{readdirSync as m}from"node:fs";import{homedir as p}from"node:os";import{join as l}from"node:path";const c=/nerd[ _-]?font|symbolsnerdfont|symbols-only/i;function y(n,t){return n==="darwin"?[l(t,"Library","Fonts"),"/Library/Fonts","/System/Library/Fonts"]:[l(t,".local","share","fonts"),l(t,".fonts"),"/usr/local/share/fonts","/usr/share/fonts"]}e(y,"fontDirs");function a(n,t){if(t<0)return null;let o;try{o=m(n,{withFileTypes:!0})}catch{return null}for(const r of o){if(r.isDirectory()){const s=a(l(n,r.name),t-1);if(s!==null)return s;continue}if(/\.(ttf|otf|ttc)$/i.test(r.name)&&c.test(r.name))return r.name}return null}e(a,"scanForNerdFont");function b(){if(u("sh",["-lc","command -v fc-list >/dev/null 2>&1"],{stdio:"ignore"}).status!==0)return null;const t=u("fc-list",[":","family"],{encoding:"utf8",timeout:5e3});if(t.status!==0||typeof t.stdout!="string")return null;for(const o of t.stdout.split(`
|
|
2
|
+
`))if(c.test(o))return o.split(",")[0].trim();return""}e(b,"queryFontconfig");function I(n=process.platform,t=p()){if(n!=="darwin"){const o=b();if(o!==null&&o!=="")return{installed:!0,evidence:o,source:"fc-list"}}for(const o of y(n,t)){const r=a(o,3);if(r!==null)return{installed:!0,evidence:r,source:"font-dir"}}return{installed:!1,evidence:null,source:null}}e(I,"detectNerdFont");const N="mkdir -p ~/.local/share/fonts && curl -fL -o /tmp/NerdFontsSymbolsOnly.zip https://github.com/ryanoasis/nerd-fonts/releases/latest/download/NerdFontsSymbolsOnly.zip && unzip -oq /tmp/NerdFontsSymbolsOnly.zip -d ~/.local/share/fonts && fc-cache -f";function L(){let n="";return t=>{n+=t;const o=n.split(/[\r\n]/);n=o.pop()??"";let r=null;for(const s of o){const i=/^\s*(\d{1,3})\s+\S+\s+\d{1,3}\s/.exec(s);if(i===null)continue;const f=Number(i[1]);f<=100&&(r=f)}return r}}e(L,"createCurlPercentReader");function T(n,t=process.platform){const o=t!=="darwin"||n==="apt-get"||n==="dnf"||n==="pacman";return n==="brew"?{command:"brew install --cask font-symbols-only-nerd-font",hint:"Homebrew cask",autoInstall:!0}:n==="pacman"?{command:"sudo pacman -S --noconfirm ttf-nerd-fonts-symbols",hint:"pacman install",autoInstall:!0}:o?{command:N,hint:"download symbols-only patch to ~/.local/share/fonts (needs curl + unzip)",autoInstall:!0}:{command:null,hint:"install Homebrew, or download a Nerd Font from https://nerdfonts.com and add it in Font Book",autoInstall:!1}}e(T,"nerdFontInstallCommand");const x=`then set your terminal profile's font to a Nerd Font (e.g. add "Symbols Nerd Font Mono" as the non-ASCII/fallback font) \u2014 installing it does not select it`;export{N as NERD_FONT_MANUAL_LINUX_COMMAND,x as NERD_FONT_SELECT_HINT,L as createCurlPercentReader,I as detectNerdFont,T as nerdFontInstallCommand};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** A running progress bar line. `setFraction` fills it from a real count;
|
|
2
|
+
* leaving it unset keeps the indeterminate slider. `stop` erases the line and
|
|
3
|
+
* resolves once the painter has released the terminal, so the caller can
|
|
4
|
+
* write its own outcome line without interleaving. */
|
|
5
|
+
export interface ProgressBar {
|
|
6
|
+
setFraction(fraction: number): void;
|
|
7
|
+
stop(): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
/** Start an animated bar on `stream`, drawn by a child process so it keeps
|
|
10
|
+
* moving while this process blocks inside the step it describes. */
|
|
11
|
+
export declare function startProgressBar(label: string, stream?: NodeJS.WriteStream & {
|
|
12
|
+
fd: number;
|
|
13
|
+
}): ProgressBar;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var p=Object.defineProperty;var n=(o,e)=>p(o,"name",{value:e,configurable:!0});import{spawn as f}from"node:child_process";import{dirname as m,join as d}from"node:path";import{assetRoot as u}from"../asset-root.js";const s={setFraction(){},stop:n(async()=>{},"stop")};function l(){return d(m(u()),"bin","progress-painter.mjs")}n(l,"painterPath");function b(o,e=process.stdout){if(!e.isTTY)return s;let t;try{t=f(process.execPath,[l(),o],{stdio:["pipe",e.fd,"ignore"]})}catch{return s}let i=!0;t.stdin?.on("error",()=>{i=!1});const a=new Promise(r=>{t.once("exit",()=>{i=!1,r()}),t.once("error",()=>{i=!1,r()})});return{setFraction(r){i&&t.stdin?.write(`${Math.min(1,Math.max(0,r))}
|
|
2
|
+
`)},async stop(){i&&t.stdin?.end();const r=new Promise(c=>setTimeout(()=>{t.kill("SIGKILL"),c()},1e3).unref());await Promise.race([a,r]),e.write("\r\x1B[2K\x1B[?25h")}}}n(b,"startProgressBar");export{b as startProgressBar};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const NO_PROVIDER_CREDENTIAL_MESSAGE = "crtr: no provider credential; run `crtr sys setup` to log in.";
|
|
2
|
+
/** Check the setup catalog before a path creates a broker-backed node. */
|
|
3
|
+
export declare function hasConfiguredProviderCredential(profileId?: string | null): Promise<boolean>;
|
|
4
|
+
export declare function exitForMissingProviderCredential(): never;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var m=Object.defineProperty;var o=(r,e)=>m(r,"name",{value:e,configurable:!0});import{ModelRegistry as a,ModelRuntime as d}from"@earendil-works/pi-coding-agent";import{join as s}from"node:path";import{PoolCredentialStore as l}from"../pool-credential-store.js";import{readProfileEnvVars as p}from"../profiles/env-store.js";import{hasProviderCredential as c}from"../provider-credential.js";import{piAgentDir as f}from"./package-health.js";import{PROVIDER_ENV_KEYS as u}from"./spawn-env.js";const E="crtr: no provider credential; run `crtr sys setup` to log in.";async function h(r=null){const e=p(r);if(Object.values(u).some(n=>(e[n]??process.env[n])?.trim()))return!0;const t=f(),i=await d.create({credentials:new l(s(t,"auth.json")),modelsPath:s(t,"models.json")});return c(i,new a(i))}o(h,"hasConfiguredProviderCredential");function j(){process.stderr.write(`${E}
|
|
2
|
+
`),process.exit(1)}o(j,"exitForMissingProviderCredential");export{E as NO_PROVIDER_CREDENTIAL_MESSAGE,j as exitForMissingProviderCredential,h as hasConfiguredProviderCredential};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PiInvocation } from './invocation.js';
|
|
2
|
+
import type { ModelProvider } from '../../types.js';
|
|
2
3
|
/** The unshimmed PATH admitted from the host. Broker and cron shells resolve
|
|
3
4
|
* crouter-owned executables from this value, while commands those shells run
|
|
4
5
|
* still receive the shim-prepended PATH. */
|
|
@@ -7,6 +8,12 @@ export declare const ADMITTED_HOST_PATH_ENV = "CRTR_ADMITTED_HOST_PATH";
|
|
|
7
8
|
* The result is absolute, or null when no PATH entry supplies the command. */
|
|
8
9
|
export declare function resolvePathExecutable(name: string, env: NodeJS.ProcessEnv, cwd: string): string | null;
|
|
9
10
|
export declare function resolveAdmittedHostCommand(name: string, env: NodeJS.ProcessEnv, cwd: string): string;
|
|
11
|
+
/** B — the exact env-var name of each crtr-configured model provider's API
|
|
12
|
+
* key. Deliberately an explicit provider→env-key mapping, NOT inferred from
|
|
13
|
+
* `MODEL_PROVIDER_KEYS` in launch.ts (that constant is a provider-ID list —
|
|
14
|
+
* `['anthropic', 'openai']` — not env-var names; conflating the two would
|
|
15
|
+
* silently admit the wrong names the moment either list changes). */
|
|
16
|
+
export declare const PROVIDER_ENV_KEYS: Record<ModelProvider, string>;
|
|
10
17
|
/** Sources A–C: the operational base shared by the broker boundary (this
|
|
11
18
|
* module's `buildBrokerEnv`) and cron executor — the single shared definition
|
|
12
19
|
* of "non-secret host state the runtime exposes to any spawned shell." Does not include
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var u=Object.defineProperty;var a=(e,t)=>u(e,"name",{value:t,configurable:!0});import{statSync as d}from"node:fs";import{delimiter as P,resolve as E}from"node:path";import{readMergedLaunchConfig as
|
|
1
|
+
var u=Object.defineProperty;var a=(e,t)=>u(e,"name",{value:t,configurable:!0});import{statSync as d}from"node:fs";import{delimiter as P,resolve as E}from"node:path";import{readMergedLaunchConfig as p}from"../config.js";import{readProfileEnvVars as T}from"../profiles/env-store.js";import{metadataEnvName as _,readProfileMetadata as m}from"../profiles/manifest.js";import{binShimDirFor as A}from"./bin-contributions.js";import{FRONT_DOOR_ENV as O}from"./front-door-env.js";const R=new Set(["HOME","PATH","SHELL","USER","LOGNAME","PWD","TMPDIR","TERM","TERMINFO","COLORTERM","LANG","LANGUAGE","TZ","NO_PROXY","no_proxy","SSH_AUTH_SOCK","CRTR_BASH_VALVE_MS"]),h=["LC_","XDG_","PI_"],f="CRTR_ADMITTED_HOST_PATH";function H(e,t,o){const n=t.PATH;if(n===void 0||n==="")return null;for(const s of n.split(P)){const c=E(o,s===""?".":s,e);try{const r=d(c);if(r.isFile()&&(r.mode&73)!==0)return c}catch{}}return null}a(H,"resolvePathExecutable");function $(e,t,o){const n=t[f]??t.PATH;if(n===void 0||n==="")throw new Error(`cannot resolve crouter-owned ${e}: the admitted host PATH is empty`);const s=H(e,{PATH:n},o);if(s!==null)return s;throw new Error(`cannot resolve crouter-owned ${e} from the admitted host PATH`)}a($,"resolveAdmittedHostCommand");const v=["HTTP_PROXY","HTTPS_PROXY","http_proxy","https_proxy"],I={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY"};function w(e){let t;try{t=new URL(e)}catch{return!1}return!(t.protocol!=="http:"&&t.protocol!=="https:"||t.hostname===""||t.username!==""||t.password!=="")}a(w,"isCredentialFreeProxyValue");function N(e,t){if(!t.includes("*"))return e===t;const o=t.split("*").map(n=>n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${o}$`).test(e)}a(N,"matchesAllowPattern");function S(e){const t=e.host??process.env,o={};for(const[r,i]of Object.entries(t))i!==void 0&&(R.has(r)||h.some(l=>r.startsWith(l)))&&(o[r]=i);for(const r of v){const i=t[r];i!==void 0&&w(i)&&(o[r]=i)}for(const r of Object.values(I)){const i=t[r];i!==void 0&&(o[r]=i)}const n=p(e.targetCwd,e.targetProfileId).spawnEnv.allow;if(n.length>0)for(const[r,i]of Object.entries(t))i!==void 0&&n.some(l=>N(r,l))&&(o[r]=i);const s=t[f]??o.PATH;s!==void 0&&s!==""&&(o[f]=s);const c=A(e.targetCwd,e.targetProfileId);if(c!==null){const r=o.PATH;o.PATH=r===void 0||r===""?c:`${c}:${r}`}return o}a(S,"buildOperationalEnvBase");function C(e){const t={};for(const[o,n]of Object.entries(m(e)))t[_(o)]=n;return t}a(C,"profileMetadataEnv");function F(e){const t=e.env.CRTR_NODE_CWD??process.cwd(),o=e.env.CRTR_PROFILE_ID||null,n=S({targetCwd:t,targetProfileId:o});return{...n,...C(o),...T(o),...e.env,[f]:n[f],[O]:"1"}}a(F,"buildBrokerEnv");export{f as ADMITTED_HOST_PATH_ENV,I as PROVIDER_ENV_KEYS,F as buildBrokerEnv,S as buildOperationalEnvBase,C as profileMetadataEnv,$ as resolveAdmittedHostCommand,H as resolvePathExecutable};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var A=Object.defineProperty;var r=(e,t)=>A(e,"name",{value:t,configurable:!0});import{canonicalSessionFile as N,findNodeBySessionFile as P,getNode as k,isWarmSpare as R,listNodeIdentities as T,recordSettledTurn as $,setPresence as _,subscriptionsOf as C,updateNode as g}from"../../../core/canvas/canvas.js";import{recordExecutionPid as I}from"../../../core/canvas/executions.js";import{bindSession as j,readLiveSession as q,transferSession as E}from"../../../core/canvas/sessions.js";import{isSafeNodeId as M}from"../../../core/canvas/paths.js";import{isPidAlive as L}from"../../../core/canvas/pid.js";import{editorLabel as B}from"../../../core/canvas/labels.js";import{assembleNodeSubject as G}from"../../../core/substrate/subject.js";import{withCanvasWrite as l}from"../../../core/canvas/db.js";import{notFound as v,usage as a}from"../../../core/errors.js";import{hasUnseenWakeMail as O}from"../../../core/canvas/deliveries.js";import{clearYieldMessage as J}from"../../../core/runtime/kickoff.js";import{transition as b}from"../../../core/runtime/lifecycle.js";import{focusOf as w,tearDownNode as S}from"../../../core/runtime/placement.js";import{hasAttachedBrokerViewers as W}from"../../../core/runtime/broker/client-registry.js";import{evaluateStop as D}from"../../../core/runtime/stop-guard.js";import{clearFault as f,recordFault as U}from"../../../core/canvas/recovery.js";import{updateModelRecipe as V}from"../../../core/runtime/model-swap.js";import{completeCompanionRequestedSubmit as Y}from"../../review/finish.js";import{emitEvent as z}from"../../../core/events/emit.js";import{consumePendingPark as H,recordPendingParkActivity as K}from"../../park-pending.js";import{shouldParkAfterSummary as Q}from"../../park-activity.js";import{requireCurrentExecution as m}from"./broker-recovery.js";function p(e,t){if(typeof e!="object"||e===null||Array.isArray(e))throw a(`${t} requires a JSON body`);return e}r(p,"objectBody");function X(e){const t=p(e,"broker session-bound");if(typeof t.executionId!="string"||t.executionId==="")throw a("executionId must be a non-empty string");if(typeof t.piSessionId!="string"||t.piSessionId==="")throw a("piSessionId must be a non-empty string");if(t.sessionFile!==null&&typeof t.sessionFile!="string")throw a("sessionFile must be a string or null");if(!Number.isSafeInteger(t.pid)||t.pid<=0)throw a("pid must be a positive safe integer");if(t.reason!==null&&typeof t.reason!="string")throw a("reason must be a string or null");if(!Array.isArray(t.reviewBoundaryIds)||!t.reviewBoundaryIds.every(n=>typeof n=="string"))throw a("reviewBoundaryIds must be an array of strings");return t}r(X,"parseSessionBoundBody");function Z(e){const t=p(e,"broker settle");if(typeof t.stopReason!="string")throw a("stopReason must be a string");for(const n of["backgroundJobsRunning","pushedFinal"])if(typeof t[n]!="boolean")throw a(`${n} must be a boolean`);return t}r(Z,"parseSettleBody");function ee(e){const t=p(e,"broker park-complete");if(t.outcome!=="completed"&&t.outcome!=="failed")throw a("outcome must be completed or failed");return t}r(ee,"parseParkCompleteBody");function te(e){const t=p(e,"broker model");if(typeof t.spec!="string"||t.spec.trim()==="")throw a("spec must be a non-empty string");if(t.pinnedOverride!==void 0&&typeof t.pinnedOverride!="boolean")throw a("pinnedOverride must be a boolean when present");if(typeof t.userSelected!="boolean")throw a("userSelected must be a boolean");return t}r(te,"parseModelCommitBody");function h(e){const t=k(e);if(t===null)throw v(`unknown node: ${e}`,{received:e});return t}r(h,"requireNode");function y(e){return{node_id:e.node_id,name:e.name,...e.description===void 0?{}:{description:e.description},...e.title===void 0?{}:{title:e.title},...e.icon===void 0?{}:{icon:e.icon},kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,parent:e.parent??null,fork_from:e.fork_from??null,profile_id:e.profile_id??null,...e.managed_worktree===void 0?{}:{managed_worktree:e.managed_worktree===null?null:{state:e.managed_worktree.state,...e.managed_worktree.cleanup===void 0?{}:{cleanup:e.managed_worktree.cleanup},path:e.managed_worktree.path,branch:e.managed_worktree.branch,base_ref:e.managed_worktree.base_ref,base_sha:e.managed_worktree.base_sha}},...e.review_binding===void 0?{}:{review_binding:e.review_binding??null},intent:e.intent??null,...e.persona_ack===void 0?{}:{persona_ack:e.persona_ack},created:e.created}}r(y,"extensionNode");function ne(e){const t=h(e),n=[],o=new Set([e]);let i=t.parent??null;for(;i!==null&&i!==""&&!o.has(i);){o.add(i);const c=k(i);if(c===null)break;n.unshift(y(c)),i=c.parent??null}const s=C(e).map(c=>k(c.node_id)).filter(c=>c!==null&&c.kind!=="human").sort((c,x)=>c.status===x.status?0:c.status==="active"?-1:x.status==="active"?1:0).map(y),u=typeof t.fork_source_file=="string"?P(t.fork_source_file):null,d=G(e);if(d===null)throw v(`unknown node: ${e}`,{received:e});return{node:y(t),warm_spare:R(e),ancestors:n,children:s,fork_source:u===null?null:y(u),subject:d,report_nodes:T()}}r(ne,"extensionState");function F(e,t){return e?.kind===t.kind&&e?.mode===t.mode&&e?.lifecycle===t.lifecycle}r(F,"samePersona");function ie(e){const t=p(e,"broker generated-name");if(t.kind!=="initial"&&t.kind!=="recap")throw a("kind must be initial or recap");if(typeof t.description!="string"||typeof t.title!="string"||typeof t.icon!="string")throw a("description, title, and icon must be strings");if(t.kind==="initial")return t;const n=t.expected;if(typeof n!="object"||n===null||Array.isArray(n)||["name","description","title","icon","kind"].some(o=>typeof n[o]!="string"))throw a("recap expected must contain name, description, title, icon, and kind strings");return t}r(ie,"parseGeneratedNameBody");function oe(e){const t=p(e,"broker persona-ack"),n=r(o=>{const i=t[o];if(typeof i!="object"||i===null||Array.isArray(i)||typeof i.kind!="string"||i.mode!=="base"&&i.mode!=="orchestrator"||i.lifecycle!=="terminal"&&i.lifecycle!=="resident")throw a(`${o} must be a persona state`);return i},"parse");return{expected_execution_id:t.expected_execution_id,from:n("from"),to:n("to")}}r(oe,"parsePersonaAckBody");function re(e){const t=e.params.id,n=X(e.body),o=n.sessionFile===null?null:N(n.sessionFile);return{status:200,body:l(()=>{const s=h(t);if(I(n.executionId,t,n.pid)==="shutdown")return{action:"shutdown"};const u=s.review_binding?.review_id;if(u!==void 0&&!n.reviewBoundaryIds.includes(u))return{action:"shutdown"};if(n.reason==="new"&&s.parent==null)return{action:"relaunch_root"};if(n.reason!=="new"&&s.fork_from!=null&&s.pi_session_id==null&&o===null)return{action:"shutdown"};const d=o===null?null:P(o);if(d!==null&&d.node_id!==t){if(L(d.pi_pid))return U(t,{link:"daemon\u2192node",op:"session-file-ownership",kind:"protocol",retry:{disposition:"fatal"},message:`refusing to bind ${o}: it is owned by live node ${d.node_id}`}),{action:"shutdown"};const c=q(d.node_id);if(c===null||E({fromNodeId:d.node_id,fromBindingId:c.bindingId,toNodeId:t,executionId:n.executionId,sessionId:n.piSessionId,transcriptPath:o})!=="transferred")return{action:"shutdown"}}else if(j(t,{executionId:n.executionId,sessionId:n.piSessionId,transcriptPath:o})==="shutdown")return{action:"shutdown"};return n.reason!=="new"&&(J(t),s.intent==="refresh"&&b(t,"revive")),{action:"none"}})}}r(re,"handleSessionBound");function se(e,t){const n=k(e);if(n===null){if(t.pushedFinal)return{action:"shutdown"};throw v(`unknown node: ${e}`,{received:e})}if($(e,new Date().toISOString()),t.stopReason==="quit")return(n.status==="active"||n.status==="idle")&&n.intent===null&&(b(e,"finish"),f(e),w(e)!==null&&S(e),_(e,{pane:null,tmux_session:null,window:null})),{action:"shutdown"};if(t.stopReason!=="stop"&&t.stopReason!=="length")return f(e,{link:"daemon\u2192node"}),n.intent==="refresh"?{action:"shutdown"}:{action:"stay_dormant"};const o={pushedFinal:t.pushedFinal};if(o.pushedFinal||n.status==="done")return f(e),w(e)!==null&&S(e),_(e,{pane:null,tmux_session:null,window:null}),{action:"shutdown"};if(n.intent==="refresh")return f(e),{action:"shutdown"};const i=D(e,o,t.backgroundJobsRunning);return f(e),i.action==="reprompt"?{action:"reprompt",prompt:i.message}:i.reason==="finished"?O(e)?{action:"stay_dormant"}:{action:"shutdown"}:i.reason!=="awaiting"&&i.reason!=="scheduled"?{action:"stay_dormant"}:w(e)!==null||W(e)||O(e)?{action:"stay_dormant"}:(b(e,"release"),{action:"shutdown"})}r(se,"settleBroker");function ae(e){const t=e.params.id,n=Z(e.body);m(t,n.expected_execution_id);const o=l(()=>se(t,n));return o.action!=="reprompt"&&Y(t),{status:200,body:o}}r(ae,"handleSettle");function de(e){const t=e.params.id,n=ee(e.body);return m(t,n.expected_execution_id),{status:200,body:l(()=>{const i=H(t);if(i===void 0)return{action:"stay_dormant"};const s=h(t);return Q(t,s,i)?(f(t),b(t,"park"),w(t)!==null&&S(t),_(t,{pane:null,tmux_session:null,window:null}),z({level:n.outcome==="completed"?"info":"warn",event:"broker.park.complete",...M(t)?{node_id:t}:{},outcome:n.outcome==="completed"?"succeeded":"failed"}),{action:"shutdown"}):{action:"stay_dormant"}})}}r(de,"handleParkComplete");function ue(e){const t=e.params.id;return m(t,p(e.body,"broker park-activity").expected_execution_id),{status:200,body:l(()=>({activity:K(t)?"recorded":"none"}))}}r(ue,"handleParkActivity");function ce(e){const t=e.params.id,n=te(e.body);return m(t,n.expected_execution_id),{status:200,body:{modelOverride:l(()=>V(h(t),n.spec,n.pinnedOverride,n.userSelected)).model_override}}}r(ce,"handleModelCommit");function le(e){return{status:200,body:ne(e.params.id)}}r(le,"handleExtensionState");function pe(e){const t=e.params.id,n=ie(e.body);return m(t,n.expected_execution_id),{status:200,body:l(()=>{const i=h(t);if(n.kind==="initial"){if((i.description??"").trim()!=="")return{applied:!1};const d=g(t,{description:n.description,...n.title.trim()===""?{}:{title:n.title},...n.icon.trim()===""?{}:{icon:n.icon}});return{applied:!0,editorLabel:B(d),description:d.description??"",title:d.title??"",icon:d.icon??""}}const s=n.expected;if(i.name!==s.name||(i.description??"")!==s.description||(i.title??"")!==s.title||(i.icon??"")!==s.icon||i.kind!==s.kind)return{applied:!1};const u=g(t,{description:n.description,title:n.title.trim()===""?void 0:n.title,icon:n.icon.trim()===""?void 0:n.icon});return{applied:!0,editorLabel:B(u),description:u.description??"",title:u.title??"",icon:u.icon??""}})}}r(pe,"handleGeneratedName");function fe(e){const t=e.params.id,n=oe(e.body);return m(t,n.expected_execution_id),{status:200,body:l(()=>{const i=h(t),s={kind:i.kind,mode:i.mode,lifecycle:i.lifecycle},u=i.persona_ack,d=u===void 0?s:{kind:u.kind??i.kind,mode:u.mode,lifecycle:u.lifecycle};return!F(s,n.to)||!F(d,n.from)?{applied:!1}:(g(t,{persona_ack:n.to}),{applied:!0})})}}r(fe,"handlePersonaAck");const qe=[{method:"POST",pattern:"/v1/nodes/:id/broker/session-bound",handler:re},{method:"POST",pattern:"/v1/nodes/:id/broker/settle",handler:ae},{method:"POST",pattern:"/v1/nodes/:id/broker/park-complete",handler:de},{method:"POST",pattern:"/v1/nodes/:id/broker/park-activity",handler:ue},{method:"POST",pattern:"/v1/nodes/:id/broker/model",handler:ce},{method:"GET",pattern:"/v1/nodes/:id/broker/extension-state",handler:le},{method:"POST",pattern:"/v1/nodes/:id/broker/generated-name",handler:pe},{method:"POST",pattern:"/v1/nodes/:id/broker/persona-ack",handler:fe}];export{qe as brokerOperationRoutes};
|
|
1
|
+
var F=Object.defineProperty;var r=(t,e)=>F(t,"name",{value:e,configurable:!0});import{canonicalSessionFile as A,findNodeBySessionFile as P,getNode as k,isWarmSpare as T,listNodeIdentities as I,recordSettledTurn as R,setPresence as w,subscriptionsOf as $,updateNode as g,updateNodeTelemetry as q}from"../../../core/canvas/canvas.js";import{recordExecutionPid as C}from"../../../core/canvas/executions.js";import{bindSession as j,readLiveSession as E,transferSession as M}from"../../../core/canvas/sessions.js";import{isSafeNodeId as D}from"../../../core/canvas/paths.js";import{isPidAlive as L}from"../../../core/canvas/pid.js";import{editorLabel as N}from"../../../core/canvas/labels.js";import{assembleNodeSubject as G}from"../../../core/substrate/subject.js";import{withCanvasWrite as l}from"../../../core/canvas/db.js";import{notFound as v,usage as s}from"../../../core/errors.js";import{hasUnseenWakeMail as O}from"../../../core/canvas/deliveries.js";import{clearYieldMessage as J}from"../../../core/runtime/kickoff.js";import{transition as h}from"../../../core/runtime/lifecycle.js";import{focusOf as b,tearDownNode as x}from"../../../core/runtime/placement.js";import{hasAttachedBrokerViewers as W}from"../../../core/runtime/broker/client-registry.js";import{evaluateStop as U}from"../../../core/runtime/stop-guard.js";import{clearFault as m,recordFault as V}from"../../../core/canvas/recovery.js";import{updateModelRecipe as Y}from"../../../core/runtime/model-swap.js";import{completeCompanionRequestedSubmit as z}from"../../review/finish.js";import{emitEvent as H}from"../../../core/events/emit.js";import{consumePendingPark as K,recordPendingParkActivity as Q}from"../../park-pending.js";import{shouldParkAfterSummary as X}from"../../park-activity.js";import{requireCurrentExecution as f}from"./broker-recovery.js";function p(t,e){if(typeof t!="object"||t===null||Array.isArray(t))throw s(`${e} requires a JSON body`);return t}r(p,"objectBody");function Z(t){const e=p(t,"broker session-bound");if(typeof e.executionId!="string"||e.executionId==="")throw s("executionId must be a non-empty string");if(typeof e.piSessionId!="string"||e.piSessionId==="")throw s("piSessionId must be a non-empty string");if(e.sessionFile!==null&&typeof e.sessionFile!="string")throw s("sessionFile must be a string or null");if(!Number.isSafeInteger(e.pid)||e.pid<=0)throw s("pid must be a positive safe integer");if(e.reason!==null&&typeof e.reason!="string")throw s("reason must be a string or null");if(!Array.isArray(e.reviewBoundaryIds)||!e.reviewBoundaryIds.every(n=>typeof n=="string"))throw s("reviewBoundaryIds must be an array of strings");return e}r(Z,"parseSessionBoundBody");function ee(t){const e=p(t,"broker settle");if(typeof e.stopReason!="string")throw s("stopReason must be a string");for(const n of["backgroundJobsRunning","pushedFinal"])if(typeof e[n]!="boolean")throw s(`${n} must be a boolean`);return e}r(ee,"parseSettleBody");function te(t){const e=p(t,"broker park-complete");if(e.outcome!=="completed"&&e.outcome!=="failed")throw s("outcome must be completed or failed");return e}r(te,"parseParkCompleteBody");function ne(t){const e=p(t,"broker telemetry");if(typeof e.expected_execution_id!="string"||e.expected_execution_id==="")throw s("expected_execution_id must be a non-empty string");if(typeof e.tokens_in!="number"||!Number.isFinite(e.tokens_in)||e.tokens_in<0)throw s("tokens_in must be a non-negative finite number");if(e.context_tokens!==null&&(typeof e.context_tokens!="number"||!Number.isFinite(e.context_tokens)||e.context_tokens<0))throw s("context_tokens must be a non-negative finite number or null");if(e.last_activity!==null&&typeof e.last_activity!="string")throw s("last_activity must be a string or null");if(typeof e.updated_at!="string"||Number.isNaN(Date.parse(e.updated_at)))throw s("updated_at must be an ISO timestamp");return{...e,updated_at:new Date(e.updated_at).toISOString()}}r(ne,"parseTelemetryBody");function ie(t){const e=p(t,"broker model");if(typeof e.spec!="string"||e.spec.trim()==="")throw s("spec must be a non-empty string");if(e.pinnedOverride!==void 0&&typeof e.pinnedOverride!="boolean")throw s("pinnedOverride must be a boolean when present");if(typeof e.userSelected!="boolean")throw s("userSelected must be a boolean");return e}r(ie,"parseModelCommitBody");function _(t){const e=k(t);if(e===null)throw v(`unknown node: ${t}`,{received:t});return e}r(_,"requireNode");function y(t){return{node_id:t.node_id,name:t.name,...t.description===void 0?{}:{description:t.description},...t.title===void 0?{}:{title:t.title},...t.icon===void 0?{}:{icon:t.icon},kind:t.kind,mode:t.mode,lifecycle:t.lifecycle,status:t.status,cwd:t.cwd,parent:t.parent??null,fork_from:t.fork_from??null,profile_id:t.profile_id??null,...t.managed_worktree===void 0?{}:{managed_worktree:t.managed_worktree===null?null:{state:t.managed_worktree.state,...t.managed_worktree.cleanup===void 0?{}:{cleanup:t.managed_worktree.cleanup},path:t.managed_worktree.path,branch:t.managed_worktree.branch,base_ref:t.managed_worktree.base_ref,base_sha:t.managed_worktree.base_sha}},...t.review_binding===void 0?{}:{review_binding:t.review_binding??null},intent:t.intent??null,...t.persona_ack===void 0?{}:{persona_ack:t.persona_ack},created:t.created}}r(y,"extensionNode");function oe(t){const e=_(t),n=[],o=new Set([t]);let i=e.parent??null;for(;i!==null&&i!==""&&!o.has(i);){o.add(i);const c=k(i);if(c===null)break;n.unshift(y(c)),i=c.parent??null}const a=$(t).map(c=>k(c.node_id)).filter(c=>c!==null&&c.kind!=="human").sort((c,S)=>c.status===S.status?0:c.status==="active"?-1:S.status==="active"?1:0).map(y),u=typeof e.fork_source_file=="string"?P(e.fork_source_file):null,d=G(t);if(d===null)throw v(`unknown node: ${t}`,{received:t});return{node:y(e),warm_spare:T(t),ancestors:n,children:a,fork_source:u===null?null:y(u),subject:d,report_nodes:I()}}r(oe,"extensionState");function B(t,e){return t?.kind===e.kind&&t?.mode===e.mode&&t?.lifecycle===e.lifecycle}r(B,"samePersona");function re(t){const e=p(t,"broker generated-name");if(e.kind!=="initial"&&e.kind!=="recap")throw s("kind must be initial or recap");if(typeof e.description!="string"||typeof e.title!="string"||typeof e.icon!="string")throw s("description, title, and icon must be strings");if(e.kind==="initial")return e;const n=e.expected;if(typeof n!="object"||n===null||Array.isArray(n)||["name","description","title","icon","kind"].some(o=>typeof n[o]!="string"))throw s("recap expected must contain name, description, title, icon, and kind strings");return e}r(re,"parseGeneratedNameBody");function se(t){const e=p(t,"broker persona-ack"),n=r(o=>{const i=e[o];if(typeof i!="object"||i===null||Array.isArray(i)||typeof i.kind!="string"||i.mode!=="base"&&i.mode!=="orchestrator"||i.lifecycle!=="terminal"&&i.lifecycle!=="resident")throw s(`${o} must be a persona state`);return i},"parse");return{expected_execution_id:e.expected_execution_id,from:n("from"),to:n("to")}}r(se,"parsePersonaAckBody");function ae(t){const e=t.params.id,n=Z(t.body),o=n.sessionFile===null?null:A(n.sessionFile);return{status:200,body:l(()=>{const a=_(e);if(C(n.executionId,e,n.pid)==="shutdown")return{action:"shutdown"};const u=a.review_binding?.review_id;if(u!==void 0&&!n.reviewBoundaryIds.includes(u))return{action:"shutdown"};if(n.reason==="new"&&a.parent==null)return{action:"relaunch_root"};if(n.reason!=="new"&&a.fork_from!=null&&a.pi_session_id==null&&o===null)return{action:"shutdown"};const d=o===null?null:P(o);if(d!==null&&d.node_id!==e){if(L(d.pi_pid))return V(e,{link:"daemon\u2192node",op:"session-file-ownership",kind:"protocol",retry:{disposition:"fatal"},message:`refusing to bind ${o}: it is owned by live node ${d.node_id}`}),{action:"shutdown"};const c=E(d.node_id);if(c===null||M({fromNodeId:d.node_id,fromBindingId:c.bindingId,toNodeId:e,executionId:n.executionId,sessionId:n.piSessionId,transcriptPath:o})!=="transferred")return{action:"shutdown"}}else if(j(e,{executionId:n.executionId,sessionId:n.piSessionId,transcriptPath:o})==="shutdown")return{action:"shutdown"};return n.reason!=="new"&&(J(e),a.intent==="refresh"&&h(e,"revive")),{action:"none"}})}}r(ae,"handleSessionBound");function de(t,e){const n=k(t);if(n===null){if(e.pushedFinal)return{action:"shutdown"};throw v(`unknown node: ${t}`,{received:t})}if(R(t,new Date().toISOString()),e.stopReason==="quit")return(n.status==="active"||n.status==="idle")&&n.intent===null&&(h(t,"finish"),m(t),b(t)!==null&&x(t),w(t,{pane:null,tmux_session:null,window:null})),{action:"shutdown"};if(e.stopReason!=="stop"&&e.stopReason!=="length")return m(t,{link:"daemon\u2192node"}),n.intent==="refresh"?{action:"shutdown"}:{action:"stay_dormant"};const o={pushedFinal:e.pushedFinal};if(o.pushedFinal||n.status==="done")return m(t),b(t)!==null&&x(t),w(t,{pane:null,tmux_session:null,window:null}),{action:"shutdown"};if(n.intent==="refresh")return m(t),{action:"shutdown"};const i=U(t,o,e.backgroundJobsRunning);return m(t),i.action==="reprompt"?{action:"reprompt",prompt:i.message}:i.reason==="finished"?O(t)?{action:"stay_dormant"}:{action:"shutdown"}:i.reason!=="awaiting"&&i.reason!=="scheduled"?{action:"stay_dormant"}:b(t)!==null||W(t)||O(t)?{action:"stay_dormant"}:(h(t,"release"),{action:"shutdown"})}r(de,"settleBroker");function ue(t){const e=t.params.id,n=ee(t.body);f(e,n.expected_execution_id);const o=l(()=>de(e,n));return o.action!=="reprompt"&&z(e),{status:200,body:o}}r(ue,"handleSettle");function ce(t){const e=t.params.id,n=te(t.body);return f(e,n.expected_execution_id),{status:200,body:l(()=>{const i=K(e);if(i===void 0)return{action:"stay_dormant"};const a=_(e);return X(e,a,i)?(m(e),h(e,"park"),b(e)!==null&&x(e),w(e,{pane:null,tmux_session:null,window:null}),H({level:n.outcome==="completed"?"info":"warn",event:"broker.park.complete",...D(e)?{node_id:e}:{},outcome:n.outcome==="completed"?"succeeded":"failed"}),{action:"shutdown"}):{action:"stay_dormant"}})}}r(ce,"handleParkComplete");function le(t){const e=t.params.id;return f(e,p(t.body,"broker park-activity").expected_execution_id),{status:200,body:l(()=>({activity:Q(e)?"recorded":"none"}))}}r(le,"handleParkActivity");function pe(t){const e=t.params.id,n=ne(t.body);return f(e,n.expected_execution_id),l(()=>{q(e,{tokensIn:n.tokens_in,contextTokens:n.context_tokens,lastActivity:n.last_activity,updatedAt:n.updated_at})}),{status:204}}r(pe,"handleTelemetry");function fe(t){const e=t.params.id,n=ie(t.body);return f(e,n.expected_execution_id),{status:200,body:{modelOverride:l(()=>Y(_(e),n.spec,n.pinnedOverride,n.userSelected)).model_override}}}r(fe,"handleModelCommit");function me(t){return{status:200,body:oe(t.params.id)}}r(me,"handleExtensionState");function _e(t){const e=t.params.id,n=re(t.body);return f(e,n.expected_execution_id),{status:200,body:l(()=>{const i=_(e);if(n.kind==="initial"){if((i.description??"").trim()!=="")return{applied:!1};const d=g(e,{description:n.description,...n.title.trim()===""?{}:{title:n.title},...n.icon.trim()===""?{}:{icon:n.icon}});return{applied:!0,editorLabel:N(d),description:d.description??"",title:d.title??"",icon:d.icon??""}}const a=n.expected;if(i.name!==a.name||(i.description??"")!==a.description||(i.title??"")!==a.title||(i.icon??"")!==a.icon||i.kind!==a.kind)return{applied:!1};const u=g(e,{description:n.description,title:n.title.trim()===""?void 0:n.title,icon:n.icon.trim()===""?void 0:n.icon});return{applied:!0,editorLabel:N(u),description:u.description??"",title:u.title??"",icon:u.icon??""}})}}r(_e,"handleGeneratedName");function ke(t){const e=t.params.id,n=se(t.body);return f(e,n.expected_execution_id),{status:200,body:l(()=>{const i=_(e),a={kind:i.kind,mode:i.mode,lifecycle:i.lifecycle},u=i.persona_ack,d=u===void 0?a:{kind:u.kind??i.kind,mode:u.mode,lifecycle:u.lifecycle};return!B(a,n.to)||!B(d,n.from)?{applied:!1}:(g(e,{persona_ack:n.to}),{applied:!0})})}}r(ke,"handlePersonaAck");const De=[{method:"POST",pattern:"/v1/nodes/:id/broker/session-bound",handler:ae},{method:"POST",pattern:"/v1/nodes/:id/broker/settle",handler:ue},{method:"POST",pattern:"/v1/nodes/:id/broker/park-complete",handler:ce},{method:"POST",pattern:"/v1/nodes/:id/broker/park-activity",handler:le},{method:"POST",pattern:"/v1/nodes/:id/broker/telemetry",handler:pe},{method:"POST",pattern:"/v1/nodes/:id/broker/model",handler:fe},{method:"GET",pattern:"/v1/nodes/:id/broker/extension-state",handler:me},{method:"POST",pattern:"/v1/nodes/:id/broker/generated-name",handler:_e},{method:"POST",pattern:"/v1/nodes/:id/broker/persona-ack",handler:ke}];export{De as brokerOperationRoutes};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
2
|
-
`);if(e.length>0){const i=s.findIndex(d=>{const o=d.toLowerCase();return e.some(c=>o.includes(c))});if(i!==-1)return s.slice(i,i+n).map(d=>d.trim()).filter(d=>d!=="").join(" \u23CE ")}const a=s.map(i=>i.trim()).filter(i=>i!=="").slice(0,n).join(" \u23CE ");return a!==""?a:t.title}u(
|
|
3
|
-
`).forEach((y,
|
|
1
|
+
var P=Object.defineProperty;var u=(t,e)=>P(t,"name",{value:e,configurable:!0});import{graphNodes as I,pruneNodes as K,pruneToLimit as A,rosterEdges as C,rosterNodes as D}from"../../../core/canvas/canvas.js";import{activeBackgroundBashJobs as q}from"../../../core/bash-jobs.js";import{contextDir as H}from"../../../core/canvas/paths.js";import{nowIso as k}from"../../../core/fs-utils.js";import{isPidPresent as J}from"../../../core/canvas/pid.js";import{dashboardRowsAllFromSource as z,enrichRowsFromSource as Q}from"../../../core/canvas/render-source.js";import{localCanvasSource as M}from"../../../core/canvas/source.js";import{ticketCountsForNodes as j,ticketsAcrossCanvas as U}from"../../../core/canvas/attention.js";import{buildCorpus as Y,groupCorpus as V,resolveRef as W}from"../../../core/canvas/history.js";import{listFocuses as R,reapEmptyNodes as X}from"../../../core/runtime/placement.js";import{notFound as Z,usage as p}from"../../../core/errors.js";import{toGraphNodeDTO as ee}from"../map.js";function te(){return{status:200,body:{items:U().map(e=>({node_id:e.node_id,name:e.name,cwd:e.cwd,count:e.count,subjects:e.subjects}))}}}u(te,"handleAttention");function ne(t){const e=t.body;if(e===null||typeof e!="object"||!Array.isArray(e.node_ids))throw p("attention count request requires node_ids: string[]");const n=e.node_ids;if(!n.every(s=>typeof s=="string"))throw p("attention count request node_ids must contain only strings");return{status:200,body:{counts:j(n)}}}u(ne,"handleAttentionCounts");function B(t){return Buffer.from(String(t),"utf8").toString("base64")}u(B,"encodeCursor");function x(t){const e=Number(Buffer.from(t,"base64").toString("utf8"));if(!Number.isInteger(e)||e<0)throw p(`invalid cursor: ${t}`);return e}u(x,"decodeCursor");function oe(t,e,n){const s=t.loadBody().split(`
|
|
2
|
+
`);if(e.length>0){const i=s.findIndex(d=>{const o=d.toLowerCase();return e.some(c=>o.includes(c))});if(i!==-1)return s.slice(i,i+n).map(d=>d.trim()).filter(d=>d!=="").join(" \u23CE ")}const a=s.map(i=>i.trim()).filter(i=>i!=="").slice(0,n).join(" \u23CE ");return a!==""?a:t.title}u(oe,"snippet");function re(t,e,n){const r=[...t];return e==="relevance"&&n!==void 0?r.sort((s,a)=>(n.get(a.ref)??0)-(n.get(s.ref)??0)||a.tsMs-s.tsMs||s.ref.localeCompare(a.ref)):e==="oldest"?r.sort((s,a)=>s.tsMs-a.tsMs||s.ref.localeCompare(a.ref)):r.sort((s,a)=>a.tsMs-s.tsMs||s.ref.localeCompare(a.ref)),r}u(re,"sortArtifacts");function se(t){if(t==null)return{};if(typeof t!="object")throw p("history search body must be a JSON object");return t}u(se,"parseSearchBody");function ie(t){if(t===null||typeof t!="object")throw p("history grep body must be a JSON object");const e=t;if(typeof e.pattern!="string"||e.pattern==="")throw p("history grep body requires a non-empty pattern");return e}u(ie,"parseGrepBody");function $(t){const e={cwd:t.cwd,allCwds:t.all_cwds===!0,under:t.under,nodes:t.nodes},n={types:t.types,reportKind:t.report_kind,kinds:t.kinds,statuses:t.statuses,sinceMs:t.since_ms,untilMs:t.until_ms,origins:t.origins,roles:t.roles,from:t.from};return Y(e,n)}u($,"buildCorpusFromQuery");function de(t){if(t==null)return{};if(typeof t!="object")throw p("history stats body must be a JSON object");return t}u(de,"parseStatsBody");const L=["origin","node","kind","day","type","role"];function ae(t){const e=de(t.body),n=e.group_by??"type";if(!L.includes(n))throw p(`--group-by must be one of: ${L.join(", ")}; received: ${String(e.group_by)}`);const r=$(e),s=V(r,n);return{status:200,body:{group_by:n,groups:s,total:s.reduce((i,d)=>i+d.count,0),scanned:r.length}}}u(ae,"handleHistoryStats");function ce(t){const e=ie(t.body),n=Math.min(100,Math.max(1,e.limit??20)),r=$(e),s=e.cursor!==void 0?x(e.cursor):0;let a;try{a=new RegExp(e.pattern,"i")}catch{throw p(`invalid regex pattern: ${e.pattern}`)}const i=[];for(const f of r)f.loadBody().split(`
|
|
3
|
+
`).forEach((y,b)=>{a.test(y)&&i.push({ref:f.ref,node:`${f.nodeName} (${f.nodeId})`,ts:f.ts,line:b+1,text:y.trim()})});i.sort((f,m)=>f.ref.localeCompare(m.ref)||f.line-m.line);const d=i.slice(s,s+n),o=s+n<i.length?B(s+n):null;return{status:200,body:{hits:d,next_cursor:o,total:i.length}}}u(ce,"handleHistoryGrep");function ue(t){const e=se(t.body),n=(e.query??"").trim(),r=e.weigh_body===!0,s=e.full===!0,a=Math.max(1,e.snippet_lines??1),i=Math.min(100,Math.max(1,e.limit??20)),d=$(e),o=e.cursor!==void 0?x(e.cursor):0,c=n.toLowerCase().split(/\s+/).filter(l=>l.length>0);let f=d,m;const y=e.sort??(c.length>0?"relevance":"recency");if(c.length>0&&y==="relevance"){m=new Map;const l=[];for(const h of d){const S=h.title.toLowerCase(),F=h.nodeName.toLowerCase(),G=h.nodeDesc.toLowerCase(),N=r?h.loadBody().toLowerCase():null;let _=0;for(const v of c)S.includes(v)&&(_+=10),F.includes(v)&&(_+=5),G.includes(v)&&(_+=3),N!==null&&N.includes(v)&&(_+=1);_>0&&(m.set(h.ref,_),l.push(h))}f=l}else c.length>0&&(f=d.filter(l=>{const h=`${l.title}
|
|
4
4
|
${l.nodeName}
|
|
5
5
|
${l.nodeDesc}${r?`
|
|
6
|
-
`+l.loadBody():""}`.toLowerCase();return c.some(S=>h.includes(S))}));const
|
|
6
|
+
`+l.loadBody():""}`.toLowerCase();return c.some(S=>h.includes(S))}));const b=re(f,y,m),T=b.slice(o,o+i),E=o+i<b.length?B(o+i):null;return{status:200,body:{hits:T.map(l=>{const h={ref:l.ref,node:`${l.nodeName} (${l.nodeId})`,kind:l.nodeKind,source:l.source==="report"&&l.reportKind?`report:${l.reportKind}`:l.source,ts:l.ts};return y==="relevance"&&m!==void 0&&(h.score=m.get(l.ref)??0),s?h.body=l.loadBody():h.snippet=oe(l,c,a),h}),next_cursor:E,total:b.length}}}u(ue,"handleHistorySearch");function le(t){const e=(t.query.get("ref")??"").trim(),n=t.query.get("frontmatter")==="true";if(!e.includes(":"))throw p(`ref must be <node-id>:<relpath>; received: ${e}`,{received:e,next:"Get a valid ref from `crtr canvas history search` or `crtr node inspect artifacts <node-id>`."});let r;try{r=W(e)}catch(o){throw p(`ref rejected: ${o.message}`,{received:e,next:"Refs come verbatim from `crtr canvas history search`; do not hand-construct relpaths."})}if(r===null)throw Z(`no artifact for ref: ${e}`,{ref:e,next:"The node or file may not exist. Re-run `crtr canvas history search` for a current ref, or `crtr node inspect artifacts <node-id>` to list a node's artifacts."});const s=r.source==="report"&&r.reportKind?`report:${r.reportKind}`:r.source,i=(t.query.get("format")==="raw"||n)&&r.raw!==null?r.raw:r.body;return{status:200,body:{ref:e,node:`${r.nodeName} (${r.nodeId})`,source:s,ts:r.ts,content:i}}}u(le,"handleHistoryRead");function fe(t){for(const[r]of t.query)if(r!=="live")throw p(`unknown snapshot query parameter: ${r}`);const e=t.query.getAll("live");if(e.length>1)throw p("live must appear at most once");const n=e[0];if(n===void 0||n==="false"||n==="0")return!1;if(n==="true"||n==="1")return!0;throw p("live must be true or false")}u(fe,"snapshotLiveOnly");async function me(t){const e=new Set(R().map(o=>o.node_id)),n=await z(M,e,fe(t)),r=j(n.map(o=>o.node_id));await Q(M,n,r);const s=n.map(o=>{const c=o.srcRow,f=c?.host_kind??"tmux";return{node_id:o.node_id,name:o.name,title:o.handle??o.name,description:o.description??null,kind:o.kind,mode:o.mode,lifecycle:o.lifecycle??c?.lifecycle,status:o.status,cwd:o.cwd,profile_id:o.profile_id??null,parent:c?.parent??null,created:o.created,host_kind:f,enterable:f==="broker",attention_count:o.asks,...c?.cycles!=null?{cycles:c.cycles}:{},...o.mtimeMs!==void 0?{last_activity:new Date(o.mtimeMs).toISOString()}:{},ctx_tokens:o.ctx_tokens,streaming:o.streaming??!1,jobs_active:c!==void 0&&J(c.pi_pid)?q(H(o.node_id)).length:0,waiting_for:c?.waiting_for??null,hanging:o.hanging??null,viewed:o.viewed??!1,final_report:c?.final_report??null,finalized_at:c?.finalized_at??null}}),a=new Map;for(const o of C()){const c=a.get(o.from_id);c===void 0?a.set(o.from_id,[o.to_id]):c.push(o.to_id)}const i=Object.fromEntries(n.map(o=>[o.node_id,a.get(o.node_id)??[]]));return{status:200,body:{generated_at:k(),nodes:s,subscriptions:i}}}u(me,"handleSnapshot");function O(){const t=D().map(n=>{const r=n.host_kind??"tmux";return{node_id:n.node_id,name:n.name,kind:n.kind,mode:n.mode,lifecycle:n.lifecycle,status:n.status,cwd:n.cwd,host_kind:r,enterable:r==="broker",parent:n.parent,created:n.created}}),e=C().map(n=>({from_id:n.from_id,to_id:n.to_id,active:n.active,created:n.created}));return{generated_at:k(),nodes:t,edges:e}}u(O,"buildRoster");let g=null,w=null;function pe(){return g===null?(g=Promise.resolve().then(()=>O()).finally(()=>{g=null}),g):(w===null&&(w=g.then(()=>O()).finally(()=>{w=null})),w)}u(pe,"rosterCoalesced");async function he(){return{status:200,body:await pe()}}u(he,"handleRoster");function ye(){return{status:200,body:{generated_at:k(),nodes:I().map(ee),edges:C().map(e=>({from_id:e.from_id,to_id:e.to_id,active:e.active,created:e.created})),focused_node_ids:R().map(e=>e.node_id)}}}u(ye,"handleGraph");function _e(t){if(t==null)return{};if(typeof t!="object")throw p("prune body must be a JSON object");const e=t,n=u(f=>{const m=e[f];if(m!==void 0){if(typeof m!="number"||!Number.isFinite(m))throw p(`${f} must be a number`);return m}},"num"),r=u(f=>{const m=e[f];if(m!==void 0){if(typeof m!="boolean")throw p(`${f} must be a boolean`);return m}},"bool"),s={},a=n("limit");a!==void 0&&(s.limit=a);const i=n("ttl_days");i!==void 0&&(s.ttl_days=i);const d=r("include_stale");d!==void 0&&(s.include_stale=d);const o=r("empty");o!==void 0&&(s.empty=o);const c=r("dry_run");return c!==void 0&&(s.dry_run=c),s}u(_e,"parsePruneBody");function be(t){const e=_e(t.body),n=e.ttl_days??14,r=e.dry_run??!1;let s;return e.limit!==void 0?s=A({maxNodes:e.limit,dryRun:r}).pruned.map(d=>({node_id:d.node_id,status:d.status,created:d.created})):e.empty===!0?s=X({dryRun:r}).map(d=>({node_id:d,status:"empty",created:""})):s=K({ttlDays:n,dryRun:r,includeStale:e.include_stale??!1}).pruned.map(d=>({node_id:d.node_id,status:d.status,created:d.created})),{status:200,body:{pruned:s,dry_run:r,ttl_days:n}}}u(be,"handlePrune");const Te=[{method:"GET",pattern:"/v1/canvas/attention",handler:te},{method:"POST",pattern:"/v1/canvas/attention/counts",handler:ne},{method:"POST",pattern:"/v1/canvas/history/search",handler:ue},{method:"POST",pattern:"/v1/canvas/history/grep",handler:ce},{method:"GET",pattern:"/v1/canvas/history/read",handler:le},{method:"POST",pattern:"/v1/canvas/history/stats",handler:ae},{method:"GET",pattern:"/v1/canvas/snapshot",handler:me},{method:"GET",pattern:"/v1/canvas/roster",handler:he},{method:"GET",pattern:"/v1/canvas/graph",handler:ye},{method:"POST",pattern:"/v1/canvas/prune",handler:be}];export{Te as canvasRoutes};
|
package/dist/daemon/api/map.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import type { CloseNodeResult } from '../../core/runtime/close.js';
|
|
|
7
7
|
import { type PushResult } from '../../core/feed/feed.js';
|
|
8
8
|
import type { PageFeedback, PageFeedbackComment } from '../../core/human/feedback.js';
|
|
9
9
|
import type { OnDiskMigrationRunResult } from '../../migrations/runner.js';
|
|
10
|
-
import type { CloseResultDTO, CronDTO, CronRunDTO, ErrorBody, NodeEdgesDTO, NodeOutcomeDTO, NodeOutcomeSummaryDTO, NodePathsDTO, NodeStatusDTO, OutcomeDeliveryDTO, NodeSummaryDTO, NodeDetailDTO, NodeWorktreeDTO, ProfileDTO, ReviewCommentDTO, ReviewCommentEventDTO, ReviewDTO, FeedbackResultDTO, PageFeedbackCommentDTO, PageFeedbackDTO, PushReportResultDTO, ReviveResultDTO, MigrateStateDTO, SubscriptionDTO } from '../../api/index.js';
|
|
10
|
+
import type { CloseResultDTO, CronDTO, CronRunDTO, ErrorBody, NodeEdgesDTO, NodeOutcomeDTO, NodeOutcomeSummaryDTO, NodePathsDTO, NodeStatusDTO, OutcomeDeliveryDTO, NodeSummaryDTO, NodeDetailDTO, NodeWorktreeDTO, ProfileDTO, ReviewCommentDTO, ReviewCommentEventDTO, ReviewDTO, FeedbackResultDTO, GraphNodeDTO, PageFeedbackCommentDTO, PageFeedbackDTO, PushReportResultDTO, ReviveResultDTO, MigrateStateDTO, SubscriptionDTO } from '../../api/index.js';
|
|
11
11
|
export declare function toMigrateStateDTO(result: OnDiskMigrationRunResult, options: {
|
|
12
12
|
resumed: boolean;
|
|
13
13
|
resumeError?: string;
|
|
@@ -37,6 +37,20 @@ export interface OutcomeDeliveryDTOInput {
|
|
|
37
37
|
/** Project a durable delivery row without exposing its execution coordinates or stderr tail. */
|
|
38
38
|
export declare function toOutcomeDeliveryDTO(row: OutcomeDeliveryDTOInput): OutcomeDeliveryDTO;
|
|
39
39
|
/** Project the queryable row (what `listNodes` yields) into a summary DTO. */
|
|
40
|
+
export declare function toGraphNodeDTO(row: {
|
|
41
|
+
node_id: string;
|
|
42
|
+
name: string;
|
|
43
|
+
description: string | null;
|
|
44
|
+
cycles: number | null;
|
|
45
|
+
kind: string;
|
|
46
|
+
status: NodeStatusDTO;
|
|
47
|
+
frozen_at: string | null;
|
|
48
|
+
pi_pid: number | null;
|
|
49
|
+
telemetry_context_tokens: number | null;
|
|
50
|
+
telemetry_last_activity: string | null;
|
|
51
|
+
fault: NodeRow['fault'];
|
|
52
|
+
streaming: boolean;
|
|
53
|
+
}): GraphNodeDTO;
|
|
40
54
|
export declare function toNodeSummaryDTO(row: NodeRow): NodeSummaryDTO;
|
|
41
55
|
/** The subscription/child edges a detail projection needs. The handler gathers
|
|
42
56
|
* these from `subscriptionsOf`/`subscribersOf` + a children query and passes
|