@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
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var S=Object.defineProperty;var m=(u,e)=>S(u,"name",{value:e,configurable:!0});import{LoginDialogComponent as k}from"@earendil-works/pi-coding-agent";import{Input as R,matchesKey as h,truncateToWidth as D}from"@earendil-works/pi-tui";import{execFile as E}from"node:child_process";import{dialogAuthInteraction as B}from"../../../core/auth-interaction.js";import{isManagedProvider as F,promoteSubscription as N,readSubscriptionPool as T,renameSubscription as U}from"../../../core/subscription-state.js";import{removeProviderRow as _}from"../../../core/provider-management.js";import{cliClient as V}from"../../api-client.js";import{loginProvider as j}from"../provider-login.js";import{fitTail as C,theme as l,visibleRange as A}from"../../../core/tui/panel.js";function M(u,e){const t=u.getProviders().filter(i=>i.auth.oauth!==void 0),o=new Set(t.map(i=>i.id)),n=new Set;return[...t.map(i=>({providerId:i.id,name:i.name,managed:F(i.id),authType:"oauth"})),...e.getAll().map(i=>({providerId:i.provider,name:e.getProviderDisplayName(i.provider),managed:F(i.provider),authType:o.has(i.provider)?"oauth":"api_key"}))].filter(i=>!n.has(i.providerId)&&!!n.add(i.providerId))}m(M,"buildProviderCatalog");function q(u,e){return e||u instanceof Error&&u.name==="AbortError"?"Login cancelled":`Login error: ${u instanceof Error?u.message:String(u)}`}m(q,"classifyLoginFailure");class Z{static{m(this,"ProviderPanel")}tui;agentDir;runtime;registry;renameInput=new R;rows=[];selected=0;mode="list";notice="";catalog=[];catalogIndex=0;loginProvider;loginFlow;mutationInFlight=!1;onChange;constructor(e,t,o,n){this.tui=e,this.agentDir=t,this.runtime=o,this.registry=n,this.renameInput.onSubmit=()=>this.rename(),this.renameInput.onEscape=()=>{this.mode="list"},this.reload()}notifyChange(){this.onChange?.(),this.tui.requestRender()}reloadAfterAuthChange(){this.reload(),this.registry.refresh().then(()=>{this.reload(),this.notifyChange()})}reload(){const e=this.registry,t=[];for(const o of M(this.runtime,e)){const n=e.getProviderAuthStatus(o.providerId);if(o.managed){const i=T(o.providerId);if(i.length===0&&!n.source)continue;t.push({...o,configured:i.length>0||n.configured,source:n.source,sourceLabel:n.label}),i.forEach((s,c)=>t.push({...o,label:s.label,preferred:c===0,cooldownUntil:s.rateLimitedUntil,accountId:s.accountId}));continue}n.source&&t.push({...o,configured:n.configured,source:n.source,sourceLabel:n.label})}this.rows=t,this.selected=Math.min(this.selected,Math.max(0,t.length))}selectedRow(){return this.rows[this.selected]}openBrowser(e){const t=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",o=process.platform==="win32"?["/c","start","",e]:[e];E(t,o,{timeout:5e3},()=>{})}openCatalog(){this.catalog=M(this.runtime,this.registry),this.catalogIndex=0,this.mode="catalog"}startLogin(e,t){this.loginProvider=e;let o;const n=m(r=>{!o.active||this.loginFlow!==o||(o.active=!1,this.loginFlow=void 0,this.mode="list",this.notice=r,this.reloadAfterAuthChange(),this.notifyChange())},"complete"),i=new k(this.tui,e.providerId,(r,p)=>{r||n(p?`Login failed: ${p}`:"Login cancelled")},e.name);o={dialog:i,active:!0,committing:!1},this.loginFlow=o,this.mode="login";const s=i.handleInput.bind(i);i.handleInput=r=>{o.committing||s(r)};const c=m(()=>o.active&&this.loginFlow===o&&!i.signal.aborted,"isActive"),d=m(()=>c()?(o.committing=!0,i.showDetails(["Saving credentials\u2026"]),!0):!1,"beginCommit"),g=m(r=>{n(q(r,i.signal.aborted))},"fail");if(e.authType==="api_key"){i.showPrompt(`Enter API key for ${e.name}:`,"sk-...").then(async r=>{if(c()){if(!r.trim()){n("No key entered \u2014 login cancelled");return}d()&&(await V().installCredential(e.providerId,{kind:"api_key",api_key:r.trim()}),n(`API key saved for ${e.name}`))}}).catch(g);return}const $=B(i,{openBrowser:m(r=>this.openBrowser(r),"openBrowser"),onChange:m(()=>this.notifyChange(),"onChange"),isActive:c});j(this.runtime,e.providerId,$,{label:t,beforeInstall:d}).then(r=>{r&&c()&&n(`Logged in to ${e.name}`)}).catch(g)}isNestedFlowActive(){return this.mode==="login"}dispose(){const e=this.loginFlow;e&&(e.active=!1,this.loginFlow=void 0,e.dialog.handleInput("\x1B"))}runMutation(e){this.mutationInFlight||(this.mutationInFlight=!0,e().catch(t=>{this.notice=t instanceof Error?t.message:String(t)}).finally(()=>{this.mutationInFlight=!1,this.notifyChange()}))}rename(){const e=this.selectedRow();!e?.managed||!e.label||(this.mode="list",this.runMutation(async()=>{await U(e.providerId,e.label,this.renameInput.getValue()),this.notice=`Renamed ${e.name} account`,this.reload()}))}remove(e){this.runMutation(async()=>{this.notice=await _(this.agentDir,e),this.reloadAfterAuthChange()})}promote(e){this.runMutation(async()=>{await N(e.providerId,e.label),this.notice=`Preferred ${e.name} account`,this.reload()})}handleInput(e){if(this.mode==="login")return this.loginFlow?.dialog.handleInput(e),!0;if(this.mutationInFlight)return!0;if(this.mode==="rename"||this.mode==="label")return this.renameInput.handleInput(e),!0;if(this.mode==="catalog"){if(h(e,"escape"))return this.mode="list",!0;if(h(e,"j")||h(e,"down"))return this.catalogIndex=Math.min(this.catalog.length-1,this.catalogIndex+1),!0;if(h(e,"k")||h(e,"up"))return this.catalogIndex=Math.max(0,this.catalogIndex-1),!0;if(h(e,"enter")){const n=this.catalog[this.catalogIndex];return n.managed?(this.loginProvider=n,this.renameInput.setValue(""),this.renameInput.onSubmit=()=>{const i=this.renameInput.getValue().trim();i&&this.startLogin(n,i)},this.mode="label"):this.startLogin(n),!0}return!0}if(this.mode==="remove"){if(h(e,"y")||h(e,"enter")){const n=this.selectedRow();n&&(n.managed||n.configured)&&this.remove(n)}return this.mode="list",!0}if(h(e,"j")||h(e,"down"))return this.selected=Math.min(this.rows.length,this.selected+1),!0;if(h(e,"k")||h(e,"up"))return this.selected=Math.max(0,this.selected-1),!0;const t=this.selectedRow();if(h(e,"p")&&t?.managed&&t.label)return this.promote(t),!0;if(h(e,"r")&&t?.managed&&t.label)return this.renameInput.setValue(t.label),this.renameInput.onSubmit=()=>this.rename(),this.mode="rename",!0;if(h(e,"x")&&(t?.managed||t?.configured))return this.mode="remove",!0;if(h(e,"a"))return this.openCatalog(),!0;const o=t?.source==="environment"||t?.source==="runtime";return h(e,"l")&&t&&!o?(t.managed&&t.label?this.startLogin(t,t.label):this.startLogin(t),!0):h(e,"enter")?(t&&!o?this.startLogin(t,t.managed&&t.label?t.label:void 0):t||this.openCatalog(),!0):!1}badge(){return String(this.rows.filter(e=>e.label===void 0).length)}render(e,t){const o=l.fg("accent",l.bold("Providers")),n=l.fg("dim",`${this.rows.filter(c=>c.label===void 0).length} configured`),i=Math.max(1,t);let s;if(this.mode==="login")s=C(this.loginFlow?.dialog.render(e)??[],i);else if(this.mode==="rename"||this.mode==="label")s=C([o,n,"",l.fg("accent",this.mode==="rename"?"Rename account":`Name the ${this.loginProvider?.name??"provider"} account`),...this.renameInput.render(Math.max(1,e-8))],i);else if(this.mode==="remove"){const c=this.selectedRow(),d=c?.label??(c?.managed?`${c.name} \xB7 all accounts`:c?.name??"account");s=C([o,n,"",l.fg("warning",`Remove ${d}? y/enter confirm \xB7 any other key cancel`)],i)}else{const c=[o,n].slice(0,Math.max(0,i-1)),d=i-c.length;if(s=[...c],this.mode==="catalog"){const g=this.catalog.length,r=g>d&&d>=2,p=r?d-1:d,{start:I,end:v}=A(g,this.catalogIndex,p);let w=d-(v-I)-(r?1:0);w>0&&(s.push(l.fg("dim","Select a provider to add \xB7 esc back")),w-=1);for(let f=I;f<v;f++){const x=this.catalog[f];s.push(`${f===this.catalogIndex?l.fg("accent","\u25B6"):" "} ${x.name}`)}r&&s.push(l.fg("dim",`(${this.catalogIndex+1}/${g})`))}else{const g=this.rows.length+1,r=g>d&&d>=2,p=r?d-1:d,{start:I,end:v}=A(g,this.selected,p);let w=d-(v-I)-(r?1:0);const f=this.rows.length===0&&w>0;f&&(w-=1);const x=!!this.notice&&w>0;f&&s.push(l.fg("warning","No provider configured yet."));for(let b=I;b<v;b++){if(b===this.rows.length){s.push(`${this.selected===this.rows.length?l.fg("accent","\u25B6"):" "} ${l.fg("accent","\uFF0B Add provider")}`);continue}const a=this.rows[b],P=b===this.selected?l.fg("accent","\u25B6"):" ";if(a.label){const L=a.cooldownUntil&&a.cooldownUntil>Date.now()?`cooldown ${Math.ceil((a.cooldownUntil-Date.now())/6e4)}m`:"ready",y=a.accountId?` \xB7 ${a.accountId.length>12?`${a.accountId.slice(0,8)}\u2026${a.accountId.slice(-4)}`:a.accountId}`:"";s.push(`${P} ${a.preferred?l.fg("success","\u25CF"):" "} ${a.label}${l.fg("dim",y)} ${l.fg("dim",L)}${a.preferred?l.fg("accent"," preferred"):""}`)}else{const L=a.managed?`${this.rows.filter(y=>y.providerId===a.providerId&&y.label).length} accounts`:a.source==="environment"||a.source==="runtime"?`${a.source}${a.sourceLabel?` \xB7 ${a.sourceLabel}`:""} (view only)`:"configured";s.push(`${P} ${l.fg("accent",a.name)}${l.fg("dim",` ${L}`)}`)}}r&&s.push(l.fg("dim",`(${this.selected+1}/${g})`)),x&&s.push(l.fg("dim",this.notice))}}return s.map(c=>D(c,e))}}export{Z as ProviderPanel,M as buildProviderCatalog,q as classifyLoginFailure};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ModelRuntime } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import type { ProviderAuthInteraction } from '@earendil-works/pi-ai';
|
|
3
|
+
export declare function openProviderLoginRuntime(): Promise<ModelRuntime>;
|
|
4
|
+
export declare function loginProvider(runtime: ModelRuntime, providerId: string, interaction: ProviderAuthInteraction, options?: {
|
|
5
|
+
label?: string;
|
|
6
|
+
beforeInstall?: () => boolean;
|
|
7
|
+
}): Promise<boolean>;
|
|
8
|
+
export declare function terminalAuthInteraction(): ProviderAuthInteraction;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
var y=Object.defineProperty;var o=(e,r)=>y(e,"name",{value:r,configurable:!0});import{execFile as b}from"node:child_process";import{createInterface as x}from"node:readline/promises";import{join as u}from"node:path";import{ModelRuntime as $}from"@earendil-works/pi-coding-agent";import{cliClient as d}from"../api-client.js";import{InputError as f}from"../../core/io.js";import{PoolCredentialStore as k}from"../../core/pool-credential-store.js";import{isManagedProvider as m,readSubscriptionPool as C}from"../../core/subscription-state.js";import{piAgentDir as P}from"../../core/runtime/package-health.js";async function U(){const e=P();return $.create({credentials:new k(u(e,"auth.json")),modelsPath:u(e,"models.json")})}o(U,"openProviderLoginRuntime");async function Y(e,r,i,t={}){const c=e.getProvider(r)?.auth.oauth;if(c===void 0)throw new f({error:"provider_login_unavailable",message:`provider ${r} has no OAuth login flow`,next:"Configure an API key through `crtr sys setup`, then run `crtr sys connect` again."});const g=m(r)?Math.max(0,...C(r).map(a=>a.lastRateLimitedAt)):void 0,n=await c.login(i);if(t.beforeInstall?.()===!1)return!1;if(m(r)){const a=typeof n.accountId=="string"&&n.accountId.trim()?n.accountId.trim():void 0;return await d().installCredential(r,{kind:"managed_account",...t.label?{label:t.label}:{auto_label:!0},...a?{account_id:a}:{},access_token:n.access,refresh_token:n.refresh,expires_at:new Date(n.expires).toISOString(),last_rate_limited_at:g}),!0}const{type:I,access:h,refresh:w,expires:_,...l}=n;return await d().installCredential(r,{kind:"oauth",access_token:h,refresh_token:w,expires_at:new Date(_).toISOString(),...Object.keys(l).length>0?{extra:l}:{}}),!0}o(Y,"loginProvider");function p(e){const r=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",i=process.platform==="win32"?["/c","start","",e]:[e];b(r,i,{timeout:5e3},()=>{})}o(p,"openBrowser");function A(e){switch(e.type){case"auth_url":process.stderr.write(`${e.instructions}
|
|
2
|
+
${e.url}
|
|
3
|
+
`),p(e.url);break;case"device_code":process.stderr.write(`${e.verificationUri}
|
|
4
|
+
Code: ${e.userCode}
|
|
5
|
+
`),p(e.verificationUri);break;case"info":case"progress":process.stderr.write(`${e.message}
|
|
6
|
+
`);break}}o(A,"notify");async function S(e){if(!process.stdin.isTTY||!process.stderr.isTTY)throw new f({error:"interactive_login_required",message:"provider login requires an interactive terminal",next:"Run `crtr sys connect` from an interactive terminal, or configure the provider credential through `crtr sys setup` first."});const r=e.type==="select"?`${e.message}
|
|
7
|
+
${e.options.map((t,s)=>`${s+1}. ${t.label}`).join(`
|
|
8
|
+
`)}
|
|
9
|
+
Select: `:`${e.message}${e.placeholder?` (${e.placeholder})`:""}: `,i=x({input:process.stdin,output:process.stderr});try{const t=await i.question(r,{signal:e.signal});if(e.type!=="select")return t;const s=e.options[Number.parseInt(t,10)-1]?.id;if(s===void 0)throw new Error("Login cancelled");return s}finally{i.close()}}o(S,"promptTerminal");function B(){return{signal:new AbortController().signal,notify:A,prompt:S}}o(B,"terminalAuthInteraction");export{Y as loginProvider,U as openProviderLoginRuntime,B as terminalAuthInteraction};
|
|
@@ -102,4 +102,8 @@ export declare function renderSetupStaticInstructions(state: SetupInitialState):
|
|
|
102
102
|
/** Refresh crouter-owned tmux bindings. Setup must never fail because tmux is unavailable. */
|
|
103
103
|
export declare function reconcileInboxFrontDoor(): Promise<void>;
|
|
104
104
|
export declare function formatSetupExecutionSummary(summary: SetupExecutionSummary): string;
|
|
105
|
+
/** The non-interactive first command reconciles only crouter-owned packages.
|
|
106
|
+
* Individual failures are reported by the CLI but never prevent later work or
|
|
107
|
+
* writing the once-per-machine marker. */
|
|
108
|
+
export declare function reconcileFirstRun(onFailure: (item: string, error: unknown) => void): Promise<string>;
|
|
105
109
|
export declare function executeSetupSubmission(submission: SetupSubmission): Promise<SetupExecutionSummary>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var T=Object.defineProperty;var s=(e,t)=>T(e,"name",{value:t,configurable:!0});import{spawnSync as g}from"node:child_process";import{homedir as m}from"node:os";import{basename as N,dirname as _,join as v,resolve as L}from"node:path";import{isDeepStrictEqual as f}from"node:util";import{BINDING_CATALOG as j,normalizeGesture as M,splitGestureExpression as K,inboxShortcut as F,resolveKeybindings as k}from"../../core/keybindings/index.js";import{builtinPiPackageDir as b}from"../../core/scope.js";import{readJsonIfExists as G}from"../../core/fs-utils.js";import{resolveBundledPiCliPath as B}from"../../core/runtime/pi-cli.js";import{installTmuxBindings as U}from"../../core/runtime/tmux-chrome.js";import{normalizeTmuxPassthrough as z}from"../../core/config.js";import{detectNerdFont as Y,nerdFontInstallCommand as q,NERD_FONT_SELECT_HINT as H}from"../../core/runtime/nerd-font.js";import{ensureRenderer as W,isRendererReady as w}from"../../core/termrender/termrender.js";import{installFromMarketplace as V}from"../pkg/plugin-manage.js";import{addMarketplace as S}from"../pkg/market-manage.js";import{findPluginByName as J,findMarketplaceByName as A}from"../../core/resolver.js";import{expandTilde as X}from"../../core/fs-utils.js";const C="crouter-official-marketplace",R="https://github.com/crouton-labs/crouter-official-marketplace.git",$="main";function E(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}s(E,"isKeybindingsObject");function h(e){return E(e)?Object.fromEntries(Object.entries(e).map(([t,n])=>[t,Array.isArray(n)?[...n]:n])):{}}s(h,"cloneKeybindings");class Ee{static{s(this,"SetupKeybindingsDraft")}expected;baseline;current;baselineInvalidRoot;invalidRoot;resolutionCache;expectedPassthrough;baselinePassthrough;currentPassthrough;constructor(t,n=void 0){this.expected=t,this.baseline=h(t),this.current=h(t),this.baselineInvalidRoot=t!==void 0&&!E(t)?t:void 0,this.invalidRoot=this.baselineInvalidRoot,this.expectedPassthrough=n,this.baselinePassthrough=z(n),this.currentPassthrough=[...this.baselinePassthrough]}get dirty(){return!f(this.current,this.baseline)||!f(this.invalidRoot,this.baselineInvalidRoot)||!f(this.currentPassthrough,this.baselinePassthrough)}overrides(){return h(this.current)}expectedKeybindings(){return this.expected}tmuxPassthrough(){return[...this.currentPassthrough]}expectedTmuxPassthrough(){return this.expectedPassthrough}usesTmuxPassthrough(t){return this.currentPassthrough.includes(t)}toggleTmuxPassthrough(t){this.currentPassthrough=this.currentPassthrough.includes(t)?this.currentPassthrough.filter(n=>n!==t):[...this.currentPassthrough,t]}resolution(){return this.resolutionCache===void 0&&(this.resolutionCache=k(this.invalidRoot===void 0?this.current:this.invalidRoot)),this.resolutionCache}hasInvalidRoot(){return this.invalidRoot!==void 0}expression(t){return this.resolution().gestures(t).join(", ")}edit(t,n){if(this.invalidRoot!==void 0)return{ok:!1,diagnostics:[{severity:"error",code:"invalid-keybindings",offendingValue:this.invalidRoot,message:"Reset all before editing: the saved keybindings root is invalid."}]};const i=j.find(u=>u.id===t);let a;try{a=n.trim()===""?[]:K(n).map(u=>M(u.trim(),i))}catch(u){return{ok:!1,diagnostics:[{severity:"error",code:"invalid-override",bindingId:t,offendingValue:n,message:u instanceof Error?u.message:String(u)}]}}const r=[...new Set(a)],c={...this.current};delete c[t];const d=[...k(c).gestures(t)],o=f(r,d)?c:{...this.current,[t]:r},l=k(o),p=l.diagnostics.filter(u=>u.bindingId===t||u.relatedBindingIds?.includes(t));return p.length>0?{ok:!1,diagnostics:p}:(this.current=o,this.resolutionCache=void 0,{ok:!0,diagnostics:l.diagnostics})}unbind(t){return this.edit(t,"")}resetRow(t){delete this.current[t],this.resolutionCache=void 0}resetAll(){this.current={},this.currentPassthrough=[],this.invalidRoot=void 0,this.resolutionCache=void 0}discard(){this.current=h(this.baseline),this.currentPassthrough=[...this.baselinePassthrough],this.invalidRoot=this.baselineInvalidRoot,this.resolutionCache=void 0}markSaved(t,n=[]){this.expected=Object.keys(t).length===0?void 0:h(t),this.baseline=h(t),this.current=h(t),this.expectedPassthrough=n.length===0?void 0:[...n],this.baselinePassthrough=[...n],this.currentPassthrough=[...n],this.baselineInvalidRoot=void 0,this.invalidRoot=void 0,this.resolutionCache=void 0}}const Q={"official-marketplace":{name:C,shortDescription:"the official crtr plugin catalog \u2014 registered as a source so its plugins are installable by ref.",longDescription:"Shallow-clones github.com/crouton-labs/crouter-official-marketplace into the user scope and registers it, which is what makes `crtr pkg plugin install crouter-official-marketplace/<name>` resolve and what fills `crtr pkg market browse`. Registering the source installs no plugin by itself. Uncheck it on a machine that should reach no external catalog \u2014 a plugin selected below still registers the marketplace it comes from, because its ref cannot resolve otherwise."},"crtr-extensions":{name:"pi-crtr-extensions",shortDescription:"crtr companion extensions \u2014 command palette, help gating, subscription/OAuth rotation, nested context.",longDescription:"Bundles the extensions built for crtr: a crtr slash-command palette, crtr/crouter help gating, surfacing of Claude Code marketplace plugin commands, nested AGENTS.md/CLAUDE.md loading, OAuth login + rotation across multiple Claude subscriptions (provider-rotation), and system-prompt trimming. The OAuth/rotation piece is what lets crtr authenticate your Claude account."},"oauth-adapter":{name:"pi-claude-oauth-adapter",shortDescription:"Anthropic OAuth / Claude Code credential compatibility for pi.",longDescription:"Third-party adapter (minzique/dotfiles-agents) letting pi authenticate with Claude using Claude Code OAuth credentials. Installed from npm, pinned to 0.1.2."},"capture-plugin":{name:"capture",shortDescription:"crtr plugin mounting `crtr capture` \u2014 browser automation and UI measurement over CDP.",longDescription:"Installs the `capture` plugin from the official crtr marketplace. It mounts `crtr capture` as a transparent passthrough to the external Capture CLI (`npm install -g @crouton-kit/capture`) for CDP screenshots, rendered-geometry measurement, HAR, accessibility trees, and JS execution against a live page. Uncheck it on a machine where agents never drive a browser \u2014 the command then costs nothing in their root prompt."},"search-plugin":{name:"search",shortDescription:"crtr plugin mounting `crtr search` \u2014 public-web discovery, grounded answers, and content extraction.",longDescription:"Installs the `search` plugin from the official crtr marketplace. It mounts `crtr search` and calls Exa directly, resolving its own API key from EXA_API_KEY or ~/.crouter/exa.key \u2014 crouter never handles that credential. Uncheck it on a machine whose agents get web search from somewhere else, such as a Northlight home where the platform serves `crtr search` from its own plugin."}},P={"official-marketplace":{kind:"marketplace-source",source:R},"crtr-extensions":{kind:"local-path",source:b("pi-crtr-extensions")},"oauth-adapter":{kind:"npm",source:"npm:pi-claude-oauth-adapter@0.1.2"},"capture-plugin":{kind:"marketplace-plugin",source:"crouter-official-marketplace/capture"},"search-plugin":{kind:"marketplace-plugin",source:"crouter-official-marketplace/search"}},Z={"official-marketplace":[],"crtr-extensions":["pi-crtr-extensions"],"oauth-adapter":[],"capture-plugin":[],"search-plugin":[]};function D(e=b){return["official-marketplace","crtr-extensions","oauth-adapter","capture-plugin","search-plugin"].map(t=>{const n=Q[t],i=P[t].kind==="local-path"?e(n.name):P[t].source;return{id:t,name:n.name,sourceKind:P[t].kind,installSource:i,shortDescription:n.shortDescription,longDescription:n.longDescription}})}s(D,"buildSetupManifest");function De(e){switch(e.sourceKind){case"marketplace-source":return`clone + register ${e.installSource}`;case"marketplace-plugin":return`crtr pkg plugin install ${e.installSource}`;default:return`pi install ${e.installSource}`}}s(De,"packagePlanAction");function ee(e){if(!e.startsWith("npm:"))return null;const t=e.slice(4),n=t.startsWith("@")?t.indexOf("@",1):t.lastIndexOf("@");return n>0?t.slice(0,n):t}s(ee,"npmPackageName");function O(e,t,n){const i=ee(e);if(i!==null)return`npm:${i}`;const a=X(e,n);return L(t,a)}s(O,"normalizePackageIdentity");function x(e){return`package:${e}`}s(x,"packageNameIdentity");function te(e){return e.startsWith("npm:")?[]:[x(N(e))]}s(te,"localPackageNameIdentities");function ne(e,t,n){const i=[O(e.installSource,t,n)];if(e.sourceKind==="local-path"){i.push(x(e.name));for(const a of Z[e.id])i.push(x(a))}return i}s(ne,"manifestIdentities");function re(e,t=D(),n=v(m(),".pi","agent","settings.json"),i=m()){const a=_(n),r=new Set,c=new Map;for(const o of t)for(const l of ne(o,a,i))c.set(l,o.id);const d=e&&typeof e=="object"?e.packages:void 0;if(!Array.isArray(d))return r;for(const o of d){const l=typeof o=="string"?o:o&&typeof o=="object"&&typeof o.source=="string"?o.source:null;if(l===null)continue;const p=[O(l,a,i),...te(l)];for(const u of p){const I=c.get(u);I!==void 0&&r.add(I)}}return r}s(re,"detectInstalledSetupPackageIds");function y(e){return g("sh",["-lc",`command -v ${e} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}s(y,"detectCommandOnPath");function ie(e=process.platform,t=y){switch(e){case"darwin":return t("brew")?"brew":"manual";case"linux":return t("apt-get")?"apt-get":t("dnf")?"dnf":t("pacman")?"pacman":"manual";default:return"manual"}}s(ie,"detectPackageManager");function se(e,t,n=y){if(e==="nerd-font"?Y().installed:n(e))return{tool:e,installed:!0,command:null,hint:"already installed",autoInstall:!1};if(e==="nerd-font"){const r=q(t);return{tool:e,installed:!1,command:r.command,hint:`${r.hint} \u2014 ${H}`,autoInstall:r.autoInstall}}const a=e==="nvim"?"neovim":"tmux";switch(t){case"brew":return{tool:e,installed:!1,command:`brew install ${a}`,hint:"Homebrew install",autoInstall:!0};case"apt-get":return{tool:e,installed:!1,command:`sudo apt-get update && sudo apt-get install -y ${a}`,hint:"apt-get install",autoInstall:!0};case"dnf":return{tool:e,installed:!1,command:`sudo dnf install -y ${a}`,hint:"dnf install",autoInstall:!0};case"pacman":return{tool:e,installed:!1,command:`sudo pacman -S --noconfirm ${a}`,hint:"pacman install",autoInstall:!0};default:return{tool:e,installed:!1,command:null,hint:`manual install required for ${e}`,autoInstall:!1}}}s(se,"buildSystemInstallPlan");function ae(e=m()){return v(e,".pi","agent","settings.json")}s(ae,"resolveSettingsPath");function Oe(e={}){const t=e.homeDir??m(),n=e.settingsPath??ae(t),i=e.manifest??D(b),a=G(n),r=re(a,i,n,t);for(const l of de(i))r.add(l);const c=e.commandExists??y,d=e.packageManager??ie(process.platform,c),o=["tmux","nvim","nerd-font"].map(l=>se(l,d,c));return{manifest:i,installedPackageIds:r,systemPlans:o}}s(Oe,"buildSetupInitialState");function Te(e){const t=e.manifest.map(i=>{const a=e.installedPackageIds.has(i.id)?"installed":"not installed";return`- ${i.name} \u2014 ${i.shortDescription} (${a})`}),n=e.systemPlans.map(i=>i.installed?`- ${i.tool}: \u2713 installed`:i.command?`- ${i.tool}: ${i.command}`:`- ${i.tool}: ${i.hint}`);return["crtr sys setup (non-interactive)","","Provider login: open the wizard in a TTY and use the Providers tab (same flow as /login) to authenticate a model provider.","","Packages:",...t,"","System deps:",...n,"",`Inbox: the inbox-toggle key (${F()??"disabled"}) is a crouter keybinding \u2014 view or rebind it in \`crtr sys settings\`; it is installed on the same tmux server as every other crouter binding.`,"Run `crtr sys setup` in a TTY to open the wizard."].join(`
|
|
1
|
+
var M=Object.defineProperty;var a=(e,t)=>M(e,"name",{value:t,configurable:!0});import{spawnSync as k}from"node:child_process";import{homedir as m}from"node:os";import{basename as j,dirname as F,join as w,resolve as G}from"node:path";import{isDeepStrictEqual as f}from"node:util";import{BINDING_CATALOG as B,normalizeGesture as U,splitGestureExpression as z,inboxShortcut as Y,resolveKeybindings as b}from"../../core/keybindings/index.js";import{builtinPiPackageDir as g}from"../../core/scope.js";import{readJsonIfExists as q,readJsonOrNull as H}from"../../core/fs-utils.js";import{resolveBundledPiCliPath as V}from"../../core/runtime/pi-cli.js";import{crtrVersion as W}from"../../shared/crtr-version.js";import{installTmuxBindings as J}from"../../core/runtime/tmux-chrome.js";import{normalizeTmuxPassthrough as X}from"../../core/config.js";import{detectNerdFont as Q,nerdFontInstallCommand as Z,NERD_FONT_SELECT_HINT as ee}from"../../core/runtime/nerd-font.js";import{ensureRenderer as te,isRendererReady as S}from"../../core/termrender/termrender.js";import{installFromMarketplace as ne}from"../pkg/plugin-manage.js";import{addMarketplace as A}from"../pkg/market-manage.js";import{findPluginByName as re,findMarketplaceByName as C}from"../../core/resolver.js";import{expandTilde as ie}from"../../core/fs-utils.js";const R="crouter-official-marketplace",E="https://github.com/crouton-labs/crouter-official-marketplace.git",$="main";function D(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}a(D,"isKeybindingsObject");function d(e){return D(e)?Object.fromEntries(Object.entries(e).map(([t,n])=>[t,Array.isArray(n)?[...n]:n])):{}}a(d,"cloneKeybindings");class Ne{static{a(this,"SetupKeybindingsDraft")}expected;baseline;current;baselineInvalidRoot;invalidRoot;resolutionCache;expectedPassthrough;baselinePassthrough;currentPassthrough;constructor(t,n=void 0){this.expected=t,this.baseline=d(t),this.current=d(t),this.baselineInvalidRoot=t!==void 0&&!D(t)?t:void 0,this.invalidRoot=this.baselineInvalidRoot,this.expectedPassthrough=n,this.baselinePassthrough=X(n),this.currentPassthrough=[...this.baselinePassthrough]}get dirty(){return!f(this.current,this.baseline)||!f(this.invalidRoot,this.baselineInvalidRoot)||!f(this.currentPassthrough,this.baselinePassthrough)}overrides(){return d(this.current)}expectedKeybindings(){return this.expected}tmuxPassthrough(){return[...this.currentPassthrough]}expectedTmuxPassthrough(){return this.expectedPassthrough}usesTmuxPassthrough(t){return this.currentPassthrough.includes(t)}toggleTmuxPassthrough(t){this.currentPassthrough=this.currentPassthrough.includes(t)?this.currentPassthrough.filter(n=>n!==t):[...this.currentPassthrough,t]}resolution(){return this.resolutionCache===void 0&&(this.resolutionCache=b(this.invalidRoot===void 0?this.current:this.invalidRoot)),this.resolutionCache}hasInvalidRoot(){return this.invalidRoot!==void 0}expression(t){return this.resolution().gestures(t).join(", ")}edit(t,n){if(this.invalidRoot!==void 0)return{ok:!1,diagnostics:[{severity:"error",code:"invalid-keybindings",offendingValue:this.invalidRoot,message:"Reset all before editing: the saved keybindings root is invalid."}]};const r=B.find(u=>u.id===t);let i;try{i=n.trim()===""?[]:z(n).map(u=>U(u.trim(),r))}catch(u){return{ok:!1,diagnostics:[{severity:"error",code:"invalid-override",bindingId:t,offendingValue:n,message:u instanceof Error?u.message:String(u)}]}}const s=[...new Set(i)],o={...this.current};delete o[t];const p=[...b(o).gestures(t)],c=f(s,p)?o:{...this.current,[t]:s},l=b(c),h=l.diagnostics.filter(u=>u.bindingId===t||u.relatedBindingIds?.includes(t));return h.length>0?{ok:!1,diagnostics:h}:(this.current=c,this.resolutionCache=void 0,{ok:!0,diagnostics:l.diagnostics})}unbind(t){return this.edit(t,"")}resetRow(t){delete this.current[t],this.resolutionCache=void 0}resetAll(){this.current={},this.currentPassthrough=[],this.invalidRoot=void 0,this.resolutionCache=void 0}discard(){this.current=d(this.baseline),this.currentPassthrough=[...this.baselinePassthrough],this.invalidRoot=this.baselineInvalidRoot,this.resolutionCache=void 0}markSaved(t,n=[]){this.expected=Object.keys(t).length===0?void 0:d(t),this.baseline=d(t),this.current=d(t),this.expectedPassthrough=n.length===0?void 0:[...n],this.baselinePassthrough=[...n],this.currentPassthrough=[...n],this.baselineInvalidRoot=void 0,this.invalidRoot=void 0,this.resolutionCache=void 0}}const se={"official-marketplace":{name:R,shortDescription:"the official crtr plugin catalog \u2014 registered as a source so its plugins are installable by ref.",longDescription:"Shallow-clones github.com/crouton-labs/crouter-official-marketplace into the user scope and registers it, which is what makes `crtr pkg plugin install crouter-official-marketplace/<name>` resolve and what fills `crtr pkg market browse`. Registering the source installs no plugin by itself. Uncheck it on a machine that should reach no external catalog \u2014 a plugin selected below still registers the marketplace it comes from, because its ref cannot resolve otherwise."},"crtr-extensions":{name:"pi-crtr-extensions",shortDescription:"crtr companion extensions \u2014 command palette, help gating, subscription/OAuth rotation, nested context.",longDescription:"Bundles the extensions built for crtr: a crtr slash-command palette, crtr/crouter help gating, surfacing of Claude Code marketplace plugin commands, nested AGENTS.md/CLAUDE.md loading, OAuth login + rotation across multiple Claude subscriptions (provider-rotation), and system-prompt trimming. The OAuth/rotation piece is what lets crtr authenticate your Claude account."},"oauth-adapter":{name:"pi-claude-oauth-adapter",shortDescription:"Anthropic OAuth / Claude Code credential compatibility for pi.",longDescription:"Third-party adapter (minzique/dotfiles-agents) letting pi authenticate with Claude using Claude Code OAuth credentials. Installed from npm, pinned to 0.1.2."},"capture-plugin":{name:"capture",shortDescription:"crtr plugin mounting `crtr capture` \u2014 browser automation and UI measurement over CDP.",longDescription:"Installs the `capture` plugin from the official crtr marketplace. It mounts `crtr capture` as a transparent passthrough to the external Capture CLI (`npm install -g @crouton-kit/capture`) for CDP screenshots, rendered-geometry measurement, HAR, accessibility trees, and JS execution against a live page. Uncheck it on a machine where agents never drive a browser \u2014 the command then costs nothing in their root prompt."},"search-plugin":{name:"search",shortDescription:"crtr plugin mounting `crtr search` \u2014 public-web discovery, grounded answers, and content extraction.",longDescription:"Installs the `search` plugin from the official crtr marketplace. It mounts `crtr search` and calls Exa directly, resolving its own API key from EXA_API_KEY or ~/.crouter/exa.key \u2014 crouter never handles that credential. Uncheck it on a machine whose agents get web search from somewhere else, such as a Northlight home where the platform serves `crtr search` from its own plugin."}},P={"official-marketplace":{kind:"marketplace-source",source:E},"crtr-extensions":{kind:"local-path",source:g("pi-crtr-extensions")},"oauth-adapter":{kind:"npm",source:"npm:pi-claude-oauth-adapter@0.1.2"},"capture-plugin":{kind:"marketplace-plugin",source:"crouter-official-marketplace/capture"},"search-plugin":{kind:"marketplace-plugin",source:"crouter-official-marketplace/search"}},ae={"official-marketplace":[],"crtr-extensions":["pi-crtr-extensions"],"oauth-adapter":[],"capture-plugin":[],"search-plugin":[]};function x(e=g){return["official-marketplace","crtr-extensions","oauth-adapter","capture-plugin","search-plugin"].map(t=>{const n=se[t],r=P[t].kind==="local-path"?e(n.name):P[t].source;return{id:t,name:n.name,sourceKind:P[t].kind,installSource:r,shortDescription:n.shortDescription,longDescription:n.longDescription}})}a(x,"buildSetupManifest");function _e(e){switch(e.sourceKind){case"marketplace-source":return`clone + register ${e.installSource}`;case"marketplace-plugin":return`crtr pkg plugin install ${e.installSource}`;default:return`pi install ${e.installSource}`}}a(_e,"packagePlanAction");function oe(e){if(!e.startsWith("npm:"))return null;const t=e.slice(4),n=t.startsWith("@")?t.indexOf("@",1):t.lastIndexOf("@");return n>0?t.slice(0,n):t}a(oe,"npmPackageName");function O(e,t,n){const r=oe(e);if(r!==null)return`npm:${r}`;const i=ie(e,n);return G(t,i)}a(O,"normalizePackageIdentity");function v(e){return`package:${e}`}a(v,"packageNameIdentity");function ce(e){return e.startsWith("npm:")?[]:[v(j(e))]}a(ce,"localPackageNameIdentities");function le(e,t,n){const r=[O(e.installSource,t,n)];if(e.sourceKind==="local-path"){r.push(v(e.name));for(const i of ae[e.id])r.push(v(i))}return r}a(le,"manifestIdentities");function T(e,t=x(),n=w(m(),".pi","agent","settings.json"),r=m()){const i=F(n),s=new Set,o=new Map;for(const c of t)for(const l of le(c,i,r))o.set(l,c.id);const p=e&&typeof e=="object"?e.packages:void 0;if(!Array.isArray(p))return s;for(const c of p){const l=typeof c=="string"?c:c&&typeof c=="object"&&typeof c.source=="string"?c.source:null;if(l===null)continue;const h=[O(l,i,r),...ce(l)];for(const u of h){const y=o.get(u);y!==void 0&&s.add(y)}}return s}a(T,"detectInstalledSetupPackageIds");function I(e){return k("sh",["-lc",`command -v ${e} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}a(I,"detectCommandOnPath");function ue(e=process.platform,t=I){switch(e){case"darwin":return t("brew")?"brew":"manual";case"linux":return t("apt-get")?"apt-get":t("dnf")?"dnf":t("pacman")?"pacman":"manual";default:return"manual"}}a(ue,"detectPackageManager");function de(e,t,n=I){if(e==="nerd-font"?Q().installed:n(e))return{tool:e,installed:!0,command:null,hint:"already installed",autoInstall:!1};if(e==="nerd-font"){const s=Z(t);return{tool:e,installed:!1,command:s.command,hint:`${s.hint} \u2014 ${ee}`,autoInstall:s.autoInstall}}const i=e==="nvim"?"neovim":"tmux";switch(t){case"brew":return{tool:e,installed:!1,command:`brew install ${i}`,hint:"Homebrew install",autoInstall:!0};case"apt-get":return{tool:e,installed:!1,command:`sudo apt-get update && sudo apt-get install -y ${i}`,hint:"apt-get install",autoInstall:!0};case"dnf":return{tool:e,installed:!1,command:`sudo dnf install -y ${i}`,hint:"dnf install",autoInstall:!0};case"pacman":return{tool:e,installed:!1,command:`sudo pacman -S --noconfirm ${i}`,hint:"pacman install",autoInstall:!0};default:return{tool:e,installed:!1,command:null,hint:`manual install required for ${e}`,autoInstall:!1}}}a(de,"buildSystemInstallPlan");function N(e=m()){return w(e,".pi","agent","settings.json")}a(N,"resolveSettingsPath");function Ke(e={}){const t=e.homeDir??m(),n=e.settingsPath??N(t),r=e.manifest??x(g),i=q(n),s=T(i,r,n,t);for(const l of K(r))s.add(l);const o=e.commandExists??I,p=e.packageManager??ue(process.platform,o),c=["tmux","nvim","nerd-font"].map(l=>de(l,p,o));return{manifest:r,installedPackageIds:s,systemPlans:c}}a(Ke,"buildSetupInitialState");function Le(e){const t=e.manifest.map(r=>{const i=e.installedPackageIds.has(r.id)?"installed":"not installed";return`- ${r.name} \u2014 ${r.shortDescription} (${i})`}),n=e.systemPlans.map(r=>r.installed?`- ${r.tool}: \u2713 installed`:r.command?`- ${r.tool}: ${r.command}`:`- ${r.tool}: ${r.hint}`);return["crtr sys setup (non-interactive)","","Provider login: open the wizard in a TTY and use the Providers tab (same flow as /login) to authenticate a model provider.","","Packages:",...t,"","System deps:",...n,"",`Inbox: the inbox-toggle key (${Y()??"disabled"}) is a crouter keybinding \u2014 view or rebind it in \`crtr sys settings\`; it is installed on the same tmux server as every other crouter binding.`,"Run `crtr sys setup` in a TTY to open the wizard."].join(`
|
|
2
2
|
`)+`
|
|
3
|
-
`}
|
|
4
|
-
`),W(),w()?"provisioned":"unavailable")}s(le,"ensureManagedRenderer");async function ue(){try{U()}catch{}}s(ue,"reconcileInboxFrontDoor");function Ne(e){return["crtr sys setup complete",e.installed.length>0?`installed: ${e.installed.join(", ")}`:"installed: none",e.skipped.length>0?`skipped: ${e.skipped.join(", ")}`:"skipped: none"].join(`
|
|
3
|
+
`}a(Le,"renderSetupStaticInstructions");function pe(e){if(k("sh",["-lc",e],{stdio:"inherit"}).status!==0)throw new Error(`command failed: ${e}`)}a(pe,"runShellCommand");function he(e,t=!1,n=V()){if(k(process.execPath,[n,"install",e],{stdio:t?"pipe":"inherit"}).status!==0)throw new Error(`pi install failed: ${e}`)}a(he,"installPiPackage");function _(e,t){return S()?"current":(e?.(),te(t),S()?"provisioned":"unavailable")}a(_,"ensureManagedRenderer");async function me(){try{J()}catch{}}a(me,"reconcileInboxFrontDoor");function Me(e){return["crtr sys setup complete",e.installed.length>0?`installed: ${e.installed.join(", ")}`:"installed: none",e.skipped.length>0?`skipped: ${e.skipped.join(", ")}`:"skipped: none"].join(`
|
|
5
4
|
`)+`
|
|
6
|
-
`}
|
|
5
|
+
`}a(Me,"formatSetupExecutionSummary");function K(e,t){const n=[];for(const r of e)try{r.sourceKind==="marketplace-source"?C(r.name,t)!==null&&n.push(r.id):r.sourceKind==="marketplace-plugin"&&re(r.name,t)!==null&&n.push(r.id)}catch{}return n}a(K,"detectInstalledMarketplaceEntries");function fe(e,t="user"){if(C(e,t)!==null)return null;if(e!==R)throw new Error(`marketplace not registered: ${e}`);return A({url:E,ref:$,scope:t}),e}a(fe,"ensureMarketplaceRegistered");async function L(e,t=!1){if(e.sourceKind==="marketplace-source")return A({url:e.installSource,ref:$,scope:"user"}),[e.name];if(e.sourceKind==="marketplace-plugin"){const[n,r]=e.installSource.split("/"),i=fe(n);return await ne({marketplace:n,plugin:r},"user"),i===null?[e.name]:[i,e.name]}return he(e.installSource,t),[e.name]}a(L,"installSetupPackage");async function je(e){const t=x(g),n=T(H(N()),t);for(const i of K(t,"user"))n.add(i);const r=new Map(t.map(i=>[i.id,i]));for(const i of["crtr-extensions","official-marketplace","capture-plugin","search-plugin"]){const s=r.get(i);if(!n.has(i))try{await L(s,!0)}catch(o){e(s.name,o)}}try{_(void 0,()=>{})==="unavailable"&&e("termrender renderer",new Error("unavailable \u2014 install uv"))}catch(i){e("termrender renderer",i)}return W()}a(je,"reconcileFirstRun");async function Fe(e){const t=[],n=[],r=[],i=[];for(const s of e.packages){if(e.installedPackageIds.has(s.id)){n.push(`${s.name} (already installed)`);continue}try{t.push(...await L(s))}catch(o){if(s.sourceKind!=="marketplace-source"&&s.sourceKind!=="marketplace-plugin")throw o;n.push(`${s.name} (${o instanceof Error?o.message:String(o)})`)}}for(const s of e.systemDeps){if(s.installed){i.push(`${s.tool} (already installed)`);continue}if(!s.autoInstall||!s.command){i.push(`${s.tool} (${s.hint})`);continue}pe(s.command),r.push(s.tool)}switch(_(()=>process.stdout.write(`Provisioning the pinned termrender renderer\u2026
|
|
6
|
+
`))){case"provisioned":t.push("termrender renderer");break;case"current":n.push("termrender renderer (current)");break;case"unavailable":n.push("termrender renderer (unavailable \u2014 install uv)");break}return await me(),{installed:[...t,...r],skipped:[...n,...i]}}a(Fe,"executeSetupSubmission");export{R as OFFICIAL_MARKETPLACE_NAME,$ as OFFICIAL_MARKETPLACE_REF,E as OFFICIAL_MARKETPLACE_URL,Ne as SetupKeybindingsDraft,Ke as buildSetupInitialState,x as buildSetupManifest,de as buildSystemInstallPlan,I as detectCommandOnPath,T as detectInstalledSetupPackageIds,ue as detectPackageManager,Fe as executeSetupSubmission,Me as formatSetupExecutionSummary,O as normalizePackageIdentity,_e as packagePlanAction,je as reconcileFirstRun,me as reconcileInboxFrontDoor,Le as renderSetupStaticInstructions,N as resolveSettingsPath};
|
package/dist/commands/sys.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var s=Object.defineProperty;var r=(o,m)=>s(o,"name",{value:m,configurable:!0});import{defineSysBranch as t}from"./sys/branch.js";import{configBranch as e}from"./sys/config.js";import{daemonBranch as f}from"./sys/daemon.js";import{sysDoctorLeaf as i}from"./sys/doctor.js";import{sysFeedbackLeaf as a}from"./sys/feedback.js";import{sysLogsLeaf as p}from"./sys/logs.js";import{sysWorktreesLeaf as n}from"./sys/worktrees.js";import{sysSettingsLeaf as y}from"./sys/settings.js";import{
|
|
1
|
+
var s=Object.defineProperty;var r=(o,m)=>s(o,"name",{value:m,configurable:!0});import{defineSysBranch as t}from"./sys/branch.js";import{configBranch as e}from"./sys/config.js";import{daemonBranch as f}from"./sys/daemon.js";import{sysDoctorLeaf as i}from"./sys/doctor.js";import{sysFeedbackLeaf as a}from"./sys/feedback.js";import{sysLogsLeaf as p}from"./sys/logs.js";import{sysWorktreesLeaf as n}from"./sys/worktrees.js";import{sysSettingsLeaf as y}from"./sys/settings.js";import{sysConnectLeaf as c}from"./sys/connect.js";import{sysSetupLeaf as L}from"./sys/setup.js";import{supportBranch as h}from"./sys/support.js";import{contextBranch as B}from"./sys/context.js";import{sysSyncBranch as g}from"./sys/sync.js";import{sysMigrateLeaf as S}from"./sys/migrate.js";import{sysUpdateLeaf as d,sysVersionLeaf as u}from"./sys/update.js";function A(){return t([y,e,c,L,i,B,a,p,n,h,d,u,S,g,f])}r(A,"registerSys");export{A as registerSys};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var Se=Object.defineProperty;var c=(a,
|
|
2
|
-
`);return}let y,
|
|
3
|
-
`)},"logAsyncFailure"),re=c(r=>{try{
|
|
1
|
+
var Se=Object.defineProperty;var c=(a,l)=>Se(a,"name",{value:l,configurable:!0});import{envNodeId as Y}from"../../../shared/env.js";import{execFileSync as S}from"node:child_process";import{resolve as xe}from"node:path";import{dashboardRowsAllFromSource as Oe,enrichRowsFromSource as D,loadPreviewFromSource as G,loadTranscriptFromSource as Ie,renderForestFromSource as Ce}from"../render-source.js";import{fullName as Te}from"../labels.js";import{setupTerminal as Re,restoreTerminal as Be,getTerminalSize as Ne,parseKeypress as Pe}from"../../tui/terminal.js";import{buildTree as qe,flatten as Me,pruneNode as ke,TABS as x}from"./model.js";import{loadPins as Fe,savePins as Ae}from"./pins.js";import{matchesTerminalInput as Q,resolveUserKeybindings as _e}from"../../keybindings/index.js";const Ke=["crtr.browse.quit","crtr.browse.down","crtr.browse.up","crtr.browse.first","crtr.browse.last","crtr.browse.expand-or-child","crtr.browse.collapse-or-parent","crtr.browse.toggle-fold","crtr.browse.tab-next","crtr.browse.tab-previous","crtr.browse.tab.1","crtr.browse.tab.2","crtr.browse.tab.3","crtr.browse.tab.4","crtr.browse.tab.5","crtr.browse.close-subtree","crtr.browse.sort","crtr.browse.scope","crtr.browse.profile","crtr.browse.residents","crtr.browse.preview","crtr.browse.report","crtr.browse.pin","crtr.browse.search","crtr.browse.revive-now","crtr.browse.focus","crtr.browse.focus-background","crtr.browse.yank-id"],Ee=["crtr.browse.search.cancel","crtr.browse.search.commit","crtr.browse.search.delete","crtr.browse.search.quit"];function J(a,l,h){return l.find(y=>Q(a,y,h))??null}c(J,"firstMatching");function He(a,l){return J(a,Ke,l)}c(He,"resolveBrowseNavAction");function We(a,l){return J(a,Ee,l)}c(We,"resolveBrowseSearchAction");const _=["attention","tree","relevance","recency"];import{renderFrame as $e,detectColorCaps as ze,headerHeight as Le,previewLayout as X,PREVIEW_HEIGHT as je}from"./render.js";import{writeClipboardTextEverywhere as Ue}from"../../clipboard-text.js";function Ve(a,l,h){const y=Math.max(8,a.rows),v=X(a.cols,h).mode==="bottom"?je:0;return Math.max(1,y-Le(l)-1-v)}c(Ve,"viewportHeight");async function ir(a){const l=a.source,h=_e();if(!process.stdin.isTTY){process.stdout.write(await Ce(l)+`
|
|
2
|
+
`);return}let y,v,N,K,u,E,P={};await c(async()=>{let r=new Set;if(a.viewedNodeIds!==void 0)try{r=await a.viewedNodeIds()}catch{}v=await l.listNodes(),y=(await Oe(l,r,!1,v)).filter(n=>n.kind!=="human"),N=v.filter(n=>n.parent===null&&n.kind!=="human").map(n=>n.node_id);const s=new Map;await Promise.all(v.map(async n=>{s.set(n.node_id,(await l.subscriptionsOf(n.node_id).catch(()=>[])).map(o=>o.node_id))})),K=s,u=qe(y,N,n=>K.get(n)??[]),E=u.nodes.size,P=await Promise.all(N.map(async n=>[n,...await l.view(n)])).then(n=>l.ticketCountsForNodes([...new Set(n.flat())])).catch(()=>({}))},"rebuildSnapshot")();const Z=a.cwd!==void 0&&a.cwd.trim()!==""?xe(a.cwd):null,q=a.profileId,e={tab:"Live",cursor:0,collapsed:new Set([...u.nodes.entries()].filter(([,r])=>r.childIds.length>0).map(([r])=>r)),query:"",search:!1,scrollOffset:0,cwdScope:null,profileScope:q,sort:"attention",preview:!0,showReport:!1,residentsOnly:!0,pendingClose:null,flash:null,pinned:Fe(),help:!1,rename:!1,renameBuf:"",renameTarget:null,message:!1,messageBuf:"",messageTarget:null};let w=[];const R=c(r=>u.nodes.get(r)?.row,"rowOf"),ee=ze();let O=!1;const I=c(()=>{if(!O){O=!0;try{Be()}catch{}}},"cleanup");process.once("exit",I);const H=c((r,s)=>{process.stderr.write(`[crtr browse] ${r}: ${String(s?.message??s)}
|
|
3
|
+
`)},"logAsyncFailure"),re=c(r=>{try{S("crtr",["node","lifecycle","revive",r,"--now"],{stdio:"ignore"})}catch{}},"reviveNow"),te=c(r=>{I();const s=a.returnPane!==void 0&&a.returnPane!==""?a.returnPane:void 0;try{s!==void 0?S("tmux",["run-shell","-b",`crtr surface node focus ${r} --pane ${s} --in-place >/dev/null 2>&1`],{stdio:"ignore"}):S("crtr",["surface","node","focus",r],{stdio:"inherit"})}catch{}process.exit(0)},"selectAndFocus"),se=c(r=>{const s=["surface","node","focus",r,...a.returnPane!==void 0&&a.returnPane!==""?["--pane",a.returnPane]:[]];try{S("crtr",s,{stdio:"ignore"})}catch{}},"selectAndFocusKeepOpen"),f=c(r=>{if(w=Me(u,{collapsed:e.collapsed,tab:e.tab,query:e.query,cwdScope:e.cwdScope,profileScope:e.profileScope,residentsOnly:e.residentsOnly,sort:e.sort,pinned:e.pinned}),r!==void 0){const s=w.findIndex(n=>n.id===r);s>=0&&(e.cursor=s)}e.cursor>w.length-1&&(e.cursor=Math.max(0,w.length-1)),e.cursor<0&&(e.cursor=0)},"recompute"),W=c(async()=>{const r=Ne(),s=e.preview&&w.length>0,n=e.search||e.rename||e.message,o=Ve(r,n,s);e.cursor<e.scrollOffset&&(e.scrollOffset=e.cursor),e.cursor>=e.scrollOffset+o&&(e.scrollOffset=e.cursor-o+1),e.scrollOffset<0&&(e.scrollOffset=0);const t=e.scrollOffset,d=Math.min(w.length,t+o),p=[];for(let g=t;g<d;g++){const V=R(w[g].id);V!==void 0&&p.push(V)}const b=m()?.id,A=c(()=>m()?.id!==b,"stale");if(await D(l,p,P),A())return;if(b!==void 0){const g=R(b);if(g!==void 0&&(await G(l,g),A()||(X(r.cols,s).mode==="side"&&await Ie(l,g),A())))return}const ve=$e({tree:u,visible:w,tab:e.tab,cursor:e.cursor,scrollOffset:e.scrollOffset,query:e.query,search:e.search,totalNodes:E,cwdScope:e.cwdScope,profileScope:e.profileScope,sort:e.sort,preview:e.preview,showReport:e.showReport,residentsOnly:e.residentsOnly,pendingClose:e.pendingClose,flash:e.flash,pinned:e.pinned,help:e.help,rename:e.rename,renameBuf:e.renameBuf,message:e.message,messageBuf:e.messageBuf,readOnly:!1},r,ee);process.stdout.write(ve)},"flush"),C=c(()=>{I(),process.exit(0)},"quit"),m=c(()=>w[e.cursor],"curRow"),M=c(r=>!e.collapsed.has(r),"isExpanded"),ne=c(r=>{const s=[],n=[r],o=new Set;for(;n.length>0;){const t=n.pop();if(!o.has(t)){o.add(t),s.push(t);for(const d of u.nodes.get(t)?.childIds??[])n.push(d)}}return s},"subtreeIds"),oe=c(r=>ne(r).some(s=>u.nodes.get(s)?.row.streaming===!0),"anyStreaming"),$=c(async r=>{e.pendingClose=null;let s=[];try{s=(await a.closeNode(r)).closed}catch{return}for(const n of s){const o=await l.getNode(n);if(o===null){ke(u,n);continue}const t=u.nodes.get(n);t!==void 0&&(t.row.status=o.status,t.row.streaming=!1,t.row.viewed=!1,t.row.hanging=null,t.row.asks=0)}f()},"doClose"),z=c(r=>{const s=x.indexOf(e.tab);e.tab=x[(s+r+x.length)%x.length],e.cursor=0,e.scrollOffset=0,f()},"cycleTab"),ie=c(()=>{const r=m()?.id,s=_.indexOf(e.sort);e.sort=_[(s+1)%_.length],f(r)},"cycleSort"),ce=c(()=>{const r=m()?.id;e.cwdScope=e.cwdScope===null?Z:null,f(r)},"toggleScope"),ae=c(()=>{if(q===void 0)return;const r=m()?.id;e.profileScope=e.profileScope===void 0?q:void 0,f(r)},"toggleProfile"),le=c(()=>{const r=m()?.id;e.residentsOnly=!e.residentsOnly,f(r)},"toggleResidents");let k=!1,F=!1,B=!1;const i=c(()=>{B=!0,!F&&(F=!0,(async()=>{try{for(;B&&!O;)B=!1,await W()}finally{F=!1,B&&!O&&i()}})().catch(()=>{I(),process.exit(1)}))},"scheduleFlush"),L=c(()=>{k||(k=!0,setImmediate(()=>{k=!1,f(),i()}))},"scheduleSearchRepaint"),de=c((r,s)=>{const n=We(h,{input:r,...s});if(n==="crtr.browse.search.cancel"){e.search=!1,e.query="",e.sort="tree",f(),i();return}if(n==="crtr.browse.search.commit"){e.search=!1,f();const t=w.findIndex(d=>d.matched);t>=0&&(e.cursor=t),i();return}if(n==="crtr.browse.search.delete"){e.query=e.query.slice(0,-1),L();return}if(n==="crtr.browse.search.quit"&&C(),s.ctrl)return;const o=[...r].filter(t=>t>=" ").join("");o.length>0&&(e.query+=o,L())},"onKeySearch"),fe=c(()=>{const r=Y();if(!(r===void 0||r===""||!u.nodes.has(r))){for(let s=u.nodes.get(r)?.parentId??null;s!==null;s=u.nodes.get(s)?.parentId??null)e.collapsed.delete(s);f(r)}},"recenterOnSelf"),ue=c(r=>{e.pinned.has(r)?e.pinned.delete(r):e.pinned.add(r),Ae(e.pinned),f(r)},"togglePin"),we=c(()=>{const r=e.renameTarget,s=e.renameBuf.trim();if(e.rename=!1,r!==null&&s!==""){try{S("crtr",["node","config",r,"--name",s],{stdio:"ignore"})}catch{}const n=u.nodes.get(r);n!==void 0&&(n.row.handle=s,n.row.name=Te({name:s,kind:n.row.kind,description:n.row.description}))}f(e.renameTarget??void 0),i()},"commitRename"),pe=c(()=>{const r=e.messageTarget,s=e.messageBuf.trim();if(e.message=!1,r!==null&&s!=="")try{S("crtr",["node","message","send","--to",r,s],{stdio:"ignore"})}catch{}i()},"commitMessage"),j=c((r,s,n,o,t,d)=>{if(s.escape){d();return}if(s.return){t();return}if(s.backspace){o(n().slice(0,-1)),i();return}if(s.ctrl){r==="c"&&C();return}const p=[...r].filter(b=>b>=" ").join("");p.length>0&&(o(n()+p),i())},"onKeyText"),me=c((r,s)=>j(r,s,()=>e.renameBuf,n=>{e.renameBuf=n},we,()=>{e.rename=!1,i()}),"onKeyRename"),he=c((r,s)=>j(r,s,()=>e.messageBuf,n=>{e.messageBuf=n},pe,()=>{e.message=!1,i()}),"onKeyMessage"),be=c((r,s)=>{if(s.ctrl&&r==="c"){C();return}e.help=!1,i()},"onKeyHelp"),ge=c((r,s)=>{const n={input:r,...s},o=He(h,n);if(e.flash=null,s.ctrl&&o===null)return;if(e.pendingClose!==null&&o==="crtr.browse.quit"&&s.ctrl&&C(),e.pendingClose!==null){if(Q(h,"crtr.browse.confirm-close",n)){const d=e.pendingClose;$(d).then(()=>i()).catch(()=>i());return}e.pendingClose=null,i();return}const t=m();if(o==="crtr.browse.quit"&&C(),o==="crtr.browse.up"){e.cursor=Math.max(0,e.cursor-1),i();return}if(o==="crtr.browse.down"){e.cursor=Math.max(0,Math.min(w.length-1,e.cursor+1)),i();return}if(o==="crtr.browse.first"){e.cursor=0,i();return}if(o==="crtr.browse.last"){e.cursor=Math.max(0,w.length-1),i();return}if(o==="crtr.browse.expand-or-child"){t!==void 0&&t.hasChildren&&(M(t.id)?e.cursor+1<w.length&&w[e.cursor+1].depth>t.depth&&(e.cursor+=1):(e.collapsed.delete(t.id),f(t.id))),i();return}if(o==="crtr.browse.collapse-or-parent"){if(t!==void 0&&t.hasChildren&&M(t.id))e.collapsed.add(t.id),f(t.id);else if(t!==void 0){const d=u.nodes.get(t.id)?.parentId??null;if(d!==null){const p=w.findIndex(b=>b.id===d);p>=0&&(e.cursor=p)}}i();return}if(o==="crtr.browse.toggle-fold"){t!==void 0&&t.hasChildren&&(M(t.id)?e.collapsed.add(t.id):e.collapsed.delete(t.id),f(t.id)),i();return}if(o==="crtr.browse.tab-next"){z(1),i();return}if(o==="crtr.browse.tab-previous"){z(-1),i();return}if(o?.startsWith("crtr.browse.tab.")){const d=Number(o.slice(-1))-1;d<x.length&&(e.tab=x[d],e.cursor=0,e.scrollOffset=0,f()),i();return}if(o==="crtr.browse.close-subtree"){if(t===void 0){i();return}if(oe(t.id)){e.pendingClose=t.id,i();return}$(t.id).then(()=>i()).catch(()=>i());return}if(o==="crtr.browse.sort"){ie(),i();return}if(o==="crtr.browse.scope"){ce(),i();return}if(o==="crtr.browse.profile"){ae(),i();return}if(o==="crtr.browse.residents"){le(),i();return}if(o==="crtr.browse.preview"){e.preview=!e.preview,i();return}if(o==="crtr.browse.report"){e.showReport=!e.showReport,i();return}if(r==="?"){e.help=!0,i();return}if(o==="crtr.browse.pin"){t!==void 0&&ue(t.id),i();return}if(r==="."){fe(),i();return}if(r==="R"){t!==void 0&&(e.rename=!0,e.renameTarget=t.id,e.renameBuf=R(t.id)?.name??""),i();return}if(r==="m"){t!==void 0&&(e.message=!0,e.messageTarget=t.id,e.messageBuf=""),i();return}if(o==="crtr.browse.search"){ye(),e.search=!0,e.query="",e.sort="relevance",e.cursor=0,e.scrollOffset=0,f(),i();return}if(o==="crtr.browse.revive-now"){t!==void 0&&R(t.id)?.hanging!=null&&re(t.id),i();return}if(o==="crtr.browse.yank-id"){if(t!==void 0){const{system:d,tmux:p}=Ue(t.id);e.flash=d||p?`Copied ${t.id}${d?"":" to the tmux buffer"}`:"No clipboard tool available \u2014 nothing copied"}i();return}if(o==="crtr.browse.focus"){t!==void 0&&te(t.id);return}if(o==="crtr.browse.focus-background"){t!==void 0&&se(t.id),i();return}},"onKeyNav");f(),w.length===0&&e.residentsOnly&&(e.residentsOnly=!1,f());const T=Y();if(T!==void 0&&T!==""&&u.nodes.has(T)){for(let r=u.nodes.get(T)?.parentId??null;r!==null;r=u.nodes.get(r)?.parentId??null)e.collapsed.delete(r);f(T)}Re(),await W();let U=!1;const ye=c(()=>{if(U)return;U=!0;const r=[...u.nodes.values()].map(t=>t.row);let s=0;const n=30,o=c(async()=>{if(O)return;const t=Math.min(s+n,r.length),d=r.slice(s,t);await D(l,d,P),await Promise.all(d.map(p=>G(l,p))),s=t,e.search&&e.query!==""&&(f(m()?.id),i()),s<r.length&&setImmediate(()=>{o().catch(p=>H("background warm failed",p))})},"warmChunk");setImmediate(()=>{o().catch(t=>H("background warm failed",t))})},"startWarm");await new Promise(()=>{const r=c(s=>{try{const{input:n,key:o}=Pe(s);e.help?be(n,o):e.search?de(n,o):e.rename?me(n,o):e.message?he(n,o):ge(n,o)}catch{I(),process.exit(1)}},"onData");process.stdin.on("data",r),process.stdout.on("resize",i)})}c(ir,"runBrowse");export{He as resolveBrowseNavAction,We as resolveBrowseSearchAction,ir as runBrowse};
|
|
@@ -88,9 +88,6 @@ export declare function recordRespawnAttempt(nodeId: string, attempt: {
|
|
|
88
88
|
failures: number;
|
|
89
89
|
notBefore: string | null;
|
|
90
90
|
}): void;
|
|
91
|
-
/** Every hydrated node whose durable profile identity equals `profileId`.
|
|
92
|
-
* Unlike `listNodes`, this includes unclaimed warm-pool spares: profile
|
|
93
|
-
* deletion owns every matching row, whether or not it is user-visible. */
|
|
94
91
|
export declare function listNodesByProfile(profileId: string): NodeMeta[];
|
|
95
92
|
/** All rows, optionally filtered by status and terminal execution traces. Unclaimed warm spares are excluded. */
|
|
96
93
|
/** Every node's durable memory-resolution coordinates, including unclaimed warm-pool spares. */
|
|
@@ -100,6 +97,9 @@ export declare function listNodes(filter?: {
|
|
|
100
97
|
withRecordedPid?: boolean;
|
|
101
98
|
withRecordedPidOrFrozen?: boolean;
|
|
102
99
|
}): NodeRow[];
|
|
100
|
+
/** The daemon's complete supervision set. Live rows participate regardless of
|
|
101
|
+
* PID; terminal rows participate only while they retain a PID or freeze mark. */
|
|
102
|
+
export declare function listNodesForSupervision(): NodeRow[];
|
|
103
103
|
/** Identity-only projection of every user-visible row: the broker's report
|
|
104
104
|
* resolver needs only "does this sender exist, and what is it called", and a
|
|
105
105
|
* three-column read stays cheap against a canvas of thousands of rows where a
|
|
@@ -1,26 +1,29 @@
|
|
|
1
|
-
var
|
|
1
|
+
var k=Object.defineProperty;var o=(e,n)=>k(e,"name",{value:n,configurable:!0});import{envNodeId as O}from"../../shared/env.js";import{existsSync as F,realpathSync as H,rmSync as R,statSync as j}from"node:fs";import{join as I,resolve as U}from"node:path";import{openDb as s,withCanvasWrite as p}from"./db.js";import{activateArmedExternalActionDelivery as M,armExternalActionDelivery as P}from"./deliveries.js";import{findNodeBySessionFileSql as C}from"./sessions.js";import{hydrateFault as $}from"./recovery.js";import{hasUnreconciledWorktree as B,openWorktree as z,readWorktree as J,worktreeFromRow as Y}from"./worktrees.js";import{isPidAlive as h,recordedPidLiveness as q}from"./pid.js";import{ensureHome as V,ensureNodeDirs as G,jobDir as K,nodeDir as S}from"./paths.js";function f(e,n){if(e==null)return null;const t=JSON.stringify(e);if(t===void 0)throw new TypeError(`${n} must be JSON-serializable`);return t}o(f,"jsonValue");function y(e,n,t){P(e,{destinationId:t.actionName,adapter:{adapter:"subprocess",argv:t.argv,cwd:t.cwd,config_origin:t.configOrigin,payload:t.payload??null},idempotencyKey:`node-outcome:${n}`})}o(y,"insertArmedOutcomeDelivery");function Q(e,n){n.prepare('INSERT INTO nodes (node_id, name, description, title, icon, cycles, kind, mode, lifecycle, cwd, host_kind, profile_id, parent, spawned_by, creator, fork_from, fork_source_file, created, passive_default, cycle_pending, model_override, persona_ack_json, review_binding_json, launch_config_json, status, intent, waiting_for, final_report, finalized_at, deadline_at, "window", tmux_session, pane) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)').run(e.node_id,e.name,e.description??null,e.title??null,e.icon??null,e.cycles??null,e.kind,e.mode,e.lifecycle,e.cwd,e.host_kind??null,e.profile_id??null,e.parent??null,e.spawned_by??null,e.creator??null,e.fork_from??null,e.fork_source_file??null,e.created,e.passive_default===!0?1:0,e.cycle_pending===!0?1:0,e.model_override??null,f(e.persona_ack,"persona_ack"),f(e.review_binding,"review_binding"),f(e.launch,"launch"),e.status??"active",e.intent??null,e.waiting_for??null,e.final_report??null,e.finalized_at??null,e.deadline_at??null,e.window??null,e.tmux_session??null,e.pane??null)}o(Q,"seedRow");function X(e){if(e.fault_id==null)return null;const n=Object.entries(e).filter(([t])=>t.startsWith("fault_")).map(([t,r])=>[t==="fault_id"?t:t.slice(6),r]);return $(Object.fromEntries(n))}o(X,"faultFrom");function _(e){const n={node_id:e.node_id,name:e.name,description:e.description??void 0,cycles:e.cycles??void 0,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,parent:e.parent??null,created:e.created,intent:e.intent??null,waiting_for:e.waiting_for??null,frozen_at:e.frozen_at??null,respawn_failures:e.respawn_failures??0,respawn_not_before:e.respawn_not_before??null,launched_at:e.launched_at??null,last_settled_at:e.last_settled_at??null,terminal_reason:e.terminal_reason??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,outcome_kind:e.outcome_kind??null,outcome_reason:e.outcome_reason??null,outcome_at:e.outcome_at??null,outcome_revision:e.outcome_revision??0,outcome_detail_json:e.outcome_detail_json??null,deadline_at:e.deadline_at??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,fault:null,streaming:!1},t=n.pi_pid===null?!1:h(n.pi_pid),r=X(e);return n.fault=r?.link==="pi\u2192provider"&&r.retry.by==="daemon"&&r.retry.disposition==="auto"&&!t?null:r,n.streaming=e.turn_open_at!==null&&e.turn_closed_at===null&&t,n}o(_,"rowFrom");function T(e,n=J(e.node_id)){return{..._(e),title:e.title??void 0,icon:e.icon??void 0,spawned_by:e.spawned_by??null,creator:e.creator??null,fork_from:e.fork_from??null,fork_source_file:e.fork_source_file??null,passive_default:e.passive_default===1,cycle_pending:e.cycle_pending===1,model_override:e.model_override??null,persona_ack:e.persona_ack_json==null?void 0:JSON.parse(e.persona_ack_json),review_binding:e.review_binding_json==null?void 0:JSON.parse(e.review_binding_json),launch:e.launch_config_json==null?void 0:JSON.parse(e.launch_config_json),pi_session_id:e.pi_session_id??null,pi_session_file:e.pi_session_file??null,...n===null?{}:{managed_worktree:n}}}o(T,"metaFrom");function Ee(e,n={}){return V(),p(t=>{Q(e,t),e.managed_worktree!==void 0&&e.managed_worktree!==null&&z(e.node_id,e.managed_worktree,t),n.outcomeDelivery!==void 0&&y(t,e.node_id,n.outcomeDelivery)}),G(e.node_id),E(e.node_id)}o(Ee,"createNode");function E(e){const n=s().prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n===void 0?null:T(n)}o(E,"getNode");function me(e){const n=U(e);return F(n)?H(n):n}o(me,"canonicalSessionFile");function we(e){const n=C(e);return n===null?null:E(n)}o(we,"findNodeBySessionFile");function Ne(e){const n=s().prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n?_(n):null}o(Ne,"getRow");function Re(e){const n=s().prepare("SELECT * FROM node_rows WHERE pane = ?").get(e);return n?_(n):null}o(Re,"getRowByPane");function Se(e){return s().prepare(`SELECT * FROM node_rows
|
|
2
2
|
WHERE deadline_at IS NOT NULL AND outcome_at IS NULL
|
|
3
3
|
AND deadline_at <= ? AND status IN ('active','idle') AND kind != 'human'
|
|
4
|
-
ORDER BY deadline_at, created, node_id`).all(e).map(_)}o(
|
|
5
|
-
WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),i=t.prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let d=0;for(const a of r){const u=Date.parse(a.deadline_at);Number.isNaN(u)||(d+=Number(i.run(new Date(u+n).toISOString(),a.node_id,a.deadline_at).changes))}return d})}o(
|
|
4
|
+
ORDER BY deadline_at, created, node_id`).all(e).map(_)}o(Se,"dueNodeDeadlines");function ge(e,n){return Number(s().prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ?").run(n,e).changes)===1}o(ge,"setNodeDeadline");function Oe(e,n){return!Number.isFinite(n)||n<=0?0:p(t=>{const r=t.prepare(`SELECT node_id, deadline_at FROM nodes
|
|
5
|
+
WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),i=t.prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let d=0;for(const a of r){const u=Date.parse(a.deadline_at);Number.isNaN(u)||(d+=Number(i.run(new Date(u+n).toISOString(),a.node_id,a.deadline_at).changes))}return d})}o(Oe,"shiftProfileNodeDeadlines");function Z(e,n){if(e==null)return null;if(typeof e=="string"||typeof e=="number"||typeof e=="bigint"||e instanceof Uint8Array)return e;throw new TypeError(`${n} must be a SQLite scalar`)}o(Z,"sqlInput");function he(e,n){const t=[],r=o((d,a=d)=>{Object.prototype.hasOwnProperty.call(n,d)&&t.push([a,Z(n[d],d)])},"add");if(r("name"),r("description"),r("title"),r("icon"),r("cycles"),r("kind"),r("mode"),r("lifecycle"),r("cwd"),r("host_kind"),r("profile_id"),r("parent"),r("spawned_by"),r("creator"),r("fork_from"),r("fork_source_file"),r("model_override"),Object.prototype.hasOwnProperty.call(n,"passive_default")&&t.push(["passive_default",n.passive_default===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"cycle_pending")&&t.push(["cycle_pending",n.cycle_pending===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"persona_ack")&&t.push(["persona_ack_json",f(n.persona_ack,"persona_ack")]),Object.prototype.hasOwnProperty.call(n,"review_binding")&&t.push(["review_binding_json",f(n.review_binding,"review_binding")]),Object.prototype.hasOwnProperty.call(n,"launch")&&t.push(["launch_config_json",f(n.launch,"launch")]),t.length===0){const d=E(e);if(d===null)throw new Error(`unknown node: ${e}`);return d}if(s().prepare(`UPDATE nodes SET ${t.map(([d])=>`${d} = ?`).join(", ")} WHERE node_id = ?`).run(...t.map(([,d])=>d),e).changes!==1)throw new Error(`unknown node: ${e}`);return E(e)}o(he,"updateNode");function ye(e,n){s().prepare("UPDATE nodes SET status = ? WHERE node_id = ?").run(n,e)}o(ye,"setStatus");function Te(e,n){s().prepare("UPDATE nodes SET intent = ? WHERE node_id = ?").run(n??null,e)}o(Te,"setIntent");function De(e,n,t={}){if(t.outcome===void 0){const i=[],d=[];Object.prototype.hasOwnProperty.call(n,"status")&&(i.push("status = ?"),d.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(i.push("intent = ?"),d.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(i.push("terminal_reason = ?"),d.push(n.terminal_reason??null));const a=["node_id = ?"];d.push(e),t.fromStatuses!==void 0&&(a.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),d.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&a.push("final_report IS NULL");const u=s().prepare(`UPDATE nodes SET ${i.join(", ")} WHERE ${a.join(" AND ")}`).run(...d);return Number(u.changes)}const r=t.outcome;return p(i=>{const d=[],a=[];Object.prototype.hasOwnProperty.call(n,"status")&&(d.push("status = ?"),a.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(d.push("intent = ?"),a.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(d.push("terminal_reason = ?"),a.push(n.terminal_reason??null));const u=o((re,W)=>r.supersede===!0?"?":`CASE WHEN outcome_at IS NULL THEN ? ELSE ${W} END`,"outcomeValue");d.push(`outcome_kind = ${u(r.kind,"outcome_kind")}`,`outcome_reason = ${u(r.reason,"outcome_reason")}`,`outcome_detail_json = ${u(r.detailJson,"outcome_detail_json")}`,`outcome_revision = ${r.supersede===!0?"outcome_revision + 1":"CASE WHEN outcome_at IS NULL THEN outcome_revision + 1 ELSE outcome_revision END"}`,`outcome_at = ${u(r.at,"outcome_at")}`),a.push(r.kind,r.reason,r.detailJson,r.at);const c=["node_id = ?"];a.push(e),t.fromStatuses!==void 0&&(c.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),a.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&c.push("final_report IS NULL");const l=i.prepare(`UPDATE nodes SET ${d.join(", ")} WHERE ${c.join(" AND ")}`).run(...a);if(Number(l.changes)===0)return 0;const N=i.prepare("SELECT outcome_at FROM nodes WHERE node_id = ?").get(e);return(r.supersede===!0||N.outcome_at===r.at)&&r.documentJson!==null&&r.documentJson!==void 0&&M(i,{idempotencyKey:`node-outcome:${e}`,label:e,bodyJson:r.documentJson,supersede:r.supersede===!0}),Number(l.changes)})}o(De,"transitionStatusIntent");function Le(e){return s().prepare("SELECT final_report FROM nodes WHERE node_id = ?").get(e)?.final_report??null}o(Le,"getFinalReport");function Ae(e,n){return s().prepare("UPDATE nodes SET final_report = NULL, finalized_at = NULL WHERE node_id = ? AND final_report = ?").run(e,n).changes>0}o(Ae,"clearFinalReportIfMatches");function be(e,n){s().prepare('UPDATE nodes SET tmux_session = ?, "window" = ?, pane = ? WHERE node_id = ?').run(n.tmux_session??null,n.window??null,n.pane??null,e)}o(be,"setPresence");function ve(e,n){s().prepare("UPDATE nodes SET launched_at = ?, frozen_at = NULL, respawn_not_before = NULL WHERE node_id = ?").run(n,e)}o(ve,"recordLaunch");function xe(e,n){s().prepare("UPDATE nodes SET last_settled_at = ? WHERE node_id = ?").run(n,e)}o(xe,"recordSettledTurn");function We(e,n){s().prepare("UPDATE nodes SET frozen_at = ? WHERE node_id = ?").run(n,e)}o(We,"setFrozen");function ke(e){s().prepare("UPDATE nodes SET frozen_at = NULL WHERE node_id = ?").run(e)}o(ke,"clearFrozen");function Fe(e,n){s().prepare("UPDATE nodes SET respawn_failures = ?, respawn_not_before = ? WHERE node_id = ?").run(n.failures,n.notBefore,e)}o(Fe,"recordRespawnAttempt");const m="node_id NOT IN (SELECT node_id FROM warm_pool)",D=["state","cleanup_state","path","branch","repo_root","base_ref","base_sha","created_at","closed_at","next_attempt_at","attempts","quarantined","sweep_reason","sweep_detail","sweep_last_at","sweep_observed_json","abandoned_json","land_intent_json","disposal_json"];function ee(e){return e.worktree_state===null?null:Y(Object.fromEntries(D.map(n=>[n,e[`worktree_${n}`]])))}o(ee,"worktreeFromProjection");function He(e){const n=D.map(r=>`w.${r} AS worktree_${r}`).join(", ");return s().prepare(`SELECT n.*, ${n} FROM node_rows n LEFT JOIN worktrees w ON w.node_id = n.node_id WHERE n.profile_id = ? ORDER BY n.created`).all(e).map(r=>T(r,ee(r)))}o(He,"listNodesByProfile");function je(){return s().prepare("SELECT node_id, cwd, profile_id FROM nodes ORDER BY created").all().map(e=>{const n=e;return{nodeId:n.node_id,cwd:n.cwd,profileId:n.profile_id}})}o(je,"listNodeMemoryTargets");function ne(e){const n=[m],t=[];if(e?.status!==void 0){const i=Array.isArray(e.status)?e.status:[e.status];n.push(`status IN (${i.map(()=>"?").join(",")})`),t.push(...i)}return e?.withRecordedPid===!0&&n.push("pi_pid IS NOT NULL"),e?.withRecordedPidOrFrozen===!0&&n.push("(pi_pid IS NOT NULL OR frozen_at IS NOT NULL)"),s().prepare(`SELECT * FROM node_rows WHERE ${n.join(" AND ")} ORDER BY created`).all(...t).map(_)}o(ne,"listNodes");function Ie(){return s().prepare(`SELECT * FROM node_rows
|
|
6
|
+
WHERE ${m} AND kind != 'human'
|
|
7
|
+
AND (status IN ('active', 'idle') OR (status IN ('done', 'canceled', 'dead') AND (pi_pid IS NOT NULL OR frozen_at IS NOT NULL)))
|
|
8
|
+
ORDER BY created`).all().map(_)}o(Ie,"listNodesForSupervision");function Ue(){return s().prepare(`SELECT node_id, name, created FROM nodes WHERE ${m} ORDER BY created`).all()}o(Ue,"listNodeIdentities");function Me(e,n){p(t=>{t.prepare("INSERT OR REPLACE INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?)").run(e,n,new Date().toISOString())})}o(Me,"registerWarmSpare");function Pe(e){return p(n=>n.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(e).changes>0)}o(Pe,"unregisterWarmSpare");function g(e,n){const t=`SELECT w.node_id AS node_id, w.recipe_key AS recipe_key, w.created AS created,
|
|
6
9
|
n.status AS status, n.pi_pid AS pi_pid, n.pi_pid_identity AS pi_pid_identity
|
|
7
|
-
FROM warm_pool w JOIN node_rows n ON n.node_id = w.node_id`+(n===void 0?"":" WHERE w.recipe_key = ?")+" ORDER BY w.created";return(n===void 0?e.prepare(t).all():e.prepare(t).all(n)).map(i=>({node_id:i.node_id,recipe_key:i.recipe_key,created:i.created,status:i.status,pi_pid:i.pi_pid??null,pi_pid_identity:i.pi_pid_identity??null}))}o(
|
|
8
|
-
FROM nodes WHERE ${m} ORDER BY created`).all().map(e=>({node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,parent:e.parent??null,created:e.created}))}o(
|
|
10
|
+
FROM warm_pool w JOIN node_rows n ON n.node_id = w.node_id`+(n===void 0?"":" WHERE w.recipe_key = ?")+" ORDER BY w.created";return(n===void 0?e.prepare(t).all():e.prepare(t).all(n)).map(i=>({node_id:i.node_id,recipe_key:i.recipe_key,created:i.created,status:i.status,pi_pid:i.pi_pid??null,pi_pid_identity:i.pi_pid_identity??null}))}o(g,"warmSpareRowsFor");function Ce(){return g(s())}o(Ce,"listWarmSpares");function $e(e){return s().prepare("SELECT 1 FROM warm_pool WHERE node_id = ?").get(e)!==void 0}o($e,"isWarmSpare");function L(e){return e.status!=="active"&&e.status!=="idle"?!1:q(e.pi_pid,e.pi_pid_identity)==="alive"}o(L,"spareIsClaimable");function Be(e,n,t={}){return p(r=>{const i=g(r,e).find(L);return i===void 0||r.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(i.node_id).changes===0?null:(r.prepare("UPDATE nodes SET created = ?, deadline_at = ? WHERE node_id = ?").run(n,t.deadlineAt??null,i.node_id),t.outcomeDelivery!==void 0&&y(r,i.node_id,t.outcomeDelivery),i.node_id)})}o(Be,"claimWarmSpare");function ze(e){return g(s(),e).filter(L).length}o(ze,"warmSpareCount");function Je(e){return s().prepare("SELECT node_id FROM nodes WHERE parent = ? ORDER BY created").all(e).map(n=>n.node_id)}o(Je,"childrenOf");function Ye(){return s().prepare(`SELECT node_id, name, kind, mode, lifecycle, status, cwd, host_kind, parent, created
|
|
11
|
+
FROM nodes WHERE ${m} ORDER BY created`).all().map(e=>({node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,parent:e.parent??null,created:e.created}))}o(Ye,"rosterNodes");function qe(){return s().prepare("SELECT from_id, to_id, active, created FROM edges WHERE type = 'subscribes_to' ORDER BY created").all().map(e=>({from_id:e.from_id,to_id:e.to_id,active:e.active===1,created:e.created}))}o(qe,"rosterEdges");function Ve(e){return s().prepare(`SELECT * FROM node_rows
|
|
9
12
|
WHERE parent IS NULL AND kind != 'human'
|
|
10
13
|
AND status IN ('active','idle') AND cwd = ?
|
|
11
14
|
AND ${m}
|
|
12
|
-
ORDER BY created DESC`).all(e).map(_)}o(
|
|
15
|
+
ORDER BY created DESC`).all(e).map(_)}o(Ve,"listResumableRoots");function A(e,n,t,r){s().prepare(`INSERT INTO edges (type, from_id, to_id, active, created)
|
|
13
16
|
VALUES (?, ?, ?, ?, ?)
|
|
14
|
-
ON CONFLICT(type, from_id, to_id) DO UPDATE SET active=excluded.active`).run(e,n,t,r?1:0,new Date().toISOString())}o(
|
|
15
|
-
WHERE type = 'subscribes_to' AND to_id = ? ORDER BY created`).all(e).map(n=>({node_id:n.node_id,active:n.active===1,created:n.created}))}o(
|
|
16
|
-
WHERE type = 'subscribes_to' AND from_id = ? ORDER BY created`).all(e).map(n=>({node_id:n.node_id,active:n.active===1,created:n.created}))}o(
|
|
17
|
+
ON CONFLICT(type, from_id, to_id) DO UPDATE SET active=excluded.active`).run(e,n,t,r?1:0,new Date().toISOString())}o(A,"addEdge");function Ge(e,n,t=!0){A("subscribes_to",e,n,t)}o(Ge,"subscribe");function Ke(e,n){s().prepare("DELETE FROM edges WHERE type = ? AND from_id = ? AND to_id = ?").run("subscribes_to",e,n)}o(Ke,"unsubscribe");function Qe(e,n,t){s().prepare("UPDATE edges SET active = ? WHERE type = ? AND from_id = ? AND to_id = ?").run(t?1:0,"subscribes_to",e,n)}o(Qe,"setSubscriptionActive");function Xe(e,n){A("spawned_by",e,n,!0)}o(Xe,"recordSpawn");function Ze(e){return s().prepare(`SELECT from_id AS node_id, active, created FROM edges
|
|
18
|
+
WHERE type = 'subscribes_to' AND to_id = ? ORDER BY created`).all(e).map(n=>({node_id:n.node_id,active:n.active===1,created:n.created}))}o(Ze,"subscribersOf");function b(e){return s().prepare(`SELECT to_id AS node_id, active, created FROM edges
|
|
19
|
+
WHERE type = 'subscribes_to' AND from_id = ? ORDER BY created`).all(e).map(n=>({node_id:n.node_id,active:n.active===1,created:n.created}))}o(b,"subscriptionsOf");function en(e){const n=new Set([e]),t=[],r=b(e).map(i=>i.node_id);for(;r.length>0;){const i=r.shift();if(!n.has(i)){n.add(i),t.push(i);for(const d of b(i))n.has(d.node_id)||r.push(d.node_id)}}return t}o(en,"view");function nn(e){return s().prepare(`SELECT 1 FROM edges e JOIN nodes n ON n.node_id = e.to_id
|
|
17
20
|
WHERE e.type = 'subscribes_to' AND e.from_id = ? AND e.active = 1
|
|
18
|
-
AND n.status IN ('active', 'idle') LIMIT 1`).get(e)!==void 0}o(
|
|
21
|
+
AND n.status IN ('active', 'idle') LIMIT 1`).get(e)!==void 0}o(nn,"hasActiveLiveSubscription");function tn(e){return s().prepare(`SELECT 1 FROM edges e JOIN nodes n ON n.node_id = e.from_id
|
|
19
22
|
WHERE e.type = 'subscribes_to' AND e.to_id = ? AND e.active = 1
|
|
20
|
-
AND n.status IN ('active', 'idle') LIMIT 1`).get(e)!==void 0}o(
|
|
23
|
+
AND n.status IN ('active', 'idle') LIMIT 1`).get(e)!==void 0}o(tn,"hasLiveSubscriber");function rn(e){const n=E(e)?.waiting_for;if(n==null)return!1;const t=E(n);return t!==null&&(t.status==="active"||t.status==="idle")}o(rn,"hasLiveMessageWait");function on(e,n){s().prepare("UPDATE nodes SET waiting_for = ?, waiting_for_generation = waiting_for_generation + 1 WHERE node_id = ?").run(n,e)}o(on,"setMessageWait");function dn(e,n,t){return p(r=>{const i=r.prepare("SELECT waiting_for_generation FROM nodes WHERE node_id = ? AND waiting_for = ?").get(e,n),d=t();return n!==null&&i!==void 0&&r.prepare("UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?").run(e,n,i.waiting_for_generation),d})}o(dn,"deliverAndSettleMessageWait");function sn(e,n,t){return p(r=>{const i=r.prepare(`SELECT waiter.waiting_for, waiter.waiting_for_generation, target.status AS controller_status
|
|
21
24
|
FROM nodes AS waiter LEFT JOIN nodes AS target ON target.node_id = waiter.waiting_for
|
|
22
|
-
WHERE waiter.node_id = ?`).get(e),d=i?.controller_status==="active"||i?.controller_status==="idle";if(i?.waiting_for!==n||d)return null;const a=t();return r.prepare("UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?").run(e,n,i.waiting_for_generation),a})}o(
|
|
25
|
+
WHERE waiter.node_id = ?`).get(e),d=i?.controller_status==="active"||i?.controller_status==="idle";if(i?.waiting_for!==n||d)return null;const a=t();return r.prepare("UPDATE nodes SET waiting_for = NULL WHERE node_id = ? AND waiting_for = ? AND waiting_for_generation = ?").run(e,n,i.waiting_for_generation),a})}o(sn,"settleDeadMessageWait");function an(e,n,t){return p(r=>{const i=r.prepare("SELECT status, final_report, frozen_at FROM nodes WHERE node_id = ?").get(e);return i===void 0?{kind:"missing"}:n(i)?{kind:"terminal",status:i.status,final_report:i.final_report}:{kind:"ran",result:t()}})}o(an,"withFreshTerminalGuard");function w(e){return B(e)}o(w,"hasUnreconciledManagedWorktree");function v(e,n={}){return!["done","dead","canceled"].includes(e.status)||e.pi_pid!==null||e.frozen_at!==null||w(e.node_id)||e.node_id===O()?!1:n.pastTtl===!0||!["crashed","stranded",null].includes(e.terminal_reason??null)}o(v,"isCollectible");function un(e){if(w(e))return{deleted:!1};const n=p(t=>(t.prepare("DELETE FROM nodes WHERE node_id = ?").run(e),{deleted:!0}));return R(S(e),{recursive:!0,force:!0}),n}o(un,"deleteNode");function ln(e){const n=[...new Set(e)];if(n.length===0)return[];const t=n.filter(w);if(t.length>0)throw new Error(`refusing to delete nodes with unreconciled managed worktrees: ${t.join(", ")}`);const r=n.map(()=>"?").join(","),i=p(d=>{const a=d.prepare(`SELECT node_id FROM nodes WHERE node_id IN (${r}) ORDER BY created`).all(...n).map(({node_id:u})=>u);return d.prepare(`DELETE FROM nodes WHERE node_id IN (${r})`).run(...n),a});for(const d of i)R(S(d),{recursive:!0,force:!0});return i}o(ln,"deleteNodes");function cn(e){const n=e.dryRun??!1,t=e.includeStale??!1,r=new Date(Date.now()-e.ttlDays*864e5).toISOString(),i=O()??"",d=s(),a=d.prepare(`SELECT * FROM node_rows
|
|
23
26
|
WHERE status IN ('dead', 'done', 'canceled') AND created < ?
|
|
24
|
-
ORDER BY created`).all(r).map(_).filter(l=>
|
|
27
|
+
ORDER BY created`).all(r).map(_).filter(l=>v(l,{pastTtl:!0})).map(l=>({node_id:l.node_id,status:l.status,created:l.created})),u=t?d.prepare(`SELECT node_id, status, created, pi_pid FROM node_rows
|
|
25
28
|
WHERE status IN ('active', 'idle') AND created < ?
|
|
26
|
-
ORDER BY created`).all(r).filter(l=>{if(l.node_id===i)return!1;const
|
|
29
|
+
ORDER BY created`).all(r).filter(l=>{if(l.node_id===i)return!1;const N=l.pi_pid;return!h(N)}).map(l=>({node_id:l.node_id,status:l.status,created:l.created})).filter(l=>!w(l.node_id)):[],c=[...a,...u];return n||c.length===0?{pruned:c,dryRun:n}:(x(c),{pruned:c,dryRun:n})}o(cn,"pruneNodes");function x(e){if(e.length!==0){p(n=>{const t=n.prepare("DELETE FROM nodes WHERE node_id = ?");for(const r of e)t.run(r.node_id)});for(const n of e)R(S(n.node_id),{recursive:!0,force:!0})}}o(x,"deletePrunedNodes");function te(e,n){try{const r=j(I(K(e),"telemetry.json"),{throwIfNoEntry:!1});if(r!==void 0)return r.mtimeMs}catch{}const t=Date.parse(n);return Number.isNaN(t)?0:t}o(te,"recencyMs");function pn(e){const n=e.dryRun??!1,r=ne().map(u=>({row:u,recency:te(u.node_id,u.created),retained:!v(u)})).sort((u,c)=>c.recency-u.recency),i=r.filter(u=>u.retained).length,d=Math.max(e.maxNodes,i),a=r.filter((u,c)=>c>=d&&!u.retained).map(({row:u})=>({node_id:u.node_id,status:u.status,created:u.created}));return n||a.length===0?{pruned:a,dryRun:n}:(x(a),{pruned:a,dryRun:n})}o(pn,"pruneToLimit");export{me as canonicalSessionFile,Je as childrenOf,Be as claimWarmSpare,Ae as clearFinalReportIfMatches,ke as clearFrozen,Ee as createNode,un as deleteNode,ln as deleteNodes,dn as deliverAndSettleMessageWait,Se as dueNodeDeadlines,we as findNodeBySessionFile,Le as getFinalReport,E as getNode,Ne as getRow,Re as getRowByPane,nn as hasActiveLiveSubscription,rn as hasLiveMessageWait,tn as hasLiveSubscriber,v as isCollectible,$e as isWarmSpare,Ue as listNodeIdentities,je as listNodeMemoryTargets,ne as listNodes,He as listNodesByProfile,Ie as listNodesForSupervision,Ve as listResumableRoots,Ce as listWarmSpares,cn as pruneNodes,pn as pruneToLimit,ve as recordLaunch,Fe as recordRespawnAttempt,xe as recordSettledTurn,Xe as recordSpawn,Me as registerWarmSpare,qe as rosterEdges,Ye as rosterNodes,We as setFrozen,Te as setIntent,on as setMessageWait,ge as setNodeDeadline,be as setPresence,ye as setStatus,Qe as setSubscriptionActive,sn as settleDeadMessageWait,Oe as shiftProfileNodeDeadlines,Ge as subscribe,Ze as subscribersOf,b as subscriptionsOf,De as transitionStatusIntent,Pe as unregisterWarmSpare,Ke as unsubscribe,he as updateNode,en as view,ze as warmSpareCount,an as withFreshTerminalGuard};
|