@north-light/crouter 0.3.320 → 0.3.322
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/runtime-selector.mjs +52 -3
- package/dist/api/client.d.ts +31 -17
- package/dist/api/client.js +2 -2
- package/dist/api/dto/broker-ops.d.ts +0 -1
- package/dist/api/dto/modelauth.d.ts +15 -0
- package/dist/api/dto/node-outcomes.d.ts +6 -0
- package/dist/api/dto/nodes.d.ts +4 -3
- package/dist/api/dto/review-comments.d.ts +8 -0
- package/dist/api/errors.d.ts +6 -3
- package/dist/api/errors.js +1 -1
- package/dist/api/index.d.ts +2 -2
- package/dist/api/index.js +1 -1
- package/dist/api/node-transport.d.ts +18 -0
- package/dist/api/node-transport.js +1 -0
- package/dist/api/routes.d.ts +2 -0
- package/dist/api/routes.js +1 -1
- package/dist/builtin-memory/crouter-sdk.md +86 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +1 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +1 -1
- package/dist/cli.js +8 -2
- package/dist/clients/attach/render/chat-view.d.ts +5 -1
- package/dist/clients/attach/render/chat-view.js +1 -1
- package/dist/clients/attach/session/frames.d.ts +1 -0
- package/dist/clients/attach/session/frames.js +1 -1
- package/dist/clients/attach/viewer.js +606 -606
- package/dist/clients/inbox/review/comments-client.d.ts +8 -1
- package/dist/clients/inbox/review/comments-client.js +1 -1
- package/dist/clients/inbox/review/companion-pane.d.ts +17 -0
- package/dist/clients/inbox/review/companion-pane.js +1 -1
- package/dist/clients/inbox/review/document-surface.d.ts +10 -0
- package/dist/clients/inbox/review/document-surface.js +2 -2
- package/dist/clients/inbox/review/frame.js +1 -1
- package/dist/clients/inbox/review/keys.d.ts +2 -0
- package/dist/clients/inbox/review/keys.js +1 -1
- package/dist/commands/api-client.js +3 -3
- package/dist/commands/human/prompts.js +1 -1
- package/dist/commands/memory/read.js +2 -2
- package/dist/commands/sys/branch.js +1 -1
- package/dist/commands/sys/connect.d.ts +1 -0
- package/dist/commands/sys/connect.js +3 -0
- package/dist/commands/sys/daemon.js +1 -1
- package/dist/commands/sys/panels/provider-panel.js +1 -1
- package/dist/commands/sys/provider-login.d.ts +8 -0
- package/dist/commands/sys/provider-login.js +9 -0
- package/dist/commands/sys/setup-core.d.ts +4 -0
- package/dist/commands/sys/setup-core.js +4 -4
- package/dist/commands/sys.js +1 -1
- package/dist/core/canvas/browse/app.js +3 -3
- package/dist/core/canvas/canvas.d.ts +3 -3
- package/dist/core/canvas/canvas.js +17 -14
- package/dist/core/canvas/migrations.js +34 -27
- package/dist/core/canvas/node-sql-migration.d.ts +1 -0
- package/dist/core/canvas/node-sql-migration.js +28 -2
- package/dist/core/canvas/paths.d.ts +8 -4
- package/dist/core/canvas/paths.js +1 -1
- package/dist/core/canvas/recovery.d.ts +1 -0
- package/dist/core/canvas/recovery.js +1 -1
- package/dist/core/canvas/worktrees.d.ts +1 -0
- package/dist/core/canvas/worktrees.js +1 -1
- package/dist/core/config.js +1 -1
- package/dist/core/human/requests.d.ts +1 -0
- package/dist/core/human/requests.js +17 -13
- package/dist/core/review/fork.d.ts +8 -0
- package/dist/core/review/fork.js +5 -0
- package/dist/core/runtime/broker/daemon-ops.js +1 -1
- package/dist/core/runtime/broker/extension-abort.d.ts +3 -0
- package/dist/core/runtime/broker/extension-abort.js +1 -1
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/spawn.d.ts +5 -1
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/stop-guard.d.ts +1 -3
- package/dist/core/runtime/stop-guard.js +2 -2
- package/dist/core/runtime/stop-signals.d.ts +0 -1
- package/dist/core/runtime/stop-signals.js +1 -1
- package/dist/core/secrets.d.ts +3 -0
- package/dist/core/secrets.js +2 -2
- package/dist/core/subscription-state.d.ts +1 -1
- package/dist/core/subscription-state.js +3 -3
- package/dist/core/termrender/termrender.d.ts +3 -1
- package/dist/core/termrender/termrender.js +13 -13
- package/dist/core/user-settings.d.ts +4 -0
- package/dist/core/user-settings.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/health.d.ts +1 -1
- package/dist/daemon/api/handlers/health.js +14 -1
- package/dist/daemon/api/handlers/inbox.js +1 -1
- package/dist/daemon/api/handlers/modelauth.js +1 -1
- package/dist/daemon/api/handlers/review-comments.js +1 -1
- package/dist/daemon/api/map.d.ts +4 -2
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/api/server.d.ts +5 -1
- package/dist/daemon/api/server.js +4 -4
- package/dist/daemon/companion-retire.d.ts +3 -1
- package/dist/daemon/companion-retire.js +1 -1
- package/dist/daemon/crtrd-cli.js +1 -1
- package/dist/daemon/crtrd.js +7 -7
- package/dist/daemon/human/finish.d.ts +4 -1
- package/dist/daemon/human/finish.js +7 -7
- package/dist/daemon/human/settle.d.ts +8 -6
- package/dist/daemon/human/settle.js +1 -1
- package/dist/daemon/manage.d.ts +1 -0
- package/dist/daemon/manage.js +2 -2
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +1 -1
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.js +1 -1
- package/docs/sdk/README.md +54 -0
- package/docs/sdk/client.md +92 -0
- package/docs/sdk/docker.md +63 -0
- package/docs/sdk/errors.md +85 -0
- package/docs/sdk/getting-started.md +160 -0
- package/docs/sdk/memory.md +107 -0
- package/docs/sdk/migration.md +108 -0
- package/docs/sdk/nodes.md +193 -0
- package/docs/sdk/resources.md +71 -0
- package/docs/sdk/streaming.md +124 -0
- package/package.json +1 -1
- package/runtime.lock.json +6 -6
package/dist/core/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var Te=Object.defineProperty;var s=(e,n)=>Te(e,"name",{value:n,configurable:!0});import{envProfileId as $e}from"../shared/env.js";import{basename as Ce,dirname as Me,join as H}from"node:path";import{isDeepStrictEqual as Le}from"node:util";import{CONFIG_FILE as Ne,STATE_FILE as Fe,CONDENSED_HISTORY_MODES as ze,MOUSE_MODE_DEFAULTS as De,WHIP_MESSAGE_MODES as Ue,DEFAULT_WHIP_MESSAGES as J,defaultScopeConfig as b,defaultScopeState as Ke,defaultModelLaddersConfig as qe,defaultKindsConfig as Ge,defaultRemoteCanvasConfig as Be}from"../types.js";import{BINDING_CATALOG as He,BINDING_IDS as Je,isAttachPaneBinding as We}from"./keybindings/catalog.js";import{notFound as Ze,usage as Ye}from"./errors.js";import{emitEvent as Ve}from"./events/emit.js";import{atomicWriteJson as W,readJsonIfExists as M,ensureDir as Z}from"./fs-utils.js";import{scopeRoot as y,requireScopeRoot as _,findProjectScopeRoots as Qe,userScopeRoot as L}from"./scope.js";import{listInstalledPluginsInRoot as Y}from"./installed-plugins.js";import{profileRoot as N,listProfiles as V}from"./profiles/manifest.js";import{canonicalRoot as F,projectStore as Xe,userStore as Q}from"./scoped-state/paths.js";import{convertLegacyScopedStore as en,initializeFreshScopedStore as nn}from"./scoped-state/migrate.js";import{mutateRawSettings as on,readBookkeeping as tn,readRawSettings as rn,readRawSettingsWithRevision as sn,replaceRawSettings as dn,writeBookkeeping as cn,writeRawSettings as un}from"./scoped-state/settings.js";import{withExclusiveDirectoryLock as ln}from"./exclusive-lock.js";import{SCOPE_CONFIG_KEYS as fn}from"./user-settings.js";import{normalizeWorkingGerunds as an}from"../shared/working-activity.js";import{mergePageComponentLayers as mn,normalizePageComponents as X}from"./human/page-catalog.js";function h(e){return H(e,Ne)}s(h,"configPathFor");function ee(e,n){return Z(Me(e)),ln(`${e}.lock`,()=>n(e),{timeoutError:s(()=>new Error(`timed out waiting for config lock: ${e}`),"timeoutError")})}s(ee,"withConfigPathLock");function pn(e){return H(e,Fe)}s(pn,"statePathFor");function co(e){const n=y(e);return n?h(n):null}s(co,"configPath");function uo(e){const n=y(e);return n?pn(n):null}s(uo,"statePath");function g(e){const n=F(e),t=F(L());if(n===t)return{store:Q(t),key:"user",kind:"user",root:t};if(Ce(n)===".crouter")return en({kind:"project",root:n}),{store:Xe(n),key:"project",kind:"project",root:n};for(const o of V()){const r=F(N(o.profileId));if(n===r)return{store:Q(t),key:`profile:${o.profileId}`,kind:"profile",root:r,profileId:o.profileId}}throw new Error(`settings root is not a recognized owner: ${e}`)}s(g,"settingsOwnerForRoot");function j(e){const n=g(e);return n.kind==="project"?M(h(n.root)):rn(n)}s(j,"readRawAtRoot");function z(e,n){const t=g(e);if(t.kind==="project"){ee(h(t.root),o=>W(o,n));return}un(t,n)}s(z,"writeRawAtRoot");function v(e,n){const t=g(e);return t.kind==="project"?ee(h(t.root),o=>{const r=n(M(o)??{});return W(o,r.next),r.value}):on(t,o=>n(o))}s(v,"mutateRawAtRoot");function gn(e){const n=y(e);return n?yn(n):b()}s(gn,"readConfig");function yn(e){const n=j(e);return n?T(n):b()}s(yn,"readConfigAtRoot");function hn(e){const n=y(e);return n?tn(g(n)):Ke()}s(hn,"readState");class bn extends Error{static{s(this,"InvalidRawSettingsError")}constructor(n){super(`settings cannot be merged: ${n instanceof Error?n.message:String(n)}`),this.name="InvalidRawSettingsError"}}function ne(e){if(e.scope==="user")return g(L());if(!V().some(n=>n.profileId===e.profileId))throw Ze(`profile not found: ${e.profileId}`,{received:e.profileId,next:"Run `crtr profile list` to see available profiles."});return g(N(e.profileId))}s(ne,"rawSettingsOwnerForTarget");function lo(e){return sn(ne(e))}s(lo,"readRawSettingsForTarget");function fo(e,n,t){return dn(ne(e),n,t,o=>{try{T(o)}catch(r){throw new bn(r)}})}s(fo,"replaceRawSettingsForTarget");function ao(e,n){const t=_(e);return v(t,o=>{const r=n(o);return{value:r,next:r}})}s(ao,"updateRawConfigAtomically");function mo(e,n){z(_(e),n)}s(mo,"writeConfig");function po(e,n){z(_(e),n)}s(po,"writeRawConfig");function _n(e,n){const t=_(e);cn(g(t),n)}s(_n,"writeState");function go(e,n){Z(n);const t=g(e==="user"?L():n);if(nn({kind:t.kind==="user"?"user":"project",root:t.store.root}),t.kind==="project"&&M(h(t.root))===null){const{modelLadders:o,keybindings:r,tmux_passthrough:i,brokerThresholds:d,lifecycle:c,...u}=b();z(t.root,u)}}s(go,"ensureScopeInitialized");function vn(e){if(e===null||typeof e!="object"||Array.isArray(e))return{};const n={};for(const[t,o]of Object.entries(e))Array.isArray(o)&&o.every(r=>typeof r=="string")&&(n[t]=[...o]);return n}s(vn,"normalizeKeybindings");const kn=new Set(He.filter(We).map(e=>e.id));function wn(e){return Array.isArray(e)?[...new Set(e.filter(n=>typeof n=="string"&&Je.has(n)&&kn.has(n)))]:[]}s(wn,"normalizeTmuxPassthrough");function S(e,n=qe()){const t=n;if(e===null||typeof e!="object")return t;const o=e,r={anthropic:{...t.anthropic},openai:{...t.openai},...t.defaultProvider!==void 0?{defaultProvider:t.defaultProvider}:{}};(o.defaultProvider==="anthropic"||o.defaultProvider==="openai")&&(r.defaultProvider=o.defaultProvider);for(const i of["anthropic","openai"]){const d=o[i];if(!(d===null||typeof d!="object"))for(const[c,u]of Object.entries(d))(c==="ultra"||c==="strong"||c==="medium"||c==="light")&&typeof u=="string"&&(r[i][c]=u)}return r}s(S,"mergeModelLadders");function oe(e){return e==="ultra"||e==="strong"||e==="medium"||e==="light"}s(oe,"validStrength");const D=["ultra","strong","medium","light"];function U(){return Object.create(null)}s(U,"routeRecord");function k(e,n,t){Object.defineProperty(e,n,{value:t,writable:!0,enumerable:!0,configurable:!0})}s(k,"setRouteRecord");function te(e){const n=U();for(const[t,o]of Object.entries(e??{}))k(n,t,o);return n}s(te,"copyRouteRecord");function w(e,n){Ve({level:"warn",event:"config.model_routes.invalid",fields:{route_id:e,rule:n}})}s(w,"routeInvalid");function x(e,n={}){const t=te(n);if(e===null||typeof e!="object"||Array.isArray(e))return t;for(const[o,r]of Object.entries(e)){if(o.trim()===""){w(o,"route id must be a non-empty string");continue}if(r===null||typeof r!="object"||Array.isArray(r)){w(o,"route must be an object");continue}const i=r,d=t[o],c={...d};let u;for(const f of["family","credentialSource","providerId"]){const l=i[f];if(l!==void 0){if(typeof l!="string"||l.trim()===""){u=`${f} must be a non-empty string`;break}c[f]=l}}if(u===void 0&&i.models!==void 0)if(i.models===null||typeof i.models!="object"||Array.isArray(i.models))u="models must be an object";else{const f={...d?.models};for(const[l,a]of Object.entries(i.models)){if(!oe(l)){u=`models.${l} is not a model strength`;break}if(typeof a!="string"||a.trim()===""){u=`models.${l} must be a non-empty provider/id ref`;break}const m=a.indexOf("/");if(m<=0||m===a.length-1){u=`models.${l} must be provider/id`;break}f[l]=a}c.models=f}if(u===void 0&&c.models!==void 0&&c.providerId!==void 0){for(const[f,l]of Object.entries(c.models))if(l.slice(0,l.indexOf("/"))!==c.providerId){u=`models.${f} provider prefix must equal providerId`;break}}if(u!==void 0){w(o,u);continue}k(t,o,c)}return t}s(x,"mergeModelRoutePatches");function re(e){const n=U(),t=U();for(const[o,r]of Object.entries(e)){if(r.family===void 0||r.credentialSource===void 0||r.providerId===void 0||r.models===void 0){w(o,"route must include family, credentialSource, providerId, and models");continue}const i=D.filter(d=>r.models[d]===void 0);if(i.length>0){w(o,`incomplete route; missing strengths: ${i.join(", ")}`),k(t,o,{family:r.family,credentialSource:r.credentialSource,providerId:r.providerId,models:r.models});continue}k(n,o,{family:r.family,credentialSource:r.credentialSource,providerId:r.providerId,models:r.models})}return{complete:n,legacy:t}}s(re,"resolveModelRoutes");function An(e,n){if(e.trim()==="")throw new Error("model route id must be a non-empty string");for(const o of["family","credentialSource","providerId"])if(typeof n[o]!="string"||n[o].trim()==="")throw new Error(`model route "${e}" ${o} must be a non-empty string`);const t=D.filter(o=>n.models?.[o]===void 0);if(t.length>0)throw new Error(`model route "${e}" is incomplete; missing strengths: ${t.join(", ")}`);for(const o of D){const r=n.models[o];if(typeof r!="string"||r.trim()==="")throw new Error(`model route "${e}" models.${o} must be a non-empty provider/id ref`);const i=r.indexOf("/");if(i<=0||i===r.length-1)throw new Error(`model route "${e}" models.${o} must be provider/id`);if(r.slice(0,i)!==n.providerId)throw new Error(`model route "${e}" models.${o} provider prefix must equal providerId`)}}s(An,"assertCompleteModelRoute");function O(e,n){if(e===void 0||e===null||typeof e!="object"||Array.isArray(e))return n;const t=e,o=s(i=>Array.isArray(i)&&i.every(d=>typeof d=="string"&&d.trim()!=="")?[...i]:void 0,"strings"),r=Array.isArray(t.strengthFallback)&&t.strengthFallback.every(i=>oe(i))?[...t.strengthFallback]:void 0;return{...o(t.credentialSourceOrder)!==void 0?{credentialSourceOrder:o(t.credentialSourceOrder)}:{},...o(t.familyOrder)!==void 0?{familyOrder:o(t.familyOrder)}:{},...r!==void 0?{strengthFallback:r}:{}}}s(O,"mergeModelRouting");function Rn(e){return e!==""&&e.replace(/\*/g,"")===""}s(Rn,"isInheritAllGlob");function E(e,n=[]){const t=e,o=Array.isArray(t?.allow)?t.allow.filter(r=>typeof r=="string"):[];for(const r of o)if(Rn(r))throw new Error(`spawnEnv.allow: "${r}" matches every env var name (inherit-all) \u2014 this is exactly the leak the spawn-env boundary closes. Name the specific vars/prefixes you actually need instead (e.g. "AWS_*", "GIT_ASKPASS").`);return{allow:[...new Set([...n,...o])]}}s(E,"mergeSpawnEnv");function I(e,n={}){const t={};for(const[o,r]of Object.entries(n))t[o]={...r};if(e!==null&&typeof e=="object")for(const[o,r]of Object.entries(e)){if(r===null||typeof r!="object")continue;const i={...t[o]},d=r.fastMode;typeof d=="boolean"&&(i.fastMode=d),t[o]=i}return t}s(I,"mergeProviderOptions");const ie=/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/,jn=new Set(["crtr","crtrd"]);function P(e,n){if(n==="bin"&&jn.has(e))return`${n}.${e} is reserved by crouter \u2014 pick another bare command name`;if(!ie.test(e))return`${n}.${e} is not a safe bare command name (expected ${ie.source})`}s(P,"bareCommandNameIssue");function Sn(e){if(e===null||typeof e!="object"||Array.isArray(e))return[{name:"bin",message:"bin must be a JSON object mapping bare command name to a relative path"}];const n=[];for(const[t,o]of Object.entries(e)){const r=P(t,"bin");r!==void 0&&n.push({name:t,message:r}),(typeof o!="string"||o.trim()==="")&&n.push({name:t,message:`bin.${t} must be a non-empty relative path to an executable inside the contributor root`})}return n}s(Sn,"binDeclarationIssues");function xn(e){if(e===null||typeof e!="object"||Array.isArray(e))return{};const n={};for(const[t,o]of Object.entries(e))P(t,"bin")===void 0&&(typeof o!="string"||o.trim()===""||(n[t]=o));return n}s(xn,"normalizeBin");const se=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function On(e){if(e===null||typeof e!="object"||Array.isArray(e))return[{name:"humanActions",reason:"humanActions must be a JSON object mapping action names to {argv, cwd}",block:!0}];const n=[];for(const[t,o]of Object.entries(e)){const r=[];if(se.test(t)||r.push(`action name must match ${se.source}`),o===null||typeof o!="object"||Array.isArray(o))r.push("action must be an object with argv and cwd");else{const i=o,d=Object.keys(i).filter(c=>c!=="argv"&&c!=="cwd");d.length>0&&r.push(`action has unsupported field${d.length===1?"":"s"}: ${d.join(", ")}`),(!Array.isArray(i.argv)||i.argv.length===0||!i.argv.every(c=>typeof c=="string"&&c.length>0))&&r.push("argv must be a non-empty array of non-empty strings"),(typeof i.cwd!="string"||i.cwd.length===0)&&r.push("cwd is required and must be a non-empty string")}r.length>0&&n.push({name:t,reason:r.join("; ")})}return n}s(On,"humanActionDeclarationIssues");function En(e){if(e===null||typeof e!="object"||Array.isArray(e))return{};const n=new Set(On(e).map(o=>o.name)),t={};for(const[o,r]of Object.entries(e)){if(n.has(o))continue;const i=r;t[o]={argv:[...i.argv],cwd:i.cwd}}return t}s(En,"normalizeHumanActions");function yo(e){return Sn(e).map(n=>n.message)}s(yo,"invalidPluginBinReasons");function ho(e){if(e===null||typeof e!="object"||Array.isArray(e))return{};const n={};for(const[t,o]of Object.entries(e))P(t,"requires")===void 0&&(typeof o!="string"||o.trim()===""||/[\r\n]/.test(o)||(n[t]=o));return n}s(ho,"normalizeRequires");function bo(e){if(e===null||typeof e!="object"||Array.isArray(e))return["requires must be a JSON object mapping a bare executable name to a one-line install hint"];const n=[];for(const[t,o]of Object.entries(e)){const r=P(t,"requires");r!==void 0&&n.push(r),typeof o!="string"||o.trim()===""?n.push(`requires.${t} must be a non-empty one-line install hint`):/[\r\n]/.test(o)&&n.push(`requires.${t} must be a one-line install hint`)}return n}s(bo,"invalidPluginRequiresReasons");function de(e){if(e===null||typeof e!="object")return null;const n=e,t={};typeof n.whenToUse=="string"&&n.whenToUse.trim()!==""&&(t.whenToUse=n.whenToUse),typeof n.model=="string"&&n.model.trim()!==""&&(t.model=n.model),typeof n.orchestratorModel=="string"&&n.orchestratorModel.trim()!==""&&(t.orchestratorModel=n.orchestratorModel);const o=s(r=>Array.isArray(r)&&r.every(i=>typeof i=="string"),"isStringArray");return o(n.tools)&&(t.tools=n.tools),o(n.extensions)&&(t.extensions=n.extensions),o(n.availableTo)&&(t.availableTo=n.availableTo),Object.keys(t).length>0?t:null}s(de,"normalizeKindFields");function A(e,n=Ge()){const t={...n};if(e!==null&&typeof e=="object")for(const[o,r]of Object.entries(e)){const i=de(r);if(i===null)continue;const d=t[o];d!==void 0?t[o]={...d,...i}:i.whenToUse!==void 0&&(t[o]=i)}return t}s(A,"mergeKinds");function ce(e,n,t){if(n===null)return t;const o=Y(e,n).filter(i=>i.enabled&&i.manifest.kinds!==void 0).sort((i,d)=>i.name.localeCompare(d.name));let r=t;for(const i of o)r=A(i.manifest.kinds,r);return r}s(ce,"layerPluginKinds");function _o(){const e=[{origin:"config.json",components:gn("user").page_components}],n=y("user");if(n!==null){const t=Y("user",n).filter(o=>o.enabled&&o.manifest.page_components!==void 0).sort((o,r)=>o.name.localeCompare(r.name));for(const o of t){const r=`plugin "${o.name}" page_components`;e.push({origin:`plugin "${o.name}"`,components:X(o.manifest.page_components,r)})}}return mn(e)}s(_o,"resolvePageComponents");const K=new Set(["whenToUse","model","orchestratorModel","tools","extensions","availableTo"]);function vo(e){if(e===null||typeof e!="object"||Array.isArray(e))return["kinds must be a JSON object keyed by kind name"];const n=[],t=s(o=>Array.isArray(o)&&o.every(r=>typeof r=="string"),"isStringArray");for(const[o,r]of Object.entries(e)){if(o.trim()===""){n.push("kinds contains an empty kind name");continue}if(r===null||typeof r!="object"||Array.isArray(r)){n.push(`kinds.${o} must be a JSON object`);continue}const i=r;for(const d of Object.keys(i))K.has(d)||n.push(`kinds.${o}.${d} is not a KindConfig field (expected one of: ${[...K].join(", ")})`);i.whenToUse!==void 0&&(typeof i.whenToUse!="string"||i.whenToUse.trim()==="")&&n.push(`kinds.${o}.whenToUse must be a non-empty string`);for(const d of["model","orchestratorModel"])i[d]!==void 0&&(typeof i[d]!="string"||i[d].trim()==="")&&n.push(`kinds.${o}.${d} must be a non-empty string`);for(const d of["tools","extensions","availableTo"])i[d]!==void 0&&!t(i[d])&&n.push(`kinds.${o}.${d} must be an array of strings`);de(r)===null&&n.push(`kinds.${o} has no valid KindConfig field \u2014 an entry must set at least one of: ${[...K].join(", ")} (whenToUse is required when the kind exists in no lower layer)`)}return n}s(vo,"invalidPluginKindsReasons");function In(e){if(e===null||typeof e!="object")return null;const n=e;if(typeof n.previewEndpoint!="string"||n.previewEndpoint.trim()===""||typeof n.relayTokenRef!="string"||n.relayTokenRef.trim()==="")return null;const t={previewEndpoint:n.previewEndpoint,relayTokenRef:n.relayTokenRef};return typeof n.cpOrigin=="string"&&n.cpOrigin.trim()!==""&&(t.cpOrigin=n.cpOrigin),t}s(In,"normalizeRemoteCanvasTarget");function Pn(e,n=Be()){const t={...n.targets};if(e!==null&&typeof e=="object"){const o=e;if(o.targets!==null&&typeof o.targets=="object")for(const[r,i]of Object.entries(o.targets)){const d=In(i);d!==null&&(t[r]=d)}}return{targets:t}}s(Pn,"mergeRemoteCanvas");function ue(e,n){return e===!0?"notify":e===!1?!1:e==="notify"||e==="apply"?e:n}s(ue,"normalizeMode");function R(e,n){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=1?e:n}s(R,"normalizePositiveInteger");function Tn(e,n){const t=e!==null&&typeof e=="object"?e:{},o=R(t.warning,n.warning),r=R(t.automaticReviveCap,n.automaticReviveCap);return o<=r?{warning:o,automaticReviveCap:r}:{...n}}s(Tn,"mergeBrokerThresholds");function $n(e,n){return{unattendedParkMs:R((e!==null&&typeof e=="object"?e:{}).unattendedParkMs,n.unattendedParkMs)}}s($n,"mergeLifecycle");function Cn(e){if(!Array.isArray(e))return[...J];const n=e.filter(t=>typeof t=="string"&&t.trim()!=="").map(t=>t.trim());return n.length>0?n:[...J]}s(Cn,"normalizeWhipMessages");function T(e){const n=b(),t=n.schema_version,o=e.marketplaces===void 0?{}:e.marketplaces,r=e.plugins===void 0?{}:e.plugins,i=e.auto_update,d=i&&typeof i.interval_hours=="number"?i.interval_hours:void 0,c=d!==void 0&&Number.isFinite(d)&&d>=0?d:n.auto_update.interval_hours,u={crtr:ue(i?.crtr,n.auto_update.crtr),content:ue(i?.content,n.auto_update.content),interval_hours:c},f=e.max_panes_per_window,l=R(f,n.max_panes_per_window),a=typeof e.auto_open_child_viewers=="boolean"?e.auto_open_child_viewers:n.auto_open_child_viewers,m=Tn(e.brokerThresholds,n.brokerThresholds),$=$n(e.lifecycle,n.lifecycle),p=typeof e.completion_bell=="boolean"?e.completion_bell:n.completion_bell,le=e.working_gerunds===void 0?[...n.working_gerunds]:an(e.working_gerunds),fe=typeof e.whip_mode=="boolean"?e.whip_mode:n.whip_mode,ae=X(e.page_components),me=typeof e.page_surface=="boolean"?e.page_surface:n.page_surface,pe=Cn(e.whip_messages),ge=Ue.includes(e.whip_message_mode)?e.whip_message_mode:n.whip_message_mode,ye=De.includes(e.mouse_mode_default)?e.mouse_mode_default:n.mouse_mode_default,he=R(e.live_cycles,n.live_cycles),be=ze.includes(e.condensed_history)?e.condensed_history:n.condensed_history,_e=typeof e.bash_tool_purpose=="boolean"?e.bash_tool_purpose:n.bash_tool_purpose,ve=typeof e.fold_finished_tools=="boolean"?e.fold_finished_tools:n.fold_finished_tools,ke=typeof e.summarize_tool_calls=="boolean"?e.summarize_tool_calls:n.summarize_tool_calls,we=typeof e.detailed_tool_recaps=="boolean"?e.detailed_tool_recaps:n.detailed_tool_recaps,Ae=vn(e.keybindings),Re=wn(e.tmux_passthrough),je=S(e.modelLadders),Se=I(e.providerOptions,n.providerOptions),C=re(x(e.modelRoutes)),G=C.complete,B=O(e.modelRouting,void 0),xe=A(e.kinds),Oe=Pn(e.remoteCanvas),Ee=E(e.spawnEnv,n.spawnEnv?.allow),Ie=xn(e.bin),Pe=En(e.humanActions);return{bin:Ie,humanActions:Pe,schema_version:t,marketplaces:o,plugins:r,auto_update:u,max_panes_per_window:l,auto_open_child_viewers:a,brokerThresholds:m,lifecycle:$,completion_bell:p,working_gerunds:le,whip_mode:fe,page_components:ae,page_surface:me,whip_messages:pe,whip_message_mode:ge,mouse_mode_default:ye,live_cycles:he,condensed_history:be,bash_tool_purpose:_e,fold_finished_tools:ve,summarize_tool_calls:ke,detailed_tool_recaps:we,keybindings:Ae,tmux_passthrough:Re,modelLadders:je,providerOptions:Se,...Object.keys(G).length>0?{modelRoutes:G}:{},...Object.keys(C.legacy).length>0?{legacyModelRoutes:C.legacy}:{},...B!==void 0?{modelRouting:B}:{},kinds:xe,remoteCanvas:Oe,spawnEnv:Ee}}s(T,"mergeConfig");function Mn(e){return j(e)}s(Mn,"readRawConfigAtRoot");function Ln(e){const n=y(e);return n?Mn(n):null}s(Ln,"readRawScopeConfig");function Nn(e){if(e===null||e==="")return null;try{return j(N(e))}catch{return null}}s(Nn,"readRawProfileConfig");function Fn(e,n){return[...Qe(e,n)].reverse().map(r=>({root:r,raw:j(r)}))}s(Fn,"readRawProjectScopeConfigs");function q(e=process.cwd(),n=$e()||null){const t=b(),o=Ln("user"),r=Nn(n),i=Fn(e,n);let d=A(o?.kinds,ce("user",y("user"),t.kinds)),c=S(o?.modelLadders,t.modelLadders),u=I(o?.providerOptions,t.providerOptions),f=x(o?.modelRoutes),l=O(o?.modelRouting,void 0),a=E(o?.spawnEnv,t.spawnEnv?.allow);r!==null&&(d=A(r.kinds,d),c=S(r.modelLadders,c),u=I(r.providerOptions,u),f=x(r.modelRoutes,f),l=O(r.modelRouting,l),a=E(r.spawnEnv,a.allow));for(const{root:$,raw:p}of i)d=A(p?.kinds,ce("project",$,d)),p!==null&&(c=S(p.modelLadders,c),u=I(p.providerOptions,u),f=x(p.modelRoutes,f),l=O(p.modelRouting,l),a=E(p.spawnEnv,a.allow));const m=re(f);return{kinds:d,modelLadders:c,providerOptions:u,...Object.keys(m.complete).length>0?{modelRoutes:m.complete}:{},...Object.keys(m.legacy).length>0?{legacyModelRoutes:m.legacy}:{},...l!==void 0?{modelRouting:l}:{},spawnEnv:a}}s(q,"readMergedLaunchConfig");function ko(e){return q().kinds[e]}s(ko,"resolveKindConfig");function wo(e){const n=Object.keys(q().kinds).sort();if(!n.includes(e))throw Ye(`unknown kind: ${e}`,{received:e,field:"kind",next:`Valid kinds: ${n.join(", ")}.`})}s(wo,"assertInstalledKind");function Ao(e){const n=q().kinds,t=[];for(const[o,r]of Object.entries(n)){const i=o.indexOf("/");if(i===-1)continue;const d=o.slice(0,i),c=r.availableTo??[d];(c.includes("*")||c.includes(e))&&t.push({kind:o,whenToUse:r.whenToUse})}return t.sort((o,r)=>o.kind.localeCompare(r.kind))}s(Ao,"subKindsAvailableTo");function zn(e,n,t){const o={...e??{}};o.anthropic!==void 0&&(o.anthropic={...o.anthropic}),o.openai!==void 0&&(o.openai={...o.openai}),t.defaultProvider!==n.defaultProvider&&t.defaultProvider!==void 0&&(o.defaultProvider=t.defaultProvider);for(const i of["anthropic","openai"])for(const d of["ultra","strong","medium","light"])t[i][d]!==n[i][d]&&(o[i]={...o[i]??{},[d]:t[i][d]});return o.defaultProvider!==void 0||o.anthropic!==void 0||o.openai!==void 0?o:void 0}s(zn,"sparseModelLaddersToPersist");function Dn(e,n){return v(e,t=>{const o=T(t),r=T(t);n(r);const i={...t};for(const c of fn)c!=="modelLadders"&&!Le(r[c],o[c])&&(i[c]=r[c]);const d=zn(t.modelLadders,o.modelLadders,r.modelLadders);return d!==void 0?i.modelLadders=d:delete i.modelLadders,{value:r,next:i}})}s(Dn,"mutateConfigAtRoot");function Ro(e,n){v(e,t=>{const o=t.modelLadders??{},r={...o};n.defaultProvider!==void 0&&(r.defaultProvider=n.defaultProvider);for(const i of["anthropic","openai"])n[i]!==void 0&&(r[i]={...o[i]??{},...n[i]});return{value:void 0,next:{...t,modelLadders:r}}})}s(Ro,"persistModelLadders");function jo(e,n,t){if(t!==void 0)An(n,t);else if(n.trim()==="")throw new Error("model route id must be a non-empty string");v(e,o=>{const r=te(o.modelRoutes??{});t===void 0?delete r[n]:k(r,n,{...t,models:{...t.models}});const i={...o};return Object.keys(r).length===0?delete i.modelRoutes:i.modelRoutes=r,{value:void 0,next:i}})}s(jo,"persistModelRoute");function Un(e,n){return Dn(e,n)}s(Un,"updateConfigAtRoot");function So(e,n){return Un(_(e),n)}s(So,"updateConfig");function xo(e){const n=e.orchestrator===!0?"orchestratorModel":"model";return v(e.root,t=>{const o={...t.kinds??{},[e.kind]:{...(t.kinds??{})[e.kind],[n]:e.model}};return{value:void 0,next:{...t,kinds:o}}}),{path:h(e.root),field:n}}s(xo,"persistDefaultKindModel");function Oo(e,n){const t=hn(e);return n(t),_n(e,t),t}s(Oo,"updateState");export{bn as InvalidRawSettingsError,wo as assertInstalledKind,Sn as binDeclarationIssues,co as configPath,go as ensureScopeInitialized,On as humanActionDeclarationIssues,yo as invalidPluginBinReasons,vo as invalidPluginKindsReasons,bo as invalidPluginRequiresReasons,xn as normalizeBin,En as normalizeHumanActions,ho as normalizeRequires,wn as normalizeTmuxPassthrough,xo as persistDefaultKindModel,Ro as persistModelLadders,jo as persistModelRoute,gn as readConfig,yn as readConfigAtRoot,q as readMergedLaunchConfig,Mn as readRawConfigAtRoot,Ln as readRawScopeConfig,lo as readRawSettingsForTarget,hn as readState,fo as replaceRawSettingsForTarget,ko as resolveKindConfig,_o as resolvePageComponents,uo as statePath,Ao as subKindsAvailableTo,So as updateConfig,Un as updateConfigAtRoot,ao as updateRawConfigAtomically,Oo as updateState,mo as writeConfig,po as writeRawConfig,_n as writeState};
|
|
1
|
+
var $e=Object.defineProperty;var s=(e,n)=>$e(e,"name",{value:n,configurable:!0});import{envProfileId as Ce}from"../shared/env.js";import{basename as Me,dirname as Le,join as H}from"node:path";import{isDeepStrictEqual as Ne}from"node:util";import{CONFIG_FILE as Fe,STATE_FILE as ze,CONDENSED_HISTORY_MODES as De,MOUSE_MODE_DEFAULTS as Ue,WHIP_MESSAGE_MODES as Ke,DEFAULT_WHIP_MESSAGES as J,defaultScopeConfig as b,defaultScopeState as qe,defaultModelLaddersConfig as Ge,defaultKindsConfig as Be,defaultRemoteCanvasConfig as He}from"../types.js";import{BINDING_CATALOG as Je,BINDING_IDS as We,isAttachPaneBinding as Ze}from"./keybindings/catalog.js";import{notFound as Ye,usage as Ve}from"./errors.js";import{emitEvent as Qe}from"./events/emit.js";import{atomicWriteJson as W,readJsonIfExists as M,ensureDir as Z}from"./fs-utils.js";import{scopeRoot as y,requireScopeRoot as _,findProjectScopeRoots as Xe,userScopeRoot as L}from"./scope.js";import{listInstalledPluginsInRoot as Y}from"./installed-plugins.js";import{profileRoot as N,listProfiles as V}from"./profiles/manifest.js";import{canonicalRoot as F,projectStore as en,userStore as Q}from"./scoped-state/paths.js";import{convertLegacyScopedStore as nn,initializeFreshScopedStore as on}from"./scoped-state/migrate.js";import{mutateRawSettings as tn,readBookkeeping as rn,readRawSettings as sn,readRawSettingsWithRevision as cn,replaceRawSettings as dn,writeBookkeeping as un,writeRawSettings as ln}from"./scoped-state/settings.js";import{withExclusiveDirectoryLock as fn}from"./exclusive-lock.js";import{SCOPE_CONFIG_KEYS as an}from"./user-settings.js";import{normalizeWorkingGerunds as mn}from"../shared/working-activity.js";import{mergePageComponentLayers as pn,normalizePageComponents as X}from"./human/page-catalog.js";function h(e){return H(e,Fe)}s(h,"configPathFor");function ee(e,n){return Z(Le(e)),fn(`${e}.lock`,()=>n(e),{timeoutError:s(()=>new Error(`timed out waiting for config lock: ${e}`),"timeoutError")})}s(ee,"withConfigPathLock");function gn(e){return H(e,ze)}s(gn,"statePathFor");function lo(e){const n=y(e);return n?h(n):null}s(lo,"configPath");function fo(e){const n=y(e);return n?gn(n):null}s(fo,"statePath");function g(e){const n=F(e),t=F(L());if(n===t)return{store:Q(t),key:"user",kind:"user",root:t};if(Me(n)===".crouter")return nn({kind:"project",root:n}),{store:en(n),key:"project",kind:"project",root:n};for(const o of V()){const r=F(N(o.profileId));if(n===r)return{store:Q(t),key:`profile:${o.profileId}`,kind:"profile",root:r,profileId:o.profileId}}throw new Error(`settings root is not a recognized owner: ${e}`)}s(g,"settingsOwnerForRoot");function R(e){const n=g(e);return n.kind==="project"?M(h(n.root)):sn(n)}s(R,"readRawAtRoot");function z(e,n){const t=g(e);if(t.kind==="project"){ee(h(t.root),o=>W(o,n));return}ln(t,n)}s(z,"writeRawAtRoot");function v(e,n){const t=g(e);return t.kind==="project"?ee(h(t.root),o=>{const r=n(M(o)??{});return W(o,r.next),r.value}):tn(t,o=>n(o))}s(v,"mutateRawAtRoot");function yn(e){const n=y(e);return n?hn(n):b()}s(yn,"readConfig");function hn(e){const n=R(e);return n?T(n):b()}s(hn,"readConfigAtRoot");function bn(e){const n=y(e);return n?rn(g(n)):qe()}s(bn,"readState");class _n extends Error{static{s(this,"InvalidRawSettingsError")}constructor(n){super(`settings cannot be merged: ${n instanceof Error?n.message:String(n)}`),this.name="InvalidRawSettingsError"}}function ne(e){if(e.scope==="user")return g(L());if(!V().some(n=>n.profileId===e.profileId))throw Ye(`profile not found: ${e.profileId}`,{received:e.profileId,next:"Run `crtr profile list` to see available profiles."});return g(N(e.profileId))}s(ne,"rawSettingsOwnerForTarget");function ao(e){return cn(ne(e))}s(ao,"readRawSettingsForTarget");function mo(e,n,t){return dn(ne(e),n,t,o=>{try{T(o)}catch(r){throw new _n(r)}})}s(mo,"replaceRawSettingsForTarget");function po(e,n){const t=_(e);return v(t,o=>{const r=n(o);return{value:r,next:r}})}s(po,"updateRawConfigAtomically");function go(e,n){z(_(e),n)}s(go,"writeConfig");function yo(e,n){z(_(e),n)}s(yo,"writeRawConfig");function vn(e,n){const t=_(e);un(g(t),n)}s(vn,"writeState");function ho(e,n){Z(n);const t=g(e==="user"?L():n);if(on({kind:t.kind==="user"?"user":"project",root:t.store.root}),t.kind==="project"&&M(h(t.root))===null){const{modelLadders:o,keybindings:r,tmux_passthrough:i,brokerThresholds:c,lifecycle:d,api:u,...f}=b();z(t.root,f)}}s(ho,"ensureScopeInitialized");function kn(e){if(e===null||typeof e!="object"||Array.isArray(e))return{};const n={};for(const[t,o]of Object.entries(e))Array.isArray(o)&&o.every(r=>typeof r=="string")&&(n[t]=[...o]);return n}s(kn,"normalizeKeybindings");const An=new Set(Je.filter(Ze).map(e=>e.id));function wn(e){return Array.isArray(e)?[...new Set(e.filter(n=>typeof n=="string"&&We.has(n)&&An.has(n)))]:[]}s(wn,"normalizeTmuxPassthrough");function S(e,n=Ge()){const t=n;if(e===null||typeof e!="object")return t;const o=e,r={anthropic:{...t.anthropic},openai:{...t.openai},...t.defaultProvider!==void 0?{defaultProvider:t.defaultProvider}:{}};(o.defaultProvider==="anthropic"||o.defaultProvider==="openai")&&(r.defaultProvider=o.defaultProvider);for(const i of["anthropic","openai"]){const c=o[i];if(!(c===null||typeof c!="object"))for(const[d,u]of Object.entries(c))(d==="ultra"||d==="strong"||d==="medium"||d==="light")&&typeof u=="string"&&(r[i][d]=u)}return r}s(S,"mergeModelLadders");function oe(e){return e==="ultra"||e==="strong"||e==="medium"||e==="light"}s(oe,"validStrength");const D=["ultra","strong","medium","light"];function U(){return Object.create(null)}s(U,"routeRecord");function k(e,n,t){Object.defineProperty(e,n,{value:t,writable:!0,enumerable:!0,configurable:!0})}s(k,"setRouteRecord");function te(e){const n=U();for(const[t,o]of Object.entries(e??{}))k(n,t,o);return n}s(te,"copyRouteRecord");function A(e,n){Qe({level:"warn",event:"config.model_routes.invalid",fields:{route_id:e,rule:n}})}s(A,"routeInvalid");function x(e,n={}){const t=te(n);if(e===null||typeof e!="object"||Array.isArray(e))return t;for(const[o,r]of Object.entries(e)){if(o.trim()===""){A(o,"route id must be a non-empty string");continue}if(r===null||typeof r!="object"||Array.isArray(r)){A(o,"route must be an object");continue}const i=r,c=t[o],d={...c};let u;for(const f of["family","credentialSource","providerId"]){const l=i[f];if(l!==void 0){if(typeof l!="string"||l.trim()===""){u=`${f} must be a non-empty string`;break}d[f]=l}}if(u===void 0&&i.models!==void 0)if(i.models===null||typeof i.models!="object"||Array.isArray(i.models))u="models must be an object";else{const f={...c?.models};for(const[l,a]of Object.entries(i.models)){if(!oe(l)){u=`models.${l} is not a model strength`;break}if(typeof a!="string"||a.trim()===""){u=`models.${l} must be a non-empty provider/id ref`;break}const m=a.indexOf("/");if(m<=0||m===a.length-1){u=`models.${l} must be provider/id`;break}f[l]=a}d.models=f}if(u===void 0&&d.models!==void 0&&d.providerId!==void 0){for(const[f,l]of Object.entries(d.models))if(l.slice(0,l.indexOf("/"))!==d.providerId){u=`models.${f} provider prefix must equal providerId`;break}}if(u!==void 0){A(o,u);continue}k(t,o,d)}return t}s(x,"mergeModelRoutePatches");function re(e){const n=U(),t=U();for(const[o,r]of Object.entries(e)){if(r.family===void 0||r.credentialSource===void 0||r.providerId===void 0||r.models===void 0){A(o,"route must include family, credentialSource, providerId, and models");continue}const i=D.filter(c=>r.models[c]===void 0);if(i.length>0){A(o,`incomplete route; missing strengths: ${i.join(", ")}`),k(t,o,{family:r.family,credentialSource:r.credentialSource,providerId:r.providerId,models:r.models});continue}k(n,o,{family:r.family,credentialSource:r.credentialSource,providerId:r.providerId,models:r.models})}return{complete:n,legacy:t}}s(re,"resolveModelRoutes");function jn(e,n){if(e.trim()==="")throw new Error("model route id must be a non-empty string");for(const o of["family","credentialSource","providerId"])if(typeof n[o]!="string"||n[o].trim()==="")throw new Error(`model route "${e}" ${o} must be a non-empty string`);const t=D.filter(o=>n.models?.[o]===void 0);if(t.length>0)throw new Error(`model route "${e}" is incomplete; missing strengths: ${t.join(", ")}`);for(const o of D){const r=n.models[o];if(typeof r!="string"||r.trim()==="")throw new Error(`model route "${e}" models.${o} must be a non-empty provider/id ref`);const i=r.indexOf("/");if(i<=0||i===r.length-1)throw new Error(`model route "${e}" models.${o} must be provider/id`);if(r.slice(0,i)!==n.providerId)throw new Error(`model route "${e}" models.${o} provider prefix must equal providerId`)}}s(jn,"assertCompleteModelRoute");function O(e,n){if(e===void 0||e===null||typeof e!="object"||Array.isArray(e))return n;const t=e,o=s(i=>Array.isArray(i)&&i.every(c=>typeof c=="string"&&c.trim()!=="")?[...i]:void 0,"strings"),r=Array.isArray(t.strengthFallback)&&t.strengthFallback.every(i=>oe(i))?[...t.strengthFallback]:void 0;return{...o(t.credentialSourceOrder)!==void 0?{credentialSourceOrder:o(t.credentialSourceOrder)}:{},...o(t.familyOrder)!==void 0?{familyOrder:o(t.familyOrder)}:{},...r!==void 0?{strengthFallback:r}:{}}}s(O,"mergeModelRouting");function Rn(e){return e!==""&&e.replace(/\*/g,"")===""}s(Rn,"isInheritAllGlob");function E(e,n=[]){const t=e,o=Array.isArray(t?.allow)?t.allow.filter(r=>typeof r=="string"):[];for(const r of o)if(Rn(r))throw new Error(`spawnEnv.allow: "${r}" matches every env var name (inherit-all) \u2014 this is exactly the leak the spawn-env boundary closes. Name the specific vars/prefixes you actually need instead (e.g. "AWS_*", "GIT_ASKPASS").`);return{allow:[...new Set([...n,...o])]}}s(E,"mergeSpawnEnv");function I(e,n={}){const t={};for(const[o,r]of Object.entries(n))t[o]={...r};if(e!==null&&typeof e=="object")for(const[o,r]of Object.entries(e)){if(r===null||typeof r!="object")continue;const i={...t[o]},c=r.fastMode;typeof c=="boolean"&&(i.fastMode=c),t[o]=i}return t}s(I,"mergeProviderOptions");const ie=/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/,Sn=new Set(["crtr","crtrd"]);function P(e,n){if(n==="bin"&&Sn.has(e))return`${n}.${e} is reserved by crouter \u2014 pick another bare command name`;if(!ie.test(e))return`${n}.${e} is not a safe bare command name (expected ${ie.source})`}s(P,"bareCommandNameIssue");function xn(e){if(e===null||typeof e!="object"||Array.isArray(e))return[{name:"bin",message:"bin must be a JSON object mapping bare command name to a relative path"}];const n=[];for(const[t,o]of Object.entries(e)){const r=P(t,"bin");r!==void 0&&n.push({name:t,message:r}),(typeof o!="string"||o.trim()==="")&&n.push({name:t,message:`bin.${t} must be a non-empty relative path to an executable inside the contributor root`})}return n}s(xn,"binDeclarationIssues");function On(e){if(e===null||typeof e!="object"||Array.isArray(e))return{};const n={};for(const[t,o]of Object.entries(e))P(t,"bin")===void 0&&(typeof o!="string"||o.trim()===""||(n[t]=o));return n}s(On,"normalizeBin");const se=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;function En(e){if(e===null||typeof e!="object"||Array.isArray(e))return[{name:"humanActions",reason:"humanActions must be a JSON object mapping action names to {argv, cwd}",block:!0}];const n=[];for(const[t,o]of Object.entries(e)){const r=[];if(se.test(t)||r.push(`action name must match ${se.source}`),o===null||typeof o!="object"||Array.isArray(o))r.push("action must be an object with argv and cwd");else{const i=o,c=Object.keys(i).filter(d=>d!=="argv"&&d!=="cwd");c.length>0&&r.push(`action has unsupported field${c.length===1?"":"s"}: ${c.join(", ")}`),(!Array.isArray(i.argv)||i.argv.length===0||!i.argv.every(d=>typeof d=="string"&&d.length>0))&&r.push("argv must be a non-empty array of non-empty strings"),(typeof i.cwd!="string"||i.cwd.length===0)&&r.push("cwd is required and must be a non-empty string")}r.length>0&&n.push({name:t,reason:r.join("; ")})}return n}s(En,"humanActionDeclarationIssues");function In(e){if(e===null||typeof e!="object"||Array.isArray(e))return{};const n=new Set(En(e).map(o=>o.name)),t={};for(const[o,r]of Object.entries(e)){if(n.has(o))continue;const i=r;t[o]={argv:[...i.argv],cwd:i.cwd}}return t}s(In,"normalizeHumanActions");function bo(e){return xn(e).map(n=>n.message)}s(bo,"invalidPluginBinReasons");function _o(e){if(e===null||typeof e!="object"||Array.isArray(e))return{};const n={};for(const[t,o]of Object.entries(e))P(t,"requires")===void 0&&(typeof o!="string"||o.trim()===""||/[\r\n]/.test(o)||(n[t]=o));return n}s(_o,"normalizeRequires");function vo(e){if(e===null||typeof e!="object"||Array.isArray(e))return["requires must be a JSON object mapping a bare executable name to a one-line install hint"];const n=[];for(const[t,o]of Object.entries(e)){const r=P(t,"requires");r!==void 0&&n.push(r),typeof o!="string"||o.trim()===""?n.push(`requires.${t} must be a non-empty one-line install hint`):/[\r\n]/.test(o)&&n.push(`requires.${t} must be a one-line install hint`)}return n}s(vo,"invalidPluginRequiresReasons");function ce(e){if(e===null||typeof e!="object")return null;const n=e,t={};typeof n.whenToUse=="string"&&n.whenToUse.trim()!==""&&(t.whenToUse=n.whenToUse),typeof n.model=="string"&&n.model.trim()!==""&&(t.model=n.model),typeof n.orchestratorModel=="string"&&n.orchestratorModel.trim()!==""&&(t.orchestratorModel=n.orchestratorModel);const o=s(r=>Array.isArray(r)&&r.every(i=>typeof i=="string"),"isStringArray");return o(n.tools)&&(t.tools=n.tools),o(n.extensions)&&(t.extensions=n.extensions),o(n.availableTo)&&(t.availableTo=n.availableTo),Object.keys(t).length>0?t:null}s(ce,"normalizeKindFields");function w(e,n=Be()){const t={...n};if(e!==null&&typeof e=="object")for(const[o,r]of Object.entries(e)){const i=ce(r);if(i===null)continue;const c=t[o];c!==void 0?t[o]={...c,...i}:i.whenToUse!==void 0&&(t[o]=i)}return t}s(w,"mergeKinds");function de(e,n,t){if(n===null)return t;const o=Y(e,n).filter(i=>i.enabled&&i.manifest.kinds!==void 0).sort((i,c)=>i.name.localeCompare(c.name));let r=t;for(const i of o)r=w(i.manifest.kinds,r);return r}s(de,"layerPluginKinds");function ko(){const e=[{origin:"config.json",components:yn("user").page_components}],n=y("user");if(n!==null){const t=Y("user",n).filter(o=>o.enabled&&o.manifest.page_components!==void 0).sort((o,r)=>o.name.localeCompare(r.name));for(const o of t){const r=`plugin "${o.name}" page_components`;e.push({origin:`plugin "${o.name}"`,components:X(o.manifest.page_components,r)})}}return pn(e)}s(ko,"resolvePageComponents");const K=new Set(["whenToUse","model","orchestratorModel","tools","extensions","availableTo"]);function Ao(e){if(e===null||typeof e!="object"||Array.isArray(e))return["kinds must be a JSON object keyed by kind name"];const n=[],t=s(o=>Array.isArray(o)&&o.every(r=>typeof r=="string"),"isStringArray");for(const[o,r]of Object.entries(e)){if(o.trim()===""){n.push("kinds contains an empty kind name");continue}if(r===null||typeof r!="object"||Array.isArray(r)){n.push(`kinds.${o} must be a JSON object`);continue}const i=r;for(const c of Object.keys(i))K.has(c)||n.push(`kinds.${o}.${c} is not a KindConfig field (expected one of: ${[...K].join(", ")})`);i.whenToUse!==void 0&&(typeof i.whenToUse!="string"||i.whenToUse.trim()==="")&&n.push(`kinds.${o}.whenToUse must be a non-empty string`);for(const c of["model","orchestratorModel"])i[c]!==void 0&&(typeof i[c]!="string"||i[c].trim()==="")&&n.push(`kinds.${o}.${c} must be a non-empty string`);for(const c of["tools","extensions","availableTo"])i[c]!==void 0&&!t(i[c])&&n.push(`kinds.${o}.${c} must be an array of strings`);ce(r)===null&&n.push(`kinds.${o} has no valid KindConfig field \u2014 an entry must set at least one of: ${[...K].join(", ")} (whenToUse is required when the kind exists in no lower layer)`)}return n}s(Ao,"invalidPluginKindsReasons");function Pn(e){if(e===null||typeof e!="object")return null;const n=e;if(typeof n.previewEndpoint!="string"||n.previewEndpoint.trim()===""||typeof n.relayTokenRef!="string"||n.relayTokenRef.trim()==="")return null;const t={previewEndpoint:n.previewEndpoint,relayTokenRef:n.relayTokenRef};return typeof n.cpOrigin=="string"&&n.cpOrigin.trim()!==""&&(t.cpOrigin=n.cpOrigin),t}s(Pn,"normalizeRemoteCanvasTarget");function Tn(e,n=He()){const t={...n.targets};if(e!==null&&typeof e=="object"){const o=e;if(o.targets!==null&&typeof o.targets=="object")for(const[r,i]of Object.entries(o.targets)){const c=Pn(i);c!==null&&(t[r]=c)}}return{targets:t}}s(Tn,"mergeRemoteCanvas");function ue(e,n){return e===!0?"notify":e===!1?!1:e==="notify"||e==="apply"?e:n}s(ue,"normalizeMode");function j(e,n){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=1?e:n}s(j,"normalizePositiveInteger");function $n(e,n){const t=e!==null&&typeof e=="object"?e:{},o=j(t.warning,n.warning),r=j(t.automaticReviveCap,n.automaticReviveCap);return o<=r?{warning:o,automaticReviveCap:r}:{...n}}s($n,"mergeBrokerThresholds");function Cn(e,n){return{unattendedParkMs:j((e!==null&&typeof e=="object"?e:{}).unattendedParkMs,n.unattendedParkMs)}}s(Cn,"mergeLifecycle");function Mn(e){if(!Array.isArray(e))return[...J];const n=e.filter(t=>typeof t=="string"&&t.trim()!=="").map(t=>t.trim());return n.length>0?n:[...J]}s(Mn,"normalizeWhipMessages");function Ln(e,n){if(e===null||typeof e!="object")return{...n};const t=e.tcp;return{tcp:typeof t=="string"?t:n.tcp}}s(Ln,"mergeApi");function T(e){const n=b(),t=n.schema_version,o=e.marketplaces===void 0?{}:e.marketplaces,r=e.plugins===void 0?{}:e.plugins,i=e.auto_update,c=i&&typeof i.interval_hours=="number"?i.interval_hours:void 0,d=c!==void 0&&Number.isFinite(c)&&c>=0?c:n.auto_update.interval_hours,u={crtr:ue(i?.crtr,n.auto_update.crtr),content:ue(i?.content,n.auto_update.content),interval_hours:d},f=e.max_panes_per_window,l=j(f,n.max_panes_per_window),a=typeof e.auto_open_child_viewers=="boolean"?e.auto_open_child_viewers:n.auto_open_child_viewers,m=$n(e.brokerThresholds,n.brokerThresholds),$=Cn(e.lifecycle,n.lifecycle),p=typeof e.completion_bell=="boolean"?e.completion_bell:n.completion_bell,le=e.working_gerunds===void 0?[...n.working_gerunds]:mn(e.working_gerunds),fe=typeof e.whip_mode=="boolean"?e.whip_mode:n.whip_mode,ae=X(e.page_components),me=typeof e.page_surface=="boolean"?e.page_surface:n.page_surface,pe=Mn(e.whip_messages),ge=Ke.includes(e.whip_message_mode)?e.whip_message_mode:n.whip_message_mode,ye=Ue.includes(e.mouse_mode_default)?e.mouse_mode_default:n.mouse_mode_default,he=j(e.live_cycles,n.live_cycles),be=De.includes(e.condensed_history)?e.condensed_history:n.condensed_history,_e=typeof e.bash_tool_purpose=="boolean"?e.bash_tool_purpose:n.bash_tool_purpose,ve=typeof e.fold_finished_tools=="boolean"?e.fold_finished_tools:n.fold_finished_tools,ke=typeof e.summarize_tool_calls=="boolean"?e.summarize_tool_calls:n.summarize_tool_calls,Ae=typeof e.detailed_tool_recaps=="boolean"?e.detailed_tool_recaps:n.detailed_tool_recaps,we=kn(e.keybindings),je=wn(e.tmux_passthrough),Re=S(e.modelLadders),Se=I(e.providerOptions,n.providerOptions),C=re(x(e.modelRoutes)),G=C.complete,B=O(e.modelRouting,void 0),xe=w(e.kinds),Oe=Tn(e.remoteCanvas),Ee=Ln(e.api,n.api),Ie=E(e.spawnEnv,n.spawnEnv?.allow),Pe=On(e.bin),Te=In(e.humanActions);return{bin:Pe,humanActions:Te,schema_version:t,marketplaces:o,plugins:r,auto_update:u,max_panes_per_window:l,auto_open_child_viewers:a,brokerThresholds:m,lifecycle:$,completion_bell:p,working_gerunds:le,whip_mode:fe,page_components:ae,page_surface:me,whip_messages:pe,whip_message_mode:ge,mouse_mode_default:ye,live_cycles:he,condensed_history:be,bash_tool_purpose:_e,fold_finished_tools:ve,summarize_tool_calls:ke,detailed_tool_recaps:Ae,keybindings:we,tmux_passthrough:je,modelLadders:Re,providerOptions:Se,...Object.keys(G).length>0?{modelRoutes:G}:{},...Object.keys(C.legacy).length>0?{legacyModelRoutes:C.legacy}:{},...B!==void 0?{modelRouting:B}:{},kinds:xe,remoteCanvas:Oe,api:Ee,spawnEnv:Ie}}s(T,"mergeConfig");function Nn(e){return R(e)}s(Nn,"readRawConfigAtRoot");function Fn(e){const n=y(e);return n?Nn(n):null}s(Fn,"readRawScopeConfig");function zn(e){if(e===null||e==="")return null;try{return R(N(e))}catch{return null}}s(zn,"readRawProfileConfig");function Dn(e,n){return[...Xe(e,n)].reverse().map(r=>({root:r,raw:R(r)}))}s(Dn,"readRawProjectScopeConfigs");function q(e=process.cwd(),n=Ce()||null){const t=b(),o=Fn("user"),r=zn(n),i=Dn(e,n);let c=w(o?.kinds,de("user",y("user"),t.kinds)),d=S(o?.modelLadders,t.modelLadders),u=I(o?.providerOptions,t.providerOptions),f=x(o?.modelRoutes),l=O(o?.modelRouting,void 0),a=E(o?.spawnEnv,t.spawnEnv?.allow);r!==null&&(c=w(r.kinds,c),d=S(r.modelLadders,d),u=I(r.providerOptions,u),f=x(r.modelRoutes,f),l=O(r.modelRouting,l),a=E(r.spawnEnv,a.allow));for(const{root:$,raw:p}of i)c=w(p?.kinds,de("project",$,c)),p!==null&&(d=S(p.modelLadders,d),u=I(p.providerOptions,u),f=x(p.modelRoutes,f),l=O(p.modelRouting,l),a=E(p.spawnEnv,a.allow));const m=re(f);return{kinds:c,modelLadders:d,providerOptions:u,...Object.keys(m.complete).length>0?{modelRoutes:m.complete}:{},...Object.keys(m.legacy).length>0?{legacyModelRoutes:m.legacy}:{},...l!==void 0?{modelRouting:l}:{},spawnEnv:a}}s(q,"readMergedLaunchConfig");function wo(e){return q().kinds[e]}s(wo,"resolveKindConfig");function jo(e){const n=Object.keys(q().kinds).sort();if(!n.includes(e))throw Ve(`unknown kind: ${e}`,{received:e,field:"kind",next:`Valid kinds: ${n.join(", ")}.`})}s(jo,"assertInstalledKind");function Ro(e){const n=q().kinds,t=[];for(const[o,r]of Object.entries(n)){const i=o.indexOf("/");if(i===-1)continue;const c=o.slice(0,i),d=r.availableTo??[c];(d.includes("*")||d.includes(e))&&t.push({kind:o,whenToUse:r.whenToUse})}return t.sort((o,r)=>o.kind.localeCompare(r.kind))}s(Ro,"subKindsAvailableTo");function Un(e,n,t){const o={...e??{}};o.anthropic!==void 0&&(o.anthropic={...o.anthropic}),o.openai!==void 0&&(o.openai={...o.openai}),t.defaultProvider!==n.defaultProvider&&t.defaultProvider!==void 0&&(o.defaultProvider=t.defaultProvider);for(const i of["anthropic","openai"])for(const c of["ultra","strong","medium","light"])t[i][c]!==n[i][c]&&(o[i]={...o[i]??{},[c]:t[i][c]});return o.defaultProvider!==void 0||o.anthropic!==void 0||o.openai!==void 0?o:void 0}s(Un,"sparseModelLaddersToPersist");function Kn(e,n){return v(e,t=>{const o=T(t),r=T(t);n(r);const i={...t};for(const d of an)d!=="modelLadders"&&!Ne(r[d],o[d])&&(i[d]=r[d]);const c=Un(t.modelLadders,o.modelLadders,r.modelLadders);return c!==void 0?i.modelLadders=c:delete i.modelLadders,{value:r,next:i}})}s(Kn,"mutateConfigAtRoot");function So(e,n){v(e,t=>{const o=t.modelLadders??{},r={...o};n.defaultProvider!==void 0&&(r.defaultProvider=n.defaultProvider);for(const i of["anthropic","openai"])n[i]!==void 0&&(r[i]={...o[i]??{},...n[i]});return{value:void 0,next:{...t,modelLadders:r}}})}s(So,"persistModelLadders");function xo(e,n,t){if(t!==void 0)jn(n,t);else if(n.trim()==="")throw new Error("model route id must be a non-empty string");v(e,o=>{const r=te(o.modelRoutes??{});t===void 0?delete r[n]:k(r,n,{...t,models:{...t.models}});const i={...o};return Object.keys(r).length===0?delete i.modelRoutes:i.modelRoutes=r,{value:void 0,next:i}})}s(xo,"persistModelRoute");function qn(e,n){return Kn(e,n)}s(qn,"updateConfigAtRoot");function Oo(e,n){return qn(_(e),n)}s(Oo,"updateConfig");function Eo(e){const n=e.orchestrator===!0?"orchestratorModel":"model";return v(e.root,t=>{const o={...t.kinds??{},[e.kind]:{...(t.kinds??{})[e.kind],[n]:e.model}};return{value:void 0,next:{...t,kinds:o}}}),{path:h(e.root),field:n}}s(Eo,"persistDefaultKindModel");function Io(e,n){const t=bn(e);return n(t),vn(e,t),t}s(Io,"updateState");export{_n as InvalidRawSettingsError,jo as assertInstalledKind,xn as binDeclarationIssues,lo as configPath,ho as ensureScopeInitialized,En as humanActionDeclarationIssues,bo as invalidPluginBinReasons,Ao as invalidPluginKindsReasons,vo as invalidPluginRequiresReasons,On as normalizeBin,In as normalizeHumanActions,_o as normalizeRequires,wn as normalizeTmuxPassthrough,Eo as persistDefaultKindModel,So as persistModelLadders,xo as persistModelRoute,yn as readConfig,hn as readConfigAtRoot,q as readMergedLaunchConfig,Nn as readRawConfigAtRoot,Fn as readRawScopeConfig,ao as readRawSettingsForTarget,bn as readState,mo as replaceRawSettingsForTarget,wo as resolveKindConfig,ko as resolvePageComponents,fo as statePath,Ro as subKindsAvailableTo,Oo as updateConfig,qn as updateConfigAtRoot,po as updateRawConfigAtomically,Io as updateState,go as writeConfig,yo as writeRawConfig,vn as writeState};
|
|
@@ -97,6 +97,7 @@ export declare function getRequestByCompanion(nodeId: string): HumanRequestRecor
|
|
|
97
97
|
export declare function getRequestByIdempotencyKey(key: string): HumanRequestRecord | null;
|
|
98
98
|
export declare function listOpenInboxRequests(): HumanRequestRecord[];
|
|
99
99
|
export declare function openRequestsByRequester(nodeId: string): HumanRequestRecord[];
|
|
100
|
+
export declare function hasOpenReplyBearingRequestByRequester(nodeId: string): boolean;
|
|
100
101
|
/** Indexed attention projection: only open inbox-listed requests with a reply target keep a node wakeable. */
|
|
101
102
|
export declare function listOpenReplyBearingRequests(): HumanRequestRecord[];
|
|
102
103
|
export declare function listBindingRequests(): HumanRequestRecord[];
|
|
@@ -1,38 +1,42 @@
|
|
|
1
|
-
var
|
|
2
|
-
`),r.syncFile(u),r.syncDirectory(n),r.syncDirectory(s),r.syncDirectory(e),r.syncDirectory(
|
|
1
|
+
var de=Object.defineProperty;var i=(e,t)=>de(e,"name",{value:t,configurable:!0});import{createHash as ue,randomBytes as j}from"node:crypto";import{existsSync as g,mkdirSync as A,readFileSync as V,readdirSync as ce,realpathSync as O,statSync as le,writeFileSync as _e}from"node:fs";import{basename as w,join as c}from"node:path";import{z as d}from"zod";import{crtrHome as z,isSafeNodeId as pe,nodesRoot as N}from"../canvas/paths.js";import{openDb as _,withCanvasWrite as f}from"../canvas/db.js";import{syncDirectory as me,syncFile as fe}from"../fs-utils.js";import{newNodeId as Ee}from"../runtime/nodes.js";import{pageManifestPath as ge,pageModulePath as ye,pagePath as he}from"./convention.js";import{preparePageSource as be}from"./page-authoring.js";import{pageDeliverySchema as qe,validatePageManifest as G}from"./page-schema.js";function Q(e){return e===1||e===!0}i(Q,"bool");function Y(e){return{request_id:e.request_id,kind:e.kind,inbox_ticket_id:e.inbox_ticket_id,request_dir:e.request_dir,presentation_dir:e.presentation_dir,requester_node_id:e.requester_node_id,companion_node_id:e.companion_node_id,idempotency_key:e.idempotency_key,state:e.state,outcome:e.outcome,inbox_listed:Q(e.inbox_listed),settleable:Q(e.settleable),title:e.title,subtitle:e.subtitle,file:e.file,specification_json:e.specification_json,action_json:e.action_json,progress_json:e.progress_json,feedback_json:e.feedback_json,result_json:e.result_json,anchor_base_sha256:e.anchor_base_sha256,anchor_base_bytes:e.anchor_base_bytes===null?null:Buffer.from(e.anchor_base_bytes),created_at:e.created_at,opened_at:e.opened_at,submit_requested_at:e.submit_requested_at,settled_at:e.settled_at,settlement_delivery_id:e.settlement_delivery_id,action_delivery_id:e.action_delivery_id,submit_note_delivery_id:e.submit_note_delivery_id,projected_at:e.projected_at,projection_error:e.projection_error,companion_retired_at:e.companion_retired_at,updated_at:e.updated_at}}i(Y,"recordFromRow");function b(e,t,...r){const s=e.prepare(`SELECT * FROM human_requests WHERE ${t}`).get(...r);return s===void 0?null:Y(s)}i(b,"one");function T(e,t,r=[],s="created_at ASC, request_id ASC"){return e.prepare(`SELECT * FROM human_requests WHERE ${t} ORDER BY ${s}`).all(...r).map(Y)}i(T,"many");function Z(){return c(z(),"requests")}i(Z,"humanRequestsRoot");function C(e){if(!pe(e))throw new TypeError(`request_id must be a safe path segment: ${e}`);const t=Z();return A(t,{recursive:!0,mode:448}),c(O(t),e)}i(C,"requestDir");function P(){return j(32).toString("hex")}i(P,"randomTicketId");function U(e,t){return ue("sha256").update(`${O(e)}\0${t}`,"utf8").digest("hex")}i(U,"legacyTicketId");const Ne={writeFile(e,t){_e(e,t,{flag:"wx",mode:384})},syncFile:fe,syncDirectory:me};function Te(e){return c(e,"revisions")}i(Te,"revisionRoot");function ee(e,t,r=Ne){A(e,{recursive:!0,mode:448});const s=Te(e);A(s,{recursive:!0,mode:448});const n=c(s,j(16).toString("hex"));A(n,{mode:448});const o=he(n,t.manifest.dialect);if(r.writeFile(o,t.document),r.syncFile(o),t.manifest.dialect==="jsx"){const a=ye(n);r.writeFile(a,t.module),r.syncFile(a)}const u=ge(n);return r.writeFile(u,`${JSON.stringify(t.manifest,null,2)}
|
|
2
|
+
`),r.syncFile(u),r.syncDirectory(n),r.syncDirectory(s),r.syncDirectory(e),r.syncDirectory(Z()),n}i(ee,"publishPageRevision");function ze(e){if(e.kind!=="page"||e.presentation_dir===null)throw new Error(`page request has no selected presentation: ${e.request_id}`);return e.presentation_dir}i(ze,"presentationDir");function Ge(e){const t=e.request_id??Ee(),r=C(t),s=ee(r,e.prepared),n=new Date().toISOString(),o=e.prepared.manifest;return f(u=>{u.prepare(`
|
|
3
3
|
INSERT INTO human_requests (
|
|
4
4
|
request_id, kind, inbox_ticket_id, request_dir, presentation_dir, requester_node_id, state, inbox_listed,
|
|
5
5
|
settleable, title, subtitle, specification_json, action_json, created_at, updated_at
|
|
6
6
|
) VALUES (?, 'page', ?, ?, ?, ?, 'open', ?, ?, ?, ?, ?, ?, ?, ?)
|
|
7
|
-
`).run(t,e.inbox_ticket_id??
|
|
7
|
+
`).run(t,e.inbox_ticket_id??P(),r,s,e.requester_node_id??null,o.delivery.inbox?1:0,o.delivery.inbox||o.delivery.reply?1:0,o.title,o.subtitle??null,JSON.stringify(o),e.action_json??null,n,n);const a=b(u,"request_id = ?",t);if(a===null)throw new Error(`page request insert did not produce a row: ${t}`);return a})}i(Ge,"createPageRequest");function Qe(e){return f(t=>{const r=t.prepare(`
|
|
8
8
|
INSERT INTO human_requests (
|
|
9
9
|
request_id, kind, inbox_ticket_id, request_dir, requester_node_id, companion_node_id,
|
|
10
10
|
idempotency_key, state, inbox_listed, settleable, title, subtitle, file,
|
|
11
11
|
specification_json, anchor_base_sha256, anchor_base_bytes, created_at, updated_at
|
|
12
12
|
) VALUES (?, 'review', ?, ?, ?, ?, ?, 'binding', ?, 1, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
13
13
|
ON CONFLICT(idempotency_key) DO NOTHING
|
|
14
|
-
`).run(e.request_id,
|
|
14
|
+
`).run(e.request_id,P(),e.request_dir,e.requester_node_id,e.companion_node_id,e.idempotency_key,e.inbox_listed?1:0,w(e.file),e.subtitle??null,e.file,JSON.stringify(e.specification),e.anchor_base_sha256,e.anchor_base_bytes,e.created_at,e.created_at),s=b(t,"idempotency_key = ?",e.idempotency_key);if(s===null)throw new Error(`review binding insert did not produce a row: ${e.idempotency_key}`);return{request_id:s.request_id,won:r.changes>0}})}i(Qe,"commitBindingRequest");function Ye(e){return b(_(),"request_id = ?",e)}i(Ye,"getRequest");function Ze(e){return b(_(),"inbox_ticket_id = ?",e)}i(Ze,"getRequestByInboxTicket");function et(e){let t=e;try{t=O(e)}catch{}return b(_(),"request_dir = ?",t)}i(et,"getRequestByDirectory");function tt(e){return b(_(),"companion_node_id = ? AND state <> 'binding'",e)}i(tt,"getRequestByCompanion");function nt(e){return b(_(),"idempotency_key = ?",e)}i(nt,"getRequestByIdempotencyKey");function rt(){return T(_(),"state = 'open' AND inbox_listed = 1",[],"created_at DESC, request_id DESC")}i(rt,"listOpenInboxRequests");function Se(e){return T(_(),"state = 'open' AND requester_node_id = ?",[e],"created_at DESC, request_id DESC")}i(Se,"openRequestsByRequester");function it(e){return Se(e).some(t=>t.kind==="review"?!0:JSON.parse(t.specification_json).delivery?.reply===!0)}i(it,"hasOpenReplyBearingRequestByRequester");function st(){return T(_(),"state = 'open' AND inbox_listed = 1 AND requester_node_id IS NOT NULL",[],"created_at DESC, request_id DESC")}i(st,"listOpenReplyBearingRequests");function ot(){return T(_(),"kind = 'review' AND state = 'binding'")}i(ot,"listBindingRequests");function at(){return T(_(),"kind = 'review' AND state = 'open' AND submit_requested_at IS NOT NULL")}i(at,"listSubmitRequestedRequests");function dt(){return T(_(),"kind = 'review' AND state = 'settled' AND projected_at IS NULL")}i(dt,"listUnprojectedReviews");function ut(e={}){const t=["1"],r=[];for(const[s,n]of Object.entries(e))n!==void 0&&(t.push(`${s} = ?`),r.push(n));return T(_(),t.join(" AND "),r)}i(ut,"listRequests");function ct(e,t){return f(r=>r.prepare("UPDATE human_requests SET state = 'open', opened_at = ?, updated_at = ? WHERE request_id = ? AND state = 'binding'").run(t,t,e).changes>0)}i(ct,"openRequest");function lt(e,t,r){return f(s=>s.prepare(`
|
|
15
15
|
UPDATE human_requests SET state = 'settled', outcome = 'canceled', result_json = ?, settled_at = ?, updated_at = ?
|
|
16
16
|
WHERE request_id = ? AND kind = 'review' AND state = 'binding'
|
|
17
|
-
`).run(JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:t,reason:r}),t,t,e).changes>0)}i(
|
|
17
|
+
`).run(JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:t,reason:r}),t,t,e).changes>0)}i(lt,"cancelBindingRequest");function _t(e,t){return f(r=>r.prepare("UPDATE human_requests SET submit_requested_at = ?, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open' AND submit_requested_at IS NULL").run(t,t,e).changes>0)}i(_t,"requestSubmit");function pt(e,t){return e.prepare(`
|
|
18
18
|
UPDATE human_requests SET state = 'settled', outcome = ?, result_json = ?, settled_at = ?,
|
|
19
19
|
progress_json = NULL, updated_at = ?
|
|
20
20
|
WHERE request_id = ? AND state = 'open'
|
|
21
|
-
`).run(t.outcome,t.result_json,t.settled_at,t.settled_at,t.request_id).changes===0?null:
|
|
21
|
+
`).run(t.outcome,t.result_json,t.settled_at,t.settled_at,t.request_id).changes===0?null:b(e,"request_id = ?",t.request_id)}i(pt,"settleRequestLocked");function mt(e,t,r){e.prepare("UPDATE human_requests SET settlement_delivery_id = ?, action_delivery_id = ?, updated_at = ? WHERE request_id = ?").run(r.settlement_delivery_id??null,r.action_delivery_id??null,new Date().toISOString(),t)}i(mt,"setSettlementDeliveryMarksLocked");function ft(e,t,r){return e.prepare("UPDATE human_requests SET submit_note_delivery_id = ?, updated_at = ? WHERE request_id = ? AND state = 'open' AND submit_note_delivery_id IS NULL").run(r,new Date().toISOString(),t).changes>0}i(ft,"setSubmitNoteDeliveryLocked");function Et(e,t){return f(r=>r.prepare(`
|
|
22
22
|
UPDATE human_requests SET presentation_dir = ?, specification_json = ?, title = ?, subtitle = ?, inbox_listed = ?, settleable = ?, updated_at = ?
|
|
23
23
|
WHERE request_id = ? AND kind = 'page' AND state = 'open'
|
|
24
|
-
`).run(t.presentation_dir,t.specification_json,t.title,t.subtitle,t.inbox_listed?1:0,t.settleable?1:0,new Date().toISOString(),e).changes>0)}i(
|
|
24
|
+
`).run(t.presentation_dir,t.specification_json,t.title,t.subtitle,t.inbox_listed?1:0,t.settleable?1:0,new Date().toISOString(),e).changes>0)}i(Et,"revisePageRequest");function gt(e,t){return f(r=>r.prepare(`
|
|
25
25
|
UPDATE human_requests SET progress_json = ?, updated_at = ?
|
|
26
26
|
WHERE inbox_ticket_id = ? AND kind = 'page' AND state = 'open' AND settleable = 1
|
|
27
|
-
`).run(JSON.stringify({kind:"page",responses:t,savedAt:new Date().toISOString()}),new Date().toISOString(),e).changes>0)}i(
|
|
27
|
+
`).run(JSON.stringify({kind:"page",responses:t,savedAt:new Date().toISOString()}),new Date().toISOString(),e).changes>0)}i(gt,"writeProgress");function yt(e,t){f(r=>r.prepare("UPDATE human_requests SET projected_at = ?, projection_error = NULL, updated_at = ? WHERE request_id = ?").run(t,t,e))}i(yt,"markProjected");function ht(e,t){f(r=>r.prepare("UPDATE human_requests SET projection_error = ?, updated_at = ? WHERE request_id = ? AND projected_at IS NULL").run(t,new Date().toISOString(),e))}i(ht,"markProjectionError");function bt(e,t){f(r=>r.prepare("UPDATE human_requests SET companion_retired_at = ?, updated_at = ? WHERE request_id = ? AND companion_retired_at IS NULL").run(t,t,e))}i(bt,"markCompanionRetired");function qt(e){const t=_().prepare("SELECT anchor_base_bytes, anchor_base_sha256 FROM human_requests WHERE request_id = ?").get(e);return t===void 0||t.anchor_base_bytes===null||t.anchor_base_sha256===null?null:{bytes:Buffer.from(t.anchor_base_bytes),sha256:t.anchor_base_sha256}}i(qt,"readAnchorBase");function Nt(e,t,r,s){e.prepare("UPDATE human_requests SET anchor_base_bytes = ?, anchor_base_sha256 = ?, updated_at = ? WHERE request_id = ?").run(r,s,new Date().toISOString(),t)}i(Nt,"replaceAnchorBaseLocked");function ve(e){if(typeof e!="object"||e===null)throw new Error("result is not an object");const t=e;return t.kind==="canceled"?{outcome:t.disposition==="dismissed"?"dismissed":"canceled",settledAt:String(t.canceledAt)}:{outcome:"answered",settledAt:String(t.completedAt)}}i(ve,"legacyPageResult");function R(e){try{return JSON.parse(V(e,"utf8"))}catch(t){throw new Error(`corrupt required input: ${e}`,{cause:t})}}i(R,"readJson");function H(){return j(16).toString("hex")}i(H,"migrationId");function Re(e){return Number(e.prepare("SELECT COALESCE(MAX(seq), 0) AS seq FROM messages").get().seq)+1}i(Re,"nextMessageSeq");function Ae(e,t,r,s){return(s==="page"?e.prepare(`SELECT d.delivery_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
28
28
|
WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ? AND m.sender_node_id = ?
|
|
29
29
|
AND m.disposition IN ('human-answer', 'human-canceled') LIMIT 1`).get(r,t):e.prepare(`SELECT d.delivery_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
30
|
-
WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ? AND m.body_json LIKE ? LIMIT 1`).get(r,`%"review_id":"${t}"%`))?.delivery_id??null}i(
|
|
30
|
+
WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ? AND m.body_json LIKE ? LIMIT 1`).get(r,`%"review_id":"${t}"%`))?.delivery_id??null}i(Ae,"importedTerminalDelivery");function te(e,t,r){if(t===null||r===null)return!1;const s=e.prepare("SELECT status, final_report FROM nodes WHERE node_id = ?").get(t);return s?.status==="canceled"||r==="approved"&&s?.status==="done"&&s.final_report!==null}i(te,"companionRetirementProven");function ne(e){if(typeof e!="object"||e===null)return"no reason was given";const t=e.reason;return typeof t=="string"&&t!==""?t:"no reason was given"}i(ne,"migratedCancellationReason");function De(e,t){const r=e.outcome==="canceled"||e.outcome==="dismissed";return[e.kind==="review"?r?`Review ${e.requestId} was canceled \u2014 ${ne(t)}.`:`Review ${e.requestId} was approved by the user.`:r?`Human request ${e.requestId} was canceled \u2014 ${ne(t)}.`:`Human request ${e.requestId} was answered.`,...e.kind==="review"?[`The review result is at ${e.requestDir}/result.json.`]:[],`Result:
|
|
31
|
+
${JSON.stringify(t,null,2)}`].join(`
|
|
32
|
+
|
|
33
|
+
`)}i(De,"migratedTerminalBody");function ke(e,t){const r=H(),s=H(),n=Date.parse(t.settledAt),o=Number.isFinite(n)?n:0,u=t.outcome==="answered"||t.outcome==="approved"?"human-answer":"human-canceled",a=JSON.parse(t.resultJson),l=De(t,a);return e.prepare(`INSERT INTO messages
|
|
31
34
|
(message_id, seq, operation_id, created_at, sender_node_id, sender_name, kind, label, body_ref, body_json, disposition)
|
|
32
|
-
VALUES (?, ?, ?, ?, NULL, 'crtrd', 'completed', ?, NULL, ?, ?)`).run(r,
|
|
35
|
+
VALUES (?, ?, ?, ?, NULL, 'crtrd', 'completed', ?, NULL, ?, ?)`).run(r,Re(e),H(),t.settledAt,l.split(`
|
|
36
|
+
`,1)[0],JSON.stringify({body:l,result:a}),u),e.prepare(`INSERT INTO deliveries
|
|
33
37
|
(delivery_id, message_id, destination_kind, destination_id, urgency, wake, state, attempts, created_at, updated_at)
|
|
34
|
-
VALUES (?, ?, 'node_inbox', ?, 'normal', 1, 'pending', 0, ?, ?)`).run(s,r,t.requesterNodeId,o,o),s}i(
|
|
35
|
-
`}i(
|
|
38
|
+
VALUES (?, ?, 'node_inbox', ?, 'normal', 1, 'pending', 0, ?, ?)`).run(s,r,t.requesterNodeId,o,o),s}i(ke,"createMigratedTerminalDelivery");function re(e,t){if(t.requesterNodeId===null||t.outcome===null||t.resultJson===null||t.settledAt===null)return null;const r=Ae(e,t.requestId,t.requesterNodeId,t.kind);return r!==null?r:t.deliveredAt!==null&&t.deliveredAt!==void 0?null:ke(e,{requestId:t.requestId,requesterNodeId:t.requesterNodeId,kind:t.kind,outcome:t.outcome,resultJson:t.resultJson,settledAt:t.settledAt,requestDir:t.requestDir})}i(re,"terminalDeliveryMark");const Ie=d.object({sessionName:d.string().optional(),askedBy:d.string().optional(),blockedSince:d.string().optional(),profileName:d.string().optional(),nodeId:d.string().optional()}).strict(),Oe=d.object({id:d.string().regex(/^[A-Za-z0-9_-]{1,64}$/).optional(),kind:d.string().min(1),step:d.number().int().nonnegative(),config:d.record(d.string(),d.unknown()),unvalidated:d.literal(!0).optional(),display:d.literal(!0).optional()}).strict(),xe=d.object({schema:d.literal("crtr.page/v1"),dialect:d.enum(["md","html","jsx"]),title:d.string().trim().min(1),subtitle:d.string().optional(),placement:d.enum(["inline","panel"]),document:d.enum(["page.md","page.html","page.tsx"]),steps:d.number().int().positive(),slots:d.array(Oe),source:Ie.optional()}).strict().superRefine((e,t)=>{const r=e.dialect==="md"?"page.md":e.dialect==="html"?"page.html":"page.tsx";e.document!==r&&t.addIssue({code:"custom",path:["document"],message:"document must agree with dialect"}),e.dialect==="md"&&e.steps!==1&&t.addIssue({code:"custom",path:["steps"],message:"md pages have exactly one step"})});function Le(e){if(e.source===void 0)return;const{blockedSince:t,...r}=e.source,s={...r,...t!==void 0&&d.string().datetime({offset:!0}).safeParse(t).success?{emittedAt:t}:{}};return Object.keys(s).length===0?void 0:s}i(Le,"legacyPresentationSource");function je(e,t,r){return`export default function LegacyPage() { return <Page title={${JSON.stringify(e)}}${t===void 0?"":` subtitle={${JSON.stringify(t)}}`}><pre>{${JSON.stringify(r)}}</pre></Page>; }
|
|
39
|
+
`}i(je,"legacyReplayDocument");function ie(e){return Array.isArray(e.slots)?{...e,slots:e.slots.map(t=>{if(typeof t!="object"||t===null||Array.isArray(t))return t;const r=t;if(r.kind!=="text"||typeof r.config!="object"||r.config===null||Array.isArray(r.config))return t;const{editable:s,...n}=r.config;return{...r,config:n}})}:e}i(ie,"withoutLegacyTextEditable");function we(e,t){const r=c(e,"page.json"),s=xe.safeParse(t);if(!s.success)throw new Error(s.error.message);const n=s.data,o=Le(n),u={placement:n.placement,inbox:!0,reply:n.source?.blockedSince!==void 0};G(ie({schema:"crtr.page/v2",dialect:"jsx",title:n.title,...n.subtitle===void 0?{}:{subtitle:n.subtitle},delivery:u,document:"page.tsx",steps:n.steps,slots:n.slots,...o===void 0?{}:{source:o}}));const a=c(e,n.document);if(!g(a))throw new Error(`corrupt required input: ${a}`);const l=V(a,"utf8"),m=be({dialect:"jsx",document:je(n.title,n.subtitle,l),source:o,delivery:u});if(o!==void 0)return m;const{source:E,...y}=m.manifest;return{...m,manifest:y}}i(we,"migrateLegacyPage");function Tt(e){e.exec(`
|
|
36
40
|
CREATE TABLE human_requests (
|
|
37
41
|
request_id TEXT PRIMARY KEY, kind TEXT NOT NULL CHECK (kind IN ('page','review')),
|
|
38
42
|
inbox_ticket_id TEXT NOT NULL UNIQUE, request_dir TEXT NOT NULL, presentation_dir TEXT,
|
|
@@ -61,4 +65,4 @@ var oe=Object.defineProperty;var i=(e,t)=>oe(e,"name",{value:t,configurable:!0})
|
|
|
61
65
|
progress_json, feedback_json, result_json, anchor_base_sha256, anchor_base_bytes, created_at, opened_at,
|
|
62
66
|
submit_requested_at, settled_at, settlement_delivery_id, action_delivery_id, projected_at, projection_error,
|
|
63
67
|
companion_retired_at, updated_at
|
|
64
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);if(e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'reviews'").get()!==void 0){const s=e.prepare("SELECT * FROM reviews").all();for(const n of s){const o=n.state,u=o==="approved"||o==="canceled",a=o==="canceled"&&n.result_json===null?JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:n.canceled_at,...n.cancel_reason===""||n.cancel_reason===null?{}:{reason:n.cancel_reason},...n.cancel_actor===null?{}:{actor:n.cancel_actor}}):n.result_json;if(u&&a===null)throw new Error(`corrupt required input: reviews/${n.review_id} has no terminal result`);const
|
|
68
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);if(e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'reviews'").get()!==void 0){const s=e.prepare("SELECT * FROM reviews").all();for(const n of s){const o=n.state,u=o==="approved"||o==="canceled",a=o==="canceled"&&n.result_json===null?JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:n.canceled_at,...n.cancel_reason===""||n.cancel_reason===null?{}:{reason:n.cancel_reason},...n.cancel_actor===null?{}:{actor:n.cancel_actor}}):n.result_json;if(u&&a===null)throw new Error(`corrupt required input: reviews/${n.review_id} has no terminal result`);const l=n.bridge_node_id===null?c(z(),"reviews",n.review_id):c(N(),n.bridge_node_id),m={origin_kind:n.origin_kind,bridge_node_id:n.bridge_node_id,origin_session_file:n.origin_session_file,origin_session_id:n.origin_session_id,origin_leaf_id:n.origin_leaf_id,model_spec:n.model_spec,branch_file:n.branch_file,baseline_sha256:n.baseline_sha256,baseline_bytes:n.baseline_bytes,captured_at:n.captured_at,output_path:n.output_path},E=u?o==="approved"?"approved":"canceled":null,y=u?o==="approved"?n.approved_at:n.canceled_at:null,S=re(e,{requestId:n.review_id,requesterNodeId:n.origin_node_id,kind:"review",outcome:E,resultJson:a,settledAt:y,requestDir:l,deliveredAt:n.delivered_at}),D=te(e,n.companion_node_id,E)?y:null;t.run(n.review_id,"review",n.origin_kind==="ticket"?U(N(),w(l)):P(),l,null,n.origin_node_id,n.companion_node_id,n.idempotency_key,u?"settled":o,E,n.origin_kind==="ticket"?1:0,1,w(n.file),n.subtitle,n.file,JSON.stringify(m),null,null,null,a,n.anchor_base_sha256,n.anchor_base_bytes,n.created,n.opened_at,n.submit_requested_at,y,S,null,n.projected_at,n.projection_error,D,n.created)}e.exec("DROP TABLE reviews")}for(const s of g(N())?ce(N(),{withFileTypes:!0}):[]){if(!s.isDirectory())continue;const n=c(N(),s.name),o=c(n,"page.json"),u=c(n,"review.json");if(!g(o)){if(g(u))continue;continue}if(e.prepare("SELECT 1 FROM human_requests WHERE request_id = ?").get(s.name)!==void 0)continue;let a,l,m,E;try{const p=R(o);if(typeof p!="object"||p===null||Array.isArray(p))throw new Error("page manifest must be an object");a=p,a.schema==="crtr.page/v1"?(l=we(n,p),a=l.manifest):a.schema==="crtr.page/v2"&&(a=ie(a));const v=qe.safeParse(a.delivery);if(typeof a.title!="string"||!v.success)throw new Error(v.success?"page title must be a string":v.error.message);E=v.data,m=G(a)}catch(p){const v=p instanceof Error&&p.cause instanceof Error?p.cause.message:p instanceof Error?p.message:String(p);console.warn(`skipping legacy page ${o}: ${v}`);continue}let y=O(n);l!==void 0&&(y=ee(C(s.name),l));const S=m.source,D=c(n,"response.json"),k=g(D)?R(D):null,h=k===null?null:ve(k),se=e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'deliveries'").get()===void 0?null:e.prepare("SELECT delivery_id FROM deliveries WHERE idempotency_key = ?").get(`human-action:${U(N(),s.name)}`),X=c(n,"action.json"),$=c(n,"progress.json"),x=c(n,"feedback-comments.json"),L=c(n,"reply-route.json"),q=g(x)?R(x):null;if(q!==null&&(typeof q!="object"||typeof q.companionNodeId<"u"&&typeof q.companionNodeId!="string"))throw new Error(`corrupt required input: ${x}`);const I=g(L)?R(L):null;if(I!==null&&(typeof I!="object"||typeof I.bridge_node_id!="string"))throw new Error(`corrupt required input: ${L}`);const M=I?.bridge_node_id,F=(typeof M!="string"||e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'nodes'").get()===void 0?null:e.prepare("SELECT parent FROM nodes WHERE node_id = ?").get(M))?.parent??(typeof S?.nodeId=="string"?S.nodeId:null),W=q?.companionNodeId,J=typeof S?.emittedAt=="string"?S.emittedAt:le(o).mtime.toISOString(),B=k===null?null:JSON.stringify(k),oe=re(e,{requestId:s.name,requesterNodeId:F,kind:"page",outcome:h?.outcome??null,resultJson:B,settledAt:h?.settledAt??null,requestDir:n}),ae=te(e,W??null,h?.outcome??null)?h?.settledAt??null:null,K=C(s.name);A(K,{recursive:!0,mode:448}),t.run(s.name,"page",U(N(),s.name),K,y,F,W??null,null,h===null?"open":"settled",h?.outcome??null,E.inbox?1:0,E.inbox||E.reply?1:0,m.title,m.subtitle??null,null,JSON.stringify(m),g(X)?JSON.stringify(R(X)):null,g($)&&h===null?JSON.stringify(R($)):null,q===null?null:JSON.stringify(q),B,null,null,J,null,null,h?.settledAt??null,oe,se?.delivery_id??null,null,null,ae,J)}const r=e.prepare("SELECT request_id FROM human_requests WHERE state = 'settled' AND result_json IS NULL").get();if(r!==void 0)throw new Error(`human request migration produced terminal row without result: ${r.request_id}`);if(e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'review_comments'").get()!==void 0){const s=e.prepare("SELECT review_id FROM review_comments WHERE review_id NOT IN (SELECT request_id FROM human_requests WHERE kind = 'review') LIMIT 1").get();if(s!==void 0)throw new Error(`review comment has no migrated review request: ${s.review_id}`)}}i(Tt,"migrateHumanRequestsState");export{lt as cancelBindingRequest,Qe as commitBindingRequest,Ge as createPageRequest,Ye as getRequest,tt as getRequestByCompanion,et as getRequestByDirectory,nt as getRequestByIdempotencyKey,Ze as getRequestByInboxTicket,it as hasOpenReplyBearingRequestByRequester,Z as humanRequestsRoot,ot as listBindingRequests,rt as listOpenInboxRequests,st as listOpenReplyBearingRequests,ut as listRequests,at as listSubmitRequestedRequests,dt as listUnprojectedReviews,bt as markCompanionRetired,yt as markProjected,ht as markProjectionError,Tt as migrateHumanRequestsState,ct as openRequest,Se as openRequestsByRequester,ze as presentationDir,ee as publishPageRevision,qt as readAnchorBase,Nt as replaceAnchorBaseLocked,C as requestDir,_t as requestSubmit,Et as revisePageRequest,mt as setSettlementDeliveryMarksLocked,ft as setSubmitNoteDeliveryLocked,pt as settleRequestLocked,gt as writeProgress};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ReviewForkResult {
|
|
2
|
+
/** The newborn fork. */
|
|
3
|
+
node_id: string;
|
|
4
|
+
/** Where the fork runs — the companion's cwd, which a viewer pane reuses. */
|
|
5
|
+
cwd: string;
|
|
6
|
+
}
|
|
7
|
+
/** Fork the review companion onto one comment. */
|
|
8
|
+
export declare function forkReviewComment(commentId: string): Promise<ReviewForkResult>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
var m=Object.defineProperty;var d=(o,n)=>m(o,"name",{value:n,configurable:!0});import{basename as c}from"node:path";import{getNode as s}from"../canvas/index.js";import{ensureReviewForkDir as w,reviewForkBranchPath as p}from"../canvas/paths.js";import{materializeSessionBranchAt as l}from"../runtime/session-branch.js";import{spawnChildPrepared as _}from"../runtime/spawn.js";import{getComment as f}from"./comments.js";import{captureOrigin as h}from"./companion.js";import{requireVisibleReview as u}from"./store.js";import{ReviewOperationError as a}from"./types.js";function v(o,n){const{line:e,end_line:i}=n.anchor,t=i>e?`lines ${e}-${i}`:`line ${e}`,r=n.anchor_line_text===""?"":`
|
|
2
|
+
> ${n.anchor_line_text}
|
|
3
|
+
`;return[`The person handed you this one comment on \`${o.file}\` so it can be worked in parallel. The review companion you were forked from keeps the rest of the document.`,`${t}:${r}`,n.text,`Address it by editing only the lines this comment is about \u2014 other forks may be editing the same file \u2014 then resolve it with \`crtr human review comment resolve ${n.comment_id}\`, and tell the companion what changed with \`crtr push update\`.`].join(`
|
|
4
|
+
|
|
5
|
+
`)}d(v,"forkTask");async function T(o){const n=f(o);if(n===null)throw new a("unknown_comment","comment was not found",{received:o});if(n.status!=="open")throw new a("comment_deleted","only an open comment can be forked",{comment_id:o,status:n.status});const e=u(n.review_id);if(e.state!=="open")throw new a("review_terminal","review already has a terminal outcome",{state:e.state,requested:"fork",review:e});const i=s(e.companion_node_id);if(i===null)throw new a("review_companion_unbound","review companion is gone",{companion_node_id:e.companion_node_id});const t=await h(e.companion_node_id);w(e.review_id);const r=p(e.review_id,o);return l(t,r),{node_id:(await _({kind:"review/companion",mode:"base",cwd:i.cwd,parent:e.companion_node_id,creator:e.companion_node_id,rootLifecycle:"resident",prompt:v(e,n),forkFrom:r,model:t.modelSpec,name:`comment on ${c(e.file)}`,reviewBinding:{review_id:e.review_id,origin_node_id:e.origin_node_id,branch_file:r,target_file:e.file}})).node.node_id,cwd:i.cwd}}d(T,"forkReviewComment");export{T as forkReviewComment};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var c=Object.defineProperty;var o=(e,r)=>c(e,"name",{value:r,configurable:!0});import{
|
|
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(s,"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 y(e){return t().getBrokerRecovery(e,n())}o(y,"brokerRecovery");function N(e,r){return t().recordNodeFault(e,r)}o(N,"recordNodeFault");function b(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(b,"clearNodeFault");function P(e,r){return t().commitBrokerModel(e,{...r,expected_execution_id:n()})}o(P,"commitBrokerModel");function w(e){return t().brokerExtensionState(e)}o(w,"brokerExtensionState");function F(e,r){return t().commitBrokerGeneratedName(e,{...r,expected_execution_id:n()})}o(F,"commitBrokerGeneratedName");function M(e,r){return t().commitBrokerPersonaAck(e,{...r,expected_execution_id:n()})}o(M,"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,w as brokerExtensionState,y as brokerRecovery,s as claimBrokerMail,b as clearNodeFault,F as commitBrokerGeneratedName,P as commitBrokerModel,M as commitBrokerPersonaAck,B as completeBrokerPark,h as mutateBrokerFault,R as mutateBrokerProviderRetry,A as publishBrokerReport,_ as recordBrokerParkActivity,E as recordBrokerTurn,N as recordNodeFault,I as relaunchBrokerRoot,m as settleBroker};
|
|
@@ -5,6 +5,9 @@ interface AbortableSession {
|
|
|
5
5
|
export declare function refuseTurn(abort: () => void): void;
|
|
6
6
|
export declare function wasTurnRefused(): boolean;
|
|
7
7
|
export declare function clearRefusedTurn(): void;
|
|
8
|
+
/** Prevent extensions from settling a turn that broker teardown will certify. */
|
|
9
|
+
export declare function beginRuntimeTeardown(): void;
|
|
10
|
+
export declare function isRuntimeTeardownInProgress(): boolean;
|
|
8
11
|
/** Mark one synchronous ExtensionContext.abort() call as a refresh boundary. */
|
|
9
12
|
export declare function runRefreshAbort(abort: () => void): void;
|
|
10
13
|
/** Bound into Pi's extension context by the broker for every session generation. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var s=Object.defineProperty;var r=(e,n)=>s(e,"name",{value:n,configurable:!0});let t=!1,o=!1;const u=globalThis;function i(e){o=!0,e()}r(i,"refuseTurn");function a(){return o}r(a,"wasTurnRefused");function c(){o=!1}r(c,"clearRefusedTurn");function l(){u.__crtrRuntimeTeardownInProgress=!0}r(l,"beginRuntimeTeardown");function T(){return u.__crtrRuntimeTeardownInProgress===!0}r(T,"isRuntimeTeardownInProgress");function d(e){t=!0;try{e()}finally{t=!1}}r(d,"runRefreshAbort");function p(e,n){t&&(e.clearQueue(),n?.()),e.abort()}r(p,"abortSessionFromExtension");export{p as abortSessionFromExtension,l as beginRuntimeTeardown,c as clearRefusedTurn,T as isRuntimeTeardownInProgress,i as refuseTurn,d as runRefreshAbort,a as wasTurnRefused};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var ve=Object.defineProperty;var e=(t,n)=>ve(t,"name",{value:n,configurable:!0});import{envModelIntent as he,envNodeCwd as _e,envNodeId as we,envProfileId as ye}from"../../shared/env.js";import{createServer as Se}from"node:net";import{existsSync as se,readFileSync as be,unlinkSync as ae}from"node:fs";import{join as K}from"node:path";import{randomUUID as M}from"node:crypto";import{mark as Ee}from"../timing.js";import{getAgentDir as V,initTheme as Te,ModelRegistry as ke,ModelRuntime as Re}from"@earendil-works/pi-coding-agent";import{nodeDir as xe,viewSocketPath as Ce}from"../canvas/paths.js";import{bindBrokerEventSource as Ae}from"../events/source.js";import{emitEvent as E}from"../events/emit.js";import{operationIdContext as Me}from"../events/operation-id.js";import{findMissingPackagePaths as Pe}from"./package-health.js";import{FRONT_DOOR_ENV as Ie}from"./front-door.js";import{CANVAS_EXTENSIONS as X,piInvocationToSdkConfig as Oe}from"./launch.js";import{assertEngineVersion as De,loadBrokerEngine as Fe}from"./broker-sdk.js";import{resolveBundledPiPackageDir as Ne}from"./pi-cli.js";import{captureSessionChatCapabilities as Le}from"./command-surface.js";import{PoolCredentialStore as $e}from"../pool-credential-store.js";import{mutateBrokerFault as U,recordBrokerTurn as de}from"./broker/daemon-ops.js";import{modelRequestFromConfig as je,selectInitialModelRoute as Be,unregisteredConcreteModel as Ge}from"../model-routes.js";import{KNOWN_STREAM_WAIT_UI as Ue}from"./stream-watchdog.js";import{probeOnline as We}from"./connectivity.js";import{CRTR_CYCLE_CUSTOM_TYPE as qe,cycleAwareMessages as Ke}from"./session-cycles.js";import{projectTranscript as Ve}from"./session-visibility.js";import{currentTurnVisibility as Xe}from"./turn-visibility.js";import{isUnknownModel as H}from"./model-selection.js";import{BrokerClientRegistry as He}from"./broker/client-registry.js";import{ToolGroupTracker as Ye}from"./broker/tool-groups.js";import{onNodeNamed as ze}from"./broker/node-named.js";import{FaultRetry as Je}from"./broker/fault-retry.js";import{createTurnAdmissionGate as Qe}from"./broker/turn-admission.js";import{BROKER_IDLE_TURN_START as Ze}from"./broker/held-deferred-inbox.js";import{EventProjection as et}from"./broker/event-projection.js";import{createFrameDispatchContext as tt,handleFrame as nt}from"./broker/frame-dispatch.js";import{hydratePersistedAdvertisedCommandMessages as ot,installAdvertisedCommandInvocationContract as rt}from"./advertised-command-invocation.js";import{RebindDriver as it}from"./broker/rebind.js";import{decodeKickoffOrigin as st,KICKOFF_ORIGIN_ENV as at}from"./stamp/protocol.js";import{announceMessageOrigin as dt}from"./stamp/channel.js";import{brokerExtensionState as lt,commitBrokerModel as ct}from"./broker/daemon-ops.js";import{FrameOverflowError as mt,normalizeSnapshotTail as ut}from"./broker-protocol.js";import{ReviewBoundaryNavigationError as fn,REVIEW_BOUNDARY_NAVIGATION_CODE as pn}from"./broker/frame-replies.js";function Y(t){return new ke(t.modelRuntime)}e(Y,"registryOf");function ft(t){return{authPath:K(t,"auth.json"),modelsPath:K(t,"models.json")}}e(ft,"modelRuntimePaths");function L(t,n){if(t==null||H(t))return null;const s=n!==void 0&&n!==""&&n!=="off"?`:${n}`:"";return`${t.provider}/${t.id}${s}`}e(L,"formatModelSpec");function pt(t,n){const s=L(t,void 0);return s===null?null:`${s}:${n===void 0||n===""?"off":n}`}e(pt,"formatExactModelSpec");const gt=12e4;let W=null;function vt(){const t=W;if(W=null,t!==null)try{t.dispose()}catch{}}e(vt,"disposeActiveSession");async function cn(t,n=process.hrtime.bigint(),s=new Date().toISOString()){Ae(t),Me.fresh(()=>{E({level:"info",event:"broker.startup.cli_entry",ts:s,duration_ms:0,fields:{runtime_version:process.version,engine_version:null,model:null}}),E({level:"info",event:"broker.startup.module_loaded",duration_ms:Number(process.hrtime.bigint()-n)/1e6,fields:{runtime_version:process.version,engine_version:null,model:null}})});const p=new Set;let i=null;const a=e((o,r=null)=>{p.has(o)||(p.add(o),Ee(o,{duration_ms:Number(process.hrtime.bigint()-n)/1e6}),E({level:"info",event:o,duration_ms:Number(process.hrtime.bigint()-n)/1e6,fields:{runtime_version:process.version,engine_version:i,model:r}}))},"emitStartupMilestone");process.env[Ie]="1",process.env.CRTR_BROKER_PID=String(process.pid),delete process.env.TMUX_PANE,delete process.env.TMUX;const d=await Fe();De(d.VERSION),i=d.VERSION;const l=xe(t),m=K(l,"broker-launch.json"),h=JSON.parse(be(m,"utf8")),g=Oe(h);g.modelExact===!0?process.env.CRTR_MODEL_EXACT="1":delete process.env.CRTR_MODEL_EXACT;let{session:_,services:S,resuming:k,runtime:T}=await yt(d,g);const R=(await lt(t)).node.review_binding?.review_id;W=_;const B=We;try{process.env.PI_PACKAGE_DIR=Ne(),Te(S.settingsManager.getTheme(),!1)}catch(o){E({level:"error",event:"broker.theme.initialization_failed",error:o})}try{for(const o of Pe(V()))E({level:"warn",event:"broker.startup.warning",fields:{stage:"package_health",source:o.source,resolved_path:o.resolved}})}catch{}const x=Ce(t),u=new He(t),D=new Map,b=new Ye(t,o=>u.broadcast(o));ze(o=>u.broadcast({type:"node_named",...o}));let P=!1,F=!1,A,$,c,C,N,z=e(()=>{},"notifyTurnAccepted"),J=e(()=>{},"resetFrameState");c=new it({nodeId:t,cfg:g,session:_,services:S,runtime:T,registry:u,toolGroups:b,uiContext:e(()=>$,"uiContext"),faultRetry:e(()=>C,"faultRetry"),projection:e(()=>N,"projection"),setActiveSession:e(o=>{W=o},"setActiveSession"),disposeAndExit:e((o,r)=>j(o,r),"disposeAndExit"),onSessionRebind:e(()=>{J()},"onSessionRebind"),reWelcomeAll:e(()=>te(),"reWelcomeAll")});const Q=e(async(o,r=!1)=>{const f=c.session(),v=L(f.model,f.thinkingLevel);if(v===null)return null;const w=await ct(t,{spec:v,pinnedOverride:o,userSelected:r});return r&&(delete process.env.CRTR_MODEL_INTENT,process.env.CRTR_MODEL_EXACT="1",g.model=w.modelOverride,g.modelExact=!0),w.modelOverride},"persistModelChoice"),Z=e(async(o=!0,r,f=!1)=>{const v=c.session(),w=L(v.model,v.thinkingLevel),y=o?await Q(r,f):w;u.broadcast({type:"model_changed",model:H(v.model)?void 0:v.model,spec:y})},"broadcastModelChanged"),q=Qe(),me=e(o=>{q.admit(r=>{const f=c.session();return f.prompt(o,{preflightResult:r,...f.isStreaming?{streamingBehavior:"steer"}:{}}).catch(v=>{E({level:"error",event:"broker.inbox.idle_prompt_failed",error:v})})})},"startIdleInboxTurn");globalThis[Ze]=me,C=new Je({nodeId:t,cfg:g,retryProbe:B,currentSession:e(()=>c.session(),"currentSession"),currentServices:e(()=>c.services(),"currentServices"),installedGeneration:e(()=>c.installedGeneration(),"installedGeneration"),registryOf:Y,formatModelSpec:L,broadcastModelChanged:Z,turnAdmission:q}),N=new et({registry:u,faultRetry:C,installedGeneration:e(()=>c.installedGeneration(),"installedGeneration"),currentSession:e(()=>c.session(),"currentSession"),notifyTurnAccepted:e(()=>z(),"notifyTurnAccepted"),emitStartupMilestone:a,formatModelSpec:L});const ue=e(o=>{const r=c.session(),f=_t(r,R),v=ut(o.snapshotTail),w=f===void 0||v===void 0?f:f.slice(-v),y=w?.map(({message:O})=>O)??r.sessionManager.buildSessionContext().messages,G=b.summaries(),ie=w!==void 0&&v!==void 0?ht(y):void 0,ge=ie===void 0?G:Object.fromEntries(Object.entries(G).filter(([O])=>ie.has(O)));return{messages:y,...w===void 0?{}:{messageIds:w.map(({id:O})=>O)},messageVisibility:w?.map(({visibility:O})=>O)??y.map(()=>"visible"),turnVisibility:Xe(),stats:r.getSessionStats(),state:{model:H(r.model)?void 0:r.model,thinkingLevel:r.thinkingLevel,isStreaming:r.isStreaming,isCompacting:r.isCompacting,steeringMode:r.steeringMode,followUpMode:r.followUpMode,sessionFile:r.sessionFile,sessionId:r.sessionId,sessionName:r.sessionName,autoCompactionEnabled:r.autoCompactionEnabled,messageCount:r.messages.length,pendingMessageCount:r.pendingMessageCount},display:{...u.displaySnapshot()},toolGroupSummaries:ge,workingActivity:N.currentWorkingActivity(),queued:{steering:[...r.getSteeringMessages()],followUp:[...r.getFollowUpMessages()]}}},"buildSnapshot"),ee=e(o=>{const r=o.role==="controller"?D.values().next().value:void 0;u.sendFrame(o,{type:"welcome",snapshot:ue(o),role:o.role,pending_dialog:r!==void 0?r.request:null,agentDir:V()},!0)},"sendWelcome"),fe=e(o=>{const r=[...D.values()];for(let f=1;f<r.length;f++)u.sendFrame(o,r[f].request)},"replayExtraPendingDialogsTo"),te=e(()=>{u.forEachHelloed(ee)},"reWelcomeAll"),ne=e(o=>{if(!P){P=!0,b.persistPendingSummary(),N.dispose(),vt();try{A?.close()}catch{}u.dispose();try{se(x)&&ae(x)}catch{}u.clearAttachState(),process.exit(o)}},"completeExit"),j=e((o,r=0)=>{if(P)return;const f=o==="shutdown-hook"||o==="shutdown-after-settle";if(f&&b.finishOpenToolGroup(!0),f&&b.hasSummaryTasks()){if(F)return;F=!0,b.waitForSummaryTasks().finally(()=>ne(r));return}ne(r)},"disposeAndExit");$=St({writable:e(()=>u.writableClients(),"writable"),forward:e((o,r)=>u.sendFrame(o,r),"forward"),pending:D,broadcast:e(o=>u.broadcastUi(o),"broadcast"),onKnownStreamWait:e(o=>N.knownStreamWait(o),"onKnownStreamWait")}),c.setRebindSession(),await c.enqueueRebind(_,S);const I=tt({nodeId:t,cfg:g,registry:u,toolGroups:b,projection:N,rebind:c,boundaryReviewId:R,pendingDialogs:D,sendWelcome:ee,replayExtraPendingDialogsTo:fe,reWelcomeAll:te,disposeAndExit:j,persistModelChoice:Q,broadcastModelChanged:Z,registryOf:Y,formatModelSpec:L,formatExactModelSpec:pt,turnAdmission:q,resolveLaunchModel:ce});z=I.notifyTurnAccepted,J=I.resetForSession;try{se(x)&&ae(x)}catch{}A=Se(o=>{const r=u.create(o);o.on("data",v=>{let w;try{w=r.decoder.push(v)}catch(y){y instanceof mt?(u.sendFrame(r,{type:"error",code:"frame_overflow",message:y.message}),u.dropClient(r,`frame overflow: ${y.message}`)):u.dropClient(r,`decoder error: ${String(y)}`);return}for(const y of w)try{nt(I,r,y)}catch{}});const f=e(()=>{u.removeClient(r)},"drop");o.on("close",f),o.on("error",()=>{})}),A.on("error",o=>{P||(E({level:"error",event:"broker.socket.failed",error:o}),j("socket-error",1))}),A.listen(x,async()=>{Promise.all([U(t,{op:"clear",link:"viewer\u2194broker"}),U(t,{op:"clear",link:"relay\u2194broker"})]).catch(r=>E({level:"error",event:"broker.daemon.operation.failed",node_id:t,error:r,fields:{operation:"broker_socket_bound_fault_clear"}}));let o;try{o=await C.recoverOnStartup()}catch(r){E({level:"error",event:"broker.daemon.operation.failed",node_id:t,error:r,fields:{operation:"recovery_startup"}}),j("recovery-startup-failed",1);return}if(o!=="retry-armed"&&g.firstPrompt!==void 0&&g.firstPrompt!==""){const r=st(process.env[at]);r!==null&&dt(g.firstPrompt,r),I.kickoff(g.firstPrompt)}}),u.persistAttachState();const pe=2500;let oe=!1;const re=e(async o=>{if(P||oe)return;if(oe=!0,c.isAgentRunActive()||c.session().isStreaming||I.pendingPromptDispatches()>0){const f=Date.now()+pe;for(;I.pendingPromptDispatches()>0&&!c.session().isStreaming&&Date.now()<f;)await new Promise(v=>setTimeout(v,25));if(c.session().isStreaming){const v=f-Date.now();if(v>0){let w;try{await Promise.race([c.session().abort().then(()=>!0,()=>!1),new Promise(G=>{w=setTimeout(()=>G(!1),v)})])&&await de(t,{event:"closed",end_reason:"teardown-aborted"})}finally{w!==void 0&&clearTimeout(w)}}}else(I.pendingPromptDispatches()>0||c.isAgentRunActive())&&await de(t,{event:"interrupted"})}j(o)},"abortAndExit");process.on("SIGTERM",()=>{re("SIGTERM")}),process.on("SIGINT",()=>{re("SIGINT")})}e(cn,"runBroker");function ht(t){const n=new Set;for(const s of t)if(!(s.role!=="assistant"||!Array.isArray(s.content)))for(const p of s.content)p!==null&&typeof p=="object"&&p.type==="toolCall"&&typeof p.id=="string"&&n.add(p.id);return n}e(ht,"toolCallIds");function _t(t,n){const s=t.sessionManager,p=Ke(s);return p!==void 0&&ot(p.map(({message:i})=>i)),p===void 0?void 0:Ve(p,{boundaryReviewId:n,sessionEntries:s.getEntries?.()})}e(_t,"snapshotMessages");function le(){const t=we();if(t===void 0||t==="")throw new Error("broker launch is missing CRTR_NODE_ID");return t}e(le,"currentBrokerNodeId");async function ce(t,n){const s=je(n.model,he(),n.modelExact===!0);if(s===void 0)return;const p=Y(t),i={cwd:_e()??n.cwd,profileId:ye()},a=Ge(s,p,i);if(a!==void 0)throw await U(le(),{op:"record",input:{link:"crtr\u2192pi",op:"model resolution at launch",kind:"model-not-found",retry:{disposition:"fatal"},message:`model '${a.request.spec}' is not registered in the serving model registry`}}),new Error(`[broker] FATAL: model '${a.request.spec}' is not registered in the serving model registry`);const d=Be(s,p,i),l=d.selected;if(l!==void 0){const m=l.candidate;return(m.rank??0)>0&&E({level:"warn",event:"broker.model.launch_fallback",fields:{requested:n.model,selected:`${m.providerId}/${m.modelId}`,route_id:m.routeId,credential_source:m.credentialSource,rank:m.rank}}),{model:l.model,thinkingLevel:m.thinkingLevel}}if(n.modelExact===!0){const m=d.rejected.map(({candidate:h,reason:g})=>`'${h.providerId}/${h.modelId}' ${g}`).join("; ");throw await U(le(),{op:"record",input:{link:"crtr\u2192pi",op:"model resolution at launch",kind:"model-not-found",retry:{disposition:"fatal"},message:`exact-consult model '${n.model}' is unavailable \u2014 refusing to substitute (${m})`}}),new Error(`[broker] FATAL: exact-consult model '${n.model}' is unavailable`)}E({level:"warn",event:"broker.model.none_viable",fields:{rejected_candidates:d.rejected.slice(0,16).map(({candidate:m,reason:h})=>({provider:m.providerId,model:m.modelId,reason:h,route_id:m.routeId,credential_source:m.credentialSource})),rejected_candidates_omitted:Math.max(0,d.rejected.length-16)}})}e(ce,"resolveLaunchModel");function wt(t){let n=!0;return{runtime:new Proxy(t,{get(p,i,a){return n&&i==="getAvailableSnapshot"?()=>[]:n&&i==="getAvailable"?async()=>[]:n&&i==="getModel"?()=>{}:Reflect.get(p,i,a)}}),reveal:e(()=>{n=!1},"reveal")}}e(wt,"modelLessRegistry");async function yt(t,n){const s=V(),p=e(async _=>{const{authPath:S,modelsPath:k}=ft(_.agentDir),T=await Re.create({credentials:new $e(S),modelsPath:k}),R=await t.createAgentSessionServices({cwd:_.cwd,agentDir:_.agentDir,modelRuntime:T,resourceLoaderOptions:{additionalExtensionPaths:n.extensionPaths,appendSystemPrompt:n.appendSystemPromptPath!==void 0?[n.appendSystemPromptPath]:void 0,noContextFiles:!0}}),B=R.resourceLoader.getExtensions();if(n.extensionPaths.some(A=>X.includes(A))){const A=new Set(B.extensions.map(c=>c.path)),$=X.filter(c=>!A.has(c));if($.length>0){const c=B.errors.filter(C=>X.includes(C.path)).map(C=>`${C.path}: ${C.error}`).join("; ");throw new Error(`[broker] FATAL: mandatory canvas extensions failed to load: ${$.join(", ")}${c===""?"":` (${c})`}`)}}const x=await ce(R,n),u=x?.model,D=x?.thinkingLevel,b=x===void 0?wt(R.modelRuntime):void 0,P=b!==void 0?{...R,modelRuntime:b.runtime}:R,F=await t.createAgentSessionFromServices({services:P,sessionManager:_.sessionManager,model:u,thinkingLevel:D,tools:n.tools,sessionStartEvent:_.sessionStartEvent});return rt(F.session),Le(F.session),b?.reveal(),{...F,services:R}},"buildForManager"),i=n.resumeSessionPath,a=n.forkFrom!==void 0&&n.forkFrom!=="";if(!a&&(i===void 0||i==="")&&n.resumeSessionId!==void 0&&n.resumeSessionId!=="")throw new Error(`[broker] resume requires a session .jsonl PATH; got only a bare id '${n.resumeSessionId}' (pi_session_file was never captured for this node)`);const d=!a&&i!==void 0&&i!=="",l=d&&n.newCycle===!0,m=d&&!l;let h;if(a)h=t.SessionManager.forkFrom(n.forkFrom,n.cwd);else if(m||l){if(h=t.SessionManager.open(i),l){const _=h.getLeafId();h.resetLeaf(),h.appendCustomEntry(qe,{cycle:Number(process.env.CRTR_CYCLES),fromLeaf:_})}}else h=t.SessionManager.create(n.cwd);if(t.createAgentSessionRuntime!==void 0){const _=e(async k=>{const T=await p({cwd:k.cwd,agentDir:k.agentDir,sessionManager:k.sessionManager,sessionStartEvent:k.sessionStartEvent});return{...T,diagnostics:T.services.diagnostics??[]}},"factory"),S=await t.createAgentSessionRuntime(_,{cwd:n.cwd,agentDir:s,sessionManager:h});return{session:S.session,services:S.services,resuming:m,runtime:S}}const g=await p({cwd:n.cwd,agentDir:s,sessionManager:h});return{session:g.session,services:g.services,resuming:m,runtime:void 0}}e(yt,"buildBrokerSession");function St(t){const n=e((i,a,d,l)=>{if(l?.signal?.aborted)return Promise.resolve(i);const m=t.writable();return m.length===0?Promise.resolve(i):new Promise(h=>{let g;const _=e(()=>{g!==void 0&&clearTimeout(g),l?.signal?.removeEventListener("abort",S),t.pending.delete(a.id)},"cleanup"),S=e(()=>{_(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),h(i)},"onAbort");l?.signal?.addEventListener("abort",S,{once:!0});const k=l?.timeout!==void 0?l.timeout:gt;g=setTimeout(()=>{_(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),h(i)},k),typeof g.unref=="function"&&g.unref(),t.pending.set(a.id,{request:a,resolve:e(T=>{_(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),h(d(T))},"resolve")});for(const T of m)t.forward(T,a)})},"dialogPromise"),s=e(()=>{},"noop");return{[Ue]:t.onKnownStreamWait??(i=>()=>{}),get theme(){const i=globalThis[Symbol.for("@earendil-works/pi-coding-agent:theme")];if(i==null)throw new Error("Theme not initialized. Call initTheme() first.");return i},select:e((i,a,d)=>n(void 0,{type:"extension_ui_request",id:M(),method:"select",title:i,options:a,timeout:d?.timeout},l=>"cancelled"in l&&l.cancelled?void 0:"value"in l?l.value:void 0,d),"select"),confirm:e((i,a,d)=>n(!1,{type:"extension_ui_request",id:M(),method:"confirm",title:i,message:a,timeout:d?.timeout},l=>"cancelled"in l&&l.cancelled?!1:"confirmed"in l?l.confirmed:!1,d),"confirm"),input:e((i,a,d)=>n(void 0,{type:"extension_ui_request",id:M(),method:"input",title:i,placeholder:a,timeout:d?.timeout},l=>"cancelled"in l&&l.cancelled?void 0:"value"in l?l.value:void 0,d),"input"),editor:e((i,a)=>n(void 0,{type:"extension_ui_request",id:M(),method:"editor",title:i,prefill:a},d=>"cancelled"in d&&d.cancelled?void 0:"value"in d?d.value:void 0),"editor"),setStatus:e((i,a)=>t.broadcast({type:"extension_ui_request",id:M(),method:"setStatus",statusKey:i,statusText:a}),"setStatus"),setWidget:e((i,a,d)=>{typeof a!="function"&&t.broadcast({type:"extension_ui_request",id:M(),method:"setWidget",widgetKey:i,widgetLines:a,widgetPlacement:d?.placement})},"setWidget"),setTitle:e(i=>t.broadcast({type:"extension_ui_request",id:M(),method:"setTitle",title:i}),"setTitle"),notify:e((i,a)=>{const d=a==="warn"?"warning":a;t.broadcast({type:"extension_ui_request",id:M(),method:"notify",message:i,notifyType:d})},"notify"),onTerminalInput:e(()=>s,"onTerminalInput"),setWorkingMessage:s,setWorkingVisible:s,setWorkingIndicator:s,setHiddenThinkingLabel:s,setFooter:s,setHeader:s,custom:e(()=>Promise.resolve(void 0),"custom"),pasteToEditor:s,setEditorText:s,getEditorText:e(()=>"","getEditorText"),addAutocompleteProvider:s,setEditorComponent:s,getEditorComponent:e(()=>{},"getEditorComponent"),getAllThemes:e(()=>[],"getAllThemes"),getTheme:e(()=>{},"getTheme"),setTheme:s,getToolsExpanded:e(()=>!1,"getToolsExpanded"),setToolsExpanded:s}}e(St,"makeBrokerUiContext");export{pn as REVIEW_BOUNDARY_NAVIGATION_CODE,fn as ReviewBoundaryNavigationError,yt as buildBrokerSession,vt as disposeActiveSession,St as makeBrokerUiContext,cn as runBroker,_t as snapshotMessages};
|
|
1
|
+
var ve=Object.defineProperty;var e=(t,n)=>ve(t,"name",{value:n,configurable:!0});import{envModelIntent as he,envNodeCwd as _e,envNodeId as we,envProfileId as ye}from"../../shared/env.js";import{createServer as Se}from"node:net";import{existsSync as se,readFileSync as be,unlinkSync as ae}from"node:fs";import{join as K}from"node:path";import{randomUUID as M}from"node:crypto";import{mark as Te}from"../timing.js";import{getAgentDir as V,initTheme as Ee,ModelRegistry as ke,ModelRuntime as Re}from"@earendil-works/pi-coding-agent";import{nodeDir as xe,viewSocketPath as Ce}from"../canvas/paths.js";import{bindBrokerEventSource as Ae}from"../events/source.js";import{emitEvent as T}from"../events/emit.js";import{operationIdContext as Me}from"../events/operation-id.js";import{findMissingPackagePaths as Pe}from"./package-health.js";import{FRONT_DOOR_ENV as Ie}from"./front-door.js";import{CANVAS_EXTENSIONS as X,piInvocationToSdkConfig as Oe}from"./launch.js";import{assertEngineVersion as De,loadBrokerEngine as Fe}from"./broker-sdk.js";import{resolveBundledPiPackageDir as Ne}from"./pi-cli.js";import{captureSessionChatCapabilities as Le}from"./command-surface.js";import{PoolCredentialStore as $e}from"../pool-credential-store.js";import{mutateBrokerFault as U,recordBrokerTurn as de}from"./broker/daemon-ops.js";import{modelRequestFromConfig as je,selectInitialModelRoute as Be,unregisteredConcreteModel as Ge}from"../model-routes.js";import{KNOWN_STREAM_WAIT_UI as Ue}from"./stream-watchdog.js";import{probeOnline as We}from"./connectivity.js";import{CRTR_CYCLE_CUSTOM_TYPE as qe,cycleAwareMessages as Ke}from"./session-cycles.js";import{projectTranscript as Ve}from"./session-visibility.js";import{currentTurnVisibility as Xe}from"./turn-visibility.js";import{isUnknownModel as H}from"./model-selection.js";import{BrokerClientRegistry as He}from"./broker/client-registry.js";import{ToolGroupTracker as Ye}from"./broker/tool-groups.js";import{onNodeNamed as ze}from"./broker/node-named.js";import{FaultRetry as Je}from"./broker/fault-retry.js";import{createTurnAdmissionGate as Qe}from"./broker/turn-admission.js";import{BROKER_IDLE_TURN_START as Ze}from"./broker/held-deferred-inbox.js";import{EventProjection as et}from"./broker/event-projection.js";import{createFrameDispatchContext as tt,handleFrame as nt}from"./broker/frame-dispatch.js";import{hydratePersistedAdvertisedCommandMessages as ot,installAdvertisedCommandInvocationContract as rt}from"./advertised-command-invocation.js";import{RebindDriver as it}from"./broker/rebind.js";import{beginRuntimeTeardown as st}from"./broker/extension-abort.js";import{decodeKickoffOrigin as at,KICKOFF_ORIGIN_ENV as dt}from"./stamp/protocol.js";import{announceMessageOrigin as lt}from"./stamp/channel.js";import{brokerExtensionState as ct,commitBrokerModel as mt}from"./broker/daemon-ops.js";import{FrameOverflowError as ut,normalizeSnapshotTail as ft}from"./broker-protocol.js";import{ReviewBoundaryNavigationError as gn,REVIEW_BOUNDARY_NAVIGATION_CODE as vn}from"./broker/frame-replies.js";function Y(t){return new ke(t.modelRuntime)}e(Y,"registryOf");function pt(t){return{authPath:K(t,"auth.json"),modelsPath:K(t,"models.json")}}e(pt,"modelRuntimePaths");function L(t,n){if(t==null||H(t))return null;const s=n!==void 0&&n!==""&&n!=="off"?`:${n}`:"";return`${t.provider}/${t.id}${s}`}e(L,"formatModelSpec");function gt(t,n){const s=L(t,void 0);return s===null?null:`${s}:${n===void 0||n===""?"off":n}`}e(gt,"formatExactModelSpec");const vt=12e4;let W=null;function ht(){const t=W;if(W=null,t!==null)try{t.dispose()}catch{}}e(ht,"disposeActiveSession");async function un(t,n=process.hrtime.bigint(),s=new Date().toISOString()){Ae(t),Me.fresh(()=>{T({level:"info",event:"broker.startup.cli_entry",ts:s,duration_ms:0,fields:{runtime_version:process.version,engine_version:null,model:null}}),T({level:"info",event:"broker.startup.module_loaded",duration_ms:Number(process.hrtime.bigint()-n)/1e6,fields:{runtime_version:process.version,engine_version:null,model:null}})});const p=new Set;let i=null;const a=e((o,r=null)=>{p.has(o)||(p.add(o),Te(o,{duration_ms:Number(process.hrtime.bigint()-n)/1e6}),T({level:"info",event:o,duration_ms:Number(process.hrtime.bigint()-n)/1e6,fields:{runtime_version:process.version,engine_version:i,model:r}}))},"emitStartupMilestone");process.env[Ie]="1",process.env.CRTR_BROKER_PID=String(process.pid),delete process.env.TMUX_PANE,delete process.env.TMUX;const d=await Fe();De(d.VERSION),i=d.VERSION;const l=xe(t),m=K(l,"broker-launch.json"),h=JSON.parse(be(m,"utf8")),g=Oe(h);g.modelExact===!0?process.env.CRTR_MODEL_EXACT="1":delete process.env.CRTR_MODEL_EXACT;let{session:_,services:S,resuming:k,runtime:E}=await St(d,g);const R=(await ct(t)).node.review_binding?.review_id;W=_;const B=We;try{process.env.PI_PACKAGE_DIR=Ne(),Ee(S.settingsManager.getTheme(),!1)}catch(o){T({level:"error",event:"broker.theme.initialization_failed",error:o})}try{for(const o of Pe(V()))T({level:"warn",event:"broker.startup.warning",fields:{stage:"package_health",source:o.source,resolved_path:o.resolved}})}catch{}const x=Ce(t),u=new He(t),D=new Map,b=new Ye(t,o=>u.broadcast(o));ze(o=>u.broadcast({type:"node_named",...o}));let P=!1,F=!1,A,$,c,C,N,z=e(()=>{},"notifyTurnAccepted"),J=e(()=>{},"resetFrameState");c=new it({nodeId:t,cfg:g,session:_,services:S,runtime:E,registry:u,toolGroups:b,uiContext:e(()=>$,"uiContext"),faultRetry:e(()=>C,"faultRetry"),projection:e(()=>N,"projection"),setActiveSession:e(o=>{W=o},"setActiveSession"),disposeAndExit:e((o,r)=>j(o,r),"disposeAndExit"),onSessionRebind:e(()=>{J()},"onSessionRebind"),reWelcomeAll:e(()=>te(),"reWelcomeAll")});const Q=e(async(o,r=!1)=>{const f=c.session(),v=L(f.model,f.thinkingLevel);if(v===null)return null;const w=await mt(t,{spec:v,pinnedOverride:o,userSelected:r});return r&&(delete process.env.CRTR_MODEL_INTENT,process.env.CRTR_MODEL_EXACT="1",g.model=w.modelOverride,g.modelExact=!0),w.modelOverride},"persistModelChoice"),Z=e(async(o=!0,r,f=!1)=>{const v=c.session(),w=L(v.model,v.thinkingLevel),y=o?await Q(r,f):w;u.broadcast({type:"model_changed",model:H(v.model)?void 0:v.model,spec:y})},"broadcastModelChanged"),q=Qe(),me=e(o=>{q.admit(r=>{const f=c.session();return f.prompt(o,{preflightResult:r,...f.isStreaming?{streamingBehavior:"steer"}:{}}).catch(v=>{T({level:"error",event:"broker.inbox.idle_prompt_failed",error:v})})})},"startIdleInboxTurn");globalThis[Ze]=me,C=new Je({nodeId:t,cfg:g,retryProbe:B,currentSession:e(()=>c.session(),"currentSession"),currentServices:e(()=>c.services(),"currentServices"),installedGeneration:e(()=>c.installedGeneration(),"installedGeneration"),registryOf:Y,formatModelSpec:L,broadcastModelChanged:Z,turnAdmission:q}),N=new et({registry:u,faultRetry:C,installedGeneration:e(()=>c.installedGeneration(),"installedGeneration"),currentSession:e(()=>c.session(),"currentSession"),notifyTurnAccepted:e(()=>z(),"notifyTurnAccepted"),emitStartupMilestone:a,formatModelSpec:L});const ue=e(o=>{const r=c.session(),f=wt(r,R),v=ft(o.snapshotTail),w=f===void 0||v===void 0?f:f.slice(-v),y=w?.map(({message:O})=>O)??r.sessionManager.buildSessionContext().messages,G=b.summaries(),ie=w!==void 0&&v!==void 0?_t(y):void 0,ge=ie===void 0?G:Object.fromEntries(Object.entries(G).filter(([O])=>ie.has(O)));return{messages:y,...w===void 0?{}:{messageIds:w.map(({id:O})=>O)},messageVisibility:w?.map(({visibility:O})=>O)??y.map(()=>"visible"),turnVisibility:Xe(),stats:r.getSessionStats(),state:{model:H(r.model)?void 0:r.model,thinkingLevel:r.thinkingLevel,isStreaming:r.isStreaming,isCompacting:r.isCompacting,steeringMode:r.steeringMode,followUpMode:r.followUpMode,sessionFile:r.sessionFile,sessionId:r.sessionId,sessionName:r.sessionName,autoCompactionEnabled:r.autoCompactionEnabled,messageCount:r.messages.length,pendingMessageCount:r.pendingMessageCount},display:{...u.displaySnapshot()},toolGroupSummaries:ge,workingActivity:N.currentWorkingActivity(),queued:{steering:[...r.getSteeringMessages()],followUp:[...r.getFollowUpMessages()]}}},"buildSnapshot"),ee=e(o=>{const r=o.role==="controller"?D.values().next().value:void 0;u.sendFrame(o,{type:"welcome",snapshot:ue(o),role:o.role,pending_dialog:r!==void 0?r.request:null,agentDir:V()},!0)},"sendWelcome"),fe=e(o=>{const r=[...D.values()];for(let f=1;f<r.length;f++)u.sendFrame(o,r[f].request)},"replayExtraPendingDialogsTo"),te=e(()=>{u.forEachHelloed(ee)},"reWelcomeAll"),ne=e(o=>{if(!P){P=!0,b.persistPendingSummary(),N.dispose(),ht();try{A?.close()}catch{}u.dispose();try{se(x)&&ae(x)}catch{}u.clearAttachState(),process.exit(o)}},"completeExit"),j=e((o,r=0)=>{if(P)return;const f=o==="shutdown-hook"||o==="shutdown-after-settle";if(f&&b.finishOpenToolGroup(!0),f&&b.hasSummaryTasks()){if(F)return;F=!0,b.waitForSummaryTasks().finally(()=>ne(r));return}ne(r)},"disposeAndExit");$=bt({writable:e(()=>u.writableClients(),"writable"),forward:e((o,r)=>u.sendFrame(o,r),"forward"),pending:D,broadcast:e(o=>u.broadcastUi(o),"broadcast"),onKnownStreamWait:e(o=>N.knownStreamWait(o),"onKnownStreamWait")}),c.setRebindSession(),await c.enqueueRebind(_,S);const I=tt({nodeId:t,cfg:g,registry:u,toolGroups:b,projection:N,rebind:c,boundaryReviewId:R,pendingDialogs:D,sendWelcome:ee,replayExtraPendingDialogsTo:fe,reWelcomeAll:te,disposeAndExit:j,persistModelChoice:Q,broadcastModelChanged:Z,registryOf:Y,formatModelSpec:L,formatExactModelSpec:gt,turnAdmission:q,resolveLaunchModel:ce});z=I.notifyTurnAccepted,J=I.resetForSession;try{se(x)&&ae(x)}catch{}A=Se(o=>{const r=u.create(o);o.on("data",v=>{let w;try{w=r.decoder.push(v)}catch(y){y instanceof ut?(u.sendFrame(r,{type:"error",code:"frame_overflow",message:y.message}),u.dropClient(r,`frame overflow: ${y.message}`)):u.dropClient(r,`decoder error: ${String(y)}`);return}for(const y of w)try{nt(I,r,y)}catch{}});const f=e(()=>{u.removeClient(r)},"drop");o.on("close",f),o.on("error",()=>{})}),A.on("error",o=>{P||(T({level:"error",event:"broker.socket.failed",error:o}),j("socket-error",1))}),A.listen(x,async()=>{Promise.all([U(t,{op:"clear",link:"viewer\u2194broker"}),U(t,{op:"clear",link:"relay\u2194broker"})]).catch(r=>T({level:"error",event:"broker.daemon.operation.failed",node_id:t,error:r,fields:{operation:"broker_socket_bound_fault_clear"}}));let o;try{o=await C.recoverOnStartup()}catch(r){T({level:"error",event:"broker.daemon.operation.failed",node_id:t,error:r,fields:{operation:"recovery_startup"}}),j("recovery-startup-failed",1);return}if(o!=="retry-armed"&&g.firstPrompt!==void 0&&g.firstPrompt!==""){const r=at(process.env[dt]);r!==null&<(g.firstPrompt,r),I.kickoff(g.firstPrompt)}}),u.persistAttachState();const pe=2500;let oe=!1;const re=e(async o=>{if(P||oe)return;if(oe=!0,c.isAgentRunActive()||c.session().isStreaming||I.pendingPromptDispatches()>0){const f=Date.now()+pe;for(;I.pendingPromptDispatches()>0&&!c.session().isStreaming&&Date.now()<f;)await new Promise(v=>setTimeout(v,25));if(c.session().isStreaming){const v=f-Date.now();if(v>0){let w;try{st(),await Promise.race([c.session().abort().then(()=>!0,()=>!1),new Promise(G=>{w=setTimeout(()=>G(!1),v)})])&&await de(t,{event:"closed",end_reason:"teardown-aborted"})}finally{w!==void 0&&clearTimeout(w)}}}else(I.pendingPromptDispatches()>0||c.isAgentRunActive())&&await de(t,{event:"interrupted"})}j(o)},"abortAndExit");process.on("SIGTERM",()=>{re("SIGTERM")}),process.on("SIGINT",()=>{re("SIGINT")})}e(un,"runBroker");function _t(t){const n=new Set;for(const s of t)if(!(s.role!=="assistant"||!Array.isArray(s.content)))for(const p of s.content)p!==null&&typeof p=="object"&&p.type==="toolCall"&&typeof p.id=="string"&&n.add(p.id);return n}e(_t,"toolCallIds");function wt(t,n){const s=t.sessionManager,p=Ke(s);return p!==void 0&&ot(p.map(({message:i})=>i)),p===void 0?void 0:Ve(p,{boundaryReviewId:n,sessionEntries:s.getEntries?.()})}e(wt,"snapshotMessages");function le(){const t=we();if(t===void 0||t==="")throw new Error("broker launch is missing CRTR_NODE_ID");return t}e(le,"currentBrokerNodeId");async function ce(t,n){const s=je(n.model,he(),n.modelExact===!0);if(s===void 0)return;const p=Y(t),i={cwd:_e()??n.cwd,profileId:ye()},a=Ge(s,p,i);if(a!==void 0)throw await U(le(),{op:"record",input:{link:"crtr\u2192pi",op:"model resolution at launch",kind:"model-not-found",retry:{disposition:"fatal"},message:`model '${a.request.spec}' is not registered in the serving model registry`}}),new Error(`[broker] FATAL: model '${a.request.spec}' is not registered in the serving model registry`);const d=Be(s,p,i),l=d.selected;if(l!==void 0){const m=l.candidate;return(m.rank??0)>0&&T({level:"warn",event:"broker.model.launch_fallback",fields:{requested:n.model,selected:`${m.providerId}/${m.modelId}`,route_id:m.routeId,credential_source:m.credentialSource,rank:m.rank}}),{model:l.model,thinkingLevel:m.thinkingLevel}}if(n.modelExact===!0){const m=d.rejected.map(({candidate:h,reason:g})=>`'${h.providerId}/${h.modelId}' ${g}`).join("; ");throw await U(le(),{op:"record",input:{link:"crtr\u2192pi",op:"model resolution at launch",kind:"model-not-found",retry:{disposition:"fatal"},message:`exact-consult model '${n.model}' is unavailable \u2014 refusing to substitute (${m})`}}),new Error(`[broker] FATAL: exact-consult model '${n.model}' is unavailable`)}T({level:"warn",event:"broker.model.none_viable",fields:{rejected_candidates:d.rejected.slice(0,16).map(({candidate:m,reason:h})=>({provider:m.providerId,model:m.modelId,reason:h,route_id:m.routeId,credential_source:m.credentialSource})),rejected_candidates_omitted:Math.max(0,d.rejected.length-16)}})}e(ce,"resolveLaunchModel");function yt(t){let n=!0;return{runtime:new Proxy(t,{get(p,i,a){return n&&i==="getAvailableSnapshot"?()=>[]:n&&i==="getAvailable"?async()=>[]:n&&i==="getModel"?()=>{}:Reflect.get(p,i,a)}}),reveal:e(()=>{n=!1},"reveal")}}e(yt,"modelLessRegistry");async function St(t,n){const s=V(),p=e(async _=>{const{authPath:S,modelsPath:k}=pt(_.agentDir),E=await Re.create({credentials:new $e(S),modelsPath:k}),R=await t.createAgentSessionServices({cwd:_.cwd,agentDir:_.agentDir,modelRuntime:E,resourceLoaderOptions:{additionalExtensionPaths:n.extensionPaths,appendSystemPrompt:n.appendSystemPromptPath!==void 0?[n.appendSystemPromptPath]:void 0,noContextFiles:!0}}),B=R.resourceLoader.getExtensions();if(n.extensionPaths.some(A=>X.includes(A))){const A=new Set(B.extensions.map(c=>c.path)),$=X.filter(c=>!A.has(c));if($.length>0){const c=B.errors.filter(C=>X.includes(C.path)).map(C=>`${C.path}: ${C.error}`).join("; ");throw new Error(`[broker] FATAL: mandatory canvas extensions failed to load: ${$.join(", ")}${c===""?"":` (${c})`}`)}}const x=await ce(R,n),u=x?.model,D=x?.thinkingLevel,b=x===void 0?yt(R.modelRuntime):void 0,P=b!==void 0?{...R,modelRuntime:b.runtime}:R,F=await t.createAgentSessionFromServices({services:P,sessionManager:_.sessionManager,model:u,thinkingLevel:D,tools:n.tools,sessionStartEvent:_.sessionStartEvent});return rt(F.session),Le(F.session),b?.reveal(),{...F,services:R}},"buildForManager"),i=n.resumeSessionPath,a=n.forkFrom!==void 0&&n.forkFrom!=="";if(!a&&(i===void 0||i==="")&&n.resumeSessionId!==void 0&&n.resumeSessionId!=="")throw new Error(`[broker] resume requires a session .jsonl PATH; got only a bare id '${n.resumeSessionId}' (pi_session_file was never captured for this node)`);const d=!a&&i!==void 0&&i!=="",l=d&&n.newCycle===!0,m=d&&!l;let h;if(a)h=t.SessionManager.forkFrom(n.forkFrom,n.cwd);else if(m||l){if(h=t.SessionManager.open(i),l){const _=h.getLeafId();h.resetLeaf(),h.appendCustomEntry(qe,{cycle:Number(process.env.CRTR_CYCLES),fromLeaf:_})}}else h=t.SessionManager.create(n.cwd);if(t.createAgentSessionRuntime!==void 0){const _=e(async k=>{const E=await p({cwd:k.cwd,agentDir:k.agentDir,sessionManager:k.sessionManager,sessionStartEvent:k.sessionStartEvent});return{...E,diagnostics:E.services.diagnostics??[]}},"factory"),S=await t.createAgentSessionRuntime(_,{cwd:n.cwd,agentDir:s,sessionManager:h});return{session:S.session,services:S.services,resuming:m,runtime:S}}const g=await p({cwd:n.cwd,agentDir:s,sessionManager:h});return{session:g.session,services:g.services,resuming:m,runtime:void 0}}e(St,"buildBrokerSession");function bt(t){const n=e((i,a,d,l)=>{if(l?.signal?.aborted)return Promise.resolve(i);const m=t.writable();return m.length===0?Promise.resolve(i):new Promise(h=>{let g;const _=e(()=>{g!==void 0&&clearTimeout(g),l?.signal?.removeEventListener("abort",S),t.pending.delete(a.id)},"cleanup"),S=e(()=>{_(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),h(i)},"onAbort");l?.signal?.addEventListener("abort",S,{once:!0});const k=l?.timeout!==void 0?l.timeout:vt;g=setTimeout(()=>{_(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),h(i)},k),typeof g.unref=="function"&&g.unref(),t.pending.set(a.id,{request:a,resolve:e(E=>{_(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),h(d(E))},"resolve")});for(const E of m)t.forward(E,a)})},"dialogPromise"),s=e(()=>{},"noop");return{[Ue]:t.onKnownStreamWait??(i=>()=>{}),get theme(){const i=globalThis[Symbol.for("@earendil-works/pi-coding-agent:theme")];if(i==null)throw new Error("Theme not initialized. Call initTheme() first.");return i},select:e((i,a,d)=>n(void 0,{type:"extension_ui_request",id:M(),method:"select",title:i,options:a,timeout:d?.timeout},l=>"cancelled"in l&&l.cancelled?void 0:"value"in l?l.value:void 0,d),"select"),confirm:e((i,a,d)=>n(!1,{type:"extension_ui_request",id:M(),method:"confirm",title:i,message:a,timeout:d?.timeout},l=>"cancelled"in l&&l.cancelled?!1:"confirmed"in l?l.confirmed:!1,d),"confirm"),input:e((i,a,d)=>n(void 0,{type:"extension_ui_request",id:M(),method:"input",title:i,placeholder:a,timeout:d?.timeout},l=>"cancelled"in l&&l.cancelled?void 0:"value"in l?l.value:void 0,d),"input"),editor:e((i,a)=>n(void 0,{type:"extension_ui_request",id:M(),method:"editor",title:i,prefill:a},d=>"cancelled"in d&&d.cancelled?void 0:"value"in d?d.value:void 0),"editor"),setStatus:e((i,a)=>t.broadcast({type:"extension_ui_request",id:M(),method:"setStatus",statusKey:i,statusText:a}),"setStatus"),setWidget:e((i,a,d)=>{typeof a!="function"&&t.broadcast({type:"extension_ui_request",id:M(),method:"setWidget",widgetKey:i,widgetLines:a,widgetPlacement:d?.placement})},"setWidget"),setTitle:e(i=>t.broadcast({type:"extension_ui_request",id:M(),method:"setTitle",title:i}),"setTitle"),notify:e((i,a)=>{const d=a==="warn"?"warning":a;t.broadcast({type:"extension_ui_request",id:M(),method:"notify",message:i,notifyType:d})},"notify"),onTerminalInput:e(()=>s,"onTerminalInput"),setWorkingMessage:s,setWorkingVisible:s,setWorkingIndicator:s,setHiddenThinkingLabel:s,setFooter:s,setHeader:s,custom:e(()=>Promise.resolve(void 0),"custom"),pasteToEditor:s,setEditorText:s,getEditorText:e(()=>"","getEditorText"),addAutocompleteProvider:s,setEditorComponent:s,getEditorComponent:e(()=>{},"getEditorComponent"),getAllThemes:e(()=>[],"getAllThemes"),getTheme:e(()=>{},"getTheme"),setTheme:s,getToolsExpanded:e(()=>!1,"getToolsExpanded"),setToolsExpanded:s}}e(bt,"makeBrokerUiContext");export{vn as REVIEW_BOUNDARY_NAVIGATION_CODE,gn as ReviewBoundaryNavigationError,St as buildBrokerSession,ht as disposeActiveSession,bt as makeBrokerUiContext,un as runBroker,wt as snapshotMessages};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type WakeOrigin } from './bearings.js';
|
|
2
|
-
import { type NodeMeta, type Mode, type Lifecycle, type OutcomeDeliveryBinding } from '../canvas/index.js';
|
|
2
|
+
import { type NodeMeta, type Mode, type Lifecycle, type OutcomeDeliveryBinding, type ReviewBinding } from '../canvas/index.js';
|
|
3
3
|
import { type ModelRegistryLike, type ModelRequest } from '../model-routes.js';
|
|
4
4
|
export interface SpawnChildOpts {
|
|
5
5
|
kind: string;
|
|
@@ -70,6 +70,10 @@ export interface SpawnChildOpts {
|
|
|
70
70
|
worktreeCwd?: string;
|
|
71
71
|
/** Preallocated node id, used when a managed worktree must be named before birth. */
|
|
72
72
|
nodeId?: string;
|
|
73
|
+
/** Bind the newborn to a review. Its transcript is then sliced at that
|
|
74
|
+
* review's durable boundary marker, so a fork of a companion shows only the
|
|
75
|
+
* review-era conversation rather than the origin context it inherited. */
|
|
76
|
+
reviewBinding?: ReviewBinding;
|
|
73
77
|
/** Hidden ambient "current situation" text — NOT the visible prompt/body.
|
|
74
78
|
* Stored as a `situational` card BEFORE launch so canvas-context-intro's
|
|
75
79
|
* session_start bearings nest it from the node's very first turn. Passed
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var Q=Object.defineProperty;var s=(e,o)=>Q(e,"name",{value:o,configurable:!0});import{accessSync as W,constants as A,cpSync as Y,readdirSync as D,existsSync as Z,rmSync as ee}from"node:fs";import{isAbsolute as ne,resolve as oe,join as g}from"node:path";import{spawnNode as re,currentNodeContext as ie,rootOfSpine as te,newNodeId as de,preflightNodeId as ae}from"./nodes.js";import{resolveProfileOperand as se}from"../profiles/manifest.js";import{selectProfileForCwd as ce,selectProfileForCwdReadOnly as le}from"../profiles/select.js";import{buildLaunchSpecAsync as M,buildPiArgv as fe}from"./launch.js";import{createManagedWorktreeAsync as ue,rollbackManagedWorktreeAsync as me}from"../worktree-mutation-async.js";import{usage as f,brokerLaunchFailed as E}from"../errors.js";import{writeGoal as he}from"./kickoff.js";import{appendSituationalContext as we,formatSituationalProse as pe}from"./situational-context.js";import{hasRoadmap as ke,seedRoadmap as _e}from"./roadmap.js";import{buildWakeBearings as ye}from"./bearings.js";import{encodeKickoffOrigin as ve,KICKOFF_ORIGIN_ENV as ge}from"./stamp/protocol.js";import{beginExecution as be,canonicalSessionFile as I,contextDir as
|
|
1
|
+
var Q=Object.defineProperty;var s=(e,o)=>Q(e,"name",{value:o,configurable:!0});import{accessSync as W,constants as A,cpSync as Y,readdirSync as D,existsSync as Z,rmSync as ee}from"node:fs";import{isAbsolute as ne,resolve as oe,join as g}from"node:path";import{spawnNode as re,currentNodeContext as ie,rootOfSpine as te,newNodeId as de,preflightNodeId as ae}from"./nodes.js";import{resolveProfileOperand as se}from"../profiles/manifest.js";import{selectProfileForCwd as ce,selectProfileForCwdReadOnly as le}from"../profiles/select.js";import{buildLaunchSpecAsync as M,buildPiArgv as fe}from"./launch.js";import{createManagedWorktreeAsync as ue,rollbackManagedWorktreeAsync as me}from"../worktree-mutation-async.js";import{usage as f,brokerLaunchFailed as E}from"../errors.js";import{writeGoal as he}from"./kickoff.js";import{appendSituationalContext as we,formatSituationalProse as pe}from"./situational-context.js";import{hasRoadmap as ke,seedRoadmap as _e}from"./roadmap.js";import{buildWakeBearings as ye}from"./bearings.js";import{encodeKickoffOrigin as ve,KICKOFF_ORIGIN_ENV as ge}from"./stamp/protocol.js";import{beginExecution as be,canonicalSessionFile as I,contextDir as B,crtrHome as xe,findNodeBySessionFile as Fe,getNode as w,fullName as H,jobDir as Oe,nodeDir as Ce,recordExecutionPid as Se,abortExecution as P,reportsDir as $e,setFrozen as Ee}from"../canvas/index.js";import{boundFleet as Re,brokerThresholdsForDaemon as De}from"./fleet.js";import{emitEvent as Ie}from"../events/emit.js";import{openViewerWindow as Be,focusOf as Pe,windowOfPane as je}from"./placement.js";import{waitForBrokerViewSocket as Ne}from"./placement-tmux.js";import{transition as b}from"./lifecycle.js";import{beginBootFaultAttempt as Te}from"../canvas/recovery.js";import{piSessionsRoot as Le}from"./pi-vendored.js";import{headlessBrokerHost as j}from"./host.js";import{ensureDaemon as We}from"../../daemon/manage.js";import{readConfig as Ae}from"../config.js";import{modelRequestFromConfig as Me,unregisteredConcreteModel as He}from"../model-routes.js";import{openModelRegistry as Ke}from"./model-registry.js";import{MODEL_SPEC_NEXT as ze}from"./model-selection.js";import{initializeForkContextExposure as qe}from"../substrate/injected-store.js";import{discoverLifecycleHookRegistry as Ue}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as Ve}from"../command-hooks/transport/exec-lifecycle.js";function x(e){return{detail:{schema:"crtr.node-outcome-detail/v1",message:e instanceof Error?e.message:String(e)}}}s(x,"launchFailureOutcome");function Xe(e,o,d){try{return j.launch(e,o,d)}catch(r){try{b(e,"crash",{reason:"launch_failed",outcome:x(r)})}catch{}const t=r.message;throw E(t.startsWith("[broker]")?t:`[broker] refusing to launch ${e}: ${t}`,"Inspect the cause above, fix the launch recipe or environment, then retry.")}}s(Xe,"launchBrokerOrCrash");function Ge(e,o){try{b(e,"crash",{reason:"launch_failed",outcome:x(o)})}catch{}try{j.teardown(e)}catch{}}s(Ge,"crashAndTearDown");function Je(e){const o=Le();if(!Z(o))throw f(`--fork-from '${e}': no pi sessions store at ${o} to resolve it from \u2014 pass a node id or an absolute .jsonl path.`,{next:"Pass a live node id, an absolute .jsonl session path, or drop --fork-from."});const d=[];for(const a of D(o,{withFileTypes:!0})){if(!a.isDirectory())continue;const c=g(o,a.name);for(const l of D(c)){if(!l.endsWith(".jsonl"))continue;const F=l.slice(0,-6),u=F.slice(F.lastIndexOf("_")+1);d.push({id:u,path:g(c,l)})}}const r=d.filter(a=>a.id===e),t=r.length>0?r:d.filter(a=>a.id.startsWith(e));if(t.length===0)throw f(`--fork-from '${e}': no pi session with that id found.`,{next:"Pass a live node id, a real session uuid/prefix, or an absolute .jsonl session path."});if(t.length>1)throw f(`--fork-from '${e}': ambiguous \u2014 ${t.length} sessions match that id prefix; pass the full id or the .jsonl path.`,{next:"Pass the full session uuid or an absolute .jsonl path to disambiguate."});return I(t[0].path)}s(Je,"resolveSessionUuid");function K(e){const o=e.trim();if(o==="")throw f("--fork-from requires a node id, session file, or session uuid.",{next:"Pass a live node id, an absolute .jsonl session path, or a session uuid/prefix."});if(o.includes("/")||o.endsWith(".jsonl"))return I(ne(o)?o:oe(process.cwd(),o));const d=w(o);if(d!==null){const r=d.pi_session_file;if(r==null||r==="")throw f(`node ${o} has no pi session yet \u2014 it has not captured a session FILE to fork from (the broker forks a .jsonl path, not a bare id).`,{next:"Pick a node that has captured a session, or drop --fork-from."});return I(r)}return Je(o)}s(K,"resolveForkSource");async function Qe(e,o,d,r={}){return e===null?null:e!==void 0&&e!==""?se(e).profileId:o!==null?w(o)?.profile_id??null:r.readOnlySelection===!0?le(d):ce(d)}s(Qe,"resolveProfileId");function z(e){const o=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return Me(e.model,o,e.modelExact===!0)}s(z,"requestFromLaunch");async function q(e,o,d){if(e===void 0||e.kind==="logical")return;const r=He(e,d??await Ke(),o);if(r!==void 0)throw f(`model '${r.request.spec}' is not registered in this daemon.`,{received:r.request.spec,next:ze})}s(q,"assertLaunchModelRegistered");function Ye(e,o,d){const r=e??o??null;if(!d&&r===null)throw new Error("spawnChild requires a calling node (CRTR_NODE_ID) or an explicit parent");return r}s(Ye,"resolveSpawner");async function U(e,o,d){try{We()}catch{}const r=ie(),t=e.root===!0,a=Ye(e.parent,r.nodeId??null,t),c=e.mode??"base",l=e.rootLifecycle??(t?"resident":"terminal"),F=t&&l==="resident",u=e.worktree===!0,p=u?e.nodeId??de():e.nodeId;e.nodeId!==void 0&&ae(e.nodeId);const k=await Qe(e.profile,a,e.cwd),N=(await M(e.kind,c,{lifecycle:l,hasManager:!t,model:e.model,modelOverride:e.model!==void 0,cwd:e.cwd,profileId:k})).launch;await q(z(N),{cwd:e.cwd,profileId:k});const O=e.forkFrom!==void 0?K(e.forkFrom):void 0,X=O===void 0?null:Fe(O)?.node_id??null;let m,C=e.cwd;try{u&&(m=await ue(e.worktreeCwd??e.cwd,p,e.worktreeBase),C=m.path);const _=u?(await M(e.kind,c,{lifecycle:l,hasManager:!t,model:e.model,modelOverride:e.model!==void 0,cwd:C,profileId:k})).launch:N;u&&await q(z(_),{cwd:C,profileId:k});const n=await re({kind:e.kind,mode:c,lifecycle:l,cwd:C,name:e.name??e.kind,description:e.description,parent:t?null:a,creator:e.creator,spawnedBy:t?a??void 0:void 0,profile_id:k,forkFrom:e.forkFrom,forkSourceFile:O,modelOverride:e.model===void 0?void 0:_.model,...m!==void 0?{managedWorktree:m}:{},...p!==void 0?{nodeId:p}:{},...e.reviewBinding===void 0?{}:{reviewBinding:e.reviewBinding},...e.deadlineAt===void 0?{}:{deadlineAt:e.deadlineAt},...e.outcomeDelivery===void 0?{}:{outcomeDelivery:e.outcomeDelivery},launch:_});if(d?.(n.node_id),e.forkFrom!==void 0)try{qe(n.node_id,X)}catch(i){throw b(n.node_id,"crash",{reason:"launch_failed",outcome:x(i)}),i}if(he(n.node_id,e.prompt),e.situationalContext!==void 0&&we(n.node_id,pe(e.situationalContext)),o!==void 0)try{o(n.node_id)}catch(i){throw b(n.node_id,"crash",{reason:"launch_failed",outcome:x(i)}),i}const R=e.prompt!=="",G=`${R&&e.wakeOrigin!==void 0?`${ye(e.wakeOrigin)}
|
|
2
2
|
|
|
3
|
-
`:""}${e.prompt}`;c==="orchestrator"&&!ke(n.node_id)&&_e(n.node_id,{goal:e.prompt.trim()}),await Ze(n);const h=fe(n,{prompt:G,forkFrom:O});if(h.env={...h.env,CRTR_SUBTREE:te(n.node_id)},R){const i=e.wakeOrigin!==void 0?{type:"runtime",kind:"wake",wake:e.wakeOrigin}:{type:"runtime",kind:"kickoff",...n.spawned_by!=null&&n.spawned_by!==""?{spawnedBy:n.spawned_by}:{}};h.env[ge]=ve(i)}const S=Re();if(!S.reserveSlot(n.node_id))return Ee(n.node_id,new Date().toISOString()),Ie({level:"info",event:"broker.frozen",node_id:n.node_id,fields:{live_count:S.size(),hard_cap:De().automaticReviveCap}}),{node:w(n.node_id),frozen:!0,window:null,session:null};const J=Te(n.node_id),y=be(n.node_id,{daemonEpoch:S.epoch()});h.env={...h.env,CRTR_EXECUTION_ID:y};let $;try{$=Xe(n.node_id,h,{cwd:n.cwd,name:H(n),resuming:!1})}catch(i){throw
|
|
3
|
+
`:""}${e.prompt}`;c==="orchestrator"&&!ke(n.node_id)&&_e(n.node_id,{goal:e.prompt.trim()}),await Ze(n);const h=fe(n,{prompt:G,forkFrom:O});if(h.env={...h.env,CRTR_SUBTREE:te(n.node_id)},R){const i=e.wakeOrigin!==void 0?{type:"runtime",kind:"wake",wake:e.wakeOrigin}:{type:"runtime",kind:"kickoff",...n.spawned_by!=null&&n.spawned_by!==""?{spawnedBy:n.spawned_by}:{}};h.env[ge]=ve(i)}const S=Re();if(!S.reserveSlot(n.node_id))return Ee(n.node_id,new Date().toISOString()),Ie({level:"info",event:"broker.frozen",node_id:n.node_id,fields:{live_count:S.size(),hard_cap:De().automaticReviveCap}}),{node:w(n.node_id),frozen:!0,window:null,session:null};const J=Te(n.node_id),y=be(n.node_id,{daemonEpoch:S.epoch()});h.env={...h.env,CRTR_EXECUTION_ID:y};let $;try{$=Xe(n.node_id,h,{cwd:n.cwd,name:H(n),resuming:!1})}catch(i){throw P(y,{reason:"launch_failed"}),i}finally{S.releaseReservation(n.node_id)}if($.pid===null){const i=new Error(`broker host returned no pid for ${n.node_id}`);throw P(y,{reason:"launch_failed"}),b(n.node_id,"crash",{reason:"launch_failed",outcome:x(i)}),E(`failed to launch the broker engine for ${n.node_id} (${n.name}) \u2014 the node was not started.`,`Inspect canonical event diagnostics with \`crtr sys logs --node ${n.node_id}\`, then verify the pi engine can start in this environment.`)}if(Se(y,n.node_id,$.pid)==="shutdown")throw P(y,{reason:"superseded"}),j.teardown(n.node_id),E(`broker execution was superseded for ${n.node_id}`,"Retry spawning the node.");if(F&&e.readiness==="await"&&!await Ne(n.node_id,$.exited)){const i=J.explanation();throw Ge(n.node_id,new Error(i??`broker view socket never bound for ${n.node_id}`)),E(i!==null?`the root broker ${n.node_id} could not start \u2014 ${i}`:`the root broker ${n.node_id} never bound its view socket \u2014 it was not started.`,i!==null?"Resolve the cause named above, then retry.":`The broker engine exited before binding its view socket. Inspect canonical event diagnostics with \`crtr sys logs --node ${n.node_id}\`, then retry.`)}let T=null,L=null;if(!t&&a!==null&&Ae("user").auto_open_child_viewers)try{const i=Pe(a);if(i!==null&&i.pane!==null&&i.pane!==""){const v=Be(n.node_id,i.session??"",{name:H(n),cwd:e.cwd,besidePane:i.pane,waitForBroker:!0,initialWhip:R});v!==null&&v.pane!==null&&v.pane!==""&&(L=v.session,T=je(v.pane))}}catch{}return{node:w(n.node_id),frozen:!1,window:T,session:L}}catch(_){throw m!==void 0&&p!==void 0&&w(p)===null&&await me(m),_}}s(U,"spawnChildPrepared");async function Pn(e){return U(e)}s(Pn,"spawnChild");async function Ze(e){const o=Ue(e.cwd,e.profile_id).plans.get("node:start")??[];await Ve(o,{node:{id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,cwd:e.cwd,nodeDir:Ce(e.node_id),contextDir:B(e.node_id),jobDir:Oe(e.node_id),reportsDir:$e(e.node_id)},runtime:{isBirth:!0,canvasHome:xe(),profile:e.profile_id??null}})}s(Ze,"invokeBirthLifecycleHooks");const V=new Set(["initial-prompt.md","yield-message.md","result.json"]);async function jn(e){const o=w(e);if(o===null)throw f(`unknown node: ${e}`,{received:e,next:"List nodes and pass the id of a node with a captured pi session."});const d=K(e),r=B(e);try{W(d,A.R_OK),W(r,A.R_OK)}catch(t){throw new Error(`cannot fork ${e}: its conversation or context is unreadable \u2014 ${t.message}`)}return U({kind:o.kind,mode:"base",cwd:o.cwd,prompt:"",root:!0,readiness:"await",forkFrom:e,profile:o.profile_id,model:o.model_override??void 0},t=>{const a=B(t);for(const c of D(r,{withFileTypes:!0}))V.has(c.name)||Y(g(r,c.name),g(a,c.name),{recursive:!0,dereference:!1,force:!0});for(const c of V)ee(g(a,c),{recursive:!0,force:!0})})}s(jn,"forkNode");export{q as assertLaunchModelRegistered,jn as forkNode,Ze as invokeBirthLifecycleHooks,K as resolveForkSource,Qe as resolveProfileId,Ye as resolveSpawner,Pn as spawnChild,U as spawnChildPrepared};
|
|
@@ -2,12 +2,10 @@ export { STALL_REPROMPT } from '../../shared/generated-context.js';
|
|
|
2
2
|
export interface StopSignals {
|
|
3
3
|
/** Did the node call `push --final` (finish) this turn? */
|
|
4
4
|
pushedFinal: boolean;
|
|
5
|
-
/** Did the node call `crtr ask` (escalate to the user) this turn? */
|
|
6
|
-
requestedHumanReply: boolean;
|
|
7
5
|
}
|
|
8
6
|
export type StopAction = {
|
|
9
7
|
action: 'allow';
|
|
10
|
-
reason: 'awaiting' | 'scheduled' | 'finished' | '
|
|
8
|
+
reason: 'awaiting' | 'scheduled' | 'finished' | 'dormant';
|
|
11
9
|
} | {
|
|
12
10
|
action: 'reprompt';
|
|
13
11
|
reason: 'stalled';
|