@north-light/cli 0.3.419 → 0.3.421
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/README.md +3 -2
- package/dist/api/dto/docs.d.ts +7 -0
- package/dist/api/dto/nodes.d.ts +1 -0
- package/dist/builtin-memory/crouter-sdk/README.md +3 -3
- package/dist/builtin-memory/crouter-sdk/getting-started.md +2 -2
- package/dist/builtin-memory/crouter-sdk/guides/README.md +1 -1
- package/dist/builtin-memory/crouter-sdk/guides/apps-on-crouter-cloud.md +222 -3
- package/dist/clients/attach/input/controller.d.ts +1 -0
- package/dist/clients/attach/input/controller.js +2 -2
- package/dist/clients/attach/render/chat-view.d.ts +44 -0
- package/dist/clients/attach/render/chat-view.js +3 -3
- package/dist/clients/attach/session/frames.d.ts +2 -0
- package/dist/clients/attach/session/frames.js +1 -1
- package/dist/clients/attach/session/input-wiring.d.ts +3 -0
- package/dist/clients/attach/session/input-wiring.js +1 -1
- package/dist/clients/attach/slash/dispatch.d.ts +4 -0
- package/dist/clients/attach/slash/dispatch.js +2 -2
- package/dist/clients/attach/viewer.js +567 -563
- package/dist/core/command-plugins/bundle.d.ts +3 -0
- package/dist/core/command-plugins/bundle.js +1 -1
- package/dist/core/config.js +1 -1
- package/dist/core/fs-utils.d.ts +7 -0
- package/dist/core/fs-utils.js +3 -3
- package/dist/core/graph/package-docs.d.ts +4 -1
- package/dist/core/graph/package-docs.js +5 -5
- package/dist/core/keybindings/catalog.d.ts +1 -1
- package/dist/core/keybindings/catalog.js +1 -1
- package/dist/core/manifest.d.ts +15 -0
- package/dist/core/manifest.js +1 -1
- package/dist/core/plugin-quarantine.d.ts +16 -0
- package/dist/core/plugin-quarantine.js +1 -0
- package/dist/core/providers/bundles.js +2 -2
- package/dist/core/runtime/broker/rebind.d.ts +5 -0
- package/dist/core/runtime/broker/rebind.js +1 -1
- package/dist/core/runtime/broker/turn-replies.d.ts +33 -0
- package/dist/core/runtime/broker/turn-replies.js +1 -0
- package/dist/core/runtime/broker-protocol.d.ts +12 -1
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/node-read.js +3 -3
- package/dist/core/runtime/tmux-bindings.js +1 -1
- package/dist/core/runtime/turn-reply-summary.d.ts +6 -0
- package/dist/core/runtime/turn-reply-summary.js +11 -0
- package/dist/core/user-settings.d.ts +15 -0
- package/dist/core/user-settings.js +1 -1
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/vendor-signin.d.ts +3 -0
- package/dist/daemon/api/vendor-signin.js +162 -47
- package/dist/daemon/crtrd.js +6 -5
- package/dist/shared/turn-replies.d.ts +27 -0
- package/dist/shared/turn-replies.js +5 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.js +1 -1
- package/docs/sdk/README.md +3 -3
- package/docs/sdk/getting-started.md +2 -2
- package/docs/sdk/guides/README.md +1 -1
- package/docs/sdk/guides/apps-on-crouter-cloud.md +218 -1
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +12 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
var v=Object.defineProperty;var s=(e,t)=>v(e,"name",{value:t,configurable:!0});import{CONDENSED_HISTORY_MODES as u,MOUSE_MODE_DEFAULTS as p,WHIP_MESSAGE_MODES as d}from"../types.js";function i(e,t,o){const r=e.indexOf(t),a=r>=0?r:0;return e[(a+o+e.length)%e.length]}s(i,"cycleChoice");function c(e,t,o){const r=e.indexOf(t);return r>=0?e[(r+o+e.length)%e.length]:o>=0?e.find(a=>a>t)??e[0]:[...e].reverse().find(a=>a<t)??e[e.length-1]}s(c,"cycleNumber");function n(e,t){return e==="true"?!0:e==="false"?!1:`${t} must be true or false`}s(n,"booleanFromString");function f(e,t){if(!/^\d+$/.test(e))return`${t} must be an integer >= 0`;const o=Number(e);return Number.isSafeInteger(o)?o:`${t} must be an integer >= 0`}s(f,"nonNegativeIntegerFromString");function _(e,t){const o=f(e,t);return typeof o=="string"||o<1?`${t} must be an integer >= 1`:o}s(_,"positiveIntegerFromString");const m=[!1,"notify","apply"],w=[0,1,6,12,24,48,72,168],b=[1,2,3,4,5,6,8,10,12],l="openai-codex";function g(e,t){const o=e.providerOptions[t];if(o!==void 0)return o;const r={};return e.providerOptions[t]=r,r}s(g,"providerOptionsFor");const x=[1,2,3,4,5,6],h={schema_version:{surface:"specialized",owner:"internal schema migration"},marketplaces:{surface:"specialized",owner:"Plugins and pkg market commands"},plugins:{surface:"specialized",owner:"Plugins tab and pkg plugin commands"},auto_update:{surface:"settings",settings:{crtr:{key:"auto_update.crtr",label:"crouter updates",description:"Notify about crouter releases, install them automatically, or turn checks off.",valueConstraint:"true|false|notify|apply; true stores notify",applies:"Applies on the next crouter command.",group:"updates",order:70,format:s(e=>e.auto_update.crtr===!1?"off":e.auto_update.crtr,"format"),cycle:s((e,t)=>{e.auto_update.crtr=i(m,e.auto_update.crtr,t)},"cycle"),setFromString:s((e,t)=>{const o=t==="true"?"notify":t;return o!=="notify"&&o!=="apply"&&o!=="false"?"auto_update.crtr must be notify, apply, or false":(e.auto_update.crtr=o==="false"?!1:o,null)},"setFromString")},content:{key:"auto_update.content",label:"Content updates",description:"Notify about plugin and marketplace updates, apply them automatically, or turn checks off.",valueConstraint:"false|notify|apply",applies:"Applies on the next crouter command.",group:"updates",order:80,format:s(e=>e.auto_update.content===!1?"off":e.auto_update.content,"format"),cycle:s((e,t)=>{e.auto_update.content=i(m,e.auto_update.content,t)},"cycle"),setFromString:s((e,t)=>t!=="notify"&&t!=="apply"&&t!=="false"?"auto_update.content must be notify, apply, or false":(e.auto_update.content=t==="false"?!1:t,null),"setFromString")},interval_hours:{key:"auto_update.interval_hours",label:"Update interval",description:"Minimum hours between automatic update checks. Zero checks on every command.",valueConstraint:"integer >= 0",applies:"Applies on the next crouter command.",group:"updates",order:90,format:s(e=>`${e.auto_update.interval_hours}h`,"format"),cycle:s((e,t)=>{e.auto_update.interval_hours=c(w,e.auto_update.interval_hours,t)},"cycle"),setFromString:s((e,t)=>{const o=f(t,"auto_update.interval_hours");return typeof o=="string"?o:(e.auto_update.interval_hours=o,null)},"setFromString")}}},max_panes_per_window:{surface:"settings",setting:{key:"max_panes_per_window",label:"Maximum panes",description:"Maximum human-review panes placed in one tmux window before using another window.",valueConstraint:"integer >= 1",applies:"Applies to the next pane placement.",group:"panes",order:20,format:s(e=>String(e.max_panes_per_window),"format"),cycle:s((e,t)=>{e.max_panes_per_window=c(b,e.max_panes_per_window,t)},"cycle"),setFromString:s((e,t)=>{const o=_(t,"max_panes_per_window");return typeof o=="string"?o:(e.max_panes_per_window=o,null)},"setFromString")}},auto_open_child_viewers:{surface:"settings",setting:{key:"auto_open_child_viewers",label:"Open child panes",description:"Open each managed child beside its watched parent. Off keeps new children running in the background.",valueConstraint:"true|false",applies:"Applies to the next managed child created; independent roots still open their attended viewer.",group:"panes",order:10,format:s(e=>e.auto_open_child_viewers?"on":"off","format"),cycle:s(e=>{e.auto_open_child_viewers=!e.auto_open_child_viewers},"cycle"),setFromString:s((e,t)=>{const o=n(t,"auto_open_child_viewers");return typeof o=="string"?o:(e.auto_open_child_viewers=o,null)},"setFromString")}},brokerThresholds:{surface:"specialized",owner:"Broker limits tab"},lifecycle:{surface:"specialized",owner:"sys config set lifecycle.unattendedParkMs"},completion_bell:{surface:"settings",setting:{key:"completion_bell",label:"Completion bell",description:"Ring a short sound when the node in an attached viewer finishes a turn.",valueConstraint:"true|false",applies:"Applies on the next turn end.",group:"display",order:41,format:s(e=>e.completion_bell?"on":"off","format"),cycle:s(e=>{e.completion_bell=!e.completion_bell},"cycle"),setFromString:s((e,t)=>{const o=n(t,"completion_bell");return typeof o=="string"?o:(e.completion_bell=o,null)},"setFromString")}},working_gerunds:{surface:"specialized",owner:"sys config set working_gerunds"},whip_mode:{surface:"settings",setting:{key:"whip_mode",label:"Whip mode",description:"Play the whip animation when you send a prompt and when a viewer opens for an agent with an initial prompt.",valueConstraint:"true|false",applies:"Applies on the next attach.",group:"display",order:39,format:s(e=>e.whip_mode?"on":"off","format"),cycle:s(e=>{e.whip_mode=!e.whip_mode},"cycle"),setFromString:s((e,t)=>{const o=n(t,"whip_mode");return typeof o=="string"?o:(e.whip_mode=o,null)},"setFromString")}},page_surface:{surface:"settings",setting:{key:"page_surface",label:"Page human surface",description:"This host reads pages in a browser rather than a terminal. Agents are told the page module runs as written, HTML pages are offered, and document review and live display leave the command tree.",valueConstraint:"true|false",applies:"Applies when human command help is assembled.",group:"display",order:37,format:s(e=>e.page_surface?"on":"off","format"),cycle:s(e=>{e.page_surface=!e.page_surface},"cycle"),setFromString:s((e,t)=>{const o=n(t,"page_surface");return typeof o=="string"?o:(e.page_surface=o,null)},"setFromString")}},whip_messages:{surface:"specialized",owner:"sys config set whip_messages"},whip_message_mode:{surface:"settings",setting:{key:"whip_message_mode",label:"Whip message",description:"What the whip action sends: a random line from whip_messages, or the fixed \u201CGo faster\u201D.",valueConstraint:d.join("|"),applies:"Applies on the next attach.",group:"display",order:40,format:s(e=>e.whip_message_mode==="go-faster"?"go faster":"random","format"),cycle:s((e,t)=>{e.whip_message_mode=i(d,e.whip_message_mode,t)},"cycle"),setFromString:s((e,t)=>d.includes(t)?(e.whip_message_mode=t,null):`whip_message_mode must be one of: ${d.join("|")}`,"setFromString")}},mouse_mode_default:{surface:"settings",setting:{key:"mouse_mode_default",label:"Default mouse mode",description:"Initial mouse wheel scrolling for each attached viewer.",valueConstraint:p.join("|"),applies:"Applies on the next attach.",group:"display",order:38,format:s(e=>e.mouse_mode_default==="tmux"?"follow tmux":e.mouse_mode_default,"format"),cycle:s((e,t)=>{e.mouse_mode_default=i(p,e.mouse_mode_default,t)},"cycle"),setFromString:s((e,t)=>p.includes(t)?(e.mouse_mode_default=t,null):`mouse_mode_default must be one of: ${p.join("|")}`,"setFromString")}},live_cycles:{surface:"settings",setting:{key:"live_cycles",label:"Live cycles",description:"Trailing refresh cycles rendered at full fidelity; older cycles condense to text.",valueConstraint:"integer >= 1",applies:"Applies on the next attach.",group:"display",order:50,format:s(e=>String(e.live_cycles),"format"),cycle:s((e,t)=>{e.live_cycles=c(x,e.live_cycles,t)},"cycle"),setFromString:s((e,t)=>{const o=_(t,"live_cycles");return typeof o=="string"?o:(e.live_cycles=o,null)},"setFromString")}},condensed_history:{surface:"settings",setting:{key:"condensed_history",label:"Condensed history",description:"Messages retained from condensed cycles. Tool calls are never kept.",valueConstraint:u.join("|"),applies:"Applies on the next attach.",group:"display",order:60,format:s(e=>e.condensed_history,"format"),cycle:s((e,t)=>{e.condensed_history=i(u,e.condensed_history,t)},"cycle"),setFromString:s((e,t)=>u.includes(t)?(e.condensed_history=t,null):`condensed_history must be one of: ${u.join("|")}`,"setFromString")}},bash_tool_purpose:{surface:"settings",setting:{key:"bash_tool_purpose",label:"Bash purpose field",description:"Expose the optional purpose label to agents in the bash tool schema. Off removes the field without disabling the bash valve.",valueConstraint:"true|false",applies:"Applies on the next node session.",group:"display",order:25,format:s(e=>e.bash_tool_purpose?"on":"off","format"),cycle:s(e=>{e.bash_tool_purpose=!e.bash_tool_purpose},"cycle"),setFromString:s((e,t)=>{const o=n(t,"bash_tool_purpose");return typeof o=="string"?o:(e.bash_tool_purpose=o,null)},"setFromString")}},fold_finished_tools:{surface:"settings",setting:{key:"fold_finished_tools",label:"Fold finished tools",description:"Fold every settled tool call to its call line. Toggle live with /fold-tools.",valueConstraint:"true|false",applies:"Applies on the next attach.",group:"display",order:30,format:s(e=>e.fold_finished_tools?"on":"off","format"),cycle:s(e=>{e.fold_finished_tools=!e.fold_finished_tools},"cycle"),setFromString:s((e,t)=>{const o=n(t,"fold_finished_tools");return typeof o=="string"?o:(e.fold_finished_tools=o,null)},"setFromString")}},summarize_tool_calls:{surface:"settings",setting:{key:"summarize_tool_calls",label:"Summarize tool calls",description:"Replace completed folded tool-call groups with a one-line broker summary when available.",valueConstraint:"true|false",applies:"Applies when the next visible message closes a tool-call group.",group:"display",order:35,format:s(e=>e.summarize_tool_calls?"on":"off","format"),cycle:s(e=>{e.summarize_tool_calls=!e.summarize_tool_calls},"cycle"),setFromString:s((e,t)=>{const o=n(t,"summarize_tool_calls");return typeof o=="string"?o:(e.summarize_tool_calls=o,null)},"setFromString")}},detailed_tool_recaps:{surface:"settings",setting:{key:"detailed_tool_recaps",label:"Detailed tool recaps",description:"Show each document read and edited file in folded tool recaps. Off shows a compact count line instead.",valueConstraint:"true|false",applies:"Applies on the next attach.",group:"display",order:36,format:s(e=>e.detailed_tool_recaps?"on":"off","format"),cycle:s(e=>{e.detailed_tool_recaps=!e.detailed_tool_recaps},"cycle"),setFromString:s((e,t)=>{const o=n(t,"detailed_tool_recaps");return typeof o=="string"?o:(e.detailed_tool_recaps=o,null)},"setFromString")}},keybindings:{surface:"specialized",owner:"Keybindings tab"},tmux_passthrough:{surface:"specialized",owner:"Keybindings tab"},providerOptions:{surface:"settings",settings:{"openai-codex.fastMode":{key:`providerOptions.${l}.fastMode`,label:"Codex fast mode",description:"Serve Codex turns at the ChatGPT priority tier: about 1.5x faster generation for about 2x the credits. Displayed cost does not reflect the premium.",valueConstraint:"true|false",applies:"Applies on each node's next turn.",group:"providers",order:40,format:s(e=>e.providerOptions[l]?.fastMode?"on":"off","format"),cycle:s(e=>{const t=g(e,l);t.fastMode=!t.fastMode},"cycle"),setFromString:s((e,t)=>{const o=n(t,`providerOptions.${l}.fastMode`);return typeof o=="string"?o:(g(e,l).fastMode=o,null)},"setFromString")}}},modelLadders:{surface:"specialized",owner:"Models tab"},modelRoutes:{surface:"specialized",owner:"Models route declarations"},modelRouting:{surface:"specialized",owner:"Models route declarations"},kinds:{surface:"specialized",owner:"Models tab and kind registry"},page_components:{surface:"specialized",owner:"Page component catalog: product-registered page component kinds"},remoteCanvas:{surface:"specialized",owner:"canvas config commands"},api:{surface:"specialized",owner:"sys connect"},paths:{surface:"specialized",owner:"runtime layout"},store:{surface:"specialized",owner:"daemon conversation store"},runtime:{surface:"specialized",owner:"app-facing listener"},spawnEnv:{surface:"specialized",owner:"spawn environment allow-list"},bin:{surface:"specialized",owner:"bare-binary contributions on every node PATH"},humanActions:{surface:"specialized",owner:"scope-configured human completion actions"}},O=Object.keys(h);function S(){const e=[];for(const t of Object.values(h))t.surface==="settings"&&("setting"in t?e.push(t.setting):e.push(...Object.values(t.settings)));return e.sort((t,o)=>t.order-o.order)}s(S,"collectUserSettings");const y=S();function z(e){return y.find(t=>t.key===e)}s(z,"findUserSetting");function A(e){return y.filter(t=>t.group===e)}s(A,"userSettingsInGroup");export{h as CONFIG_SETTINGS_COVERAGE,O as SCOPE_CONFIG_KEYS,y as USER_SETTINGS,z as findUserSetting,A as userSettingsInGroup};
|
|
1
|
+
var v=Object.defineProperty;var s=(e,t)=>v(e,"name",{value:t,configurable:!0});import{CONDENSED_HISTORY_MODES as u,MOUSE_MODE_DEFAULTS as p,WHIP_MESSAGE_MODES as d}from"../types.js";function i(e,t,o){const r=e.indexOf(t),a=r>=0?r:0;return e[(a+o+e.length)%e.length]}s(i,"cycleChoice");function c(e,t,o){const r=e.indexOf(t);return r>=0?e[(r+o+e.length)%e.length]:o>=0?e.find(a=>a>t)??e[0]:[...e].reverse().find(a=>a<t)??e[e.length-1]}s(c,"cycleNumber");function n(e,t){return e==="true"?!0:e==="false"?!1:`${t} must be true or false`}s(n,"booleanFromString");function f(e,t){if(!/^\d+$/.test(e))return`${t} must be an integer >= 0`;const o=Number(e);return Number.isSafeInteger(o)?o:`${t} must be an integer >= 0`}s(f,"nonNegativeIntegerFromString");function _(e,t){const o=f(e,t);return typeof o=="string"||o<1?`${t} must be an integer >= 1`:o}s(_,"positiveIntegerFromString");const m=[!1,"notify","apply"],w=[0,1,6,12,24,48,72,168],b=[1,2,3,4,5,6,8,10,12],l="openai-codex";function g(e,t){const o=e.providerOptions[t];if(o!==void 0)return o;const r={};return e.providerOptions[t]=r,r}s(g,"providerOptionsFor");const x=[1,2,3,4,5,6],h={schema_version:{surface:"specialized",owner:"internal schema migration"},marketplaces:{surface:"specialized",owner:"Plugins and pkg market commands"},plugins:{surface:"specialized",owner:"Plugins tab and pkg plugin commands"},auto_update:{surface:"settings",settings:{crtr:{key:"auto_update.crtr",label:"crouter updates",description:"Notify about crouter releases, install them automatically, or turn checks off.",valueConstraint:"true|false|notify|apply; true stores notify",applies:"Applies on the next crouter command.",group:"updates",order:70,format:s(e=>e.auto_update.crtr===!1?"off":e.auto_update.crtr,"format"),cycle:s((e,t)=>{e.auto_update.crtr=i(m,e.auto_update.crtr,t)},"cycle"),setFromString:s((e,t)=>{const o=t==="true"?"notify":t;return o!=="notify"&&o!=="apply"&&o!=="false"?"auto_update.crtr must be notify, apply, or false":(e.auto_update.crtr=o==="false"?!1:o,null)},"setFromString")},content:{key:"auto_update.content",label:"Content updates",description:"Notify about plugin and marketplace updates, apply them automatically, or turn checks off.",valueConstraint:"false|notify|apply",applies:"Applies on the next crouter command.",group:"updates",order:80,format:s(e=>e.auto_update.content===!1?"off":e.auto_update.content,"format"),cycle:s((e,t)=>{e.auto_update.content=i(m,e.auto_update.content,t)},"cycle"),setFromString:s((e,t)=>t!=="notify"&&t!=="apply"&&t!=="false"?"auto_update.content must be notify, apply, or false":(e.auto_update.content=t==="false"?!1:t,null),"setFromString")},interval_hours:{key:"auto_update.interval_hours",label:"Update interval",description:"Minimum hours between automatic update checks. Zero checks on every command.",valueConstraint:"integer >= 0",applies:"Applies on the next crouter command.",group:"updates",order:90,format:s(e=>`${e.auto_update.interval_hours}h`,"format"),cycle:s((e,t)=>{e.auto_update.interval_hours=c(w,e.auto_update.interval_hours,t)},"cycle"),setFromString:s((e,t)=>{const o=f(t,"auto_update.interval_hours");return typeof o=="string"?o:(e.auto_update.interval_hours=o,null)},"setFromString")}}},max_panes_per_window:{surface:"settings",setting:{key:"max_panes_per_window",label:"Maximum panes",description:"Maximum human-review panes placed in one tmux window before using another window.",valueConstraint:"integer >= 1",applies:"Applies to the next pane placement.",group:"panes",order:20,format:s(e=>String(e.max_panes_per_window),"format"),cycle:s((e,t)=>{e.max_panes_per_window=c(b,e.max_panes_per_window,t)},"cycle"),setFromString:s((e,t)=>{const o=_(t,"max_panes_per_window");return typeof o=="string"?o:(e.max_panes_per_window=o,null)},"setFromString")}},auto_open_child_viewers:{surface:"settings",setting:{key:"auto_open_child_viewers",label:"Open child panes",description:"Open each managed child beside its watched parent. Off keeps new children running in the background.",valueConstraint:"true|false",applies:"Applies to the next managed child created; independent roots still open their attended viewer.",group:"panes",order:10,format:s(e=>e.auto_open_child_viewers?"on":"off","format"),cycle:s(e=>{e.auto_open_child_viewers=!e.auto_open_child_viewers},"cycle"),setFromString:s((e,t)=>{const o=n(t,"auto_open_child_viewers");return typeof o=="string"?o:(e.auto_open_child_viewers=o,null)},"setFromString")}},brokerThresholds:{surface:"specialized",owner:"Broker limits tab"},lifecycle:{surface:"specialized",owner:"sys config set lifecycle.unattendedParkMs"},completion_bell:{surface:"settings",setting:{key:"completion_bell",label:"Completion bell",description:"Ring a short sound when the node in an attached viewer finishes a turn.",valueConstraint:"true|false",applies:"Applies on the next turn end.",group:"display",order:41,format:s(e=>e.completion_bell?"on":"off","format"),cycle:s(e=>{e.completion_bell=!e.completion_bell},"cycle"),setFromString:s((e,t)=>{const o=n(t,"completion_bell");return typeof o=="string"?o:(e.completion_bell=o,null)},"setFromString")}},working_gerunds:{surface:"specialized",owner:"sys config set working_gerunds"},whip_mode:{surface:"settings",setting:{key:"whip_mode",label:"Whip mode",description:"Play the whip animation when you send a prompt and when a viewer opens for an agent with an initial prompt.",valueConstraint:"true|false",applies:"Applies on the next attach.",group:"display",order:39,format:s(e=>e.whip_mode?"on":"off","format"),cycle:s(e=>{e.whip_mode=!e.whip_mode},"cycle"),setFromString:s((e,t)=>{const o=n(t,"whip_mode");return typeof o=="string"?o:(e.whip_mode=o,null)},"setFromString")}},page_surface:{surface:"settings",setting:{key:"page_surface",label:"Page human surface",description:"This host reads pages in a browser rather than a terminal. Agents are told the page module runs as written, HTML pages are offered, and document review and live display leave the command tree.",valueConstraint:"true|false",applies:"Applies when human command help is assembled.",group:"display",order:37,format:s(e=>e.page_surface?"on":"off","format"),cycle:s(e=>{e.page_surface=!e.page_surface},"cycle"),setFromString:s((e,t)=>{const o=n(t,"page_surface");return typeof o=="string"?o:(e.page_surface=o,null)},"setFromString")}},whip_messages:{surface:"specialized",owner:"sys config set whip_messages"},whip_message_mode:{surface:"settings",setting:{key:"whip_message_mode",label:"Whip message",description:"What the whip action sends: a random line from whip_messages, or the fixed \u201CGo faster\u201D.",valueConstraint:d.join("|"),applies:"Applies on the next attach.",group:"display",order:40,format:s(e=>e.whip_message_mode==="go-faster"?"go faster":"random","format"),cycle:s((e,t)=>{e.whip_message_mode=i(d,e.whip_message_mode,t)},"cycle"),setFromString:s((e,t)=>d.includes(t)?(e.whip_message_mode=t,null):`whip_message_mode must be one of: ${d.join("|")}`,"setFromString")}},mouse_mode_default:{surface:"settings",setting:{key:"mouse_mode_default",label:"Default mouse mode",description:"Initial mouse wheel scrolling for each attached viewer.",valueConstraint:p.join("|"),applies:"Applies on the next attach.",group:"display",order:38,format:s(e=>e.mouse_mode_default==="tmux"?"follow tmux":e.mouse_mode_default,"format"),cycle:s((e,t)=>{e.mouse_mode_default=i(p,e.mouse_mode_default,t)},"cycle"),setFromString:s((e,t)=>p.includes(t)?(e.mouse_mode_default=t,null):`mouse_mode_default must be one of: ${p.join("|")}`,"setFromString")}},live_cycles:{surface:"settings",setting:{key:"live_cycles",label:"Live cycles",description:"Trailing refresh cycles rendered at full fidelity; older cycles condense to text.",valueConstraint:"integer >= 1",applies:"Applies on the next attach.",group:"display",order:50,format:s(e=>String(e.live_cycles),"format"),cycle:s((e,t)=>{e.live_cycles=c(x,e.live_cycles,t)},"cycle"),setFromString:s((e,t)=>{const o=_(t,"live_cycles");return typeof o=="string"?o:(e.live_cycles=o,null)},"setFromString")}},condensed_history:{surface:"settings",setting:{key:"condensed_history",label:"Condensed history",description:"Messages retained from condensed cycles. Tool calls are never kept.",valueConstraint:u.join("|"),applies:"Applies on the next attach.",group:"display",order:60,format:s(e=>e.condensed_history,"format"),cycle:s((e,t)=>{e.condensed_history=i(u,e.condensed_history,t)},"cycle"),setFromString:s((e,t)=>u.includes(t)?(e.condensed_history=t,null):`condensed_history must be one of: ${u.join("|")}`,"setFromString")}},bash_tool_purpose:{surface:"settings",setting:{key:"bash_tool_purpose",label:"Bash purpose field",description:"Expose the optional purpose label to agents in the bash tool schema. Off removes the field without disabling the bash valve.",valueConstraint:"true|false",applies:"Applies on the next node session.",group:"display",order:25,format:s(e=>e.bash_tool_purpose?"on":"off","format"),cycle:s(e=>{e.bash_tool_purpose=!e.bash_tool_purpose},"cycle"),setFromString:s((e,t)=>{const o=n(t,"bash_tool_purpose");return typeof o=="string"?o:(e.bash_tool_purpose=o,null)},"setFromString")}},fold_finished_tools:{surface:"settings",setting:{key:"fold_finished_tools",label:"Fold finished tools",description:"Fold every settled tool call to its call line. Toggle live with /fold-tools.",valueConstraint:"true|false",applies:"Applies on the next attach.",group:"display",order:30,format:s(e=>e.fold_finished_tools?"on":"off","format"),cycle:s(e=>{e.fold_finished_tools=!e.fold_finished_tools},"cycle"),setFromString:s((e,t)=>{const o=n(t,"fold_finished_tools");return typeof o=="string"?o:(e.fold_finished_tools=o,null)},"setFromString")}},summarize_tool_calls:{surface:"settings",setting:{key:"summarize_tool_calls",label:"Summarize tool calls",description:"Replace completed folded tool-call groups with a one-line broker summary when available.",valueConstraint:"true|false",applies:"Applies when the next visible message closes a tool-call group.",group:"display",order:35,format:s(e=>e.summarize_tool_calls?"on":"off","format"),cycle:s(e=>{e.summarize_tool_calls=!e.summarize_tool_calls},"cycle"),setFromString:s((e,t)=>{const o=n(t,"summarize_tool_calls");return typeof o=="string"?o:(e.summarize_tool_calls=o,null)},"setFromString")}},detailed_tool_recaps:{surface:"settings",setting:{key:"detailed_tool_recaps",label:"Detailed tool recaps",description:"Show each document read and edited file in folded tool recaps. Off shows a compact count line instead.",valueConstraint:"true|false",applies:"Applies on the next attach.",group:"display",order:36,format:s(e=>e.detailed_tool_recaps?"on":"off","format"),cycle:s(e=>{e.detailed_tool_recaps=!e.detailed_tool_recaps},"cycle"),setFromString:s((e,t)=>{const o=n(t,"detailed_tool_recaps");return typeof o=="string"?o:(e.detailed_tool_recaps=o,null)},"setFromString")}},consolidate_replies:{surface:"settings",setting:{key:"consolidate_replies",label:"Consolidate replies",description:"Experiment: show one rewritten agent reply per message you type, with the working folded behind it (/show-working).",valueConstraint:"true|false",applies:"Applies on the next attach; the broker reads it per turn.",group:"display",order:36.5,format:s(e=>e.consolidate_replies?"on":"off","format"),cycle:s(e=>{e.consolidate_replies=!e.consolidate_replies},"cycle"),setFromString:s((e,t)=>{const o=n(t,"consolidate_replies");return typeof o=="string"?o:(e.consolidate_replies=o,null)},"setFromString")}},keybindings:{surface:"specialized",owner:"Keybindings tab"},tmux_passthrough:{surface:"specialized",owner:"Keybindings tab"},providerOptions:{surface:"settings",settings:{"openai-codex.fastMode":{key:`providerOptions.${l}.fastMode`,label:"Codex fast mode",description:"Serve Codex turns at the ChatGPT priority tier: about 1.5x faster generation for about 2x the credits. Displayed cost does not reflect the premium.",valueConstraint:"true|false",applies:"Applies on each node's next turn.",group:"providers",order:40,format:s(e=>e.providerOptions[l]?.fastMode?"on":"off","format"),cycle:s(e=>{const t=g(e,l);t.fastMode=!t.fastMode},"cycle"),setFromString:s((e,t)=>{const o=n(t,`providerOptions.${l}.fastMode`);return typeof o=="string"?o:(g(e,l).fastMode=o,null)},"setFromString")}}},modelLadders:{surface:"specialized",owner:"Models tab"},modelRoutes:{surface:"specialized",owner:"Models route declarations"},modelRouting:{surface:"specialized",owner:"Models route declarations"},kinds:{surface:"specialized",owner:"Models tab and kind registry"},page_components:{surface:"specialized",owner:"Page component catalog: product-registered page component kinds"},remoteCanvas:{surface:"specialized",owner:"canvas config commands"},api:{surface:"specialized",owner:"sys connect"},paths:{surface:"specialized",owner:"runtime layout"},store:{surface:"specialized",owner:"daemon conversation store"},runtime:{surface:"specialized",owner:"app-facing listener"},spawnEnv:{surface:"specialized",owner:"spawn environment allow-list"},bin:{surface:"specialized",owner:"bare-binary contributions on every node PATH"},humanActions:{surface:"specialized",owner:"scope-configured human completion actions"}},O=Object.keys(h);function S(){const e=[];for(const t of Object.values(h))t.surface==="settings"&&("setting"in t?e.push(t.setting):e.push(...Object.values(t.settings)));return e.sort((t,o)=>t.order-o.order)}s(S,"collectUserSettings");const y=S();function A(e){return y.find(t=>t.key===e)}s(A,"findUserSetting");function z(e){return y.filter(t=>t.group===e)}s(z,"userSettingsInGroup");export{h as CONFIG_SETTINGS_COVERAGE,O as SCOPE_CONFIG_KEYS,y as USER_SETTINGS,A as findUserSetting,z as userSettingsInGroup};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var Se=Object.defineProperty;var a=(e,t)=>Se(e,"name",{value:t,configurable:!0});import{prepared as X}from"../../../core/sqlite-statements.js";import{envProfileId as Oe}from"../../../shared/env.js";import{pausedCanvasProfiles as Re}from"../../../core/profiles/manifest.js";import{existsSync as A,realpathSync as Z,statSync as q}from"node:fs";import{isAbsolute as F,resolve as T}from"node:path";import{appendSituationalContext as Ie,formatSituationalProse as $e}from"../../../core/runtime/situational-context.js";import{closeNode as Ce}from"../../../core/runtime/close.js";import{reviveNode as Ne}from"../../../core/runtime/revive.js";import{nowIso as G}from"../../../core/fs-utils.js";import{assertLaunchModelRegistered as B,forkNode as Ae,resolveForkSource as Te,spawnChildPrepared as Pe}from"../../../core/runtime/spawn.js";import{forkSourceNode as Ee,newNodeId as ee}from"../../../core/runtime/nodes.js";import{abandonCreateRequest as ne,childrenOf as De,completeCreateRequest as te,findCreateRequest as Le,getNode as k,recordCreateRequestNode as je,reserveCreateRequest as oe,reserveCreateRequestNode as Me,listNodes as re,recordRespawnAttempt as Fe,subscribersOf as Ge,subscriptionsOf as ie,setMessageWait as Be,updateNode as N}from"../../../core/canvas/canvas.js";import{subtreeIds as xe}from"../../../core/canvas/nav-model.js";import{withCanvasWrite as x}from"../../../core/canvas/db.js";import{nodeObject as Ke}from"../../../core/graph/objects.js";import{recordActedOn as We}from"../../../core/graph/edges.js";import{publish as Ve}from"../../../core/graph/events.js";import{readerFor as ze}from"../reader.js";import{relocateSessionCwd as Je,unbindSession as Ue}from"../../../core/canvas/sessions.js";import{ticketCountsForNodes as He}from"../../../core/canvas/attention.js";import{isSafeNodeId as Ye}from"../../../core/canvas/paths.js";import{contextDir as de,nodeAgentDir as K}from"../../../core/canvas/node-agent-paths.js";import{checkCronBirth as Qe}from"../../cron/authority.js";import{cronBirthPlacement as Xe}from"../../cron/armed-context.js";import{existsBeneath as Ze,isAbsentOrRefused as qe,isBeneathRefusal as en,readdirBeneath as nn}from"../../../core/spaces/open-beneath.js";import{readNodeMessagesPage as tn,readNodeSession as on,readNodeSnapshot as rn,transcriptMarkdown as dn}from"../../../core/runtime/node-read.js";import{assembleNodeSubject as sn}from"../../../core/substrate/subject.js";import{reviveAll as an}from"../../../core/runtime/revive-all.js";import{promoteAsync as ln,requestYieldAsync as cn,reshapeNodeAsync as W}from"../../../core/runtime/promote.js";import{recycleNode as fn}from"../../../core/runtime/recycle.js";import{relaunchRoot as un}from"../../../core/runtime/reset.js";import{assertReopenGate as pn}from"../../../core/runtime/reopen.js";import{writeYieldMessage as mn,readGoal as hn}from"../../../core/runtime/kickoff.js";import{ensureRoadmap as wn,hasRoadmap as yn}from"../../../core/runtime/roadmap.js";import{renameWindow as _n}from"../../../core/runtime/placement.js";import{buildLaunchSpecAsync as gn,explicitModelIntent as bn,normalizeModel as vn,readMergedLaunchConfigAsync as se}from"../../../core/runtime/launch.js";import{modelRequestFromConfig as kn}from"../../../core/model-routes.js";import{persistDormantModel as Sn,setModelLive as On}from"../../../core/runtime/model-swap.js";import{waitForBrokerViewSocket as Rn}from"../../../core/runtime/view-socket.js";import{BrokerUnreachableError as In}from"../../../core/runtime/broker-request.js";import{boundFleet as V}from"../../../core/runtime/fleet.js";import{admitLegacyStructuredOutput as $n}from"../../structured-requests/sidecar.js";import{OUTCOME_PAYLOAD_MAX_BYTES as ae}from"../../../core/canvas/types.js";import{HUMAN_ACTION_NAME_PATTERN as Cn}from"../../../core/human/action-binding.js";import{resolveHumanAction as Nn}from"../../../core/human-actions.js";import{parseDurationMs as An}from"../../../core/wake.js";import{claimWarmNode as Tn,refillWarmPool as le,resumeWarmClaim as Pn,warmPoolEnabled as En}from"../../../core/runtime/warm-pool.js";import{assertLaunchKind as z,isLaunchKind as Dn,resolveLaunchTarget as Ln}from"../../../core/runtime/launch-target.js";import{fullName as jn}from"../../../core/canvas/labels.js";import{reportsForNode as ce}from"./reports.js";import{requireUsableProfile as Mn}from"./profiles.js";import{assertProfileActive as Fn,loadExactProfileManifest as Gn}from"../../../core/profiles/manifest.js";import{getCron as fe}from"../../../core/canvas/crons.js";import{cronWakeOrigin as Bn}from"../../../core/runtime/bearings.js";import{boundDaemonControl as xn}from"../../control.js";import{notFound as P,usage as h}from"../../../core/errors.js";import{assertScope as Kn,validateScopes as ue}from"../../../core/scopes.js";import{scopeAllowed as R}from"../../../shared/env.js";import{toCloseResultDTO as Wn,toNodeDetailDTO as J,toNodeSummaryDTO as Vn,toReviveResultDTO as zn}from"../map.js";import{ApiError as m}from"../../../api/index.js";import{InputError as w}from"../../../core/io.js";import{brokerMayReach as U,canReadNode as pe,resolvedScopes as Jn}from"../router.js";import{fileRoot as Un}from"../../../core/spaces/file-root.js";import{activeGrant as Hn,terminalGrant as Yn}from"../../../core/grants/mirror.js";import{readConfig as Qn}from"../../../core/config.js";import{hasConfiguredProviderCredential as Xn,NO_PROVIDER_CREDENTIAL_MESSAGE as me}from"../../../core/runtime/provider-credential-gate.js";function y(e){const t=k(e);if(t===null)throw P(`unknown node: ${e}`,{received:e});return t}a(y,"requireMeta");function H(e){return{subscribesTo:ie(e),subscribers:Ge(e),children:De(e)}}a(H,"edgesFor");function g(e){const t=y(e);return J(t,H(e))}a(g,"detailOf");function Zn(e){let t=ce(e).length;try{t+=nn(K(e),de(e)).length}catch(n){if(!qe(n))throw n}return t}a(Zn,"countFiles");function qn(e){if(typeof e!="object"||e===null)throw h("a node create requires a JSON body");const t=e;if(t.kind!==void 0&&(typeof t.kind!="string"||t.kind.trim()===""))throw h("kind must be a non-empty string when provided");if(t.description!==void 0&&(typeof t.description!="string"||t.description.trim()===""))throw h("description must be a non-empty string when provided");if(t.creator!==void 0&&(typeof t.creator!="string"||t.creator.trim()===""))throw h("creator must be a non-empty node id when provided");if(t.scopes!==void 0&&ue(t.scopes),t.isolated!==void 0&&typeof t.isolated!="boolean")throw new m(400,"invalid_request","isolated must be a boolean",{param:"isolated"});const n=t.root_lifecycle;if(n!==void 0&&n!=="resident"&&n!=="terminal")throw h("root_lifecycle must be 'resident' or 'terminal'");if(t.request_key!==void 0&&(typeof t.request_key!="string"||t.request_key.trim()===""||t.request_key.length>128))throw h("request_key must be a non-empty string of at most 128 characters when provided");return t}a(qn,"parseCreateBody");function et(e){if(e===void 0)return;const t=An(e),n=t===null?null:new Date(Date.now()+t);if(t===null||!Number.isFinite(t)||t<=0||n===null||!Number.isFinite(n.getTime()))throw new m(422,"invalid_deadline","`deadline` must be a positive representable duration");return n.toISOString()}a(et,"parseDeadline");function nt(e){if(e!==void 0){if(typeof e!="object"||e===null||Array.isArray(e))throw new m(400,"invalid_request","`outcome_delivery` must be an object");if(typeof e.action!="string"||!Cn.test(e.action))throw new m(400,"invalid_request","`outcome_delivery.action` must be a declared action name");if(e.payload!==void 0){let t;try{t=JSON.stringify(e.payload)}catch{throw new m(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable")}if(t===void 0)throw new m(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable");if(Buffer.byteLength(t,"utf8")>ae)throw new m(413,"payload_too_large",`serialized payload exceeds ${ae} bytes`)}return e}}a(nt,"parseOutcomeDelivery");function tt(e,t){const n=Nn(e.action,t);if(!("kind"in n))return{actionName:e.action,argv:n.argv,cwd:n.cwd,configOrigin:n.configOrigin,...e.payload===void 0?{}:{payload:e.payload}};throw n.kind==="unknown_action"?new m(422,"unknown_action",`no action named ${e.action} is declared from ${t}`):new m(422,"invalid_action",`${e.action} is declared in ${n.configOrigin} but unusable: ${n.reason}`,{reason:n.reason,configOrigin:n.configOrigin})}a(tt,"resolveOutcomeDelivery");function ot(e,t,n){const r={kind:e.kind,cwd:n,prompt:e.prompt??""};return e.mode!==void 0&&(r.mode=e.mode),e.name!==void 0&&(r.name=e.name),e.description!==void 0&&(r.description=e.description),t!==void 0&&(r.parent=t),e.creator!==void 0&&(r.creator=e.creator),e.scopes!==void 0&&(r.scopes=e.scopes),e.isolated!==void 0&&(r.isolated=e.isolated),e.root===!0&&(r.root=!0),e.root_lifecycle!==void 0&&(r.rootLifecycle=e.root_lifecycle),(e.worktree===!0||typeof e.worktree=="string")&&(r.worktree=!0),typeof e.worktree=="string"&&(r.worktreeBase=e.worktree),e.worktree!==void 0&&(r.worktreeCwd=T(e.pin_cwd??e.cwd??n)),e.fork_from!==void 0&&(r.forkFrom=e.fork_from),e.model!==void 0&&(r.model=e.model),e.profile!==void 0&&(r.profile=e.profile),e.situational_context!==void 0&&(r.situationalContext=e.situational_context),e.node_id!==void 0&&(r.nodeId=e.node_id),r}a(ot,"buildRecipe");function rt(e,t,n){return!En()||e.prefer_warm!==!0||e.root!==!0||e.parent!=null||e.root_lifecycle==="terminal"||(e.prompt??"")!==""||e.model!==void 0||e.fork_from!==void 0||e.worktree!==void 0||e.node_id!==void 0||e.scopes!==void 0||e.isolated!==void 0?null:{kind:e.kind,mode:e.mode??"base",cwd:t,profileId:n,model:e.model??null,situationalContext:e.situational_context??null,name:e.name??null,creator:e.creator??null}}a(rt,"warmRequestFor");import{resolveCreateKind as Qo}from"../../../core/runtime/launch-target.js";function he(e){const t=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return kn(e.model,t,e.modelExact===!0)}a(he,"requestFromLaunch");function it(e,t){if(t===null)return e;if(e.scopes===void 0)return{...e,scopes:[...t]};const n=e.scopes.filter(r=>!R(t,r));if(n.length===0)return e;throw new m(403,"scope_denied",`scopes exceed the bearer token's ceiling: ${n.join(", ")}`,{scopes:n,ceiling:t})}a(it,"withinCeiling");async function we(e,t,n){const r=(await gn(t.kind,t.mode,{lifecycle:t.lifecycle,hasManager:e.parent!==null,model:t.model,modelOverride:!0,cwd:e.cwd,profileId:e.profile_id??null})).launch;await B(he(r),{cwd:e.cwd,profileId:e.profile_id??null},n)}a(we,"assertNodeModelChangeRegistered");function ye(e,t){const n=e.principal;if(n.class!=="broker"&&n.class!=="cron")return;const r=Un({app:n.app,resolved:Jn(n),launched:n.scopes},t,"read");if("root"in r)return;const o="missing"in r?r.missing:null;throw new m(403,"scope_missing",o?`the child's directory ${t} needs missing scope ${o}`:`no permission of this run names the child's directory ${t}`,void 0,void 0,o?{scope:o}:void 0)}a(ye,"assertCallerReaches");const Y=new Map;async function dt(e,t={},n={}){const r=it(qn(e.body),e.ceiling);if(e.principal.class==="broker"){const l=e.principal;if(r.prefer_warm===!0&&l.app!=="app:terminal"&&(r.prefer_warm=!1),r.parent!=null){const i=y(r.parent);if(i.grantee!==l.app)throw new m(403,"other_app_run","cannot create a child under another app's node");if(!U(l,r.parent,i.grantee??"app:terminal"))throw P(`unknown node: ${r.parent}`,{received:r.parent})}if(r.creator!==void 0&&r.creator!==l.node)throw new m(403,"other_app_run","cannot create for another node");if(r.fork_from!==void 0){let i=null;try{i=Ee(Te(r.fork_from))}catch{}if(i?.grantee!==l.app||!U(l,i.node_id,i.grantee))throw new m(403,"other_app_run","cannot fork another app's conversation")}r.creator=l.node}if(e.principal.class==="cron"){const l=e.principal;for(const c of["parent","creator","fork_from","node_id"])if(r[c]!=null)throw new m(403,"permission_error",`a cron cannot set ${c} on a node it starts`);r.prefer_warm=!1;const i=Qe({grantee:l.app,sub:l.sub,grant_id:l.grant,scopes:l.scopes});if(!i.allowed)throw new m(i.reason==="scope_missing"?403:401,i.reason==="scope_missing"?"scope_missing":"grant_revoked",i.message);if(r.scopes!==void 0){const c=r.scopes.find(p=>!R(i.effectiveScopes,p)||!R(l.scopes,p));if(c!==void 0)throw new m(403,"scope_missing",`scope ${c} is not held by this cron`,void 0,void 0,{scope:c})}else l.scopes!==null&&(r.scopes=[...l.scopes]);r.node_id=ee(),l.isolated&&(r.isolated=!0,r.cwd=K(r.node_id,l.app))}r.creator!==void 0&&Kn(y(r.creator),"crtr:act");const o=r.request_key?.trim();if(o===void 0||r.node_id!==void 0&&Ye(r.node_id)&&k(r.node_id)!==null&&Le(o)?.nodeId!==r.node_id)return E(e,r,t,n);const d=Y.get(o);if(d!==void 0)return d;const s=st(e,r,o,t,n);Y.set(o,s);try{return await s}finally{Y.delete(o)}}a(dt,"handleCreate");async function st(e,t,n,r,o){const d=oe(n);if(d.nodeId!==null&&k(d.nodeId)!==null){if(d.state!=="warm_claimed"){const s=k(d.nodeId);if(e.principal.class!=="person"&&!pe(e.principal,s.grantee??"app:terminal",d.nodeId))throw new m(409,"create_request_conflict","request_key belongs to another caller");return{status:201,body:g(d.nodeId)}}return E(e,t,r,o,d)}try{return await E(e,t,r,o,d)}catch(s){const l=oe(n);throw(l.nodeId===null||k(l.nodeId)===null)&&ne(n,l.nodeId),s}}a(st,"handleKeyedCreateRequest");async function E(e,t,n,r,o=void 0){const d=r.deadlineAt??et(t.deadline),s=nt(t.outcome_delivery),l=e.principal.class==="cron"?Xe({grantee:e.principal.app,sub:e.principal.sub,grant_id:e.principal.grant,scopes:e.principal.scopes,cron_id:e.principal.cron,origin_run_id:e.principal.origin_run,isolated:e.principal.isolated,creator:fe(e.principal.cron)?.created_by??null},t.node_id):null;l!==null&&(t.root=l.root===!0);const i=l?.parent??t.parent??void 0;if(i==null&&t.root!==!0)throw h("a node create requires a parent (or root: true for an independent root)");let c=null;if(t.output_schema!==void 0)try{c=JSON.parse(t.output_schema)}catch{throw h("output_schema must be a JSON schema string")}const{profileId:p,kind:u,cwd:f,launch:_}=await Ln(t,{validateKind:ke});ye(e,f),t.worktree!==void 0&&ye(e,T(t.pin_cwd??t.cwd??f));const S={...t,kind:u},I=s===void 0?void 0:tt(s,f);if(await B(he(_),{cwd:f,profileId:p},n.modelRegistry),!await Xn(p))throw new m(412,"no_provider_credential",me,{error:"no_provider_credential",message:me,next:"The person running this runtime logs a provider in with `crtr sys setup`, or stores a provider key on the profile."});let L=null;{const $=o===void 0||o.nodeId===null||o.state==="warm_claimed"?rt(S,f,p):null,j=c===null&&r.beforeBrokerLaunch===void 0?void 0:v=>{c!==null&&$n(v,"terminal",c),r.beforeBrokerLaunch?.(v)};if(o?.state==="warm_claimed"&&o.nodeId!==null){const v=$===null?null:await Pn($,o.nodeId,j);if(v===null)throw ne(o.requestKey,o.nodeId),new m(503,"create_resume_failed",`could not resume warm claim ${o.nodeId}; retry the create`);return te(o.requestKey,v),{status:201,body:g(v)}}if($!==null){const v=await Tn($,{...d===void 0?{}:{deadlineAt:d},...I===void 0?{}:{outcomeDelivery:I},...o===void 0?{}:{requestKey:o.requestKey}},j);if(v!==null)return o!==void 0&&te(o.requestKey,v),le($),{status:201,body:g(v)};L=$}const M=o?.nodeId??t.node_id??(o===void 0?void 0:ee());o!==void 0&&o.nodeId===null&&Me(o.requestKey,M);const O=ot(M===void 0?S:{...S,node_id:M},i,f);l!==null&&(l.rootLifecycle!==void 0&&(O.rootLifecycle=l.rootLifecycle),l.scopes!==void 0&&S.scopes===void 0&&(O.scopes=l.scopes),l.run!==void 0&&(O.run=l.run),l.withinCreate!==void 0&&(O.withinCreate=l.withinCreate)),d!==void 0&&(O.deadlineAt=d),I!==void 0&&(O.outcomeDelivery=I),O.readiness=t.root===!0?"await":"launch";const Q=await Pe(O,j,()=>{L!==null&&le(L)});return o!==void 0&&je(o.requestKey,Q.node.node_id),{status:201,body:g(Q.node.node_id)}}}a(E,"handleCreateRequest");function b(e,t){const n=e.query.getAll(t);if(n.length>1)throw h(`${t} must appear at most once`);return n[0]}a(b,"singleQueryValue");function _e(e,t){if(e!==void 0){if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw h(`${t} must be true or false`)}}a(_e,"optionalBoolean");function D(e,t,n){if(e!==void 0){if(n.includes(e))return e;throw h(`${t} must be one of: ${n.join(", ")}`)}}a(D,"oneOf");function at(e){const t=new Set(["status","lifecycle","kind","mode","profile_id","profile_prefix","parent","top_level","under","hanging","include"]);for(const[_]of e.query)if(!t.has(_))throw h(`unknown nodes query parameter: ${_}`);const n=D(b(e,"status"),"status",["active","idle","done","dead","canceled"]),r=D(b(e,"lifecycle"),"lifecycle",["terminal","resident"]),o=b(e,"kind"),d=D(b(e,"mode"),"mode",["base","orchestrator"]),s=b(e,"profile_id"),l=b(e,"profile_prefix"),i=b(e,"parent"),c=_e(b(e,"top_level"),"top_level"),p=b(e,"under"),u=_e(b(e,"hanging"),"hanging"),f=D(b(e,"include"),"include",["activity"]);if(i!==void 0&&c===!0)throw h("parent and top_level=true cannot be combined");return{...n!==void 0?{status:n}:{},...r!==void 0?{lifecycle:r}:{},...o!==void 0?{kind:o}:{},...d!==void 0?{mode:d}:{},...s!==void 0?{profile_id:s}:{},...l!==void 0?{profile_prefix:l}:{},...i!==void 0?{parent:i}:{},...c!==void 0?{top_level:c}:{},...p!==void 0?{under:p}:{},...u!==void 0?{hanging:u}:{},...f!==void 0?{include:f}:{}}}a(at,"parseListQuery");function lt(e){const t=at(e);let n=t.status!==void 0?re({status:t.status}):re();if(e.principal.class!=="person"&&(n=n.filter(s=>pe(e.principal,s.grantee??"app:terminal",s.node_id))),t.lifecycle!==void 0&&(n=n.filter(s=>s.lifecycle===t.lifecycle)),t.kind!==void 0&&(n=n.filter(s=>s.kind===t.kind)),t.mode!==void 0&&(n=n.filter(s=>s.mode===t.mode)),t.profile_id!==void 0&&(n=n.filter(s=>s.profile_id===t.profile_id)),t.profile_prefix!==void 0&&(n=n.filter(s=>s.profile_id?.startsWith(t.profile_prefix))),t.parent!==void 0&&(n=n.filter(s=>s.parent===t.parent)),t.top_level===!0&&(n=n.filter(s=>s.parent===null)),t.under!==void 0){const s=new Set(xe(t.under));n=n.filter(l=>s.has(l.node_id))}t.hanging===!0&&(n=n.filter(s=>s.parent!==null&&k(s.parent)===null));const r=t.include==="activity"?He(n.map(s=>s.node_id)):null,o=n.length>0?Re():new Set;return{status:200,body:n.map(s=>{const l=Vn(s,s.profile_id!==null&&o.has(s.profile_id));if(r!==null){const i=ce(s.node_id);l.activity={latest_report:i[0]??null,final_report:s.final_report===null?null:i.find(c=>c.name===s.final_report)??null,pending_human_count:r[s.node_id]??0}}return l})}}a(lt,"handleList");function ct(e){const t=e.params.id;return y(t),{status:200,body:g(t)}}a(ct,"handleDetail");async function ft(e){const t=e.params.id;y(t);const n=await rn(t);return{status:200,body:{node_id:t,snapshot:{messages:n.snapshot.messages,...n.snapshot.messageIds===void 0?{}:{messageIds:n.snapshot.messageIds},messageVisibility:n.snapshot.messageVisibility,turnVisibility:n.snapshot.turnVisibility,stats:n.snapshot.stats,state:n.snapshot.state,display:n.snapshot.display,...n.snapshot.queued===void 0?{}:{queued:n.snapshot.queued},...n.snapshot.toolGroupSummaries===void 0?{}:{toolGroupSummaries:n.snapshot.toolGroupSummaries},...n.snapshot.workingActivity===void 0?{}:{workingActivity:n.snapshot.workingActivity}},commands:n.commands.map(o=>({name:o.name,description:o.description,source:o.source})),captured_at:G()}}}a(ft,"handleSnapshot");async function ut(e){const t=e.params.id,n=sn(t);if(n===null)throw P(`unknown node: ${t}`,{received:t});return{status:200,body:n}}a(ut,"handleSubject");function pt(e){for(const[d]of e.query)if(d!=="cursor"&&d!=="limit")throw h(`unknown messages query parameter: ${d}`);const t=e.query.getAll("cursor"),n=e.query.getAll("limit");if(t.length>1)throw h("cursor must appear at most once");if(n.length>1)throw h("limit must appear at most once");if(n.length===0)return t.length===0?{}:{cursor:t[0]};const r=n[0],o=Number(r);if(!Number.isSafeInteger(o)||r==="")throw h("limit must be an integer from 1 through 500");return t.length===0?{limit:o}:{cursor:t[0],limit:o}}a(pt,"parseMessagesQuery");async function mt(e){const t=e.params.id,n=await tn(t,pt(e));return{status:200,body:{node_id:t,messages:n.messages,...n.messageIds===void 0?{}:{message_ids:n.messageIds},message_visibility:n.messageVisibility,next_cursor:n.nextCursor,captured_at:G()}}}a(mt,"handleMessages");function ht(e){const t=e.params.id;y(t);const n=on(t);return{status:200,body:{node_id:t,session_file:n.sessionFile,session_jsonl:n.sessionJsonl,system_prompt:n.systemPrompt,captured_at:G()}}}a(ht,"handleSession");async function wt(e){const t=e.params.id;return y(t),{status:200,body:{node_id:t,markdown:await dn(t)}}}a(wt,"handleTranscript");function yt(e){const t=e.params.id;y(t);const n=a((o,d)=>({node_id:o,label:k(o)?.name??o,dir:de(o),self:d,files:Zn(o)}),"root"),r=[n(t,!0),...ie(t).map(o=>n(o.node_id,!1))].filter(o=>_t(o.node_id,o.dir)||o.files>0);return{status:200,body:{node_id:t,roots:r}}}a(yt,"handleContext");function _t(e,t){try{return Ze(K(e),t)}catch(n){if(en(n))return!1;throw n}}a(_t,"hasDir");async function gt(e){const t=y(e.params.id),n=e.principal.class==="broker"?e.principal.scopes:e.ceiling,r=n===null?void 0:t.scopes==null?[...n]:[...new Set([...t.scopes.filter(d=>R(n,d)),...n.filter(d=>R(t.scopes,d))])],o=await Ae(t.node_id,r,e.principal.class==="broker"?e.principal.node:void 0);return{status:201,body:g(o.node.node_id)}}a(gt,"handleFork");async function bt(e){const t=e.params.id;y(t);const n=e.body,r=n?.resume??!0,o=n?.reopen??!1;pn(t,o);const d=!r&&n?.cron_id!==void 0?fe(n.cron_id):null,s=await Ne(t,{resume:r,capacity:"refuse",...d!==null?{wakeReason:Bn(d,"schedule_revive")}:{}});s.outcome!=="already-live"&&Fe(t,{failures:0,notBefore:null});const l=k(t)?.status??"active";return{status:200,body:zn(t,s,l)}}a(bt,"handleRevive");async function vt(e){const t=e.params.id;return{status:200,body:{newNodeId:(await un(t))?.newNodeId??null}}}a(vt,"handleRelaunchRoot");function kt(e){const t=e.params.id;y(t);const n=e.body;if(n?.caller_pid!==void 0&&(!Number.isInteger(n.caller_pid)||n.caller_pid<=0))throw h("caller_pid must be a positive integer when provided");const r=xn(),o=Ce(t,{rootEvent:n?.finish===!0?"finish":"cancel",callerPid:n?.caller_pid,...e.principal.class==="broker"?{closer:e.principal.node}:{},...r===null?{}:{registerDetached:r.registerDetached}});return{status:200,body:Wn(o)}}a(kt,"handleClose");async function St(e){const t=e.params.id;y(t);const n=await fn(t);return{status:200,body:{recycled:n.recycled,finalized:n.finalized,new_root:n.newRoot,delivered:n.delivered}}}a(St,"handleRecycle");async function Ot(e){const t=e.params.id;return y(t),await W(t,{lifecycle:"terminal"}),C(e,t,["lifecycle"]),{status:200,body:g(t)}}a(Ot,"handleDemote");async function Rt(e,t={}){const n=e.params.id,r=y(n),o=e.body??{};o.kind!==void 0&&await z(o.kind,r.cwd,r.profile_id??null),o.model!==void 0&&await we(r,{kind:o.kind??r.kind,mode:"orchestrator",lifecycle:o.resident===!0?"resident":r.lifecycle,model:o.model},t.modelRegistry);const d=await ln(n,{...o.kind!==void 0?{kind:o.kind}:{},...o.resident===!0?{resident:!0}:{},...o.model!==void 0?{model:o.model}:{}});C(e,n,["mode",...o.kind!==void 0?["kind"]:[],...o.resident===!0?["lifecycle"]:[],...o.model!==void 0?["model"]:[]]);const s=J(d.meta,H(n));return s.roadmap_written=d.roadmapWritten,s.roadmap_ref=d.roadmapRef,s.goal_path=d.goalPath,{status:200,body:s}}a(Rt,"handlePromote");async function It(e,t={}){const n=e.params.id,r=y(n),o=e.body??{};o.kind!==void 0&&await z(o.kind,r.cwd,r.profile_id??null),o.model!==void 0&&await we(r,{kind:o.kind??r.kind,mode:o.promote===!0?"orchestrator":r.mode,lifecycle:r.lifecycle,model:o.model},t.modelRegistry);const d=o.note??"Refresh: continue against your roadmap or goal.";mn(n,d);const s=await cn(n,{...o.promote===!0?{promote:!0}:{},...o.kind!==void 0?{kind:o.kind}:{},...o.model!==void 0?{model:o.model}:{}});return{status:200,body:J(s.meta,H(n))}}a(It,"handleYield");function $t(e){const t=e.params.id;y(t);const n=e.body;if(n===void 0||typeof n.controller!="string"||n.controller.trim()==="")throw h("a wait requires a controller node id");const r=k(n.controller);if(r===null)throw P(`unknown controller: ${n.controller}`,{received:n.controller});if(r.status!=="active"&&r.status!=="idle")throw new m(422,"unprocessable",`controller ${n.controller} is ${r.status}`);return Be(t,n.controller),{status:200,body:g(t)}}a($t,"handleWait");async function Ct(e){const t=e.principal,n=await an(t.class==="broker"?o=>o.grantee===t.app&&U(t,o.node_id,o.grantee):void 0);return{status:200,body:{revived:[...n.revived],failed:[...n.failed],frozen:[...n.frozen]}}}a(Ct,"handleReviveAll");const Nt=new Set(["interrupt","steer","after-turn","next-turn"]);function At(e){if(e===null)return null;const t=a(r=>{throw new w({error:"invalid_listen",message:r,received:e,field:"listen",next:'Send an object mapping levels "1".."10" to interrupt|steer|after-turn|next-turn (e.g. {"3":"next-turn"}), or null to reset to the global default.'})},"bad");if(typeof e!="object"||Array.isArray(e))return t("listen must be an object or null");const n=Object.entries(e);if(n.length===0)return t("listen must name at least one level");for(const[r,o]of n)/^(?:[1-9]|10)$/.test(r)||t(`listen level must be 1..10: ${r}`),(typeof o!="string"||!Nt.has(o))&&t(`listen delivery must be interrupt|steer|after-turn|next-turn: ${String(o)}`);return JSON.stringify(Object.fromEntries(n))}a(At,"listenJson");function C(e,t,n,r){n.length===0&&r===void 0||x(o=>{if(r?.(o),n.length===0)return;const d=Ke(o,t),s=ze(o,e),l=s.class==="person"?s.person:s.class==="app"?s.app:s.node;We(o,l,d),Ve(o,{event:"configured",object:d,actor:l,attrs:{changed:n.join(",")}})})}a(C,"recordConfigured");function ge(e){const t=V().get(e);if(t===void 0)return!1;try{return process.kill(t.pid,"SIGTERM"),!0}catch{return!1}}a(ge,"restartLiveBroker");function be(e,t){try{return Z(e)===Z(t)}catch{return!1}}a(be,"sameDirectory");async function Tt(e,t={}){const n=e.params.id,r=e.body;let o;if(r===void 0)o={};else if(typeof r=="object"&&r!==null&&!Array.isArray(r))o=r;else throw new w({error:"cwd_invalid",message:"cwd repair requires a non-null object with a non-empty cwd string",received:r,field:"cwd",next:"Send a config patch with a non-empty absolute cwd string."});if(o.profile!==void 0){if(typeof o.profile!="string"||o.profile==="")throw new w({error:"profile_invalid",message:"profile must be a non-empty profile id or name",received:o.profile,field:"profile",next:"Send a profile id or exact name."});if(Object.keys(o).some(u=>u!=="profile"&&u!=="restart"&&o[u]!==void 0))throw new w({error:"profile_not_exclusive",message:"profile can only be combined with restart",field:"profile",next:"Send profile (and optionally restart) alone."});const i=y(n),c=Mn(e,o.profile);Fn(c.profileId);const p=Gn(c.profileId).manifest.grantee??"app:terminal";if(p!==(i.grantee??"app:terminal"))throw new w({error:"profile_grantee_mismatch",message:`profile ${c.profileId} belongs to ${p}, node ${n} to ${i.grantee}`,received:o.profile,field:"profile",next:"Pick a profile owned by the same app as the node."});return(i.profile_id??null)!==c.profileId&&(Dn(i.kind)?(await z(i.kind,i.cwd,c.profileId),await W(n,{profileId:c.profileId})):N(n,{profile_id:c.profileId}),C(e,n,["profile"])),o.restart===!0&&ge(n),{status:200,body:g(n)}}if(Object.prototype.hasOwnProperty.call(o,"cwd")){const i=o.cwd;if(typeof i!="string"||i==="")throw new w({error:"cwd_invalid",message:"cwd must be a non-empty string",received:i,field:"cwd",next:"Send a non-empty absolute cwd string."});if(Object.keys(o).some(f=>f!=="cwd"&&f!=="keep_session"&&f!=="restart"&&o[f]!==void 0))throw new w({error:"cwd_not_exclusive",message:"cwd repair cannot be combined with another config field",received:o,field:"cwd",next:"Send cwd as the only config field."});const c=y(n),p=A(c.cwd);if(o.keep_session===!0||p&&F(i)&&A(i)&&be(c.cwd,i)){if(!F(i))throw new w({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${i}`,received:i,field:"cwd",next:"Send an absolute path."});const f=T(i);let _=!1;try{_=q(f).isDirectory()}catch{}if(!_)throw new w({error:"cwd_missing",message:`cwd is not an existing directory: ${f}`,received:i,field:"cwd",next:"Send an existing absolute directory."});if(p&&!be(c.cwd,f))throw new w({error:"cwd_not_same_directory",message:`${f} is not the same directory as the recorded ${c.cwd}; --keep-session only relocates an alias`,received:i,field:"cwd",next:"Drop --keep-session to repair a gone cwd, or pass the real path of the recorded directory."});if(c.managed_worktree?.state==="open")throw new w({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot relocate its cwd`,received:i,field:"cwd",next:"Reconcile the managed worktree first."});const S=c.cwd;return S!==f&&(x(I=>{N(n,{cwd:f}),X(I,"UPDATE crons SET cwd = ? WHERE anchor_node = ? AND cwd = ?").run(f,n,S),Je(n,S,f)}),C(e,n,["cwd"])),o.restart===!0&&ge(n),{status:200,body:g(n)}}if(V().has(n)){const f=`${n} cannot repair its cwd while its broker is live`;throw new m(409,"cwd_node_live",f,{error:"cwd_node_live",message:f,received:i,field:"cwd",next:"Let the node become dormant, then retry the cwd repair."})}if(c.fork_from!=null)throw new w({error:"cwd_node_forked",message:`${n} is a fork and cannot repair its cwd; recorded cwd: ${c.cwd}`,received:i,field:"cwd",next:`Restore ${c.cwd}, then revive the fork normally.`});if(c.managed_worktree?.state==="open")throw new w({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot repair its cwd`,received:i,field:"cwd",next:"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon flow."});if(A(c.cwd))throw new w({error:"cwd_still_present",message:`${n} recorded cwd still exists: ${c.cwd}; cwd repair is not a relocation command`,received:i,field:"cwd",next:"This command only repairs a node whose recorded cwd is gone."});if(!F(i))throw new w({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${i}`,received:i,field:"cwd",next:"Send an absolute path."});const u=T(i);if(!A(u))throw new w({error:"cwd_missing",message:`cwd does not exist: ${u}`,received:i,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."});try{if(!q(u).isDirectory())throw new w({error:"cwd_not_a_directory",message:`cwd is not a directory: ${u}`,received:i,field:"cwd",next:"Send an existing absolute directory."})}catch(f){throw f instanceof w?f:new w({error:"cwd_missing",message:`cwd does not exist: ${u}`,received:i,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."})}return x(()=>{N(n,{cwd:u}),Ue(n)}),C(e,n,["cwd"]),{status:200,body:g(n)}}let d=y(n);const s=o.listen===void 0?void 0:At(o.listen);if(o.scopes!==void 0){const i=ue(o.scopes),c=d.grantee==="app:terminal"?Yn():d.grant_id?Hn(d.grant_id):null,p=d.grantee==="app:terminal"&&!Qn("user").runtime?.issuer;if(!i.every(u=>R(d.scopes,u)&&(c?R(c.resolved,u):p)))throw new w({error:"unknown_scope",message:"scopes may only narrow the node's current effective set",received:i,field:"scopes",next:"Send only scopes the node currently holds."});if(i.includes("crtr:act")&&!R(i,"crtr:llm"))throw new m(400,"invalid_scope","crtr:act requires crtr:llm");d=N(n,{scopes:i})}if(o.situational_context!==void 0&&Ie(n,$e(o.situational_context)),o.model!==void 0){const i=(await se(d.cwd,d.profile_id??null)).modelLadders,c=bn(o.model,i),p=vn(o.model,i);await B({kind:"concrete",spec:p},{cwd:d.cwd,profileId:d.profile_id??null},t.modelRegistry);const u=V();let f=!1;if(u.isClaimed(n)&&await Rn(n,u.get(n)?.handle.exited)&&(f=await On(n,p,c).then(()=>!0,_=>{if(_ instanceof In)return!1;throw _})),!f){if(u.isClaimed(n)){const _=`${n}'s broker did not accept the model switch; the model was not changed`;throw new m(409,"broker_not_ready",_,{error:"broker_not_ready",message:_,received:o.model,field:"model",next:"Check the node with `crtr node show`, then retry the model change."})}if(!p.includes("/"))throw h(`model must resolve to a provider/id spec: ${o.model}`);Sn(n,p,c)}d=y(n)}if(o.kind!==void 0||o.mode!==void 0||o.lifecycle!==void 0){o.kind!==void 0&&await ke(o.kind);const i=o.kind??d.kind,c=o.mode??d.mode,p=o.lifecycle??d.lifecycle;let u;c==="orchestrator"&&!yn(n)&&(u=a(()=>{const f=hn(n);wn(n,f!==null&&f.trim()!==""?{goal:f.trim()}:{})},"beforePersist")),d=await W(n,{...o.kind!==void 0?{kind:i}:{},...o.mode!==void 0?{mode:c}:{},...o.lifecycle!==void 0?{lifecycle:p}:{}},u)}o.name!==void 0&&(d=N(n,{name:o.name}),d.window&&_n(d.window,jn(d)));const l=["scopes","situational_context","model","kind","mode","lifecycle","name","listen"].filter(i=>o[i]!==void 0);return C(e,n,l,s===void 0?void 0:i=>{X(i,"UPDATE objects SET listen_json = ? WHERE id = ? AND type = 'node'").run(s,n)}),{status:200,body:g(n)}}a(Tt,"handleConfig");async function ve(){return(await se(process.cwd(),Oe()||null)).kinds}a(ve,"daemonKinds");async function ke(e){const t=Object.keys(await ve());if(!t.includes(e))throw h(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${t.sort().join(", ")}.`})}a(ke,"assertKindServer");async function Pt(){const e=await ve();return{status:200,body:{kinds:Object.keys(e).sort().map(n=>({kind:n,when_to_use:e[n]?.whenToUse??null,available_to:e[n]?.availableTo??null}))}}}a(Pt,"handleListKinds");const Uo=[{method:"POST",pattern:"/v1/nodes",scope:"crtr:act",handler:dt},{method:"GET",pattern:"/v1/nodes",handler:lt},{method:"GET",pattern:"/v1/kinds",handler:a(()=>Pt(),"handler")},{method:"POST",pattern:"/v1/nodes/revive-all",scope:"crtr:act",handler:Ct},{method:"GET",pattern:"/v1/nodes/:id",handler:ct},{method:"GET",pattern:"/v1/nodes/:id/snapshot",handler:ft},{method:"GET",pattern:"/v1/nodes/:id/subject",handler:ut},{method:"GET",pattern:"/v1/nodes/:id/messages",handler:mt},{method:"GET",pattern:"/v1/nodes/:id/session",handler:ht},{method:"GET",pattern:"/v1/nodes/:id/transcript",handler:wt},{method:"GET",pattern:"/v1/nodes/:id/context",handler:yt},{method:"POST",pattern:"/v1/nodes/:id/fork",scope:"crtr:act",handler:gt},{method:"POST",pattern:"/v1/nodes/:id/revive",scope:"crtr:act",handler:bt},{method:"POST",pattern:"/v1/nodes/:id/relaunch-root",scope:"crtr:act",handler:vt},{method:"POST",pattern:"/v1/nodes/:id/close",handler:kt},{method:"POST",pattern:"/v1/nodes/:id/recycle",scope:"crtr:act",handler:St},{method:"POST",pattern:"/v1/nodes/:id/demote",scope:"crtr:act",handler:Ot},{method:"POST",pattern:"/v1/nodes/:id/promote",scope:"crtr:act",handler:Rt},{method:"POST",pattern:"/v1/nodes/:id/yield",scope:"crtr:act",handler:It},{method:"POST",pattern:"/v1/nodes/:id/wait",handler:$t},{method:"PATCH",pattern:"/v1/nodes/:id/config",handler:Tt}];export{Tt as handleConfig,dt as handleCreate,gt as handleFork,lt as handleList,Rt as handlePromote,It as handleYield,Uo as nodeRoutes,Qo as resolveCreateKind};
|
|
1
|
+
var Se=Object.defineProperty;var a=(e,t)=>Se(e,"name",{value:t,configurable:!0});import{prepared as X}from"../../../core/sqlite-statements.js";import{envProfileId as Re}from"../../../shared/env.js";import{pausedCanvasProfiles as Oe}from"../../../core/profiles/manifest.js";import{existsSync as A,realpathSync as Z,statSync as q}from"node:fs";import{isAbsolute as F,resolve as T}from"node:path";import{appendSituationalContext as Ie,formatSituationalProse as $e}from"../../../core/runtime/situational-context.js";import{closeNode as Ce}from"../../../core/runtime/close.js";import{reviveNode as Ne}from"../../../core/runtime/revive.js";import{nowIso as G}from"../../../core/fs-utils.js";import{assertLaunchModelRegistered as B,forkNode as Ae,resolveForkSource as Te,spawnChildPrepared as Pe}from"../../../core/runtime/spawn.js";import{forkSourceNode as Ee,newNodeId as ee}from"../../../core/runtime/nodes.js";import{abandonCreateRequest as ne,childrenOf as De,completeCreateRequest as te,findCreateRequest as Le,getNode as k,recordCreateRequestNode as je,reserveCreateRequest as oe,reserveCreateRequestNode as Me,listNodes as re,recordRespawnAttempt as Fe,subscribersOf as Ge,subscriptionsOf as ie,setMessageWait as Be,updateNode as N}from"../../../core/canvas/canvas.js";import{subtreeIds as xe}from"../../../core/canvas/nav-model.js";import{withCanvasWrite as x}from"../../../core/canvas/db.js";import{nodeObject as Ke}from"../../../core/graph/objects.js";import{recordActedOn as We}from"../../../core/graph/edges.js";import{publish as Ve}from"../../../core/graph/events.js";import{readerFor as ze}from"../reader.js";import{relocateSessionCwd as Je,unbindSession as Ue}from"../../../core/canvas/sessions.js";import{ticketCountsForNodes as He}from"../../../core/canvas/attention.js";import{isSafeNodeId as Ye}from"../../../core/canvas/paths.js";import{contextDir as de,nodeAgentDir as K}from"../../../core/canvas/node-agent-paths.js";import{checkCronBirth as Qe}from"../../cron/authority.js";import{cronBirthPlacement as Xe}from"../../cron/armed-context.js";import{existsBeneath as Ze,isAbsentOrRefused as qe,isBeneathRefusal as en,readdirBeneath as nn}from"../../../core/spaces/open-beneath.js";import{readNodeMessagesPage as tn,readNodeSession as on,readNodeSnapshot as rn,transcriptMarkdown as dn}from"../../../core/runtime/node-read.js";import{assembleNodeSubject as sn}from"../../../core/substrate/subject.js";import{reviveAll as an}from"../../../core/runtime/revive-all.js";import{promoteAsync as ln,requestYieldAsync as cn,reshapeNodeAsync as W}from"../../../core/runtime/promote.js";import{recycleNode as fn}from"../../../core/runtime/recycle.js";import{relaunchRoot as un}from"../../../core/runtime/reset.js";import{assertReopenGate as pn}from"../../../core/runtime/reopen.js";import{writeYieldMessage as mn,readGoal as hn}from"../../../core/runtime/kickoff.js";import{ensureRoadmap as wn,hasRoadmap as yn}from"../../../core/runtime/roadmap.js";import{renameWindow as _n}from"../../../core/runtime/placement.js";import{buildLaunchSpecAsync as gn,explicitModelIntent as bn,normalizeModel as vn,readMergedLaunchConfigAsync as se}from"../../../core/runtime/launch.js";import{modelRequestFromConfig as kn}from"../../../core/model-routes.js";import{persistDormantModel as Sn,setModelLive as Rn}from"../../../core/runtime/model-swap.js";import{waitForBrokerViewSocket as On}from"../../../core/runtime/view-socket.js";import{BrokerUnreachableError as In}from"../../../core/runtime/broker-request.js";import{boundFleet as V}from"../../../core/runtime/fleet.js";import{admitLegacyStructuredOutput as $n}from"../../structured-requests/sidecar.js";import{OUTCOME_PAYLOAD_MAX_BYTES as ae}from"../../../core/canvas/types.js";import{HUMAN_ACTION_NAME_PATTERN as Cn}from"../../../core/human/action-binding.js";import{resolveHumanAction as Nn}from"../../../core/human-actions.js";import{parseDurationMs as An}from"../../../core/wake.js";import{claimWarmNode as Tn,refillWarmPool as le,resumeWarmClaim as Pn,warmPoolEnabled as En}from"../../../core/runtime/warm-pool.js";import{assertLaunchKind as z,isLaunchKind as Dn,resolveLaunchTarget as Ln}from"../../../core/runtime/launch-target.js";import{fullName as jn}from"../../../core/canvas/labels.js";import{reportsForNode as ce}from"./reports.js";import{requireUsableProfile as Mn}from"./profiles.js";import{assertProfileActive as Fn,loadExactProfileManifest as Gn}from"../../../core/profiles/manifest.js";import{getCron as fe}from"../../../core/canvas/crons.js";import{cronWakeOrigin as Bn}from"../../../core/runtime/bearings.js";import{boundDaemonControl as xn}from"../../control.js";import{notFound as P,usage as h}from"../../../core/errors.js";import{assertScope as Kn,validateScopes as ue}from"../../../core/scopes.js";import{scopeAllowed as O}from"../../../shared/env.js";import{toCloseResultDTO as Wn,toNodeDetailDTO as J,toNodeSummaryDTO as Vn,toReviveResultDTO as zn}from"../map.js";import{ApiError as m}from"../../../api/index.js";import{InputError as w}from"../../../core/io.js";import{brokerMayReach as U,canReadNode as pe,resolvedScopes as Jn}from"../router.js";import{fileRoot as Un}from"../../../core/spaces/file-root.js";import{activeGrant as Hn,terminalGrant as Yn}from"../../../core/grants/mirror.js";import{readConfig as Qn}from"../../../core/config.js";import{hasConfiguredProviderCredential as Xn,NO_PROVIDER_CREDENTIAL_MESSAGE as me}from"../../../core/runtime/provider-credential-gate.js";function y(e){const t=k(e);if(t===null)throw P(`unknown node: ${e}`,{received:e});return t}a(y,"requireMeta");function H(e){return{subscribesTo:ie(e),subscribers:Ge(e),children:De(e)}}a(H,"edgesFor");function g(e){const t=y(e);return J(t,H(e))}a(g,"detailOf");function Zn(e){let t=ce(e).length;try{t+=nn(K(e),de(e)).length}catch(n){if(!qe(n))throw n}return t}a(Zn,"countFiles");function qn(e){if(typeof e!="object"||e===null)throw h("a node create requires a JSON body");const t=e;if(t.kind!==void 0&&(typeof t.kind!="string"||t.kind.trim()===""))throw h("kind must be a non-empty string when provided");if(t.description!==void 0&&(typeof t.description!="string"||t.description.trim()===""))throw h("description must be a non-empty string when provided");if(t.creator!==void 0&&(typeof t.creator!="string"||t.creator.trim()===""))throw h("creator must be a non-empty node id when provided");if(t.scopes!==void 0&&ue(t.scopes),t.isolated!==void 0&&typeof t.isolated!="boolean")throw new m(400,"invalid_request","isolated must be a boolean",{param:"isolated"});const n=t.root_lifecycle;if(n!==void 0&&n!=="resident"&&n!=="terminal")throw h("root_lifecycle must be 'resident' or 'terminal'");if(t.request_key!==void 0&&(typeof t.request_key!="string"||t.request_key.trim()===""||t.request_key.length>128))throw h("request_key must be a non-empty string of at most 128 characters when provided");return t}a(qn,"parseCreateBody");function et(e){if(e===void 0)return;const t=An(e),n=t===null?null:new Date(Date.now()+t);if(t===null||!Number.isFinite(t)||t<=0||n===null||!Number.isFinite(n.getTime()))throw new m(422,"invalid_deadline","`deadline` must be a positive representable duration");return n.toISOString()}a(et,"parseDeadline");function nt(e){if(e!==void 0){if(typeof e!="object"||e===null||Array.isArray(e))throw new m(400,"invalid_request","`outcome_delivery` must be an object");if(typeof e.action!="string"||!Cn.test(e.action))throw new m(400,"invalid_request","`outcome_delivery.action` must be a declared action name");if(e.payload!==void 0){let t;try{t=JSON.stringify(e.payload)}catch{throw new m(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable")}if(t===void 0)throw new m(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable");if(Buffer.byteLength(t,"utf8")>ae)throw new m(413,"payload_too_large",`serialized payload exceeds ${ae} bytes`)}return e}}a(nt,"parseOutcomeDelivery");function tt(e,t){const n=Nn(e.action,t);if(!("kind"in n))return{actionName:e.action,argv:n.argv,cwd:n.cwd,configOrigin:n.configOrigin,...e.payload===void 0?{}:{payload:e.payload}};throw n.kind==="unknown_action"?new m(422,"unknown_action",`no action named ${e.action} is declared from ${t}`):new m(422,"invalid_action",`${e.action} is declared in ${n.configOrigin} but unusable: ${n.reason}`,{reason:n.reason,configOrigin:n.configOrigin})}a(tt,"resolveOutcomeDelivery");function ot(e,t,n){const r={kind:e.kind,cwd:n,prompt:e.prompt??""};return e.mode!==void 0&&(r.mode=e.mode),e.name!==void 0&&(r.name=e.name),e.description!==void 0&&(r.description=e.description),t!==void 0&&(r.parent=t),e.creator!==void 0&&(r.creator=e.creator),e.scopes!==void 0&&(r.scopes=e.scopes),e.isolated!==void 0&&(r.isolated=e.isolated),e.root===!0&&(r.root=!0),e.root_lifecycle!==void 0&&(r.rootLifecycle=e.root_lifecycle),(e.worktree===!0||typeof e.worktree=="string")&&(r.worktree=!0),typeof e.worktree=="string"&&(r.worktreeBase=e.worktree),e.worktree!==void 0&&(r.worktreeCwd=T(e.pin_cwd??e.cwd??n)),e.fork_from!==void 0&&(r.forkFrom=e.fork_from),e.model!==void 0&&(r.model=e.model),e.profile!==void 0&&(r.profile=e.profile),e.situational_context!==void 0&&(r.situationalContext=e.situational_context),e.node_id!==void 0&&(r.nodeId=e.node_id),r}a(ot,"buildRecipe");function rt(e,t,n){return!En()||e.prefer_warm!==!0||e.root!==!0||e.parent!=null||e.root_lifecycle==="terminal"||(e.prompt??"")!==""||e.model!==void 0||e.fork_from!==void 0||e.worktree!==void 0||e.node_id!==void 0||e.scopes!==void 0||e.isolated!==void 0?null:{kind:e.kind,mode:e.mode??"base",cwd:t,profileId:n,model:e.model??null,situationalContext:e.situational_context??null,name:e.name??null,creator:e.creator??null}}a(rt,"warmRequestFor");import{resolveCreateKind as Qo}from"../../../core/runtime/launch-target.js";function he(e){const t=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return kn(e.model,t,e.modelExact===!0)}a(he,"requestFromLaunch");function it(e,t){if(t===null)return e;if(e.scopes===void 0)return{...e,scopes:[...t]};const n=e.scopes.filter(r=>!O(t,r));if(n.length===0)return e;throw new m(403,"scope_denied",`scopes exceed the bearer token's ceiling: ${n.join(", ")}`,{scopes:n,ceiling:t})}a(it,"withinCeiling");async function we(e,t,n){const r=(await gn(t.kind,t.mode,{lifecycle:t.lifecycle,hasManager:e.parent!==null,model:t.model,modelOverride:!0,cwd:e.cwd,profileId:e.profile_id??null})).launch;await B(he(r),{cwd:e.cwd,profileId:e.profile_id??null},n)}a(we,"assertNodeModelChangeRegistered");function ye(e,t){const n=e.principal;if(n.class!=="broker"&&n.class!=="cron")return;const r=Un({app:n.app,resolved:Jn(n),launched:n.scopes},t,"read");if("root"in r)return;const o="missing"in r?r.missing:null;throw new m(403,"scope_missing",o?`the child's directory ${t} needs missing scope ${o}`:`no permission of this run names the child's directory ${t}`,void 0,void 0,o?{scope:o}:void 0)}a(ye,"assertCallerReaches");const Y=new Map;async function dt(e,t={},n={}){const r=it(qn(e.body),e.ceiling);if(e.principal.class==="broker"){const l=e.principal;if(r.prefer_warm===!0&&l.app!=="app:terminal"&&(r.prefer_warm=!1),r.parent!=null){const i=y(r.parent);if(i.grantee!==l.app)throw new m(403,"other_app_run","cannot create a child under another app's node");if(!U(l,r.parent,i.grantee??"app:terminal"))throw P(`unknown node: ${r.parent}`,{received:r.parent})}if(r.creator!==void 0&&r.creator!==l.node)throw new m(403,"other_app_run","cannot create for another node");if(r.fork_from!==void 0){let i=null;try{i=Ee(Te(r.fork_from))}catch{}if(i?.grantee!==l.app||!U(l,i.node_id,i.grantee))throw new m(403,"other_app_run","cannot fork another app's conversation")}r.creator=l.node}if(e.principal.class==="cron"){const l=e.principal;for(const c of["parent","creator","fork_from","node_id"])if(r[c]!=null)throw new m(403,"permission_error",`a cron cannot set ${c} on a node it starts`);r.prefer_warm=!1;const i=Qe({grantee:l.app,sub:l.sub,grant_id:l.grant,scopes:l.scopes});if(!i.allowed)throw new m(i.reason==="scope_missing"?403:401,i.reason==="scope_missing"?"scope_missing":"grant_revoked",i.message);if(r.scopes!==void 0){const c=r.scopes.find(p=>!O(i.effectiveScopes,p)||!O(l.scopes,p));if(c!==void 0)throw new m(403,"scope_missing",`scope ${c} is not held by this cron`,void 0,void 0,{scope:c})}else l.scopes!==null&&(r.scopes=[...l.scopes]);r.node_id=ee(),l.isolated&&(r.isolated=!0,r.cwd=K(r.node_id,l.app))}r.creator!==void 0&&Kn(y(r.creator),"crtr:act");const o=r.request_key?.trim();if(o===void 0||r.node_id!==void 0&&Ye(r.node_id)&&k(r.node_id)!==null&&Le(o)?.nodeId!==r.node_id)return E(e,r,t,n);const d=Y.get(o);if(d!==void 0)return d;const s=st(e,r,o,t,n);Y.set(o,s);try{return await s}finally{Y.delete(o)}}a(dt,"handleCreate");async function st(e,t,n,r,o){const d=oe(n);if(d.nodeId!==null&&k(d.nodeId)!==null){if(d.state!=="warm_claimed"){const s=k(d.nodeId);if(e.principal.class!=="person"&&!pe(e.principal,s.grantee??"app:terminal",d.nodeId))throw new m(409,"create_request_conflict","request_key belongs to another caller");return{status:201,body:g(d.nodeId)}}return E(e,t,r,o,d)}try{return await E(e,t,r,o,d)}catch(s){const l=oe(n);throw(l.nodeId===null||k(l.nodeId)===null)&&ne(n,l.nodeId),s}}a(st,"handleKeyedCreateRequest");async function E(e,t,n,r,o=void 0){const d=r.deadlineAt??et(t.deadline),s=nt(t.outcome_delivery),l=e.principal.class==="cron"?Xe({grantee:e.principal.app,sub:e.principal.sub,grant_id:e.principal.grant,scopes:e.principal.scopes,cron_id:e.principal.cron,origin_run_id:e.principal.origin_run,isolated:e.principal.isolated,creator:fe(e.principal.cron)?.created_by??null},t.node_id):null;l!==null&&(t.root=l.root===!0);const i=l?.parent??t.parent??void 0;if(i==null&&t.root!==!0)throw h("a node create requires a parent (or root: true for an independent root)");let c=null;if(t.output_schema!==void 0)try{c=JSON.parse(t.output_schema)}catch{throw h("output_schema must be a JSON schema string")}const{profileId:p,kind:u,cwd:f,launch:_}=await Ln(t,{validateKind:ke});ye(e,f),t.worktree!==void 0&&ye(e,T(t.pin_cwd??t.cwd??f));const S={...t,kind:u},I=s===void 0?void 0:tt(s,f);if(await B(he(_),{cwd:f,profileId:p},n.modelRegistry),!await Xn(p))throw new m(412,"no_provider_credential",me,{error:"no_provider_credential",message:me,next:"The person running this runtime logs a provider in with `crtr sys setup`, or stores a provider key on the profile."});let L=null;{const $=o===void 0||o.nodeId===null||o.state==="warm_claimed"?rt(S,f,p):null,j=c===null&&r.beforeBrokerLaunch===void 0?void 0:v=>{c!==null&&$n(v,"terminal",c),r.beforeBrokerLaunch?.(v)};if(o?.state==="warm_claimed"&&o.nodeId!==null){const v=$===null?null:await Pn($,o.nodeId,j);if(v===null)throw ne(o.requestKey,o.nodeId),new m(503,"create_resume_failed",`could not resume warm claim ${o.nodeId}; retry the create`);return te(o.requestKey,v),{status:201,body:g(v)}}if($!==null){const v=await Tn($,{...d===void 0?{}:{deadlineAt:d},...I===void 0?{}:{outcomeDelivery:I},...o===void 0?{}:{requestKey:o.requestKey}},j);if(v!==null)return o!==void 0&&te(o.requestKey,v),le($),{status:201,body:g(v)};L=$}const M=o?.nodeId??t.node_id??(o===void 0?void 0:ee());o!==void 0&&o.nodeId===null&&Me(o.requestKey,M);const R=ot(M===void 0?S:{...S,node_id:M},i,f);l!==null&&(l.rootLifecycle!==void 0&&(R.rootLifecycle=l.rootLifecycle),l.scopes!==void 0&&S.scopes===void 0&&(R.scopes=l.scopes),l.run!==void 0&&(R.run=l.run),l.withinCreate!==void 0&&(R.withinCreate=l.withinCreate)),d!==void 0&&(R.deadlineAt=d),I!==void 0&&(R.outcomeDelivery=I),R.readiness=t.root===!0?"await":"launch";const Q=await Pe(R,j,()=>{L!==null&&le(L)});return o!==void 0&&je(o.requestKey,Q.node.node_id),{status:201,body:g(Q.node.node_id)}}}a(E,"handleCreateRequest");function b(e,t){const n=e.query.getAll(t);if(n.length>1)throw h(`${t} must appear at most once`);return n[0]}a(b,"singleQueryValue");function _e(e,t){if(e!==void 0){if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw h(`${t} must be true or false`)}}a(_e,"optionalBoolean");function D(e,t,n){if(e!==void 0){if(n.includes(e))return e;throw h(`${t} must be one of: ${n.join(", ")}`)}}a(D,"oneOf");function at(e){const t=new Set(["status","lifecycle","kind","mode","profile_id","profile_prefix","parent","top_level","under","hanging","include"]);for(const[_]of e.query)if(!t.has(_))throw h(`unknown nodes query parameter: ${_}`);const n=D(b(e,"status"),"status",["active","idle","done","dead","canceled"]),r=D(b(e,"lifecycle"),"lifecycle",["terminal","resident"]),o=b(e,"kind"),d=D(b(e,"mode"),"mode",["base","orchestrator"]),s=b(e,"profile_id"),l=b(e,"profile_prefix"),i=b(e,"parent"),c=_e(b(e,"top_level"),"top_level"),p=b(e,"under"),u=_e(b(e,"hanging"),"hanging"),f=D(b(e,"include"),"include",["activity"]);if(i!==void 0&&c===!0)throw h("parent and top_level=true cannot be combined");return{...n!==void 0?{status:n}:{},...r!==void 0?{lifecycle:r}:{},...o!==void 0?{kind:o}:{},...d!==void 0?{mode:d}:{},...s!==void 0?{profile_id:s}:{},...l!==void 0?{profile_prefix:l}:{},...i!==void 0?{parent:i}:{},...c!==void 0?{top_level:c}:{},...p!==void 0?{under:p}:{},...u!==void 0?{hanging:u}:{},...f!==void 0?{include:f}:{}}}a(at,"parseListQuery");function lt(e){const t=at(e);let n=t.status!==void 0?re({status:t.status}):re();if(e.principal.class!=="person"&&(n=n.filter(s=>pe(e.principal,s.grantee??"app:terminal",s.node_id))),t.lifecycle!==void 0&&(n=n.filter(s=>s.lifecycle===t.lifecycle)),t.kind!==void 0&&(n=n.filter(s=>s.kind===t.kind)),t.mode!==void 0&&(n=n.filter(s=>s.mode===t.mode)),t.profile_id!==void 0&&(n=n.filter(s=>s.profile_id===t.profile_id)),t.profile_prefix!==void 0&&(n=n.filter(s=>s.profile_id?.startsWith(t.profile_prefix))),t.parent!==void 0&&(n=n.filter(s=>s.parent===t.parent)),t.top_level===!0&&(n=n.filter(s=>s.parent===null)),t.under!==void 0){const s=new Set(xe(t.under));n=n.filter(l=>s.has(l.node_id))}t.hanging===!0&&(n=n.filter(s=>s.parent!==null&&k(s.parent)===null));const r=t.include==="activity"?He(n.map(s=>s.node_id)):null,o=n.length>0?Oe():new Set;return{status:200,body:n.map(s=>{const l=Vn(s,s.profile_id!==null&&o.has(s.profile_id));if(r!==null){const i=ce(s.node_id);l.activity={latest_report:i[0]??null,final_report:s.final_report===null?null:i.find(c=>c.name===s.final_report)??null,pending_human_count:r[s.node_id]??0}}return l})}}a(lt,"handleList");function ct(e){const t=e.params.id;return y(t),{status:200,body:g(t)}}a(ct,"handleDetail");async function ft(e){const t=e.params.id;y(t);const n=await rn(t);return{status:200,body:{node_id:t,snapshot:{messages:n.snapshot.messages,...n.snapshot.messageIds===void 0?{}:{messageIds:n.snapshot.messageIds},messageVisibility:n.snapshot.messageVisibility,turnVisibility:n.snapshot.turnVisibility,stats:n.snapshot.stats,state:n.snapshot.state,display:n.snapshot.display,...n.snapshot.queued===void 0?{}:{queued:n.snapshot.queued},...n.snapshot.toolGroupSummaries===void 0?{}:{toolGroupSummaries:n.snapshot.toolGroupSummaries},...n.snapshot.turnReplies===void 0?{}:{turnReplies:n.snapshot.turnReplies},...n.snapshot.workingActivity===void 0?{}:{workingActivity:n.snapshot.workingActivity}},commands:n.commands.map(o=>({name:o.name,description:o.description,source:o.source})),captured_at:G()}}}a(ft,"handleSnapshot");async function ut(e){const t=e.params.id,n=sn(t);if(n===null)throw P(`unknown node: ${t}`,{received:t});return{status:200,body:n}}a(ut,"handleSubject");function pt(e){for(const[d]of e.query)if(d!=="cursor"&&d!=="limit")throw h(`unknown messages query parameter: ${d}`);const t=e.query.getAll("cursor"),n=e.query.getAll("limit");if(t.length>1)throw h("cursor must appear at most once");if(n.length>1)throw h("limit must appear at most once");if(n.length===0)return t.length===0?{}:{cursor:t[0]};const r=n[0],o=Number(r);if(!Number.isSafeInteger(o)||r==="")throw h("limit must be an integer from 1 through 500");return t.length===0?{limit:o}:{cursor:t[0],limit:o}}a(pt,"parseMessagesQuery");async function mt(e){const t=e.params.id,n=await tn(t,pt(e));return{status:200,body:{node_id:t,messages:n.messages,...n.messageIds===void 0?{}:{message_ids:n.messageIds},message_visibility:n.messageVisibility,next_cursor:n.nextCursor,captured_at:G()}}}a(mt,"handleMessages");function ht(e){const t=e.params.id;y(t);const n=on(t);return{status:200,body:{node_id:t,session_file:n.sessionFile,session_jsonl:n.sessionJsonl,system_prompt:n.systemPrompt,captured_at:G()}}}a(ht,"handleSession");async function wt(e){const t=e.params.id;return y(t),{status:200,body:{node_id:t,markdown:await dn(t)}}}a(wt,"handleTranscript");function yt(e){const t=e.params.id;y(t);const n=a((o,d)=>({node_id:o,label:k(o)?.name??o,dir:de(o),self:d,files:Zn(o)}),"root"),r=[n(t,!0),...ie(t).map(o=>n(o.node_id,!1))].filter(o=>_t(o.node_id,o.dir)||o.files>0);return{status:200,body:{node_id:t,roots:r}}}a(yt,"handleContext");function _t(e,t){try{return Ze(K(e),t)}catch(n){if(en(n))return!1;throw n}}a(_t,"hasDir");async function gt(e){const t=y(e.params.id),n=e.principal.class==="broker"?e.principal.scopes:e.ceiling,r=n===null?void 0:t.scopes==null?[...n]:[...new Set([...t.scopes.filter(d=>O(n,d)),...n.filter(d=>O(t.scopes,d))])],o=await Ae(t.node_id,r,e.principal.class==="broker"?e.principal.node:void 0);return{status:201,body:g(o.node.node_id)}}a(gt,"handleFork");async function bt(e){const t=e.params.id;y(t);const n=e.body,r=n?.resume??!0,o=n?.reopen??!1;pn(t,o);const d=!r&&n?.cron_id!==void 0?fe(n.cron_id):null,s=await Ne(t,{resume:r,capacity:"refuse",...d!==null?{wakeReason:Bn(d,"schedule_revive")}:{}});s.outcome!=="already-live"&&Fe(t,{failures:0,notBefore:null});const l=k(t)?.status??"active";return{status:200,body:zn(t,s,l)}}a(bt,"handleRevive");async function vt(e){const t=e.params.id;return{status:200,body:{newNodeId:(await un(t))?.newNodeId??null}}}a(vt,"handleRelaunchRoot");function kt(e){const t=e.params.id;y(t);const n=e.body;if(n?.caller_pid!==void 0&&(!Number.isInteger(n.caller_pid)||n.caller_pid<=0))throw h("caller_pid must be a positive integer when provided");const r=xn(),o=Ce(t,{rootEvent:n?.finish===!0?"finish":"cancel",callerPid:n?.caller_pid,...e.principal.class==="broker"?{closer:e.principal.node}:{},...r===null?{}:{registerDetached:r.registerDetached}});return{status:200,body:Wn(o)}}a(kt,"handleClose");async function St(e){const t=e.params.id;y(t);const n=await fn(t);return{status:200,body:{recycled:n.recycled,finalized:n.finalized,new_root:n.newRoot,delivered:n.delivered}}}a(St,"handleRecycle");async function Rt(e){const t=e.params.id;return y(t),await W(t,{lifecycle:"terminal"}),C(e,t,["lifecycle"]),{status:200,body:g(t)}}a(Rt,"handleDemote");async function Ot(e,t={}){const n=e.params.id,r=y(n),o=e.body??{};o.kind!==void 0&&await z(o.kind,r.cwd,r.profile_id??null),o.model!==void 0&&await we(r,{kind:o.kind??r.kind,mode:"orchestrator",lifecycle:o.resident===!0?"resident":r.lifecycle,model:o.model},t.modelRegistry);const d=await ln(n,{...o.kind!==void 0?{kind:o.kind}:{},...o.resident===!0?{resident:!0}:{},...o.model!==void 0?{model:o.model}:{}});C(e,n,["mode",...o.kind!==void 0?["kind"]:[],...o.resident===!0?["lifecycle"]:[],...o.model!==void 0?["model"]:[]]);const s=J(d.meta,H(n));return s.roadmap_written=d.roadmapWritten,s.roadmap_ref=d.roadmapRef,s.goal_path=d.goalPath,{status:200,body:s}}a(Ot,"handlePromote");async function It(e,t={}){const n=e.params.id,r=y(n),o=e.body??{};o.kind!==void 0&&await z(o.kind,r.cwd,r.profile_id??null),o.model!==void 0&&await we(r,{kind:o.kind??r.kind,mode:o.promote===!0?"orchestrator":r.mode,lifecycle:r.lifecycle,model:o.model},t.modelRegistry);const d=o.note??"Refresh: continue against your roadmap or goal.";mn(n,d);const s=await cn(n,{...o.promote===!0?{promote:!0}:{},...o.kind!==void 0?{kind:o.kind}:{},...o.model!==void 0?{model:o.model}:{}});return{status:200,body:J(s.meta,H(n))}}a(It,"handleYield");function $t(e){const t=e.params.id;y(t);const n=e.body;if(n===void 0||typeof n.controller!="string"||n.controller.trim()==="")throw h("a wait requires a controller node id");const r=k(n.controller);if(r===null)throw P(`unknown controller: ${n.controller}`,{received:n.controller});if(r.status!=="active"&&r.status!=="idle")throw new m(422,"unprocessable",`controller ${n.controller} is ${r.status}`);return Be(t,n.controller),{status:200,body:g(t)}}a($t,"handleWait");async function Ct(e){const t=e.principal,n=await an(t.class==="broker"?o=>o.grantee===t.app&&U(t,o.node_id,o.grantee):void 0);return{status:200,body:{revived:[...n.revived],failed:[...n.failed],frozen:[...n.frozen]}}}a(Ct,"handleReviveAll");const Nt=new Set(["interrupt","steer","after-turn","next-turn"]);function At(e){if(e===null)return null;const t=a(r=>{throw new w({error:"invalid_listen",message:r,received:e,field:"listen",next:'Send an object mapping levels "1".."10" to interrupt|steer|after-turn|next-turn (e.g. {"3":"next-turn"}), or null to reset to the global default.'})},"bad");if(typeof e!="object"||Array.isArray(e))return t("listen must be an object or null");const n=Object.entries(e);if(n.length===0)return t("listen must name at least one level");for(const[r,o]of n)/^(?:[1-9]|10)$/.test(r)||t(`listen level must be 1..10: ${r}`),(typeof o!="string"||!Nt.has(o))&&t(`listen delivery must be interrupt|steer|after-turn|next-turn: ${String(o)}`);return JSON.stringify(Object.fromEntries(n))}a(At,"listenJson");function C(e,t,n,r){n.length===0&&r===void 0||x(o=>{if(r?.(o),n.length===0)return;const d=Ke(o,t),s=ze(o,e),l=s.class==="person"?s.person:s.class==="app"?s.app:s.node;We(o,l,d),Ve(o,{event:"configured",object:d,actor:l,attrs:{changed:n.join(",")}})})}a(C,"recordConfigured");function ge(e){const t=V().get(e);if(t===void 0)return!1;try{return process.kill(t.pid,"SIGTERM"),!0}catch{return!1}}a(ge,"restartLiveBroker");function be(e,t){try{return Z(e)===Z(t)}catch{return!1}}a(be,"sameDirectory");async function Tt(e,t={}){const n=e.params.id,r=e.body;let o;if(r===void 0)o={};else if(typeof r=="object"&&r!==null&&!Array.isArray(r))o=r;else throw new w({error:"cwd_invalid",message:"cwd repair requires a non-null object with a non-empty cwd string",received:r,field:"cwd",next:"Send a config patch with a non-empty absolute cwd string."});if(o.profile!==void 0){if(typeof o.profile!="string"||o.profile==="")throw new w({error:"profile_invalid",message:"profile must be a non-empty profile id or name",received:o.profile,field:"profile",next:"Send a profile id or exact name."});if(Object.keys(o).some(u=>u!=="profile"&&u!=="restart"&&o[u]!==void 0))throw new w({error:"profile_not_exclusive",message:"profile can only be combined with restart",field:"profile",next:"Send profile (and optionally restart) alone."});const i=y(n),c=Mn(e,o.profile);Fn(c.profileId);const p=Gn(c.profileId).manifest.grantee??"app:terminal";if(p!==(i.grantee??"app:terminal"))throw new w({error:"profile_grantee_mismatch",message:`profile ${c.profileId} belongs to ${p}, node ${n} to ${i.grantee}`,received:o.profile,field:"profile",next:"Pick a profile owned by the same app as the node."});return(i.profile_id??null)!==c.profileId&&(Dn(i.kind)?(await z(i.kind,i.cwd,c.profileId),await W(n,{profileId:c.profileId})):N(n,{profile_id:c.profileId}),C(e,n,["profile"])),o.restart===!0&&ge(n),{status:200,body:g(n)}}if(Object.prototype.hasOwnProperty.call(o,"cwd")){const i=o.cwd;if(typeof i!="string"||i==="")throw new w({error:"cwd_invalid",message:"cwd must be a non-empty string",received:i,field:"cwd",next:"Send a non-empty absolute cwd string."});if(Object.keys(o).some(f=>f!=="cwd"&&f!=="keep_session"&&f!=="restart"&&o[f]!==void 0))throw new w({error:"cwd_not_exclusive",message:"cwd repair cannot be combined with another config field",received:o,field:"cwd",next:"Send cwd as the only config field."});const c=y(n),p=A(c.cwd);if(o.keep_session===!0||p&&F(i)&&A(i)&&be(c.cwd,i)){if(!F(i))throw new w({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${i}`,received:i,field:"cwd",next:"Send an absolute path."});const f=T(i);let _=!1;try{_=q(f).isDirectory()}catch{}if(!_)throw new w({error:"cwd_missing",message:`cwd is not an existing directory: ${f}`,received:i,field:"cwd",next:"Send an existing absolute directory."});if(p&&!be(c.cwd,f))throw new w({error:"cwd_not_same_directory",message:`${f} is not the same directory as the recorded ${c.cwd}; --keep-session only relocates an alias`,received:i,field:"cwd",next:"Drop --keep-session to repair a gone cwd, or pass the real path of the recorded directory."});if(c.managed_worktree?.state==="open")throw new w({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot relocate its cwd`,received:i,field:"cwd",next:"Reconcile the managed worktree first."});const S=c.cwd;return S!==f&&(x(I=>{N(n,{cwd:f}),X(I,"UPDATE crons SET cwd = ? WHERE anchor_node = ? AND cwd = ?").run(f,n,S),Je(n,S,f)}),C(e,n,["cwd"])),o.restart===!0&&ge(n),{status:200,body:g(n)}}if(V().has(n)){const f=`${n} cannot repair its cwd while its broker is live`;throw new m(409,"cwd_node_live",f,{error:"cwd_node_live",message:f,received:i,field:"cwd",next:"Let the node become dormant, then retry the cwd repair."})}if(c.fork_from!=null)throw new w({error:"cwd_node_forked",message:`${n} is a fork and cannot repair its cwd; recorded cwd: ${c.cwd}`,received:i,field:"cwd",next:`Restore ${c.cwd}, then revive the fork normally.`});if(c.managed_worktree?.state==="open")throw new w({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot repair its cwd`,received:i,field:"cwd",next:"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon flow."});if(A(c.cwd))throw new w({error:"cwd_still_present",message:`${n} recorded cwd still exists: ${c.cwd}; cwd repair is not a relocation command`,received:i,field:"cwd",next:"This command only repairs a node whose recorded cwd is gone."});if(!F(i))throw new w({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${i}`,received:i,field:"cwd",next:"Send an absolute path."});const u=T(i);if(!A(u))throw new w({error:"cwd_missing",message:`cwd does not exist: ${u}`,received:i,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."});try{if(!q(u).isDirectory())throw new w({error:"cwd_not_a_directory",message:`cwd is not a directory: ${u}`,received:i,field:"cwd",next:"Send an existing absolute directory."})}catch(f){throw f instanceof w?f:new w({error:"cwd_missing",message:`cwd does not exist: ${u}`,received:i,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."})}return x(()=>{N(n,{cwd:u}),Ue(n)}),C(e,n,["cwd"]),{status:200,body:g(n)}}let d=y(n);const s=o.listen===void 0?void 0:At(o.listen);if(o.scopes!==void 0){const i=ue(o.scopes),c=d.grantee==="app:terminal"?Yn():d.grant_id?Hn(d.grant_id):null,p=d.grantee==="app:terminal"&&!Qn("user").runtime?.issuer;if(!i.every(u=>O(d.scopes,u)&&(c?O(c.resolved,u):p)))throw new w({error:"unknown_scope",message:"scopes may only narrow the node's current effective set",received:i,field:"scopes",next:"Send only scopes the node currently holds."});if(i.includes("crtr:act")&&!O(i,"crtr:llm"))throw new m(400,"invalid_scope","crtr:act requires crtr:llm");d=N(n,{scopes:i})}if(o.situational_context!==void 0&&Ie(n,$e(o.situational_context)),o.model!==void 0){const i=(await se(d.cwd,d.profile_id??null)).modelLadders,c=bn(o.model,i),p=vn(o.model,i);await B({kind:"concrete",spec:p},{cwd:d.cwd,profileId:d.profile_id??null},t.modelRegistry);const u=V();let f=!1;if(u.isClaimed(n)&&await On(n,u.get(n)?.handle.exited)&&(f=await Rn(n,p,c).then(()=>!0,_=>{if(_ instanceof In)return!1;throw _})),!f){if(u.isClaimed(n)){const _=`${n}'s broker did not accept the model switch; the model was not changed`;throw new m(409,"broker_not_ready",_,{error:"broker_not_ready",message:_,received:o.model,field:"model",next:"Check the node with `crtr node show`, then retry the model change."})}if(!p.includes("/"))throw h(`model must resolve to a provider/id spec: ${o.model}`);Sn(n,p,c)}d=y(n)}if(o.kind!==void 0||o.mode!==void 0||o.lifecycle!==void 0){o.kind!==void 0&&await ke(o.kind);const i=o.kind??d.kind,c=o.mode??d.mode,p=o.lifecycle??d.lifecycle;let u;c==="orchestrator"&&!yn(n)&&(u=a(()=>{const f=hn(n);wn(n,f!==null&&f.trim()!==""?{goal:f.trim()}:{})},"beforePersist")),d=await W(n,{...o.kind!==void 0?{kind:i}:{},...o.mode!==void 0?{mode:c}:{},...o.lifecycle!==void 0?{lifecycle:p}:{}},u)}o.name!==void 0&&(d=N(n,{name:o.name}),d.window&&_n(d.window,jn(d)));const l=["scopes","situational_context","model","kind","mode","lifecycle","name","listen"].filter(i=>o[i]!==void 0);return C(e,n,l,s===void 0?void 0:i=>{X(i,"UPDATE objects SET listen_json = ? WHERE id = ? AND type = 'node'").run(s,n)}),{status:200,body:g(n)}}a(Tt,"handleConfig");async function ve(){return(await se(process.cwd(),Re()||null)).kinds}a(ve,"daemonKinds");async function ke(e){const t=Object.keys(await ve());if(!t.includes(e))throw h(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${t.sort().join(", ")}.`})}a(ke,"assertKindServer");async function Pt(){const e=await ve();return{status:200,body:{kinds:Object.keys(e).sort().map(n=>({kind:n,when_to_use:e[n]?.whenToUse??null,available_to:e[n]?.availableTo??null}))}}}a(Pt,"handleListKinds");const Uo=[{method:"POST",pattern:"/v1/nodes",scope:"crtr:act",handler:dt},{method:"GET",pattern:"/v1/nodes",handler:lt},{method:"GET",pattern:"/v1/kinds",handler:a(()=>Pt(),"handler")},{method:"POST",pattern:"/v1/nodes/revive-all",scope:"crtr:act",handler:Ct},{method:"GET",pattern:"/v1/nodes/:id",handler:ct},{method:"GET",pattern:"/v1/nodes/:id/snapshot",handler:ft},{method:"GET",pattern:"/v1/nodes/:id/subject",handler:ut},{method:"GET",pattern:"/v1/nodes/:id/messages",handler:mt},{method:"GET",pattern:"/v1/nodes/:id/session",handler:ht},{method:"GET",pattern:"/v1/nodes/:id/transcript",handler:wt},{method:"GET",pattern:"/v1/nodes/:id/context",handler:yt},{method:"POST",pattern:"/v1/nodes/:id/fork",scope:"crtr:act",handler:gt},{method:"POST",pattern:"/v1/nodes/:id/revive",scope:"crtr:act",handler:bt},{method:"POST",pattern:"/v1/nodes/:id/relaunch-root",scope:"crtr:act",handler:vt},{method:"POST",pattern:"/v1/nodes/:id/close",handler:kt},{method:"POST",pattern:"/v1/nodes/:id/recycle",scope:"crtr:act",handler:St},{method:"POST",pattern:"/v1/nodes/:id/demote",scope:"crtr:act",handler:Rt},{method:"POST",pattern:"/v1/nodes/:id/promote",scope:"crtr:act",handler:Ot},{method:"POST",pattern:"/v1/nodes/:id/yield",scope:"crtr:act",handler:It},{method:"POST",pattern:"/v1/nodes/:id/wait",handler:$t},{method:"PATCH",pattern:"/v1/nodes/:id/config",handler:Tt}];export{Tt as handleConfig,dt as handleCreate,gt as handleFork,lt as handleList,Ot as handlePromote,It as handleYield,Uo as nodeRoutes,Qo as resolveCreateKind};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import { type StartedFlow } from '../../core/model-auth/flows.js';
|
|
2
3
|
import type { AppPrincipalResolver } from './principal.js';
|
|
3
4
|
export declare const VENDOR_SIGNIN_PATH = "/signin/vendor";
|
|
4
5
|
export declare function isVendorSignInPath(pathname: string): boolean;
|
|
6
|
+
export declare function anthropicPage(flow: StartedFlow, nonce: string, returnTo: string, handoff: string): string;
|
|
7
|
+
export declare function openaiPage(flow: StartedFlow, nonce: string, returnTo: string, handoff: string, now?: number): string;
|
|
5
8
|
/** Serve one `/signin/vendor*` request; errors propagate as RunErrors so the
|
|
6
9
|
* listener answers them with contract 2's envelope (RT-LLM-53). */
|
|
7
10
|
export declare function handleVendorSignIn(req: IncomingMessage, res: ServerResponse, url: URL, principal: AppPrincipalResolver): Promise<void>;
|
|
@@ -1,77 +1,192 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
var O=Object.defineProperty;var a=(e,t)=>O(e,"name",{value:t,configurable:!0});import{randomBytes as j}from"node:crypto";import{joinedOwner as E}from"../../core/directory/join.js";import{consumeHandoffJti as z,handoffJtiConsumed as y}from"../../core/model-auth/handoff-jti.js";import{completeModelAuthFlow as I,modelAuthProvider as N,readModelAuthFlow as k,startModelAuthFlow as P,waitModelAuthFlow as L}from"../../core/model-auth/flows.js";import{RunError as d}from"../../core/runs/operations.js";import{LONG_POLL_MAX_WAIT_SECONDS as R}from"../../api/long-poll.js";const l="/signin/vendor",$=900,B=R*1e3,G="https://chatgpt.com/#settings/Security";function ce(e){return e===l||e.startsWith(`${l}/`)}a(ce,"isVendorSignInPath");function u(){return new d(401,"unauthorized","invalid vendor sign-in handoff")}a(u,"unauthorized");async function C(e,t){const n=await e.verifyHandoff(t);let r;try{r=E()}catch{r=null}if(n.sub!==r)throw u();return n}a(C,"verifyOwnerHandoff");function U(e){const t=e.headers.authorization;return t?.startsWith("Bearer ")&&t.length>7?t.slice(7):void 0}a(U,"bearer");function x(e,t){const n=e.getAll(t);return n.length===1?n[0]:void 0}a(x,"single");function H(e,t){const n=new URL(e);return n.searchParams.set("status",t),n.toString()}a(H,"returnUrl");function p(e){return e.replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[t])}a(p,"escapeHtml");function h(e,t,n){e.writeHead(t,{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}),e.end(JSON.stringify(n))}a(h,"sendJson");async function J(e){const t=[];let n=0;for await(const o of e){if(n+=o.length,n>64*1024)throw new d(400,"invalid_request","request body too large");t.push(o)}let r;try{r=JSON.parse(Buffer.concat(t).toString("utf8"))}catch{throw new d(400,"invalid_request","invalid JSON body")}if(typeof r!="object"||r===null||Array.isArray(r))throw new d(400,"invalid_request","request body must be a JSON object");return r}a(J,"jsonBody");const D=`
|
|
2
|
+
:root{color-scheme:light dark;
|
|
3
|
+
--canvas:#f0f2f4;--surface:#fff;--sunken:#e5e7ea;--zone:#e5e7ea;--neutral:#e5e7ea;--neutral-hover:#d7d9dc;--neutral-pressed:#cbcdd0;
|
|
4
|
+
--accent:#1f4fbf;--accent-hover:#1b45a8;--accent-pressed:#173b8f;--accent-border:#1f4fbf;--accent-subtle:#dce6fb;--accent-fg:#1f4fbf;--on-accent:#fff;
|
|
5
|
+
--warning-bg:#fcedd4;--warning-fg:#8f5200;--danger-bg:#fce5e2;--danger-fg:#bf2a1f;--danger-line:#bf2a1f;
|
|
6
|
+
--text:#15171a;--muted:#505256;--disabled:#919498;--line:#d7d9dc;--line-strong:#787b7f;--focus:#1f4fbf;
|
|
7
|
+
--sans:system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
|
|
8
|
+
--mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
|
|
9
|
+
@media (prefers-color-scheme:dark){:root{
|
|
10
|
+
--canvas:#0e1012;--surface:#181a1d;--sunken:#212326;--zone:#212326;--neutral:#212326;--neutral-hover:#2f3134;--neutral-pressed:#3c3e41;
|
|
11
|
+
--accent:#2a5cd0;--accent-hover:#2452c4;--accent-pressed:#1f4fbf;--accent-border:#5585ec;--accent-subtle:#15233f;--accent-fg:#7aa7ff;--on-accent:#fff;
|
|
12
|
+
--warning-bg:#35260f;--warning-fg:#f4b45a;--danger-bg:#3b1715;--danger-fg:#ff8175;--danger-line:#d0342a;
|
|
13
|
+
--text:#f0f2f4;--muted:#acaeb2;--disabled:#505256;--line:#2f3134;--line-strong:#787b7f;--focus:#7aa7ff}}
|
|
14
|
+
*,*::before,*::after{box-sizing:border-box}
|
|
15
|
+
[hidden]{display:none!important}
|
|
16
|
+
body{margin:0;min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;background:var(--canvas);color:var(--text);font:400 .9375rem/1.5333 var(--sans);-webkit-text-size-adjust:100%}
|
|
17
|
+
p,h1,ol{margin:0}
|
|
18
|
+
a{color:inherit}
|
|
19
|
+
:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
|
|
20
|
+
.top{display:flex;align-items:center;gap:.5rem;height:3.5rem;flex:none;padding:0 1rem;background:var(--surface);border-bottom:1px solid var(--line)}
|
|
21
|
+
.top svg{width:20px;height:20px;color:var(--accent-fg)}
|
|
22
|
+
.top span{font-weight:600}
|
|
23
|
+
main{flex:1;display:flex;flex-direction:column;align-items:center;padding:2.5rem 1rem}
|
|
24
|
+
.col{width:100%;max-width:36rem}
|
|
25
|
+
.card{display:flex;flex-direction:column;gap:1.5rem;padding:1.5rem;background:var(--surface);border:1px solid var(--line);border-radius:12px}
|
|
26
|
+
.head{display:flex;align-items:center;gap:1rem}
|
|
27
|
+
.logo{position:relative;flex:none;width:3.5rem;height:3.5rem;border-radius:12px;overflow:hidden}
|
|
28
|
+
.logo svg{display:block;width:100%;height:100%}
|
|
29
|
+
.logo::after{content:"";position:absolute;inset:0;border:1px solid var(--line);border-radius:inherit}
|
|
30
|
+
.eyebrow{display:block;font-size:.8125rem;line-height:1.2308;font-weight:500;color:var(--muted)}
|
|
31
|
+
h1{margin-top:.25rem;font-size:1.25rem;line-height:1.3;font-weight:600;letter-spacing:-.02em}
|
|
32
|
+
.steps{list-style:none;padding:0;display:flex;flex-direction:column;gap:1.25rem}
|
|
33
|
+
.steps>li{display:flex;gap:.875rem}
|
|
34
|
+
.n{position:relative;flex:none;display:flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;border-radius:9999px;background:var(--neutral);font-size:.8125rem;font-weight:500;font-variant-numeric:tabular-nums}
|
|
35
|
+
.n svg{display:none;width:1rem;height:1rem}
|
|
36
|
+
li.done .n{background:var(--accent-subtle);color:var(--accent-fg)}
|
|
37
|
+
li.done .n span{display:none}
|
|
38
|
+
li.done .n svg{display:block}
|
|
39
|
+
.body{flex:1;min-width:0;display:flex;flex-direction:column;gap:.625rem;padding-top:.125rem}
|
|
40
|
+
.title{font-weight:500}
|
|
41
|
+
.small{font-size:.84375rem;line-height:1.4815;color:var(--muted)}
|
|
42
|
+
.ic{flex:none;width:1rem;height:1rem;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
|
|
43
|
+
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;min-height:2.5rem;padding:.4rem 1.125rem;border:1px solid transparent;border-radius:8px;background:var(--neutral);color:var(--text);font:500 .9375rem/1.3 var(--sans);text-align:center;text-decoration:none;cursor:pointer;overflow-wrap:break-word;transition:background-color .12s cubic-bezier(.2,0,0,1)}
|
|
44
|
+
.btn:hover{background:var(--neutral-hover)}
|
|
45
|
+
.btn:active{background:var(--neutral-pressed)}
|
|
46
|
+
.btn.primary{background:var(--accent);border-color:var(--accent-border);color:var(--on-accent)}
|
|
47
|
+
.btn.primary:hover{background:var(--accent-hover)}
|
|
48
|
+
.btn.primary:active{background:var(--accent-pressed)}
|
|
49
|
+
.btn.sm{min-height:2rem;padding:.25rem .75rem;font-size:.84375rem}
|
|
50
|
+
.btn.lg{min-height:3rem;padding:.5rem 1.375rem}
|
|
51
|
+
.btn.wide{width:100%}
|
|
52
|
+
.btn:disabled,.btn[aria-disabled=true]{opacity:.4;cursor:default;pointer-events:none}
|
|
53
|
+
.field{display:flex;flex-direction:column;gap:.375rem}
|
|
54
|
+
label{width:fit-content;font-size:.8125rem;line-height:1.2308;font-weight:500}
|
|
55
|
+
input[type=text]{width:100%;min-width:0;height:3rem;padding:0 .875rem;background:var(--surface);color:var(--text);border:1px solid var(--line-strong);border-radius:8px;font:400 .9375rem/1.5 var(--mono)}
|
|
56
|
+
input[type=text]:focus{outline:2px solid var(--focus);outline-offset:2px}
|
|
57
|
+
input[type=text][aria-invalid=true]{border-color:var(--danger-line)}
|
|
58
|
+
form{display:flex;flex-direction:column;gap:.75rem}
|
|
59
|
+
.err{display:none;align-items:flex-start;gap:.375rem;color:var(--danger-fg);font-size:.84375rem;line-height:1.4815}
|
|
60
|
+
.err.on{display:flex}
|
|
61
|
+
.err .ic{margin-top:.125rem}
|
|
62
|
+
.alert{display:flex;flex-wrap:wrap;align-items:flex-start;gap:.75rem;padding:.75rem .875rem;border-radius:8px;background:var(--warning-bg);font-size:.84375rem;line-height:1.4815}
|
|
63
|
+
.alert>.ic{width:1.125rem;height:1.125rem;margin-top:1px;color:var(--warning-fg)}
|
|
64
|
+
.alert .text{flex:1 1 12rem;min-width:0}
|
|
65
|
+
.alert strong{display:block;font-weight:600}
|
|
66
|
+
.alert .act{flex:none;align-self:center}
|
|
67
|
+
.codebox{display:flex;flex-wrap:wrap;align-items:center;gap:.75rem;padding:1rem;border-radius:12px;background:var(--sunken)}
|
|
68
|
+
.code{flex:1 1 auto;min-width:0;font:600 clamp(1.25rem,7vw,1.75rem)/1.2143 var(--mono);letter-spacing:.18em;overflow-wrap:anywhere}
|
|
69
|
+
.code.expired{color:var(--disabled);text-decoration:line-through}
|
|
70
|
+
.badge{display:inline-flex;align-items:center;gap:.375rem;height:1.25rem;padding:0 .375rem;border-radius:6px;background:var(--danger-bg);color:var(--danger-fg);font-size:.8125rem;font-weight:500;white-space:nowrap}
|
|
71
|
+
.badge::before{content:"";width:.375rem;height:.375rem;border-radius:9999px;background:currentColor}
|
|
72
|
+
.wait{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;border-radius:12px;background:var(--zone)}
|
|
73
|
+
.wait .spin{width:1rem;height:1rem;color:var(--accent-fg);fill:none;stroke:currentColor;stroke-width:3;stroke-linecap:round}
|
|
74
|
+
.wait .msg{flex:1;min-width:0;display:flex;flex-direction:column;font-size:.84375rem;line-height:1.4815}
|
|
75
|
+
.wait .msg b{font-weight:500}
|
|
76
|
+
.wait .msg span{color:var(--muted)}
|
|
77
|
+
.clock{display:flex;align-items:center;gap:.375rem;color:var(--muted);font-size:.84375rem;font-variant-numeric:tabular-nums}
|
|
78
|
+
.clock .ic{width:.875rem;height:.875rem}
|
|
79
|
+
.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
|
|
80
|
+
.foot{flex:none;display:flex;justify-content:center;padding:0 1rem 2rem;color:var(--muted);font-size:.84375rem;line-height:1.4815;text-align:center}
|
|
81
|
+
.foot a{color:var(--text);text-underline-offset:2px}
|
|
82
|
+
.foot a:hover{color:var(--accent-fg)}
|
|
83
|
+
@media (prefers-reduced-motion:no-preference){.wait .spin{animation:spin 1s linear infinite}}
|
|
84
|
+
@keyframes spin{to{transform:rotate(360deg)}}
|
|
85
|
+
@media (min-width:40rem){.top{padding:0 1.5rem}main{padding:3.5rem 1rem}}
|
|
86
|
+
@media (max-width:30rem){.card{padding:1.25rem}.btn{padding-left:.875rem;padding-right:.875rem}#device-link{font-size:.84375rem}.steps>li{gap:.75rem}.alert .act{margin-left:1.875rem}}
|
|
87
|
+
`,q=`
|
|
12
88
|
(function(){
|
|
13
89
|
var cfg=JSON.parse(document.getElementById('cfg').textContent);
|
|
14
90
|
history.replaceState(null,'',location.pathname);
|
|
15
91
|
var auth={'Authorization':'Bearer '+cfg.handoff};
|
|
16
92
|
function back(status){var u=new URL(cfg.returnTo);u.searchParams.set('status',status);location.assign(u.toString());}
|
|
17
|
-
function
|
|
18
|
-
var error
|
|
93
|
+
function $(id){return document.getElementById(id);}
|
|
94
|
+
var error=$('error'),errorText=$('error-text');
|
|
95
|
+
function setError(msg){errorText.textContent=msg;error.className=msg?'err on':'err';}
|
|
19
96
|
if(cfg.kind==='anthropic'){
|
|
20
|
-
var form
|
|
97
|
+
var form=$('paste'),input=form.elements.code;
|
|
21
98
|
form.addEventListener('submit',function(e){
|
|
22
99
|
e.preventDefault();
|
|
23
|
-
var button=form.querySelector('button');button.disabled=true;
|
|
24
|
-
|
|
100
|
+
var button=form.querySelector('button');button.disabled=true;setError('');input.removeAttribute('aria-invalid');
|
|
101
|
+
function reject(msg){
|
|
102
|
+
setError(msg);input.setAttribute('aria-invalid','true');button.disabled=false;
|
|
103
|
+
var pre=document.querySelectorAll('[data-pre]');for(var i=0;i<pre.length;i++)pre[i].classList.add('done');
|
|
104
|
+
input.focus();
|
|
105
|
+
}
|
|
106
|
+
fetch(cfg.base,{method:'POST',headers:Object.assign({'Content-Type':'application/json'},auth),body:JSON.stringify({input:input.value})})
|
|
25
107
|
.then(function(r){return r.json().then(function(b){return {ok:r.ok,s:r.status,b:b};});})
|
|
26
108
|
.then(function(x){
|
|
27
109
|
if(x.ok){back(x.b.status==='connected'?'connected':'failed');return;}
|
|
28
110
|
if(x.s===401||x.s===404){back('failed');return;}
|
|
29
|
-
|
|
111
|
+
reject((x.b&&x.b.error&&x.b.error.message)||'That code was not accepted.');
|
|
30
112
|
})
|
|
31
|
-
.catch(function(){
|
|
113
|
+
.catch(function(){reject('Could not reach your runtime. Try again.');});
|
|
32
114
|
});
|
|
33
115
|
}else{
|
|
34
|
-
|
|
35
|
-
|
|
116
|
+
var copyLabel=$('copy-label');
|
|
117
|
+
$('copy').addEventListener('click',function(){
|
|
118
|
+
function done(){copyLabel.textContent='Copied';setTimeout(function(){copyLabel.textContent='Copy';},2000);}
|
|
119
|
+
if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(cfg.userCode).then(done,function(){});return;}
|
|
120
|
+
var r=document.createRange();r.selectNodeContents($('user-code'));var s=getSelection();s.removeAllRanges();s.addRange(r);
|
|
121
|
+
});
|
|
122
|
+
$('renew').addEventListener('click',function(){back('failed');});
|
|
123
|
+
var deadline=Date.now()+cfg.remainingSeconds*1000,left=$('left'),said=-1,timer;
|
|
124
|
+
function tick(){
|
|
125
|
+
var s=Math.max(0,Math.ceil((deadline-Date.now())/1000));
|
|
126
|
+
left.textContent=Math.floor(s/60)+':'+('0'+(s%60)).slice(-2);
|
|
127
|
+
var m=Math.ceil(s/60);
|
|
128
|
+
if(m!==said){said=m;$('left-live').textContent='Code expires in '+m+(m===1?' minute':' minutes');}
|
|
129
|
+
}
|
|
130
|
+
tick();timer=setInterval(tick,1000);
|
|
131
|
+
function expire(){
|
|
132
|
+
clearInterval(timer);
|
|
133
|
+
$('user-code').className='code expired';$('copy').hidden=true;$('expired-badge').hidden=false;
|
|
134
|
+
var link=$('device-link');link.removeAttribute('href');link.setAttribute('aria-disabled','true');
|
|
135
|
+
$('settings').hidden=true;$('waiting').hidden=true;$('expired').hidden=false;
|
|
136
|
+
}
|
|
36
137
|
(function poll(){
|
|
37
138
|
fetch(cfg.base+'/wait',{headers:auth})
|
|
38
139
|
.then(function(r){if(r.status===401||r.status===404)return {status:'failed'};if(!r.ok)throw new Error(String(r.status));return r.json();})
|
|
39
140
|
.then(function(b){
|
|
40
141
|
if(b.status==='pending'){poll();return;}
|
|
41
142
|
if(b.status==='connected'){back('connected');return;}
|
|
42
|
-
if(b.status==='expired'){
|
|
143
|
+
if(b.status==='expired'){expire();return;}
|
|
43
144
|
back('failed');
|
|
44
145
|
})
|
|
45
146
|
.catch(function(){setTimeout(poll,3000);});
|
|
46
147
|
})();
|
|
47
148
|
}
|
|
48
149
|
})();
|
|
49
|
-
|
|
150
|
+
`,F={arrow:'<path d="M7 7h10v10"/><path d="M7 17 17 7"/>',copy:'<rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>',clock:'<circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/>',warn:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',alert:'<circle cx="12" cy="12" r="10"/><path d="M12 8v4"/><path d="M12 16h.01"/>',check:'<path d="M20 6 9 18l-5-5"/>'};function c(e,t=""){return`<svg class="ic${t}" viewBox="0 0 24 24" aria-hidden="true" focusable="false">${F[e]}</svg>`}a(c,"icon");const W='<svg viewBox="0 0 32 32" aria-hidden="true" focusable="false"><path d="M23.4 8.6A10.5 10.5 0 1 0 23.4 23.4" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"/><path d="M16 16 L27.5 16" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/><circle cx="16" cy="16" r="3.6" fill="currentColor"/><circle cx="27.5" cy="16" r="3.2" fill="currentColor"/></svg>',V={claude:'<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><rect width="24" height="24" fill="#d97757"/><path d="M12 5v14M5 12h14M7 7l10 10M17 7 7 17" stroke="#fff" stroke-width="1.8" stroke-linecap="round"/></svg>',chatgpt:'<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><rect width="24" height="24" fill="#141816"/><circle cx="12" cy="12" r="5.5" fill="none" stroke="#fff" stroke-width="1.8"/></svg>'},S="team@northlight.ai";function T(e){const t=JSON.stringify(e.config).replace(/</g,"\\u003c");return`<!doctype html>
|
|
50
151
|
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
51
|
-
<
|
|
52
|
-
<
|
|
152
|
+
<meta name="color-scheme" content="light dark">
|
|
153
|
+
<title>${p(e.title)}</title><style nonce="${e.nonce}">${D}</style></head>
|
|
154
|
+
<body>
|
|
155
|
+
<header class="top">${W}<span>Northlight</span></header>
|
|
156
|
+
<main><div class="col">${e.body}</div></main>
|
|
157
|
+
<footer class="foot"><span>Need help? Email <a href="mailto:${S}">${S}</a></span></footer>
|
|
53
158
|
<script type="application/json" id="cfg">${t}<\/script>
|
|
54
|
-
<script nonce="${e.nonce}">${
|
|
55
|
-
</body></html>`}a(
|
|
56
|
-
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
<
|
|
70
|
-
<
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
<
|
|
159
|
+
<script nonce="${e.nonce}">${q}<\/script>
|
|
160
|
+
</body></html>`}a(T,"page");function M(e,t){return`<div class="head"><div class="logo">${V[e]}</div><div><span class="eyebrow">AI subscription</span><h1>Connect your ${t} account</h1></div></div>`}a(M,"header");function f(e,t,n="",r=""){return`<li${r}><span class="n"><span>${e}</span>${c("check")}</span><div class="body"><span class="title">${t}</span>${n}</div></li>`}a(f,"step");function X(e,t,n,r){return T({nonce:t,title:"Connect Claude",body:`<div class="card">
|
|
161
|
+
${M("claude","Claude")}
|
|
162
|
+
<ol class="steps">
|
|
163
|
+
${f(1,"Sign in to Claude in a new tab",`<div><a class="btn" href="${p(e.url)}" target="_blank" rel="noopener noreferrer">Open claude.ai${c("arrow")}</a></div>`," data-pre")}
|
|
164
|
+
${f(2,"Copy the code Claude shows you",""," data-pre")}
|
|
165
|
+
${f(3,"Paste it here",`<form id="paste" autocomplete="off">
|
|
166
|
+
<div class="field"><label for="code">Code from Claude</label>
|
|
167
|
+
<input type="text" id="code" name="code" required spellcheck="false" autocapitalize="off" aria-describedby="error">
|
|
168
|
+
<div id="error" class="err" role="alert">${c("alert")}<span id="error-text"></span></div></div>
|
|
169
|
+
<button class="btn primary lg wide" type="submit">Connect Claude</button>
|
|
170
|
+
</form>`)}
|
|
171
|
+
</ol>
|
|
172
|
+
</div>`,config:{kind:"anthropic",base:`${l}/${encodeURIComponent(e.flow_id)}`,returnTo:n,handoff:r}})}a(X,"anthropicPage");function Y(e,t){const n=Date.parse(e.expires_at)-t;return Math.max(0,Math.floor(Math.min(Number.isNaN(n)?$*1e3:n,$*1e3)/1e3))}a(Y,"codeSecondsLeft");function K(e,t,n,r,o=Date.now()){const i=e.user_code??"";return T({nonce:t,title:"Connect ChatGPT",body:`<div class="card">
|
|
173
|
+
${M("chatgpt","ChatGPT")}
|
|
174
|
+
<div class="alert" id="settings" role="alert">${c("warn")}
|
|
175
|
+
<div class="text"><strong>Turn on device code sign-in first</strong>OpenAI refuses this sign-in unless device code authorization for Codex is on in ChatGPT's Security settings.</div>
|
|
176
|
+
<div class="act"><a class="btn sm" href="${G}" target="_blank" rel="noopener noreferrer">Open settings${c("arrow")}</a></div></div>
|
|
177
|
+
<ol class="steps" id="device">
|
|
178
|
+
${f(1,"Open the OpenAI device page",`<div><a class="btn" id="device-link" href="${p(e.url)}" target="_blank" rel="noopener noreferrer">${p(e.url.replace(/^https:\/\//,""))}${c("arrow")}</a></div>`)}
|
|
179
|
+
${f(2,"Enter this code",`<div class="codebox"><span class="code" id="user-code">${p(i)}</span>
|
|
180
|
+
<span class="badge" id="expired-badge" hidden>Expired</span>
|
|
181
|
+
<button class="btn sm" type="button" id="copy">${c("copy")}<span id="copy-label">Copy</span></button></div>`)}
|
|
182
|
+
${f(3,"Approve the sign-in",`<span class="small">When OpenAI shows an account email, check it's the account you want to use: approving connects that account.</span>`)}
|
|
183
|
+
</ol>
|
|
184
|
+
<div class="wait" id="waiting">
|
|
185
|
+
<svg class="spin" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M21 12a9 9 0 1 1-9-9"/></svg>
|
|
186
|
+
<div class="msg" aria-live="polite"><b>Waiting for your approval at OpenAI</b><span>This page moves on by itself.</span></div>
|
|
187
|
+
<div class="clock">${c("clock")}<span id="left" aria-hidden="true"></span><span class="sr" id="left-live" aria-live="polite"></span></div>
|
|
76
188
|
</div>
|
|
77
|
-
<
|
|
189
|
+
<div class="alert" id="expired" role="alert" hidden>${c("warn")}
|
|
190
|
+
<div class="text"><strong>The code expired before it was approved</strong>Codes last 15 minutes. Getting a new one starts the sign-in over.</div>
|
|
191
|
+
<div class="act"><button class="btn primary sm" type="button" id="renew">Get a new code</button></div></div>
|
|
192
|
+
</div>`,config:{kind:"openai",base:`${l}/${encodeURIComponent(e.flow_id)}`,returnTo:n,handoff:r,userCode:i,expiresAt:e.expires_at,remainingSeconds:Y(e,o)}})}a(K,"openaiPage");async function Q(e,t,n,r){const o=x(n.searchParams,"handoff"),i=await C(r,o);if(y(i.jti))throw u();const s=x(n.searchParams,"return_to");let b;try{b=s===void 0?void 0:new URL(s).origin}catch{b=void 0}if(s===void 0||b!==new URL(r.issuer).origin)throw new d(400,"invalid_request","return_to must be an absolute URL on the directory origin","return_to");const g=x(n.searchParams,"vendor");if(g!=="anthropic"&&g!=="openai")throw new d(400,"invalid_request","vendor must be anthropic or openai","vendor");if(!z(i.jti,i.exp))throw u();let v;try{v=await P({provider:N(g),jti:i.jti})}catch(w){console.error("[vendor-signin] start failed:",w instanceof Error?w.message:w),t.writeHead(303,{Location:H(s,"failed"),"Cache-Control":"no-store","Referrer-Policy":"no-referrer"}),t.end();return}const m=j(16).toString("base64"),A=g==="anthropic"?X(v,m,s,o):K(v,m,s,o);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store","Referrer-Policy":"no-referrer","X-Content-Type-Options":"nosniff","Content-Security-Policy":`default-src 'none'; script-src 'nonce-${m}'; style-src 'nonce-${m}'; connect-src 'self'; form-action 'none'; base-uri 'none'; frame-ancestors 'none'`}),t.end(A)}a(Q,"startPage");async function _(e,t,n){const r=await C(t,U(e)),o=k(n);if(!o){if(y(r.jti))return!1;throw u()}if(o.jti===void 0||o.jti!==r.jti)throw u();return!0}a(_,"followUpFlow");async function Z(e,t,n,r){if(!await _(e,n,r)){h(t,200,{status:"failed"});return}const o=await J(e);try{await I(r,o.input),h(t,200,{status:"connected"})}catch(i){const s=k(r);if(s&&s.status!=="pending"){h(t,200,{status:"failed"});return}throw i}}a(Z,"submitCode");async function ee(e,t,n,r){if(!await _(e,n,r)){h(t,200,{status:"failed"});return}const o=new AbortController;t.once("close",()=>o.abort());const i=await L(r,B,o.signal);h(t,200,{status:i?.status??"failed"})}a(ee,"waitFlow");async function de(e,t,n,r){const o=e.method??"GET";if(n.pathname===l&&o==="GET"){await Q(e,t,n,r);return}const i=n.pathname.slice(l.length+1).split("/");let s="";try{s=i[0]?decodeURIComponent(i[0]):""}catch{throw new d(404,"not_found","unknown operation")}if(s&&i.length===1&&o==="POST"){await Z(e,t,r,s);return}if(s&&i.length===2&&i[1]==="wait"&&o==="GET"){await ee(e,t,r,s);return}throw new d(404,"not_found","unknown operation")}a(de,"handleVendorSignIn");export{l as VENDOR_SIGNIN_PATH,X as anthropicPage,de as handleVendorSignIn,ce as isVendorSignInPath,K as openaiPage};
|