@north-light/crouter 0.3.331 → 0.3.332
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/dist/builtin-memory/crouter-plugin/README.md +3 -6
- package/dist/builtin-memory/crouter-plugin/bundles-and-memory.md +2 -4
- package/dist/builtin-memory/crouter-plugin/commands.md +3 -6
- package/dist/builtin-memory/crouter-plugin/deploying.md +3 -6
- package/dist/builtin-memory/crouter-plugin/errors.md +2 -5
- package/dist/builtin-memory/crouter-plugin/getting-started.md +2 -5
- package/dist/builtin-memory/crouter-plugin/output.md +1 -3
- package/dist/builtin-memory/crouter-plugin/parameters.md +3 -4
- package/dist/builtin-memory/crouter-sdk/README.md +3 -4
- package/dist/builtin-memory/crouter-sdk/bash.md +2 -3
- package/dist/builtin-memory/crouter-sdk/client.md +3 -4
- package/dist/builtin-memory/crouter-sdk/docker.md +2 -4
- package/dist/builtin-memory/crouter-sdk/errors.md +9 -4
- package/dist/builtin-memory/crouter-sdk/files.md +2 -3
- package/dist/builtin-memory/crouter-sdk/getting-started.md +19 -6
- package/dist/builtin-memory/crouter-sdk/memory.md +3 -4
- package/dist/builtin-memory/crouter-sdk/migration.md +2 -6
- package/dist/builtin-memory/crouter-sdk/nodes.md +3 -3
- package/dist/builtin-memory/crouter-sdk/resources.md +2 -4
- package/dist/builtin-memory/crouter-sdk/streaming.md +3 -4
- package/dist/clients/attach/viewer.js +773 -776
- package/dist/commands/sys/connect.js +3 -3
- package/dist/core/runtime/spawn.d.ts +3 -1
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/scopes.d.ts +4 -2
- package/dist/core/scopes.js +1 -1
- package/dist/core/secrets.d.ts +11 -0
- package/dist/core/secrets.js +2 -2
- package/dist/daemon/api/bridge.d.ts +4 -0
- package/dist/daemon/api/bridge.js +2 -2
- package/dist/daemon/api/handlers/attach.d.ts +1 -1
- package/dist/daemon/api/handlers/attach.js +1 -1
- package/dist/daemon/api/handlers/bash.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.d.ts +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/broker-recovery.d.ts +1 -1
- package/dist/daemon/api/handlers/broker-recovery.js +1 -1
- package/dist/daemon/api/handlers/canvas.js +4 -4
- package/dist/daemon/api/handlers/crons.d.ts +1 -1
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/daemon.d.ts +1 -1
- package/dist/daemon/api/handlers/daemon.js +1 -1
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/focus.d.ts +1 -1
- package/dist/daemon/api/handlers/focus.js +1 -1
- package/dist/daemon/api/handlers/human-requests.js +1 -1
- package/dist/daemon/api/handlers/memory.js +1 -1
- package/dist/daemon/api/handlers/messages.d.ts +1 -1
- package/dist/daemon/api/handlers/messages.js +2 -2
- package/dist/daemon/api/handlers/model-config.d.ts +1 -1
- package/dist/daemon/api/handlers/model-config.js +1 -1
- package/dist/daemon/api/handlers/modelauth.js +1 -1
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/reports.js +1 -1
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/handlers/worktree.d.ts +1 -1
- package/dist/daemon/api/handlers/worktree.js +1 -1
- package/dist/daemon/api/router.d.ts +20 -1
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.js +1 -11
- package/docs/plugin/README.md +5 -0
- package/docs/plugin/bundles-and-memory.md +5 -0
- package/docs/plugin/commands.md +5 -0
- package/docs/plugin/deploying.md +5 -0
- package/docs/plugin/errors.md +5 -0
- package/docs/plugin/getting-started.md +5 -0
- package/docs/plugin/output.md +5 -0
- package/docs/plugin/parameters.md +5 -0
- package/docs/sdk/README.md +5 -0
- package/docs/sdk/bash.md +5 -0
- package/docs/sdk/client.md +6 -1
- package/docs/sdk/docker.md +5 -0
- package/docs/sdk/errors.md +12 -0
- package/docs/sdk/files.md +5 -0
- package/docs/sdk/getting-started.md +21 -1
- package/docs/sdk/memory.md +5 -0
- package/docs/sdk/migration.md +5 -0
- package/docs/sdk/nodes.md +6 -1
- package/docs/sdk/resources.md +5 -0
- package/docs/sdk/streaming.md +5 -0
- package/package.json +3 -2
- package/runtime.lock.json +6570 -506
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type RouteTable } from '../router.js';
|
|
2
2
|
export declare const focusRoutes: RouteTable;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var r=Object.defineProperty;var
|
|
1
|
+
var r=Object.defineProperty;var o=(n,e)=>r(n,"name",{value:e,configurable:!0});import{focusByPane as i,focusOf as d,listFocuses as a,registerViewerFocus as c}from"../../../core/runtime/placement.js";import{closeFocusRow as f,setFocusPane as p}from"../../../core/canvas/focuses.js";import{usage as s}from"../../../core/errors.js";import{ownerOnly as l}from"../router.js";function u(n){return n===null?null:{focus_id:n.focus_id,pane:n.pane,session:n.session,node_id:n.node_id}}o(u,"toFocusDTO");function y(){return{status:200,body:a().map(e=>u(e))}}o(y,"handleListFocuses");function h(n){const e=n.query.get("node_id");if(e===null||e==="")throw s("focuses/by-node requires a node_id query param");return{status:200,body:u(d(e))}}o(h,"handleFocusByNode");function m(n){const e=n.query.get("pane");if(e===null||e==="")throw s("focuses/by-pane requires a pane query param");return{status:200,body:u(i(e))}}o(m,"handleFocusByPane");function _(n){if(typeof n!="object"||n===null)throw s("register-focus body must be a JSON object");const e=n;if(typeof e.node_id!="string"||e.node_id==="")throw s("node_id is required");if(typeof e.pane!="string"||e.pane==="")throw s("pane is required");return{node_id:e.node_id,pane:e.pane,session:typeof e.session=="string"?e.session:null,window:typeof e.window=="string"?e.window:null}}o(_,"parseRegisterBody");function b(n){const e=_(n.body),t=c(e.node_id,e.pane,e.session,e.window);return{status:200,body:u(t)}}o(b,"handleRegisterFocus");function w(n){if(typeof n!="object"||n===null)throw s("set-focus-pane body must be a JSON object");const e=n;return{pane:typeof e.pane=="string"?e.pane:null,session:typeof e.session=="string"?e.session:null}}o(w,"parseSetPaneBody");function g(n){const e=n.params.focus_id;if(e===void 0||e==="")throw s("focus_id is required");const t=w(n.body);return p(e,t.pane,t.session),{status:204}}o(g,"handleSetFocusPane");function q(n){const e=n.params.focus_id;if(e===void 0||e==="")throw s("focus_id is required");return f(e),{status:204}}o(q,"handleCloseFocus");const O=l([{method:"GET",pattern:"/v1/focuses",handler:y},{method:"POST",pattern:"/v1/focuses",handler:b},{method:"GET",pattern:"/v1/focuses/by-node",handler:h},{method:"GET",pattern:"/v1/focuses/by-pane",handler:m},{method:"PATCH",pattern:"/v1/focuses/:focus_id",handler:g},{method:"DELETE",pattern:"/v1/focuses/:focus_id",handler:q}]);export{O as focusRoutes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var R=Object.defineProperty;var o=(e,t)=>R(e,"name",{value:t,configurable:!0});import{statSync as j}from"node:fs";import{isAbsolute as E}from"node:path";import{ApiError as s}from"../../../api/index.js";import{readExternalActionDelivery as N}from"../../../core/canvas/deliveries.js";import{isSafeNodeId as P}from"../../../core/canvas/paths.js";import{getNode as x}from"../../../core/canvas/canvas.js";import{assertScope as T}from"../../../core/scopes.js";import{resolvePageComponents as C}from"../../../core/config.js";import{resolveHumanAction as I}from"../../../core/human-actions.js";import{HUMAN_ACTION_NAME_PATTERN as $}from"../../../core/human/action-binding.js";import{createPageRequest as D,getRequest as J}from"../../../core/human/requests.js";import{preparePageSource as F}from"../../../core/human/page-authoring.js";import{publishPage as M,validatePageTicketResponses as H}from"../../../core/human/tickets.js";import{cancelHumanTicket as L,resolvePageTicket as U}from"../../human/finish.js";import{inboxPageProjection as B}from"./inbox-page.js";const G=1e3,_=200,p={placement:"inline",inbox:!0,reply:!1},b=["sessionName","askedBy","emittedAt","profileName","nodeId"];function c(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(c,"isPlainObject");function l(e,t,n){for(const r of Object.keys(e))if(!t.includes(r))throw new s(400,"invalid_request",`unexpected field in ${n}: ${r}`)}o(l,"requireNoExtraKeys");function i(e){return new s(400,"invalid_request",e)}o(i,"invalid");function g(e){if(!c(e))throw i("`page` must be an object");if(l(e,["dialect","source"],"`page`"),e.dialect!=="jsx"&&e.dialect!=="html")throw i('`page.dialect` must be "jsx" or "html"');if(typeof e.source!="string"||e.source.trim()==="")throw i("`page.source` must be the authored page text");return{dialect:e.dialect,source:e.source}}o(g,"validatePage");function q(e,t){const n=e??t;if(n!=="inline"&&n!=="panel")throw i('`delivery.placement` must be "inline" or "panel"');return n}o(q,"validatePlacement");function K(e,t){if(e===void 0)return p;if(!c(e))throw i("`delivery` must be an object");l(e,["placement","inbox","reply"],"`delivery`");const n=e.inbox??p.inbox,r=e.reply??p.reply;if(typeof n!="boolean")throw i("`delivery.inbox` must be boolean");if(typeof r!="boolean")throw i("`delivery.reply` must be boolean");if(r&&t===null)throw i("`delivery.reply` requires `requester_node_id`");return{placement:q(e.placement,p.placement),inbox:n,reply:r}}o(K,"validateCreateDelivery");function X(e,t){if(e===void 0)return t;if(!c(e))throw i("`delivery` must be an object");return l(e,["placement"],"`delivery`"),{...t,placement:q(e.placement,t.placement)}}o(X,"validateReplaceDelivery");function z(e){if(e===void 0)return;if(!c(e))throw i("`source` must be an object");l(e,b,"`source`");const t={};for(const n of b){const r=e[n];if(r!==void 0){if(typeof r!="string"||r==="")throw i(`\`source.${n}\` must be a nonempty string`);t[n]=r}}return t}o(z,"validateSource");function V(e){if(typeof e!="string"||e==="")throw i("`creator_cwd` is required");if(!E(e))throw i("`creator_cwd` must be an absolute path");try{if(!j(e).isDirectory())throw i(`\`creator_cwd\` is not a directory: ${e}`)}catch(t){throw t instanceof s?t:i(`\`creator_cwd\` does not exist: ${e}`)}return e}o(V,"validateCreatorCwd");function Y(e){if(e!==void 0){if(!c(e))throw i("`action` must be an object");if(l(e,["name","payload"],"`action`"),typeof e.name!="string"||!$.test(e.name))throw i("`action.name` must be a declared action name");return{name:e.name,payload:e.payload??null}}}o(Y,"validateActionSelection");function Q(e){if(e==null)return null;if(typeof e!="string"||!P(e))throw i("`requester_node_id` must be a safe node id or null");return e}o(Q,"validateRequesterNodeId");function W(e){if(!c(e))throw i("request body is required");l(e,["page","delivery","source","requester_node_id","creator_cwd","action"],"the request body");const t=z(e.source),n=Q(e.requester_node_id),r=Y(e.action);return{page:g(e.page),delivery:K(e.delivery,n),...t===void 0?{}:{source:t},requesterNodeId:n,creatorCwd:V(e.creator_cwd),...r===void 0?{}:{action:r}}}o(W,"validateCreateRequest");function Z(e,t){if(!c(e))throw i("request body is required");return l(e,["page","delivery"],"the request body"),{page:g(e.page),delivery:X(e.delivery,t)}}o(Z,"validateReplaceRequest");function y(e,t,n){if(e!==void 0){if(typeof e!="string"||e.trim()===""||e.length>n)throw i(`\`${t}\` must be nonempty after trim and at most ${n} characters`);return e}}o(y,"optionalBoundedString");function ee(e){if(!c(e))throw i("request body is required");if(l(e,["responses","actor"],"the request body"),!c(e.responses))throw i("`responses` must be an object");const t=y(e.actor,"actor",_);return{responses:e.responses,...t===void 0?{}:{actor:t}}}o(ee,"validateRespondRequest");function te(e){if(e===void 0)return{};if(!c(e))throw i("request body must be an object");l(e,["reason","actor"],"the request body");const t=y(e.reason,"reason",G),n=y(e.actor,"actor",_);return{...t===void 0?{}:{reason:t},...n===void 0?{}:{actor:n}}}o(te,"validateSettleRequest");function m(e){const t=e.params.request_id;if(typeof t!="string"||t==="")throw i("request id is required");return t}o(m,"requestId");function f(e){const t=J(e);if(t===null||t.kind!=="page")throw new s(404,"not_found","no request with that id");return t}o(f,"requirePageRequest");function v(e){try{const t=JSON.parse(e.specification_json);if(!c(t))throw new Error("not an object");return t}catch{throw new s(500,"internal","the request specification could not be read")}}o(v,"manifest");function ne(e){if(e.result_json===null)return null;try{return JSON.parse(e.result_json)}catch{throw new s(500,"internal","the request result could not be read")}}o(ne,"terminalResult");function re(e){if(e.action_json===null)return null;try{const t=JSON.parse(e.action_json);if(t.schema!=="crtr.human-action-binding/v1"||typeof t.name!="string")throw new Error("invalid action");return t}catch{throw new s(500,"internal","the request action could not be read")}}o(re,"frozenAction");function oe(e){return e.state!=="settled"?"pending":e.outcome==="answered"?"answered":e.outcome==="dismissed"?"dismissed":"canceled"}o(oe,"requestState");function ie(e){if(e.action_delivery_id===null)return{state:"none",attempt:0};const t=N(`human-action:${e.inbox_ticket_id}`);if(t===null)return{state:"none",attempt:0};const n=t.state==="acknowledged"?"accepted":t.state==="permanent_failed"?"permanent_failed":t.state==="handed_off"?"running":"pending",r={state:n,attempt:t.attempts};return n==="pending"&&t.nextAttemptAt!==null&&(r.next_attempt_at=new Date(t.nextAttemptAt).toISOString()),t.acknowledgedAt!==null&&(r.accepted_at=new Date(t.acknowledgedAt).toISOString()),t.failedAt!==null&&(r.permanent_failed_at=new Date(t.failedAt).toISOString()),t.lastFailure!==null&&(r.last_failure=t.lastFailure),r}o(ie,"deliveryDetail");function h(e){const t=v(e),n=ne(e),r=oe(e),a={request_id:e.request_id,inbox_ticket_id:e.inbox_ticket_id,request_dir:e.request_dir,kind:e.kind,state:r,title:e.title,source:t.source??{},emitted_at:t.source?.emittedAt??e.created_at};e.subtitle!==null&&(a.subtitle=e.subtitle),e.kind==="page"&&(a.page=B(e)),n!==null&&(a.settled_at=e.settled_at??e.updated_at,n.kind==="page"&&r==="answered"&&(a.responses=n.responses),n.kind==="canceled"&&n.reason!==void 0&&(a.reason=n.reason),n.kind==="page"&&n.actor!==void 0&&(a.actor=n.actor),n.kind==="canceled"&&n.actor!==void 0&&(a.actor=n.actor));const u=re(e);return u!==null&&(a.action={name:u.name,payload:u.payload},a.delivery=ie(e)),a}o(h,"requestToDTO");function w(e,t,n,r){try{return F({dialect:e,document:t,source:n,delivery:r,productKinds:C()})}catch(a){throw i(a instanceof Error?a.message:"the page could not be prepared")}}o(w,"prepareOrReject");function ae(e){const t=W(e.body),n=t.requesterNodeId??t.source?.nodeId;if(n!=null){const d=x(n);d!==null&&T(d,"ask")}let r;if(t.action!==void 0){const d=I(t.action.name,t.creatorCwd);if("kind"in d){const O=d.kind==="unknown_action"?`no action named ${d.name} is declared from ${t.creatorCwd}`:`${d.name} is declared in ${d.configOrigin} but unusable: ${d.reason}`;throw new s(400,d.kind,O)}r=JSON.stringify({schema:"crtr.human-action-binding/v1",name:t.action.name,payload:t.action.payload,creatorCwd:t.creatorCwd,configOrigin:d.configOrigin,argv:d.argv,cwd:d.cwd})}const a=w(t.page.dialect,t.page.source,t.source,t.delivery),u=D({prepared:a,requester_node_id:t.requesterNodeId,...r===void 0?{}:{action_json:r}});return{status:201,body:{request_id:u.request_id,request_dir:u.request_dir,state:"pending",...t.action===void 0?{}:{action:{name:t.action.name}},delivery_state:"none"}}}o(ae,"handleCreate");function se(e){return{status:200,body:h(f(m(e)))}}o(se,"handleGet");function de(e){const t=f(m(e));if(t.state==="settled")throw new s(409,"already_settled","the request already has a terminal result");const n=v(t),r=Z(e.body,n.delivery),a=w(r.page.dialect,r.page.source,n.source,r.delivery);try{M(t.request_dir,a)}catch(u){throw u instanceof Error&&u.message===`page request is not open: ${t.request_id}`?new s(409,"already_settled","the request already has a terminal result"):u}return{status:200,body:h(f(t.request_id))}}o(de,"handleReplace");function S(e){return e instanceof s?e:e instanceof Error&&e.message.includes("unknown page request")?new s(404,"not_found","no request with that id"):e instanceof Error&&e.message==="page_has_no_response_lifecycle"?new s(409,"not_settleable","this request carries no response lifecycle"):new s(500,"internal","the request could not be settled")}o(S,"settlementError");function A(e){if(e.state==="settled")throw new s(409,"already_settled","the request already has a terminal result");if(!e.settleable)throw new s(409,"not_settleable","this request carries no response lifecycle")}o(A,"requireSettleable");async function ce(e){const t=f(m(e)),n=ee(e.body);A(t);try{H(t.request_dir,n.responses)}catch(r){throw i(r instanceof Error?r.message:"the response map is invalid")}try{await U(t.request_id,n.responses,n.actor===void 0?{}:{actor:n.actor})}catch(r){throw S(r)}return{status:200,body:h(f(t.request_id))}}o(ce,"handleRespond");async function k(e,t){const n=f(m(e)),r=te(e.body);A(n);try{await L(n.request_id,{...r,disposition:t})}catch(a){throw S(a)}return{status:200,body:h(f(n.request_id))}}o(k,"settle");const Oe=[{method:"POST",pattern:"/v1/human/requests",handler:ae},{method:"GET",pattern:"/v1/human/requests/:request_id",handler:se},{method:"POST",pattern:"/v1/human/requests/:request_id/replace",handler:de},{method:"POST",pattern:"/v1/human/requests/:request_id/respond",handler:ce},{method:"POST",pattern:"/v1/human/requests/:request_id/dismiss",handler:o(e=>k(e,"dismissed"),"handler")},{method:"POST",pattern:"/v1/human/requests/:request_id/cancel",handler:o(e=>k(e,"canceled"),"handler")}];export{Oe as humanRequestRoutes};
|
|
1
|
+
var R=Object.defineProperty;var o=(e,t)=>R(e,"name",{value:t,configurable:!0});import{statSync as j}from"node:fs";import{isAbsolute as E}from"node:path";import{ApiError as s}from"../../../api/index.js";import{readExternalActionDelivery as N}from"../../../core/canvas/deliveries.js";import{isSafeNodeId as P}from"../../../core/canvas/paths.js";import{getNode as x}from"../../../core/canvas/canvas.js";import{assertScope as T}from"../../../core/scopes.js";import{resolvePageComponents as C}from"../../../core/config.js";import{resolveHumanAction as I}from"../../../core/human-actions.js";import{HUMAN_ACTION_NAME_PATTERN as $}from"../../../core/human/action-binding.js";import{createPageRequest as D,getRequest as J}from"../../../core/human/requests.js";import{preparePageSource as F}from"../../../core/human/page-authoring.js";import{publishPage as M,validatePageTicketResponses as H}from"../../../core/human/tickets.js";import{cancelHumanTicket as L,resolvePageTicket as U}from"../../human/finish.js";import{inboxPageProjection as B}from"./inbox-page.js";const G=1e3,_=200,p={placement:"inline",inbox:!0,reply:!1},b=["sessionName","askedBy","emittedAt","profileName","nodeId"];function c(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(c,"isPlainObject");function l(e,t,n){for(const r of Object.keys(e))if(!t.includes(r))throw new s(400,"invalid_request",`unexpected field in ${n}: ${r}`)}o(l,"requireNoExtraKeys");function i(e){return new s(400,"invalid_request",e)}o(i,"invalid");function g(e){if(!c(e))throw i("`page` must be an object");if(l(e,["dialect","source"],"`page`"),e.dialect!=="jsx"&&e.dialect!=="html")throw i('`page.dialect` must be "jsx" or "html"');if(typeof e.source!="string"||e.source.trim()==="")throw i("`page.source` must be the authored page text");return{dialect:e.dialect,source:e.source}}o(g,"validatePage");function q(e,t){const n=e??t;if(n!=="inline"&&n!=="panel")throw i('`delivery.placement` must be "inline" or "panel"');return n}o(q,"validatePlacement");function K(e,t){if(e===void 0)return p;if(!c(e))throw i("`delivery` must be an object");l(e,["placement","inbox","reply"],"`delivery`");const n=e.inbox??p.inbox,r=e.reply??p.reply;if(typeof n!="boolean")throw i("`delivery.inbox` must be boolean");if(typeof r!="boolean")throw i("`delivery.reply` must be boolean");if(r&&t===null)throw i("`delivery.reply` requires `requester_node_id`");return{placement:q(e.placement,p.placement),inbox:n,reply:r}}o(K,"validateCreateDelivery");function X(e,t){if(e===void 0)return t;if(!c(e))throw i("`delivery` must be an object");return l(e,["placement"],"`delivery`"),{...t,placement:q(e.placement,t.placement)}}o(X,"validateReplaceDelivery");function z(e){if(e===void 0)return;if(!c(e))throw i("`source` must be an object");l(e,b,"`source`");const t={};for(const n of b){const r=e[n];if(r!==void 0){if(typeof r!="string"||r==="")throw i(`\`source.${n}\` must be a nonempty string`);t[n]=r}}return t}o(z,"validateSource");function V(e){if(typeof e!="string"||e==="")throw i("`creator_cwd` is required");if(!E(e))throw i("`creator_cwd` must be an absolute path");try{if(!j(e).isDirectory())throw i(`\`creator_cwd\` is not a directory: ${e}`)}catch(t){throw t instanceof s?t:i(`\`creator_cwd\` does not exist: ${e}`)}return e}o(V,"validateCreatorCwd");function Y(e){if(e!==void 0){if(!c(e))throw i("`action` must be an object");if(l(e,["name","payload"],"`action`"),typeof e.name!="string"||!$.test(e.name))throw i("`action.name` must be a declared action name");return{name:e.name,payload:e.payload??null}}}o(Y,"validateActionSelection");function Q(e){if(e==null)return null;if(typeof e!="string"||!P(e))throw i("`requester_node_id` must be a safe node id or null");return e}o(Q,"validateRequesterNodeId");function W(e){if(!c(e))throw i("request body is required");l(e,["page","delivery","source","requester_node_id","creator_cwd","action"],"the request body");const t=z(e.source),n=Q(e.requester_node_id),r=Y(e.action);return{page:g(e.page),delivery:K(e.delivery,n),...t===void 0?{}:{source:t},requesterNodeId:n,creatorCwd:V(e.creator_cwd),...r===void 0?{}:{action:r}}}o(W,"validateCreateRequest");function Z(e,t){if(!c(e))throw i("request body is required");return l(e,["page","delivery"],"the request body"),{page:g(e.page),delivery:X(e.delivery,t)}}o(Z,"validateReplaceRequest");function y(e,t,n){if(e!==void 0){if(typeof e!="string"||e.trim()===""||e.length>n)throw i(`\`${t}\` must be nonempty after trim and at most ${n} characters`);return e}}o(y,"optionalBoundedString");function ee(e){if(!c(e))throw i("request body is required");if(l(e,["responses","actor"],"the request body"),!c(e.responses))throw i("`responses` must be an object");const t=y(e.actor,"actor",_);return{responses:e.responses,...t===void 0?{}:{actor:t}}}o(ee,"validateRespondRequest");function te(e){if(e===void 0)return{};if(!c(e))throw i("request body must be an object");l(e,["reason","actor"],"the request body");const t=y(e.reason,"reason",G),n=y(e.actor,"actor",_);return{...t===void 0?{}:{reason:t},...n===void 0?{}:{actor:n}}}o(te,"validateSettleRequest");function m(e){const t=e.params.request_id;if(typeof t!="string"||t==="")throw i("request id is required");return t}o(m,"requestId");function f(e){const t=J(e);if(t===null||t.kind!=="page")throw new s(404,"not_found","no request with that id");return t}o(f,"requirePageRequest");function v(e){try{const t=JSON.parse(e.specification_json);if(!c(t))throw new Error("not an object");return t}catch{throw new s(500,"internal","the request specification could not be read")}}o(v,"manifest");function ne(e){if(e.result_json===null)return null;try{return JSON.parse(e.result_json)}catch{throw new s(500,"internal","the request result could not be read")}}o(ne,"terminalResult");function re(e){if(e.action_json===null)return null;try{const t=JSON.parse(e.action_json);if(t.schema!=="crtr.human-action-binding/v1"||typeof t.name!="string")throw new Error("invalid action");return t}catch{throw new s(500,"internal","the request action could not be read")}}o(re,"frozenAction");function oe(e){return e.state!=="settled"?"pending":e.outcome==="answered"?"answered":e.outcome==="dismissed"?"dismissed":"canceled"}o(oe,"requestState");function ie(e){if(e.action_delivery_id===null)return{state:"none",attempt:0};const t=N(`human-action:${e.inbox_ticket_id}`);if(t===null)return{state:"none",attempt:0};const n=t.state==="acknowledged"?"accepted":t.state==="permanent_failed"?"permanent_failed":t.state==="handed_off"?"running":"pending",r={state:n,attempt:t.attempts};return n==="pending"&&t.nextAttemptAt!==null&&(r.next_attempt_at=new Date(t.nextAttemptAt).toISOString()),t.acknowledgedAt!==null&&(r.accepted_at=new Date(t.acknowledgedAt).toISOString()),t.failedAt!==null&&(r.permanent_failed_at=new Date(t.failedAt).toISOString()),t.lastFailure!==null&&(r.last_failure=t.lastFailure),r}o(ie,"deliveryDetail");function h(e){const t=v(e),n=ne(e),r=oe(e),a={request_id:e.request_id,inbox_ticket_id:e.inbox_ticket_id,request_dir:e.request_dir,kind:e.kind,state:r,title:e.title,source:t.source??{},emitted_at:t.source?.emittedAt??e.created_at};e.subtitle!==null&&(a.subtitle=e.subtitle),e.kind==="page"&&(a.page=B(e)),n!==null&&(a.settled_at=e.settled_at??e.updated_at,n.kind==="page"&&r==="answered"&&(a.responses=n.responses),n.kind==="canceled"&&n.reason!==void 0&&(a.reason=n.reason),n.kind==="page"&&n.actor!==void 0&&(a.actor=n.actor),n.kind==="canceled"&&n.actor!==void 0&&(a.actor=n.actor));const u=re(e);return u!==null&&(a.action={name:u.name,payload:u.payload},a.delivery=ie(e)),a}o(h,"requestToDTO");function w(e,t,n,r){try{return F({dialect:e,document:t,source:n,delivery:r,productKinds:C()})}catch(a){throw i(a instanceof Error?a.message:"the page could not be prepared")}}o(w,"prepareOrReject");function ae(e){const t=W(e.body),n=t.requesterNodeId??t.source?.nodeId;if(n!=null){const d=x(n);d!==null&&T(d,"ask")}let r;if(t.action!==void 0){const d=I(t.action.name,t.creatorCwd);if("kind"in d){const O=d.kind==="unknown_action"?`no action named ${d.name} is declared from ${t.creatorCwd}`:`${d.name} is declared in ${d.configOrigin} but unusable: ${d.reason}`;throw new s(400,d.kind,O)}r=JSON.stringify({schema:"crtr.human-action-binding/v1",name:t.action.name,payload:t.action.payload,creatorCwd:t.creatorCwd,configOrigin:d.configOrigin,argv:d.argv,cwd:d.cwd})}const a=w(t.page.dialect,t.page.source,t.source,t.delivery),u=D({prepared:a,requester_node_id:t.requesterNodeId,...r===void 0?{}:{action_json:r}});return{status:201,body:{request_id:u.request_id,request_dir:u.request_dir,state:"pending",...t.action===void 0?{}:{action:{name:t.action.name}},delivery_state:"none"}}}o(ae,"handleCreate");function se(e){return{status:200,body:h(f(m(e)))}}o(se,"handleGet");function de(e){const t=f(m(e));if(t.state==="settled")throw new s(409,"already_settled","the request already has a terminal result");const n=v(t),r=Z(e.body,n.delivery),a=w(r.page.dialect,r.page.source,n.source,r.delivery);try{M(t.request_dir,a)}catch(u){throw u instanceof Error&&u.message===`page request is not open: ${t.request_id}`?new s(409,"already_settled","the request already has a terminal result"):u}return{status:200,body:h(f(t.request_id))}}o(de,"handleReplace");function S(e){return e instanceof s?e:e instanceof Error&&e.message.includes("unknown page request")?new s(404,"not_found","no request with that id"):e instanceof Error&&e.message==="page_has_no_response_lifecycle"?new s(409,"not_settleable","this request carries no response lifecycle"):new s(500,"internal","the request could not be settled")}o(S,"settlementError");function k(e){if(e.state==="settled")throw new s(409,"already_settled","the request already has a terminal result");if(!e.settleable)throw new s(409,"not_settleable","this request carries no response lifecycle")}o(k,"requireSettleable");async function ce(e){const t=f(m(e)),n=ee(e.body);k(t);try{H(t.request_dir,n.responses)}catch(r){throw i(r instanceof Error?r.message:"the response map is invalid")}try{await U(t.request_id,n.responses,n.actor===void 0?{}:{actor:n.actor})}catch(r){throw S(r)}return{status:200,body:h(f(t.request_id))}}o(ce,"handleRespond");async function A(e,t){const n=f(m(e)),r=te(e.body);k(n);try{await L(n.request_id,{...r,disposition:t})}catch(a){throw S(a)}return{status:200,body:h(f(n.request_id))}}o(A,"settle");const Oe=[{method:"POST",pattern:"/v1/human/requests",scope:"ask",handler:ae},{method:"GET",pattern:"/v1/human/requests/:request_id",handler:se},{method:"POST",pattern:"/v1/human/requests/:request_id/replace",handler:de},{method:"POST",pattern:"/v1/human/requests/:request_id/respond",handler:ce},{method:"POST",pattern:"/v1/human/requests/:request_id/dismiss",handler:o(e=>A(e,"dismissed"),"handler")},{method:"POST",pattern:"/v1/human/requests/:request_id/cancel",handler:o(e=>A(e,"canceled"),"handler")}];export{Oe as humanRequestRoutes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var Y=Object.defineProperty;var a=(e,n)=>Y(e,"name",{value:n,configurable:!0});import{getNode as N}from"../../../core/canvas/canvas.js";import{ApiError as l}from"../../../api/errors.js";import{assertScope as J}from"../../../core/scopes.js";import{CrtrError as X}from"../../../core/errors.js";import{memoryDir as x}from"../../../core/runtime/memory.js";import{NEUTRAL_PROJECT_MEMORY as K,projectScopeRoots as L,scopeMemoryDir as Q}from"../../../core/scope.js";import{profileMemoryDir as F}from"../../../core/profiles/manifest.js";import{openProjectMemoryStore as V}from"../../../core/memory-resolver.js";import{candidateLocation as ee,createDoc as te,deleteDoc as ne,listDocs as oe,moveDoc as re,readDoc as ie,readHistory as se,searchDocs as de,updateDoc as ae}from"../../../core/memory/service.js";import{MEMORY_SCOPES as z,isMemoryDocName as S}from"../../../api/dto/memory.js";import{invalidRequest as w,isRecord as R,objectBody as j,optionalString as y,requiredString as b}from"./validate.js";const _="memory:read",I="memory:write",E=100,G=100;function q(e){const n=e.params.name;if(n===void 0||!S(n))throw new l(400,"invalid_memory_doc_name","memory document name must be slash-joined [A-Za-z0-9_-] segments");return n}a(q,"requireName");function k(e){return Object.fromEntries(e.query.entries())}a(k,"queryObject");function $(e,n){return{scope:e,storeRoot:n,namespace:"",mountStatus:"ready",projectMemory:K}}a($,"nativeStore");function p(e,n){const t=[];for(const m of Object.keys(e))n.includes(m)||t.push({field:m,problem:"is not allowed",received:e[m]});const r=y(e,"node",t),i=y(e,"cwd",t),o=y(e,"profile",t),s=y(e,"store",t);s!==void 0&&!z.includes(s)&&t.push({field:"store",problem:`must be one of ${z.join(", ")}`,received:s}),r!==void 0&&(i!==void 0||o!==void 0)&&t.push({field:"node",problem:"derives cwd and profile and cannot be combined with either"}),t.length>0&&w("memory scope",t);let d,u;if(r!==void 0){const m=N(r);if(m===null)throw new l(404,"node_not_found",`unknown node: ${r}`);d={cwd:m.cwd,profileId:m.profile_id??null,nodeId:m.node_id},u=m.node_id}else d={cwd:i??"/",profileId:o??null,nodeId:null};const c=s;if(c==="node"&&u===void 0)throw new l(400,"invalid_request","store node requires node");if(c==="profile"&&d.profileId===null)throw new l(400,"invalid_request","store profile requires profile or node with a profile");return{target:d,...c===void 0?{}:{scope:c},...u===void 0?{}:{nodeId:u}}}a(p,"resolveScope");function h(e,n){if(e.nodeId===void 0)return;const t=N(e.nodeId);if(t===null)throw new l(404,"node_not_found",`unknown node: ${e.nodeId}`);J(t,n)}a(h,"requireScope");function f(e,n){const t=e.scope;if(!n)return{...t===void 0?{}:{scope:t}};const r=t??(L(e.target.cwd,e.target.profileId).length>0?"project":"user");if(r==="builtin")throw new l(400,"invalid_request","builtin memory is read-only");if(r==="node")return{scope:r,store:$("node",x(e.target.nodeId)),memoryDir:x(e.target.nodeId)};if(r==="profile")return{scope:r,store:$("profile",F(e.target.profileId)),memoryDir:F(e.target.profileId)};if(r==="project"){const o=L(e.target.cwd,e.target.profileId)[0];if(o===void 0)throw new l(400,"invalid_request","store project requires a project memory store in cwd or profile");const s=V(o.slice(0,-8).replace(/\/$/,""));return{scope:r,store:s,memoryDir:s.storeRoot}}const i=Q("user");if(i===null)throw new Error("user memory directory unavailable");return{scope:"user",store:$("user",i),memoryDir:i}}a(f,"selection");function Z(e,n){return e.length>1?e.map(t=>ee(t,n)):void 0}a(Z,"candidates");function B(e){return{name:e.name,short_form:e.shortForm,kind:e.kind,scope:e.scope,extensions:e.extensions,path:e.path,store_root:e.storeRoot,physical_relative_path:e.physicalRelativePath,...Z(e.candidates,e.candidates[0])===void 0?{}:{candidates:Z(e.candidates,e.candidates[0])}}}a(B,"summary");function H(e){try{const n=ie(e);if(n.kind==="document")return n}catch(n){if(!(n instanceof X)||n.code!=="not_found")throw n}throw new l(404,"memory_document_not_found",`memory document not found: ${e.name}`)}a(H,"requestedDocument");function A(e,n,t=f(n,!1),r=!1){const i=H({target:n.target,...t,name:e,frontmatter:r,interpolateNodePaths:!1}),o=i.doc;return{...B({name:o.name,kind:String(o.frontmatter?.kind??""),scope:o.scope,path:o.path,storeRoot:o.root,physicalRelativePath:o.physicalRelativePath,shortForm:String(o.frontmatter?.["short-form"]??""),slash:o.frontmatter?.slash===!0,extensions:o.frontmatter?.extensions??{},candidates:i.candidates}),body:i.content,frontmatter:o.frontmatter,representation:o.representation,links:[...i.links]}}a(A,"document");function T(e,n,t){if(e===void 0)return t;const r=typeof e=="number"?e:Number(e);if(!Number.isInteger(r)||r<1||r>G)throw new l(400,"invalid_request",`${n} must be an integer from 1 through ${G}`);return r}a(T,"number");function U(e,n){const t=typeof e=="number"?e:Number(e);if(!Number.isFinite(t)||t<1)throw new l(400,"invalid_request",`${n} must be a finite number of at least 1`);return t}a(U,"positiveNumber");function D(e,n){const t=e[n];if(t!==void 0){if(t===!0||t==="true")return!0;if(t===!1||t==="false")return!1;throw new l(400,"invalid_request",`${n} must be a boolean`)}}a(D,"optionalBoolean");function W(e,n,t=[]){if(e!==void 0&&!R(e))throw new l(400,"invalid_request","frontmatter must be an object");const r=e===void 0?{}:e;for(const s of t)if(s in r)throw new l(400,"invalid_request",`frontmatter.${s} cannot be set directly`);const i={},o={"short-form":"shortForm","when-and-why-to-read":"whenAndWhyToRead","lint-ignore":"lintIgnore",rationale:"docRationale",kind:"kind",unlisted:"unlisted",surfaces:"surface",gate:"gate",slash:"slash"};for(const[s,d]of Object.entries(r)){const u=o[s];if(u===void 0)throw new l(400,"invalid_request",`frontmatter.${s} is not writable through this route`);if(s==="unlisted"||s==="slash"){if(d!==!0)throw new l(400,"invalid_request",`frontmatter.${s} must be true; remove it with unset`)}else if(s==="surfaces"){if(!Array.isArray(d)||!d.every(c=>typeof c=="string"))throw new l(400,"invalid_request","frontmatter.surfaces must be a string array")}else if(s==="lint-ignore"){if(!Array.isArray(d)||!d.every(c=>typeof c=="string"))throw new l(400,"invalid_request","frontmatter.lint-ignore must be a string array")}else if(typeof d!="string"||d.trim()==="")throw new l(400,"invalid_request",`frontmatter.${s} must be a non-empty string`);i[u]=d}if(n!==void 0){if(!R(n))throw new l(400,"invalid_request","extensions must be an object");const s=[];for(const[d,u]of Object.entries(n)){if(!R(u))throw new l(400,"invalid_request",`extensions.${d} must be an object`);for(const[c,m]of Object.entries(u))s.push(`extensions.${d}.${c}=${String(m)}`)}i.extension=s}return i}a(W,"frontmatterFields");function le(e){const n=k(e),t=[],r=y(n,"kind",t),i=y(n,"after",t);t.length>0&&w("memory list query",t);const o=p(n,["node","cwd","profile","store","kind","limit","after"]);h(o,_);const s=oe({target:o.target,...f(o,!1),...r===void 0?{}:{kind:r}}).sort((m,g)=>m.name.localeCompare(g.name)),d=i===void 0?s:s.filter(m=>m.name.localeCompare(i)>0),u=d.slice(0,T(n.limit,"limit",E)).map(B);return{status:200,body:{object:"list",data:u,has_more:d.length>u.length}}}a(le,"handleList");function ue(e){const n=k(e),t=p(n,["node","cwd","profile","store","frontmatter"]);return h(t,_),{status:200,body:A(q(e),t,f(t,!1),D(n,"frontmatter")===!0)}}a(ue,"handleRetrieve");function me(e){const n=[],t=j(e.body,["name","kind","when_and_why_to_read","body","frontmatter","extensions","node","cwd","profile","store"],n),r=b(t,"name",n),i=b(t,"kind",n),o=b(t,"when_and_why_to_read",n),s=b(t,"body",n);if(n.length>0&&w("memory create request",n),!S(r))throw new l(400,"invalid_memory_doc_name","memory document name must be slash-joined [A-Za-z0-9_-] segments");const d=p(t,["name","kind","when_and_why_to_read","body","frontmatter","extensions","node","cwd","profile","store"]);h(d,I);const u=f(d,!0),c={name:r,kind:i,whenAndWhyToRead:o,body:s,...W(t.frontmatter,t.extensions,["kind","when-and-why-to-read","origin","last-updated"])},m=te({target:d.target,scope:u.scope,memoryDir:u.memoryDir,store:u.store,isExplicitProjectStore:!1,origin:{created:new Date().toISOString(),cwd:d.target.cwd,...d.target.nodeId===null?{}:{node:d.target.nodeId}},fields:c}),g=A(m.name,d,u);return{status:200,body:m.findings===void 0?g:{...g,findings:m.findings}}}a(me,"handleCreate");function ce(e){const n=[],t=j(e.body,["rationale","body","frontmatter","extensions","unset","node","cwd","profile","store"],n),r=b(t,"rationale",n);t.body!==void 0&&typeof t.body!="string"&&n.push({field:"body",problem:"must be a string",received:t.body}),t.unset!==void 0&&(!Array.isArray(t.unset)||!t.unset.every(d=>typeof d=="string"))&&n.push({field:"unset",problem:"must be a string array",received:t.unset}),n.length>0&&w("memory update request",n);const i=q(e),o=p(t,["rationale","body","frontmatter","extensions","unset","node","cwd","profile","store"]);h(o,I);const s=W(t.frontmatter,t.extensions,["kind","when-and-why-to-read","origin","last-updated"]);return ae({target:o.target,selection:{target:o.target,...f(o,!1)},fields:{name:i,rationale:r,...t.body===void 0?{}:{body:t.body},...t.unset===void 0?{}:{unset:t.unset},...s}}),{status:200,body:A(i,o)}}a(ce,"handleUpdate");function fe(e){const n=p(k(e),["node","cwd","profile","store"]);h(n,I);const t=q(e);return{status:200,body:{...ne({target:n.target,selection:{target:n.target,...f(n,!1)},fields:{name:t}}),deleted:!0}}}a(fe,"handleDelete");function pe(e){const n=[],t=j(e.body,["to","node","cwd","profile","store"],n),r=b(t,"to",n);if(n.length>0&&w("memory move request",n),!S(r))throw new l(400,"invalid_memory_doc_name","memory document name must be slash-joined [A-Za-z0-9_-] segments");const i=p(t,["to","node","cwd","profile","store"]);h(i,I);const o=q(e);return{status:200,body:re({target:i.target,selection:{target:i.target,...f(i,!1)},fields:{name:o,to:r}})}}a(pe,"handleMove");function O(e){return"line"in e?`${e.name}\0${e.scope}\0${e.physical_relative_path}\0${String(e.line).padStart(10,"0")}`:e.name}a(O,"grepCursor");function he(e){const n=[],t=j(e.body,["query","kind","grep","body","limit","after","min_score","node","cwd","profile","store"],n),r=b(t,"query",n),i=y(t,"kind",n),o=y(t,"after",n);n.length>0&&w("memory search request",n);const s=p(t,["query","kind","grep","body","limit","after","min_score","node","cwd","profile","store"]);h(s,_);const d=D(t,"grep"),u=D(t,"body"),c=t.min_score===void 0?void 0:U(t.min_score,"min_score");if(d===!0&&u===!0)throw new l(400,"invalid_request","grep and body cannot both be true");if(d===!0&&c!==void 0)throw new l(400,"invalid_request","min_score is only available in ranked mode");const g=[...de({target:s.target,...f(s,!1),query:r,...i===void 0?{}:{kind:i},...d===void 0?{}:{grep:d},...u===void 0?{}:{body:u},...c===void 0?{}:{minScore:c}}).hits].sort((v,C)=>d===!0?O(v).localeCompare(O(C)):v.name.localeCompare(C.name)),P=o===void 0?g:g.filter(v=>(d===!0?O(v):v.name).localeCompare(o)>0),M=P.slice(0,T(t.limit,"limit",E));return{status:200,body:{object:"list",data:M,has_more:P.length>M.length}}}a(he,"handleSearch");function ye(e){const n=k(e),t=p(n,["node","cwd","profile","store","limit","revision","diff"]);h(t,_);const r=n.revision===void 0?void 0:U(n.revision,"revision"),i=D(n,"diff"),o=se({target:t.target,...f(t,!1),name:q(e),limit:T(n.limit,"limit",E),...r===void 0?{}:{revision:r},...i===void 0?{}:{diff:i}});return{status:200,body:{name:o.name,scope:o.scope,log_path:o.logPath,total:o.total,...o.deleted===void 0?{}:{deleted:o.deleted},..."record"in o?{record:o.record}:{revisions:[...o.revisions]}}}}a(ye,"handleHistory");function ge(e){const n=k(e),t=e.query.get("name");if(t===null||!S(t))throw new l(400,"invalid_memory_doc_name","memory document name must be slash-joined [A-Za-z0-9_-] segments");const r=p(n,["name","node","cwd","profile","store"]);h(r,_);const i=H({target:r.target,...f(r,!1),name:t});return{status:200,body:{name:i.doc.name,scope:i.doc.scope,path:i.doc.path,store_root:i.doc.root,physical_relative_path:i.doc.physicalRelativePath,...i.doc.plugin===void 0?{}:{plugin:i.doc.plugin}}}}a(ge,"handleResolve");const $e=[{method:"GET",pattern:"/v1/memory/docs",handler:le},{method:"GET",pattern:"/v1/memory/docs/:name",handler:ue},{method:"POST",pattern:"/v1/memory/docs",handler:me},{method:"PATCH",pattern:"/v1/memory/docs/:name",handler:ce},{method:"DELETE",pattern:"/v1/memory/docs/:name",handler:fe},{method:"POST",pattern:"/v1/memory/docs/:name/move",handler:pe},{method:"POST",pattern:"/v1/memory/search",handler:he},{method:"GET",pattern:"/v1/memory/docs/:name/history",handler:ye},{method:"GET",pattern:"/v1/memory/resolve",handler:ge}];export{$e as memoryRoutes};
|
|
1
|
+
var Y=Object.defineProperty;var a=(e,n)=>Y(e,"name",{value:n,configurable:!0});import{getNode as N}from"../../../core/canvas/canvas.js";import{ApiError as m}from"../../../api/errors.js";import{assertScope as J}from"../../../core/scopes.js";import{CrtrError as X}from"../../../core/errors.js";import{memoryDir as x}from"../../../core/runtime/memory.js";import{NEUTRAL_PROJECT_MEMORY as K,projectScopeRoots as L,scopeMemoryDir as Q}from"../../../core/scope.js";import{profileMemoryDir as F}from"../../../core/profiles/manifest.js";import{openProjectMemoryStore as V}from"../../../core/memory-resolver.js";import{candidateLocation as ee,createDoc as te,deleteDoc as ne,listDocs as oe,moveDoc as re,readDoc as ie,readHistory as se,searchDocs as de,updateDoc as ae}from"../../../core/memory/service.js";import{MEMORY_SCOPES as z,isMemoryDocName as S}from"../../../api/dto/memory.js";import{invalidRequest as b,isRecord as R,objectBody as j,optionalString as h,requiredString as w}from"./validate.js";const _="memory:read",I="memory:write",E=100,G=100;function q(e){const n=e.params.name;if(n===void 0||!S(n))throw new m(400,"invalid_memory_doc_name","memory document name must be slash-joined [A-Za-z0-9_-] segments");return n}a(q,"requireName");function k(e){return Object.fromEntries(e.query.entries())}a(k,"queryObject");function $(e,n){return{scope:e,storeRoot:n,namespace:"",mountStatus:"ready",projectMemory:K}}a($,"nativeStore");function p(e,n){const t=[];for(const c of Object.keys(e))n.includes(c)||t.push({field:c,problem:"is not allowed",received:e[c]});const r=h(e,"node",t),i=h(e,"cwd",t),o=h(e,"profile",t),s=h(e,"store",t);s!==void 0&&!z.includes(s)&&t.push({field:"store",problem:`must be one of ${z.join(", ")}`,received:s}),r!==void 0&&(i!==void 0||o!==void 0)&&t.push({field:"node",problem:"derives cwd and profile and cannot be combined with either"}),t.length>0&&b("memory scope",t);let d,l;if(r!==void 0){const c=N(r);if(c===null)throw new m(404,"node_not_found",`unknown node: ${r}`);d={cwd:c.cwd,profileId:c.profile_id??null,nodeId:c.node_id},l=c.node_id}else d={cwd:i??"/",profileId:o??null,nodeId:null};const u=s;if(u==="node"&&l===void 0)throw new m(400,"invalid_request","store node requires node");if(u==="profile"&&d.profileId===null)throw new m(400,"invalid_request","store profile requires profile or node with a profile");return{target:d,...u===void 0?{}:{scope:u},...l===void 0?{}:{nodeId:l}}}a(p,"resolveScope");function y(e,n){if(e.nodeId===void 0)return;const t=N(e.nodeId);if(t===null)throw new m(404,"node_not_found",`unknown node: ${e.nodeId}`);J(t,n)}a(y,"requireScope");function f(e,n){const t=e.scope;if(!n)return{...t===void 0?{}:{scope:t}};const r=t??(L(e.target.cwd,e.target.profileId).length>0?"project":"user");if(r==="builtin")throw new m(400,"invalid_request","builtin memory is read-only");if(r==="node")return{scope:r,store:$("node",x(e.target.nodeId)),memoryDir:x(e.target.nodeId)};if(r==="profile")return{scope:r,store:$("profile",F(e.target.profileId)),memoryDir:F(e.target.profileId)};if(r==="project"){const o=L(e.target.cwd,e.target.profileId)[0];if(o===void 0)throw new m(400,"invalid_request","store project requires a project memory store in cwd or profile");const s=V(o.slice(0,-8).replace(/\/$/,""));return{scope:r,store:s,memoryDir:s.storeRoot}}const i=Q("user");if(i===null)throw new Error("user memory directory unavailable");return{scope:"user",store:$("user",i),memoryDir:i}}a(f,"selection");function Z(e,n){return e.length>1?e.map(t=>ee(t,n)):void 0}a(Z,"candidates");function B(e){return{name:e.name,short_form:e.shortForm,kind:e.kind,scope:e.scope,extensions:e.extensions,path:e.path,store_root:e.storeRoot,physical_relative_path:e.physicalRelativePath,...Z(e.candidates,e.candidates[0])===void 0?{}:{candidates:Z(e.candidates,e.candidates[0])}}}a(B,"summary");function H(e){try{const n=ie(e);if(n.kind==="document")return n}catch(n){if(!(n instanceof X)||n.code!=="not_found")throw n}throw new m(404,"memory_document_not_found",`memory document not found: ${e.name}`)}a(H,"requestedDocument");function A(e,n,t=f(n,!1),r=!1){const i=H({target:n.target,...t,name:e,frontmatter:r,interpolateNodePaths:!1}),o=i.doc;return{...B({name:o.name,kind:String(o.frontmatter?.kind??""),scope:o.scope,path:o.path,storeRoot:o.root,physicalRelativePath:o.physicalRelativePath,shortForm:String(o.frontmatter?.["short-form"]??""),slash:o.frontmatter?.slash===!0,extensions:o.frontmatter?.extensions??{},candidates:i.candidates}),body:i.content,frontmatter:o.frontmatter,representation:o.representation,links:[...i.links]}}a(A,"document");function T(e,n,t){if(e===void 0)return t;const r=typeof e=="number"?e:Number(e);if(!Number.isInteger(r)||r<1||r>G)throw new m(400,"invalid_request",`${n} must be an integer from 1 through ${G}`);return r}a(T,"number");function U(e,n){const t=typeof e=="number"?e:Number(e);if(!Number.isFinite(t)||t<1)throw new m(400,"invalid_request",`${n} must be a finite number of at least 1`);return t}a(U,"positiveNumber");function D(e,n){const t=e[n];if(t!==void 0){if(t===!0||t==="true")return!0;if(t===!1||t==="false")return!1;throw new m(400,"invalid_request",`${n} must be a boolean`)}}a(D,"optionalBoolean");function W(e,n,t=[]){if(e!==void 0&&!R(e))throw new m(400,"invalid_request","frontmatter must be an object");const r=e===void 0?{}:e;for(const s of t)if(s in r)throw new m(400,"invalid_request",`frontmatter.${s} cannot be set directly`);const i={},o={"short-form":"shortForm","when-and-why-to-read":"whenAndWhyToRead","lint-ignore":"lintIgnore",rationale:"docRationale",kind:"kind",unlisted:"unlisted",surfaces:"surface",gate:"gate",slash:"slash"};for(const[s,d]of Object.entries(r)){const l=o[s];if(l===void 0)throw new m(400,"invalid_request",`frontmatter.${s} is not writable through this route`);if(s==="unlisted"||s==="slash"){if(d!==!0)throw new m(400,"invalid_request",`frontmatter.${s} must be true; remove it with unset`)}else if(s==="surfaces"){if(!Array.isArray(d)||!d.every(u=>typeof u=="string"))throw new m(400,"invalid_request","frontmatter.surfaces must be a string array")}else if(s==="lint-ignore"){if(!Array.isArray(d)||!d.every(u=>typeof u=="string"))throw new m(400,"invalid_request","frontmatter.lint-ignore must be a string array")}else if(typeof d!="string"||d.trim()==="")throw new m(400,"invalid_request",`frontmatter.${s} must be a non-empty string`);i[l]=d}if(n!==void 0){if(!R(n))throw new m(400,"invalid_request","extensions must be an object");const s=[];for(const[d,l]of Object.entries(n)){if(!R(l))throw new m(400,"invalid_request",`extensions.${d} must be an object`);for(const[u,c]of Object.entries(l))s.push(`extensions.${d}.${u}=${String(c)}`)}i.extension=s}return i}a(W,"frontmatterFields");function me(e){const n=k(e),t=[],r=h(n,"kind",t),i=h(n,"after",t);t.length>0&&b("memory list query",t);const o=p(n,["node","cwd","profile","store","kind","limit","after"]);y(o,_);const s=oe({target:o.target,...f(o,!1),...r===void 0?{}:{kind:r}}).sort((c,g)=>c.name.localeCompare(g.name)),d=i===void 0?s:s.filter(c=>c.name.localeCompare(i)>0),l=d.slice(0,T(n.limit,"limit",E)).map(B);return{status:200,body:{object:"list",data:l,has_more:d.length>l.length}}}a(me,"handleList");function le(e){const n=k(e),t=p(n,["node","cwd","profile","store","frontmatter"]);return y(t,_),{status:200,body:A(q(e),t,f(t,!1),D(n,"frontmatter")===!0)}}a(le,"handleRetrieve");function ce(e){const n=[],t=j(e.body,["name","kind","when_and_why_to_read","body","frontmatter","extensions","node","cwd","profile","store"],n),r=w(t,"name",n),i=w(t,"kind",n),o=w(t,"when_and_why_to_read",n),s=w(t,"body",n);if(n.length>0&&b("memory create request",n),!S(r))throw new m(400,"invalid_memory_doc_name","memory document name must be slash-joined [A-Za-z0-9_-] segments");const d=p(t,["name","kind","when_and_why_to_read","body","frontmatter","extensions","node","cwd","profile","store"]);y(d,I);const l=f(d,!0),u={name:r,kind:i,whenAndWhyToRead:o,body:s,...W(t.frontmatter,t.extensions,["kind","when-and-why-to-read","origin","last-updated"])},c=te({target:d.target,scope:l.scope,memoryDir:l.memoryDir,store:l.store,isExplicitProjectStore:!1,origin:{created:new Date().toISOString(),cwd:d.target.cwd,...d.target.nodeId===null?{}:{node:d.target.nodeId}},fields:u}),g=A(c.name,d,l);return{status:200,body:c.findings===void 0?g:{...g,findings:c.findings}}}a(ce,"handleCreate");function ue(e){const n=[],t=j(e.body,["rationale","body","frontmatter","extensions","unset","node","cwd","profile","store"],n),r=w(t,"rationale",n);t.body!==void 0&&typeof t.body!="string"&&n.push({field:"body",problem:"must be a string",received:t.body}),t.unset!==void 0&&(!Array.isArray(t.unset)||!t.unset.every(d=>typeof d=="string"))&&n.push({field:"unset",problem:"must be a string array",received:t.unset}),n.length>0&&b("memory update request",n);const i=q(e),o=p(t,["rationale","body","frontmatter","extensions","unset","node","cwd","profile","store"]);y(o,I);const s=W(t.frontmatter,t.extensions,["kind","when-and-why-to-read","origin","last-updated"]);return ae({target:o.target,selection:{target:o.target,...f(o,!1)},fields:{name:i,rationale:r,...t.body===void 0?{}:{body:t.body},...t.unset===void 0?{}:{unset:t.unset},...s}}),{status:200,body:A(i,o)}}a(ue,"handleUpdate");function fe(e){const n=p(k(e),["node","cwd","profile","store"]);y(n,I);const t=q(e);return{status:200,body:{...ne({target:n.target,selection:{target:n.target,...f(n,!1)},fields:{name:t}}),deleted:!0}}}a(fe,"handleDelete");function pe(e){const n=[],t=j(e.body,["to","node","cwd","profile","store"],n),r=w(t,"to",n);if(n.length>0&&b("memory move request",n),!S(r))throw new m(400,"invalid_memory_doc_name","memory document name must be slash-joined [A-Za-z0-9_-] segments");const i=p(t,["to","node","cwd","profile","store"]);y(i,I);const o=q(e);return{status:200,body:re({target:i.target,selection:{target:i.target,...f(i,!1)},fields:{name:o,to:r}})}}a(pe,"handleMove");function O(e){return"line"in e?`${e.name}\0${e.scope}\0${e.physical_relative_path}\0${String(e.line).padStart(10,"0")}`:e.name}a(O,"grepCursor");function ye(e){const n=[],t=j(e.body,["query","kind","grep","body","limit","after","min_score","node","cwd","profile","store"],n),r=w(t,"query",n),i=h(t,"kind",n),o=h(t,"after",n);n.length>0&&b("memory search request",n);const s=p(t,["query","kind","grep","body","limit","after","min_score","node","cwd","profile","store"]);y(s,_);const d=D(t,"grep"),l=D(t,"body"),u=t.min_score===void 0?void 0:U(t.min_score,"min_score");if(d===!0&&l===!0)throw new m(400,"invalid_request","grep and body cannot both be true");if(d===!0&&u!==void 0)throw new m(400,"invalid_request","min_score is only available in ranked mode");const g=[...de({target:s.target,...f(s,!1),query:r,...i===void 0?{}:{kind:i},...d===void 0?{}:{grep:d},...l===void 0?{}:{body:l},...u===void 0?{}:{minScore:u}}).hits].sort((v,C)=>d===!0?O(v).localeCompare(O(C)):v.name.localeCompare(C.name)),P=o===void 0?g:g.filter(v=>(d===!0?O(v):v.name).localeCompare(o)>0),M=P.slice(0,T(t.limit,"limit",E));return{status:200,body:{object:"list",data:M,has_more:P.length>M.length}}}a(ye,"handleSearch");function he(e){const n=k(e),t=p(n,["node","cwd","profile","store","limit","revision","diff"]);y(t,_);const r=n.revision===void 0?void 0:U(n.revision,"revision"),i=D(n,"diff"),o=se({target:t.target,...f(t,!1),name:q(e),limit:T(n.limit,"limit",E),...r===void 0?{}:{revision:r},...i===void 0?{}:{diff:i}});return{status:200,body:{name:o.name,scope:o.scope,log_path:o.logPath,total:o.total,...o.deleted===void 0?{}:{deleted:o.deleted},..."record"in o?{record:o.record}:{revisions:[...o.revisions]}}}}a(he,"handleHistory");function ge(e){const n=k(e),t=e.query.get("name");if(t===null||!S(t))throw new m(400,"invalid_memory_doc_name","memory document name must be slash-joined [A-Za-z0-9_-] segments");const r=p(n,["name","node","cwd","profile","store"]);y(r,_);const i=H({target:r.target,...f(r,!1),name:t});return{status:200,body:{name:i.doc.name,scope:i.doc.scope,path:i.doc.path,store_root:i.doc.root,physical_relative_path:i.doc.physicalRelativePath,...i.doc.plugin===void 0?{}:{plugin:i.doc.plugin}}}}a(ge,"handleResolve");const $e=[{method:"GET",pattern:"/v1/memory/docs",scope:"memory:read",handler:me},{method:"GET",pattern:"/v1/memory/docs/:name",scope:"memory:read",handler:le},{method:"POST",pattern:"/v1/memory/docs",scope:"memory:write",handler:ce},{method:"PATCH",pattern:"/v1/memory/docs/:name",scope:"memory:write",handler:ue},{method:"DELETE",pattern:"/v1/memory/docs/:name",scope:"memory:write",handler:fe},{method:"POST",pattern:"/v1/memory/docs/:name/move",scope:"memory:write",handler:pe},{method:"POST",pattern:"/v1/memory/search",scope:"memory:read",handler:ye},{method:"GET",pattern:"/v1/memory/docs/:name/history",scope:"memory:read",handler:he},{method:"GET",pattern:"/v1/memory/resolve",scope:"memory:read",handler:ge}];export{$e as memoryRoutes};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var E=Object.defineProperty;var c=(r,e)=>E(r,"name",{value:e,configurable:!0});import{join as J}from"node:path";import{claimNodeMail as W,acknowledgeNodeMail as D}from"../../../core/canvas/deliveries.js";import{nodeMailEntry as L}from"../../../core/feed/inbox.js";import{enqueueNodeMail as q,cancelPendingNodeMail as G}from"../../../core/feed/messages.js";import{reviveNode as
|
|
2
|
-
`)[0].slice(0,120)}c(
|
|
1
|
+
var E=Object.defineProperty;var c=(r,e)=>E(r,"name",{value:e,configurable:!0});import{join as J}from"node:path";import{claimNodeMail as W,acknowledgeNodeMail as D}from"../../../core/canvas/deliveries.js";import{nodeMailEntry as L}from"../../../core/feed/inbox.js";import{enqueueNodeMail as q,cancelPendingNodeMail as G}from"../../../core/feed/messages.js";import{reviveNode as O}from"../../../core/runtime/revive.js";import{BrokerUnreachableError as F}from"../../../core/runtime/broker-request.js";import{isBrokerLive as C}from"../../../core/runtime/model-swap.js";import{deliverLive as U,interruptLive as H}from"../../../core/runtime/interactive-deliver.js";import{isProfilePaused as K}from"../../../core/profiles/manifest.js";import{getNode as x,withFreshTerminalGuard as Q}from"../../../core/canvas/canvas.js";import{reportsDir as V}from"../../../core/canvas/paths.js";import{withCanvasWrite as X}from"../../../core/canvas/db.js";import{cancelCronsOnWake as I}from"../../../core/canvas/crons.js";import{assertNotFinalized as N,assertFinalizedForReopen as Y,commitReopenResident as A}from"../../../core/runtime/reopen.js";import{writeOutputSchema as Z}from"../../../core/runtime/structured-output.js";import{appendSituationalContext as j,formatSituationalProse as ee}from"../../../core/runtime/situational-context.js";import{formatDataCard as P}from"../../../shared/generated-context.js";import{hasNoNaturalCycle as te}from"../../../core/runtime/revive-all.js";import{recordPendingParkActivity as re}from"../../park-pending.js";import{wantsExecution as ne}from"../../reconcilers/node-lifecycle/wants-execution.js";import{hasFreshGroundState as oe}from"../../../core/runtime/revive.js";import{notFound as S,usage as a}from"../../../core/errors.js";import{assertScope as ie}from"../../../core/scopes.js";import{InputError as ae}from"../../../core/io.js";import{ApiError as se}from"../../../api/index.js";import{ownerOnly as de}from"../router.js";const ce=["critical","urgent","normal","deferred"];function M(r,e){if(typeof r!="object"||r===null||Array.isArray(r))throw a(`${e} must be an object { kind, facts?, body? }`);const i=r,t=i.kind;if(typeof t!="string"||t.trim()==="")throw a(`${e}.kind is required`);if(!t.includes(":"))throw a(`${e}.kind must be namespaced (contain ':'): ${t}`);const s={kind:t},n=i.facts;if(n!==void 0){if(typeof n!="object"||n===null||Array.isArray(n))throw a(`${e}.facts must be an object of string or number values`);const y={};for(const[m,f]of Object.entries(n)){if(typeof f!="string"&&typeof f!="number")throw a(`${e}.facts.${m} must be a string or number`);y[m]=f}s.facts=y}const o=i.body;if(o!==void 0){if(typeof o!="string")throw a(`${e}.body must be a string`);s.body=o}return s}c(M,"parseCardRequest");function T(r,e){try{return P(r.kind,r.facts??{},r.body??"")}catch(i){throw a(`${e}: ${i instanceof Error?i.message:String(i)}`)}}c(T,"renderCard");function ue(r){if(typeof r!="object"||r===null)throw a("a message requires a JSON body { body, tier?, fresh? }");const e=r,i=e.body,t=e.fresh===!0,s=e.tier,n=e.situational_context,o=e.output_schema,y=typeof i=="string"&&i.trim()!=="",m=typeof n=="string"&&n.trim()!=="",f=typeof o=="string"&&o.trim()!=="",g=e.situational_card,h=e.context_cards,b=g===void 0?void 0:M(g,"situational_card");if(h!==void 0&&!Array.isArray(h))throw a("context_cards must be an array of { kind, facts?, body? }");const l=h?.map((v,k)=>M(v,`context_cards[${k}]`));if(b!==void 0&&typeof n=="string"&&n!=="")throw a("situational_card and situational_context are mutually exclusive");const _=b!==void 0||l!==void 0&&l.length>0;if(!t&&!y&&!m&&!f&&!_)throw a("a message requires a non-empty body (or fresh: true, situational_context, a runtime card, or output_schema)");if(t&&l!==void 0&&l.length>0)throw a("context_cards cannot ride a fresh revive (no inbox entry carries them)");if(s!==void 0&&!ce.includes(s))throw a(`invalid tier: ${String(s)} (expected critical|urgent|normal|deferred)`);const u={body:typeof i=="string"?i:""};s!==void 0&&(u.tier=s),t&&(u.fresh=!0),e.reopen===!0&&(u.reopen=!0),typeof n=="string"&&(u.situational_context=n),b!==void 0&&(u.situational_card=b),l!==void 0&&(u.context_cards=l),typeof o=="string"&&(u.output_schema=o),typeof e.from=="string"&&(u.from=e.from);const p=e.delivery;if(p!==void 0&&p!=="interactive")throw a(`invalid delivery: ${String(p)} (expected interactive)`);if(p==="interactive"){if(t||u.situational_context!==void 0||u.output_schema!==void 0)throw a("interactive delivery supports a body, runtime cards, and reopen only (no fresh, situational_context, or output_schema)");if(!y)throw a("interactive delivery requires a non-empty body");if(u.tier==="deferred")throw a("interactive delivery cannot be deferred");u.delivery="interactive"}return u}c(ue,"parseSendBody");function fe(r){try{return JSON.parse(r)}catch{throw a("output_schema must be a JSON schema string")}}c(fe,"parseSchema");function le(r){return r.split(`
|
|
2
|
+
`)[0].slice(0,120)}c(le,"label");function z(r,e){if(e===null)return"";const i=J(V(r),e);return P("reopen-final-report",{path:i},"This node previously completed work. Read this final report before acting on the new instruction.")}c(z,"previousFinalReportCard");function me(r,e){return new ae({error:"deferred_no_natural_cycle",message:`${r} is ${e} with no natural next cycle ahead of it \u2014 a deferred message would never be delivered.`,next:"Use --tier normal, urgent, or critical to wake it now, or --reopen (with a body or --fresh) to re-task it first."})}c(me,"deferredNoNaturalCycle");function pe(r){if(!oe(r))throw new se(422,"unprocessable",`node ${r} has no goal/roadmap on disk \u2014 a fresh revive would resume amnesiac.`)}c(pe,"assertRecoverableForFresh");async function ye(r){const e=r.params.id,i=x(e);if(i===null)throw S(`unknown node: ${e}`,{received:e});const t=ue(r.body),s=t.tier??"normal",n=K(i.profile_id),o=t.from??null;if(o!==null){const d=x(o);d!==null&&ie(d,"act")}const y=t.body.trim()!=="",m=t.situational_card!==void 0?T(t.situational_card,"situational_card"):t.situational_context!==void 0?ee(t.situational_context.trim()):"",f=m!=="",g=(t.context_cards??[]).map((d,w)=>T(d,`context_cards[${w}]`)),h=t.output_schema!==void 0&&t.output_schema.trim()!==""?fe(t.output_schema):null;if(t.fresh){const d=t.reopen?Y(e):null;t.reopen||N(e),pe(e),f&&j(e,m),t.reopen&&A(e,d);const w=await O(e,{resume:!1,capacity:"refuse"});return{status:201,body:{node_id:e,delivered:!1,revived:w.launch!==void 0}}}t.delivery==="interactive"&&!t.reopen&&N(e);let b=!1,l="";if(t.delivery==="interactive"&&t.reopen&&(l=z(e,A(e)),b=!0),t.delivery==="interactive"&&!n&&C(i))try{return f&&j(e,m),await U(e,t.body,{cards:[...l===""?[]:[l],...f?[m]:[],...g],origin:o==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:[{...o===null?{}:{from:o},kind:"message",tier:s}]}}),I(e),{status:201,body:{node_id:e,delivered:!0,revived:!1,delivered_via:"engine"}}}catch(d){if(!(d instanceof F))throw d}const _=c(()=>{t.reopen||N(e),h!==null&&Z(e,"oneoff",h),f&&j(e,m),t.reopen&&!b&&(l=z(e,A(e)));const d=[...l===""?[]:[l],...g],w=d.length>0?{cards:d}:{};if(y||h!==null){const $=y?t.body:"A one-off structured-output request has been granted. Submit a result matching the requested schema with `crtr push result` before you stop; after it is accepted, continue normally.";return q(e,{senderNodeId:o,urgency:s,wake:1,kind:"message",label:le($),bodyJson:{body:$,...f?{situational:!0}:{},...w}})}return q(e,{senderNodeId:o,urgency:s,wake:1,kind:"message",label:f?"(ambient context updated)":"(context delivered)",bodyJson:{...f?{situational:!0}:{},situationalOnly:!0,...w}})},"deliverImmediate"),p=c(()=>{if(s==="deferred"){const d=Q(e,te,_);if(d.kind==="missing")throw S(`unknown node: ${e}`,{received:e});if(d.kind==="terminal")throw me(e,d.status);return d.result}return _()},"deliver")();p.urgency!=="deferred"&&X(()=>re(e));const v=x(e);if(v===null)throw S(`unknown node: ${e}`,{received:e});i.frozen_at!==null&&I(e);let k=!1,R=!1;if((t.reopen||v.lifecycle==="terminal"||!ne(v))&&p.urgency!=="deferred"&&!n&&!C(v))try{const d=await O(e,{resume:!0,capacity:"freeze"});k=d.launch!==void 0,R=d.outcome==="frozen"}catch{}return{status:201,body:{node_id:e,delivered:!0,revived:k,...R?{not_revived_reason:"capacity_frozen"}:{},delivered_at:p.createdAt,...p.urgency===s?{}:{delivered_tier:p.urgency},...t.delivery==="interactive"?{delivered_via:"inbox"}:{}}}}c(ye,"handleMessage");async function he(r){const e=r.params.id,i=x(e);if(i===null)throw S(`unknown node: ${e}`,{received:e});const t=G(e,{senderNodeId:"human",kind:"message"});let s=!1;if(C(i))try{s=await H(e)!=="idle"}catch(o){if(!(o instanceof F))throw o}return{status:200,body:{node_id:e,outcome:s?"aborted_turn":t.length>0?"canceled_pending":"idle",aborted_turn:s,canceled_pending:t.length}}}c(he,"handleInterrupt");function B(r){if(typeof r.body!="object"||r.body===null||Array.isArray(r.body))throw a("mail requires an object body");const e=r.body;if(typeof e.execution_id!="string"||e.execution_id.trim()==="")throw a("execution_id is required");return e}c(B,"mailBody");function be(r){const e=B(r),i=e.channel;if(i!=="wake"&&i!=="passive")throw a("channel must be wake or passive");const t=W(r.params.id,e.execution_id,i);return{status:200,body:{action:t.action,deliveries:t.deliveries.map(n=>({delivery_id:n.deliveryId,attempts:n.attempts,handoff:n.handoff,entry:L(n)}))}}}c(be,"handleMailClaim");function ve(r){const e=B(r);if(!Array.isArray(e.deliveries))throw a("deliveries must be an array");const i=e.deliveries.map(n=>{if(typeof n!="object"||n===null||Array.isArray(n))throw a("each delivery must be an object");const o=n;if(typeof o.delivery_id!="string"||o.delivery_id==="")throw a("delivery_id is required");if(!Number.isSafeInteger(o.attempts)||o.attempts<1)throw a("attempts must be a positive integer");if(o.disposition!=="acknowledged"&&o.disposition!=="released")throw a("disposition must be acknowledged or released");return{delivery_id:o.delivery_id,attempts:o.attempts,disposition:o.disposition}}),t=D(r.params.id,e.execution_id,i.map(n=>({deliveryId:n.delivery_id,attempts:n.attempts,disposition:n.disposition})));return{status:200,body:{action:t.action,results:t.results.map(n=>({delivery_id:n.deliveryId,outcome:n.outcome}))}}}c(ve,"handleMailAcknowledge");const Ke=de([{method:"POST",pattern:"/v1/nodes/:id/mail/claim",handler:be},{method:"POST",pattern:"/v1/nodes/:id/mail/acknowledge",handler:ve}]),Qe=[{method:"POST",pattern:"/v1/nodes/:id/messages",scope:"act",handler:ye},{method:"POST",pattern:"/v1/nodes/:id/interrupt",scope:"act",handler:he}];export{Ke as brokerMailRoutes,Qe as messageRoutes};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type RouteTable } from '../router.js';
|
|
2
2
|
export declare const modelConfigRoutes: RouteTable;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var f=Object.defineProperty;var i=(e,o)=>f(e,"name",{value:o,configurable:!0});import{ApiError as t}from"../../../api/errors.js";import{validateCoreModelConfig as a,replaceCoreModelConfig as c}from"../../../core/model-config.js";import{parseModelSpec as d}from"../../../core/model-routes.js";import{openModelRegistry as l}from"../../../core/runtime/model-registry.js";function g(e){if(e===null||typeof e!="object"||Array.isArray(e))throw new t(400,"invalid_request","model config must be an object");const o=e;if(typeof o.config_version!="string"||o.config_version.trim()==="")throw new t(400,"invalid_request","config_version must be a non-empty string");try{return{configVersion:o.config_version,config:a(o)}}catch(r){throw new t(400,"invalid_request",r instanceof Error?r.message:String(r))}}i(g,"parseRequest");async function
|
|
1
|
+
var f=Object.defineProperty;var i=(e,o)=>f(e,"name",{value:o,configurable:!0});import{ApiError as t}from"../../../api/errors.js";import{validateCoreModelConfig as a,replaceCoreModelConfig as c}from"../../../core/model-config.js";import{parseModelSpec as d}from"../../../core/model-routes.js";import{openModelRegistry as l}from"../../../core/runtime/model-registry.js";import{ownerOnly as m}from"../router.js";function g(e){if(e===null||typeof e!="object"||Array.isArray(e))throw new t(400,"invalid_request","model config must be an object");const o=e;if(typeof o.config_version!="string"||o.config_version.trim()==="")throw new t(400,"invalid_request","config_version must be a non-empty string");try{return{configVersion:o.config_version,config:a(o)}}catch(r){throw new t(400,"invalid_request",r instanceof Error?r.message:String(r))}}i(g,"parseRequest");async function u(e){const o=await l();for(const r of Object.values(e.modelRoutes))for(const n of Object.values(r.models)){const s=d(n);if(s===void 0||o.find(s.providerId,s.modelId)===void 0)throw new t(422,"unprocessable",`route ref ${n} is absent from the baked model registry`)}}i(u,"validateCatalog");async function p(e){const{configVersion:o,config:r}=g(e.body);await u(r);try{c(r)}catch(n){throw new t(500,"model_config_write_failed",n instanceof Error?n.message:String(n))}return{status:200,body:{config_version:o,delivered:!0}}}i(p,"handlePut");const C=m([{method:"PUT",pattern:"/v1/model-config",handler:p}]);export{C as modelConfigRoutes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var L=Object.defineProperty;var o=(n,t)=>L(n,"name",{value:t,configurable:!0});import{homedir as P}from"node:os";import{join as k}from"node:path";import{deleteAuthCredential as A,readAuthCredentials as I,setAuthCredential as q}from"../../../core/auth-file.js";import{ApiError as u}from"../../../api/index.js";import{usage as y}from"../../../core/errors.js";import{resolveLaunchTarget as R}from"../../../core/runtime/launch-target.js";import{ANTHROPIC_PROVIDER_ID as D,OPENAI_CODEX_PROVIDER_ID as O,commitManagedLogin as $,readSubscriptionPool as
|
|
1
|
+
var L=Object.defineProperty;var o=(n,t)=>L(n,"name",{value:t,configurable:!0});import{homedir as P}from"node:os";import{join as k}from"node:path";import{deleteAuthCredential as A,readAuthCredentials as I,setAuthCredential as q}from"../../../core/auth-file.js";import{ApiError as u}from"../../../api/index.js";import{usage as y}from"../../../core/errors.js";import{resolveLaunchTarget as R}from"../../../core/runtime/launch-target.js";import{ANTHROPIC_PROVIDER_ID as D,OPENAI_CODEX_PROVIDER_ID as O,commitManagedLogin as $,readSubscriptionPool as g,removeAllManagedAccounts as M}from"../../../core/subscription-state.js";function l(){const n=process.env.PI_CODING_AGENT_DIR,t=n!==void 0&&n!==""?n:k(P(),".pi","agent");return k(t,"auth.json")}o(l,"authPath");function f(n){return n===D||n===O}o(f,"isManagedProvider");function E(n,t){if(typeof t!="string"||t==="")throw new u(400,"invalid_request",`oauth credential requires \`${n}\``);const e=Date.parse(t);if(Number.isNaN(e))throw new u(400,"invalid_request",`\`${n}\` is not a valid ISO timestamp`);return e}o(E,"parseExpiry");function h(n,t,e){if(typeof e!="string"||e==="")throw new u(400,"invalid_request",`${n} credential requires \`${t}\``);return e}o(h,"requireField");function N(n){return{label:n.label,expires_at:new Date(n.expires).toISOString(),rate_limited_until:new Date(n.rateLimitedUntil).toISOString(),...n.authFailure?{auth_failure:n.authFailure}:{},...n.accountId?{account_id:n.accountId}:{}}}o(N,"toManagedAccountStatus");function S(n){const t=g(n).map(N);return{provider:n,managed:!0,configured:t.length>0,accounts:t}}o(S,"managedStatus");function w(n,t){const e=n.query.getAll(t);if(e.length>1)throw y(`${t} must appear at most once`);return e[0]}o(w,"singleQueryValue");function T(n){const t=n.indexOf("/"),e=t>0?n.slice(0,t):"";if(e==="")throw new u(422,"unresolved_model","the selected launch has no concrete model provider");return e}o(T,"providerFromModel");async function C(){const n=await I(l()),t=[S(D),S(O)];for(const[e,a]of Object.entries(n))f(e)||a.type!=="api_key"&&a.type!=="oauth"||t.push({provider:e,managed:!1,configured:!0,kind:a.type});return{status:200,body:{providers:t}}}o(C,"handleList");async function F(n){for(const[s]of n.query)if(s!=="profile"&&s!=="cwd"&&s!=="kind"&&s!=="model")throw y(`unknown model-auth readiness query parameter: ${s}`);const t=w(n,"profile"),e=w(n,"cwd"),a=w(n,"kind"),r=w(n,"model");if(a!==void 0&&a.trim()==="")throw y("kind must be a non-empty string when provided");if(r!==void 0&&r.trim()==="")throw y("model must be a non-empty string when provided");const d=await R({root:!0,...t!==void 0?{profile:t}:{},...e!==void 0?{cwd:e}:{},...a!==void 0?{kind:a}:{},...r!==void 0?{model:r}:{}},{readOnlyProfileSelection:!0});if(d.launch.model===void 0)throw new u(422,"unresolved_model","the selected launch has no concrete model");const i=T(d.launch.model),c=await I(l());if(f(i)){const s=g(i),m=s.filter(p=>p.authFailure===void 0);if(m.length===0)return{status:200,body:s.length===0?{provider:i,model:d.launch.model,credential:"missing"}:{provider:i,model:d.launch.model,credential:"unusable",reason:"invalid_grant"}};const v=Date.now(),x=m.some(p=>p.rateLimitedUntil<=v),b=Math.min(...m.map(p=>p.rateLimitedUntil));return{status:200,body:{provider:i,model:d.launch.model,credential:"ready",...!x&&b>v?{rate_limited_until:new Date(b).toISOString()}:{}}}}const _=c[i];return{status:200,body:{provider:i,model:d.launch.model,credential:_?.type==="api_key"||_?.type==="oauth"?"ready":"missing"}}}o(F,"handleReadiness");async function j(n){const t=n.params.provider,e=n.body;if(e===void 0||typeof e!="object"||typeof e.kind!="string")throw new u(400,"invalid_request","a credential `kind` is required");switch(e.kind){case"api_key":{const a=h("api_key","api_key",e.api_key);return await q(t,{type:"api_key",key:a},l()),{status:200,body:{provider:t,installed:!0,managed:!1}}}case"oauth":{if(f(t))throw new u(422,"unprocessable",`provider ${t} stores oauth credentials as managed accounts \u2014 use kind \`managed_account\``);const a=h("oauth","access_token",e.access_token),r=h("oauth","refresh_token",e.refresh_token),d=E("expires_at",e.expires_at),i=e.extra??{};await q(t,{type:"oauth",...i,access:a,refresh:r,expires:d},l());const c={provider:t,installed:!0,managed:!1};return typeof e.account_id=="string"&&e.account_id!==""&&(c.account_id=e.account_id),{status:200,body:c}}case"managed_account":{if(!f(t))throw new u(422,"unprocessable",`provider ${t} does not support managed accounts`);const a=typeof e.label=="string"&&e.label.trim()?e.label.trim():void 0;if(!a&&e.auto_label!==!0)throw new u(400,"invalid_request","managed_account credential requires `label` or `auto_label`");const r=typeof e.account_id=="string"&&e.account_id!==""?e.account_id:void 0,d=h("managed_account","access_token",e.access_token),i=h("managed_account","refresh_token",e.refresh_token),c=E("expires_at",e.expires_at),_=typeof e.last_rate_limited_at=="number"?e.last_rate_limited_at:Math.max(0,...g(t).map(m=>m.lastRateLimitedAt));await $(t,a,{refresh:i,access:d,expires:c,...r?{accountId:r}:{},lastRateLimitedAt:_,autoLabel:e.auto_label===!0});const s={provider:t,installed:!0,managed:!0};return r&&(s.account_id=r),{status:200,body:s}}default:throw new u(400,"invalid_request",`unknown credential kind: ${String(e.kind)}`)}}o(j,"handleInstall");async function G(n){const t=n.params.provider;if(f(t)){const a=await M(t),r=await A(t,l());return{status:200,body:{provider:t,removed_accounts:a+(r?1:0)}}}const e=await A(t,l())?1:0;return{status:200,body:{provider:t,removed_accounts:e}}}o(G,"handleDelete");const J=[{method:"GET",pattern:"/v1/model-auth",handler:C},{method:"GET",pattern:"/v1/model-auth/readiness",handler:F},{method:"PUT",pattern:"/v1/model-auth/:provider",ownerOnly:!0,handler:j},{method:"DELETE",pattern:"/v1/model-auth/:provider",ownerOnly:!0,handler:G}];export{J as modelAuthRoutes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var U=Object.defineProperty;var s=(e,t)=>U(e,"name",{value:t,configurable:!0});import{envProfileId as X}from"../../../shared/env.js";import{existsSync as C,readdirSync as Z,statSync as q}from"node:fs";import{basename as ee,isAbsolute as ne,resolve as I}from"node:path";import{appendSituationalContext as te,formatSituationalProse as oe}from"../../../core/runtime/situational-context.js";import{closeNode as ie}from"../../../core/runtime/close.js";import{reviveNode as re}from"../../../core/runtime/revive.js";import{nowIso as T}from"../../../core/fs-utils.js";import{assertLaunchModelRegistered as A,forkNode as de,spawnChildPrepared as se}from"../../../core/runtime/spawn.js";import{childrenOf as ae,getNode as b,listNodes as M,subscribersOf as le,subscriptionsOf as E,setMessageWait as ce,updateNode as $}from"../../../core/canvas/canvas.js";import{subtreeIds as ue}from"../../../core/canvas/nav-model.js";import{withCanvasWrite as fe}from"../../../core/canvas/db.js";import{unbindSession as me}from"../../../core/canvas/sessions.js";import{ticketCountsForNodes as pe}from"../../../core/canvas/attention.js";import{contextDir as P,reportsDir as he}from"../../../core/canvas/paths.js";import{nodeArtifacts as we}from"../../../core/canvas/history.js";import{readNodeMessagesPage as ye,readNodeSession as _e,readNodeSnapshot as ge,transcriptMarkdown as be}from"../../../core/runtime/node-read.js";import{assembleNodeSubject as ve}from"../../../core/substrate/subject.js";import{reviveAll as ke}from"../../../core/runtime/revive-all.js";import{promoteAsync as Se,requestYieldAsync as Oe,reshapeNodeAsync as L}from"../../../core/runtime/promote.js";import{recycleNode as Ne}from"../../../core/runtime/recycle.js";import{relaunchRoot as Te}from"../../../core/runtime/reset.js";import{assertReopenGate as Ae}from"../../../core/runtime/reopen.js";import{writeYieldMessage as $e,readGoal as Pe}from"../../../core/runtime/kickoff.js";import{hasRoadmap as Re,seedRoadmap as xe}from"../../../core/runtime/roadmap.js";import{renameWindow as De}from"../../../core/runtime/placement.js";import{buildLaunchSpecAsync as Ce,isProviderPinnedModelToken as Ie,normalizeModel as Me,readMergedLaunchConfigAsync as j}from"../../../core/runtime/launch.js";import{modelRequestFromConfig as Ee}from"../../../core/model-routes.js";import{BrokerUnreachableError as Le}from"../../../core/runtime/broker-request.js";import{isBrokerLive as je,persistDormantModel as Fe,setModelLive as Ge}from"../../../core/runtime/model-swap.js";import{boundFleet as ze}from"../../../core/runtime/fleet.js";import{writeOutputSchema as F}from"../../../core/runtime/structured-output.js";import{OUTCOME_PAYLOAD_MAX_BYTES as G}from"../../../core/canvas/types.js";import{HUMAN_ACTION_NAME_PATTERN as We}from"../../../core/human/action-binding.js";import{resolveHumanAction as Be}from"../../../core/human-actions.js";import{parseDurationMs as Je}from"../../../core/wake.js";import{claimWarmNode as Ve,refillWarmPool as z,warmPoolEnabled as Ke}from"../../../core/runtime/warm-pool.js";import{resolveLaunchTarget as Ye}from"../../../core/runtime/launch-target.js";import{fullName as He}from"../../../core/canvas/labels.js";import{reportsForNode as Qe}from"./reports.js";import{getCron as Ue}from"../../../core/canvas/crons.js";import{cronWakeOrigin as Xe}from"../../../core/runtime/bearings.js";import{boundDaemonControl as Ze}from"../../control.js";import{notFound as R,usage as u}from"../../../core/errors.js";import{assertScope as qe,validateScopes as W}from"../../../core/scopes.js";import{scopeAllowed as en}from"../../../shared/env.js";import{toCloseResultDTO as nn,toNodeDetailDTO as x,toNodeSummaryDTO as tn,toReviveResultDTO as on}from"../map.js";import{ApiError as w}from"../../../api/index.js";import{InputError as m}from"../../../core/io.js";function f(e){const t=b(e);if(t===null)throw R(`unknown node: ${e}`,{received:e});return t}s(f,"requireMeta");function D(e){return{subscribesTo:E(e),subscribers:le(e),children:ae(e)}}s(D,"edgesFor");function y(e){const t=f(e);return x(t,D(e))}s(y,"detailOf");function B(e){let t=0;for(const n of[P(e),he(e)])try{t+=Z(n).length}catch{}return t}s(B,"countFiles");function rn(e){if(typeof e!="object"||e===null)throw u("a node create requires a JSON body");const t=e;if(t.kind!==void 0&&(typeof t.kind!="string"||t.kind.trim()===""))throw u("kind must be a non-empty string when provided");if(t.description!==void 0&&(typeof t.description!="string"||t.description.trim()===""))throw u("description must be a non-empty string when provided");if(t.creator!==void 0&&(typeof t.creator!="string"||t.creator.trim()===""))throw u("creator must be a non-empty node id when provided");t.scopes!==void 0&&W(t.scopes);const n=t.root_lifecycle;if(n!==void 0&&n!=="resident"&&n!=="terminal")throw u("root_lifecycle must be 'resident' or 'terminal'");return t}s(rn,"parseCreateBody");function dn(e){if(e===void 0)return;const t=Je(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 w(422,"invalid_deadline","`deadline` must be a positive representable duration");return n.toISOString()}s(dn,"parseDeadline");function sn(e){if(e!==void 0){if(typeof e!="object"||e===null||Array.isArray(e))throw new w(400,"invalid_request","`outcome_delivery` must be an object");if(typeof e.action!="string"||!We.test(e.action))throw new w(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 w(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable")}if(t===void 0)throw new w(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable");if(Buffer.byteLength(t,"utf8")>G)throw new w(413,"payload_too_large",`serialized payload exceeds ${G} bytes`)}return e}}s(sn,"parseOutcomeDelivery");function an(e,t){const n=Be(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 w(422,"unknown_action",`no action named ${e.action} is declared from ${t}`):new w(422,"invalid_action",`${e.action} is declared in ${n.configOrigin} but unusable: ${n.reason}`,{reason:n.reason,configOrigin:n.configOrigin})}s(an,"resolveOutcomeDelivery");function ln(e,t,n){const o={kind:e.kind,cwd:n,prompt:e.prompt??""};return e.mode!==void 0&&(o.mode=e.mode),e.name!==void 0&&(o.name=e.name),e.description!==void 0&&(o.description=e.description),t!==void 0&&(o.parent=t),e.creator!==void 0&&(o.creator=e.creator),e.scopes!==void 0&&(o.scopes=e.scopes),e.root===!0&&(o.root=!0),e.root_lifecycle!==void 0&&(o.rootLifecycle=e.root_lifecycle),(e.worktree===!0||typeof e.worktree=="string")&&(o.worktree=!0),typeof e.worktree=="string"&&(o.worktreeBase=e.worktree),e.worktree!==void 0&&(o.worktreeCwd=I(e.pin_cwd??e.cwd??n)),e.fork_from!==void 0&&(o.forkFrom=e.fork_from),e.model!==void 0&&(o.model=e.model),e.profile!==void 0&&(o.profile=e.profile),e.situational_context!==void 0&&(o.situationalContext=e.situational_context),e.node_id!==void 0&&(o.nodeId=e.node_id),o}s(ln,"buildRecipe");function cn(e,t,n){return!Ke()||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?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}}s(cn,"warmRequestFor");import{resolveCreateKind as Dt}from"../../../core/runtime/launch-target.js";function J(e){const t=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return Ee(e.model,t,e.modelExact===!0)}s(J,"requestFromLaunch");async function V(e,t,n){const o=(await Ce(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 A(J(o),{cwd:e.cwd,profileId:e.profile_id??null},n)}s(V,"assertNodeModelChangeRegistered");async function un(e,t={}){const n=rn(e.body);n.creator!==void 0&&qe(f(n.creator),"act");const o=dn(n.deadline),r=sn(n.outcome_delivery),i=n.parent??void 0;if(i==null&&n.root!==!0)throw u("a node create requires a parent (or root: true for an independent root)");let d=null;if(n.output_schema!==void 0)try{d=JSON.parse(n.output_schema)}catch{throw u("output_schema must be a JSON schema string")}const{profileId:a,kind:c,cwd:l,launch:p}=await Ye(n,{validateKind:Y}),v={...n,kind:c},_=r===void 0?void 0:an(r,l);await A(J(p),{cwd:l,profileId:a},t.modelRegistry);let g=null;{const k=cn(v,l,a);if(k!==null){const O=await Ve(k,{...o===void 0?{}:{deadlineAt:o},..._===void 0?{}:{outcomeDelivery:_}},d===null?void 0:Q=>F(Q,"terminal",d));if(O!==null)return z(k),{status:201,body:y(O)};g=k}const S=ln(v,i,l);o!==void 0&&(S.deadlineAt=o),_!==void 0&&(S.outcomeDelivery=_),S.readiness=n.root===!0?"await":"launch";const H=await se(S,d===null?void 0:O=>F(O,"terminal",d),()=>{g!==null&&z(g)});return{status:201,body:y(H.node.node_id)}}}s(un,"handleCreate");function h(e,t){const n=e.query.getAll(t);if(n.length>1)throw u(`${t} must appear at most once`);return n[0]}s(h,"singleQueryValue");function K(e,t){if(e!==void 0){if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw u(`${t} must be true or false`)}}s(K,"optionalBoolean");function N(e,t,n){if(e!==void 0){if(n.includes(e))return e;throw u(`${t} must be one of: ${n.join(", ")}`)}}s(N,"oneOf");function fn(e){const t=new Set(["status","lifecycle","kind","mode","profile_id","profile_prefix","parent","top_level","under","hanging","include"]);for(const[g]of e.query)if(!t.has(g))throw u(`unknown nodes query parameter: ${g}`);const n=N(h(e,"status"),"status",["active","idle","done","dead","canceled"]),o=N(h(e,"lifecycle"),"lifecycle",["terminal","resident"]),r=h(e,"kind"),i=N(h(e,"mode"),"mode",["base","orchestrator"]),d=h(e,"profile_id"),a=h(e,"profile_prefix"),c=h(e,"parent"),l=K(h(e,"top_level"),"top_level"),p=h(e,"under"),v=K(h(e,"hanging"),"hanging"),_=N(h(e,"include"),"include",["activity"]);if(c!==void 0&&l===!0)throw u("parent and top_level=true cannot be combined");return{...n!==void 0?{status:n}:{},...o!==void 0?{lifecycle:o}:{},...r!==void 0?{kind:r}:{},...i!==void 0?{mode:i}:{},...d!==void 0?{profile_id:d}:{},...a!==void 0?{profile_prefix:a}:{},...c!==void 0?{parent:c}:{},...l!==void 0?{top_level:l}:{},...p!==void 0?{under:p}:{},...v!==void 0?{hanging:v}:{},..._!==void 0?{include:_}:{}}}s(fn,"parseListQuery");function mn(e){const t=fn(e);let n=t.status!==void 0?M({status:t.status}):M();if(t.lifecycle!==void 0&&(n=n.filter(i=>i.lifecycle===t.lifecycle)),t.kind!==void 0&&(n=n.filter(i=>i.kind===t.kind)),t.mode!==void 0&&(n=n.filter(i=>i.mode===t.mode)),t.profile_id!==void 0&&(n=n.filter(i=>i.profile_id===t.profile_id)),t.profile_prefix!==void 0&&(n=n.filter(i=>i.profile_id?.startsWith(t.profile_prefix))),t.parent!==void 0&&(n=n.filter(i=>i.parent===t.parent)),t.top_level===!0&&(n=n.filter(i=>i.parent===null)),t.under!==void 0){const i=new Set(ue(t.under));n=n.filter(d=>i.has(d.node_id))}t.hanging===!0&&(n=n.filter(i=>i.parent!==null&&b(i.parent)===null));const o=t.include==="activity"?pe(n.map(i=>i.node_id)):null;return{status:200,body:n.map(i=>{const d=tn(i);if(o!==null){const a=Qe(i.node_id);d.activity={latest_report:a[0]??null,final_report:i.final_report===null?null:a.find(c=>ee(c.path)===i.final_report)??null,pending_human_count:o[i.node_id]??0}}return d})}}s(mn,"handleList");function pn(e){const t=e.params.id;return f(t),{status:200,body:y(t)}}s(pn,"handleDetail");async function hn(e){const t=e.params.id;f(t);const n=await ge(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(r=>({name:r.name,description:r.description,source:r.source})),captured_at:T()}}}s(hn,"handleSnapshot");async function wn(e){const t=e.params.id,n=ve(t);if(n===null)throw R(`unknown node: ${t}`,{received:t});return{status:200,body:n}}s(wn,"handleSubject");function yn(e){for(const[i]of e.query)if(i!=="cursor"&&i!=="limit")throw u(`unknown messages query parameter: ${i}`);const t=e.query.getAll("cursor"),n=e.query.getAll("limit");if(t.length>1)throw u("cursor must appear at most once");if(n.length>1)throw u("limit must appear at most once");if(n.length===0)return t.length===0?{}:{cursor:t[0]};const o=n[0],r=Number(o);if(!Number.isSafeInteger(r)||o==="")throw u("limit must be an integer from 1 through 500");return t.length===0?{limit:r}:{cursor:t[0],limit:r}}s(yn,"parseMessagesQuery");async function _n(e){const t=e.params.id,n=await ye(t,yn(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:T()}}}s(_n,"handleMessages");function gn(e){const t=e.params.id;f(t);const n=_e(t);return{status:200,body:{node_id:t,session_file:n.sessionFile,session_jsonl:n.sessionJsonl,system_prompt:n.systemPrompt,captured_at:T()}}}s(gn,"handleSession");async function bn(e){const t=e.params.id;return f(t),{status:200,body:{node_id:t,markdown:await be(t)}}}s(bn,"handleTranscript");function vn(e){const t=e.params.id;f(t);const n=[{node_id:t,label:b(t)?.name??t,dir:P(t),self:!0,files:B(t)}];for(const o of E(t))n.push({node_id:o.node_id,label:b(o.node_id)?.name??o.node_id,dir:P(o.node_id),self:!1,files:B(o.node_id)});return{status:200,body:{node_id:t,roots:n}}}s(vn,"handleContext");function kn(e){const t=e.params.id;f(t);const n=e.query.get("type"),o=we(t,n!==null?[n]:void 0).map(i=>({ref:i.ref,source:i.source==="report"&&i.reportKind!==void 0?`report:${i.reportKind}`:i.source,ts:i.ts,title:i.title}));return{status:200,body:{node_id:t,artifacts:o}}}s(kn,"handleArtifacts");async function Sn(e){const t=await de(e.params.id);return{status:201,body:y(t.node.node_id)}}s(Sn,"handleFork");async function On(e){const t=e.params.id;f(t);const n=e.body,o=n?.resume??!0,r=n?.reopen??!1;Ae(t,r);const i=!o&&n?.cron_id!==void 0?Ue(n.cron_id):null,d=await re(t,{resume:o,capacity:"refuse",...i!==null?{wakeReason:Xe(i,"schedule_revive")}:{}}),a=b(t)?.status??"active";return{status:200,body:on(t,d,a)}}s(On,"handleRevive");async function Nn(e){const t=e.params.id;return{status:200,body:{newNodeId:(await Te(t))?.newNodeId??null}}}s(Nn,"handleRelaunchRoot");function Tn(e){const t=e.params.id;f(t);const n=e.body;if(n?.caller_pid!==void 0&&(!Number.isInteger(n.caller_pid)||n.caller_pid<=0))throw u("caller_pid must be a positive integer when provided");const o=Ze(),r=ie(t,{rootEvent:n?.finish===!0?"finish":"cancel",callerPid:n?.caller_pid,...o===null?{}:{registerDetached:o.registerDetached}});return{status:200,body:nn(r)}}s(Tn,"handleClose");async function An(e){const t=e.params.id;f(t);const n=await Ne(t);return{status:200,body:{recycled:n.recycled,finalized:n.finalized,new_root:n.newRoot,delivered:n.delivered}}}s(An,"handleRecycle");async function $n(e){const t=e.params.id;return f(t),await L(t,{lifecycle:"terminal"}),{status:200,body:y(t)}}s($n,"handleDemote");async function Pn(e,t={}){const n=e.params.id,o=f(n),r=e.body??{};r.model!==void 0&&await V(o,{kind:r.kind??o.kind,mode:"orchestrator",lifecycle:r.resident===!0?"resident":o.lifecycle,model:r.model},t.modelRegistry);const i=await Se(n,{...r.kind!==void 0?{kind:r.kind}:{},...r.resident===!0?{resident:!0}:{},...r.model!==void 0?{model:r.model}:{}}),d=x(i.meta,D(n));return d.roadmap_written=i.roadmapWritten,d.roadmap_path=i.roadmapPath,d.goal_path=i.goalPath,{status:200,body:d}}s(Pn,"handlePromote");async function Rn(e,t={}){const n=e.params.id,o=f(n),r=e.body??{};r.model!==void 0&&await V(o,{kind:r.kind??o.kind,mode:r.promote===!0?"orchestrator":o.mode,lifecycle:o.lifecycle,model:r.model},t.modelRegistry);const i=r.note??"Refresh: continue against your roadmap or goal.";$e(n,i);const d=await Oe(n,{...r.promote===!0?{promote:!0}:{},...r.kind!==void 0?{kind:r.kind}:{},...r.model!==void 0?{model:r.model}:{}});return{status:200,body:x(d.meta,D(n))}}s(Rn,"handleYield");function xn(e){const t=e.params.id;f(t);const n=e.body;if(n===void 0||typeof n.controller!="string"||n.controller.trim()==="")throw u("a wait requires a controller node id");const o=b(n.controller);if(o===null)throw R(`unknown controller: ${n.controller}`,{received:n.controller});if(o.status!=="active"&&o.status!=="idle")throw new w(422,"unprocessable",`controller ${n.controller} is ${o.status}`);return ce(t,n.controller),{status:200,body:y(t)}}s(xn,"handleWait");async function Dn(){const e=await ke();return{status:200,body:{revived:[...e.revived],failed:[...e.failed],frozen:[...e.frozen]}}}s(Dn,"handleReviveAll");async function Cn(e,t={}){const n=e.params.id,o=e.body;let r;if(o===void 0)r={};else if(typeof o=="object"&&o!==null&&!Array.isArray(o))r=o;else throw new m({error:"cwd_invalid",message:"cwd repair requires a non-null object with a non-empty cwd string",received:o,field:"cwd",next:"Send a config patch with a non-empty absolute cwd string."});if(Object.prototype.hasOwnProperty.call(r,"cwd")){const d=r.cwd;if(typeof d!="string"||d==="")throw new m({error:"cwd_invalid",message:"cwd must be a non-empty string",received:d,field:"cwd",next:"Send a non-empty absolute cwd string."});if(Object.keys(r).some(l=>l!=="cwd"&&r[l]!==void 0))throw new m({error:"cwd_not_exclusive",message:"cwd repair cannot be combined with another config field",received:r,field:"cwd",next:"Send cwd as the only config field."});const a=f(n);if(ze().has(n)){const l=`${n} cannot repair its cwd while its broker is live`;throw new w(409,"cwd_node_live",l,{error:"cwd_node_live",message:l,received:d,field:"cwd",next:"Let the node become dormant, then retry the cwd repair."})}if(a.fork_from!=null)throw new m({error:"cwd_node_forked",message:`${n} is a fork and cannot repair its cwd; recorded cwd: ${a.cwd}`,received:d,field:"cwd",next:`Restore ${a.cwd}, then revive the fork normally.`});if(a.managed_worktree?.state==="open")throw new m({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot repair its cwd`,received:d,field:"cwd",next:"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon flow."});if(C(a.cwd))throw new m({error:"cwd_still_present",message:`${n} recorded cwd still exists: ${a.cwd}; cwd repair is not a relocation command`,received:d,field:"cwd",next:"This command only repairs a node whose recorded cwd is gone."});if(!ne(d))throw new m({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${d}`,received:d,field:"cwd",next:"Send an absolute path."});const c=I(d);if(!C(c))throw new m({error:"cwd_missing",message:`cwd does not exist: ${c}`,received:d,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."});try{if(!q(c).isDirectory())throw new m({error:"cwd_not_a_directory",message:`cwd is not a directory: ${c}`,received:d,field:"cwd",next:"Send an existing absolute directory."})}catch(l){throw l instanceof m?l:new m({error:"cwd_missing",message:`cwd does not exist: ${c}`,received:d,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."})}return fe(()=>{$(n,{cwd:c}),me(n)}),{status:200,body:y(n)}}let i=f(n);if(r.scopes!==void 0){const d=W(r.scopes);if(!d.every(a=>en(i.scopes,a)))throw new m({error:"unknown_scope",message:"scopes may only narrow the node's current list",received:d,field:"scopes",next:"Send only scopes the node already holds."});i=$(n,{scopes:d})}if(r.situational_context!==void 0&&te(n,oe(r.situational_context)),r.model!==void 0){const d=Ie(r.model),a=(await j(i.cwd,i.profile_id??null)).modelLadders,c=Me(r.model,a);await A({kind:"concrete",spec:c},{cwd:i.cwd,profileId:i.profile_id??null},t.modelRegistry);const l=s(()=>{if(!c.includes("/"))throw u(`model must resolve to a provider/id spec: ${r.model}`);Fe(n,c,d)},"persistDormant");if(je(i))try{await Ge(n,c,d)}catch(p){if(!(p instanceof Le))throw p;l()}else l();i=f(n)}if(r.kind!==void 0||r.mode!==void 0||r.lifecycle!==void 0){r.kind!==void 0&&await Y(r.kind);const d=r.kind??i.kind,a=r.mode??i.mode,c=r.lifecycle??i.lifecycle;let l;a==="orchestrator"&&!Re(n)&&(l=s(()=>{const p=Pe(n);xe(n,p!==null&&p.trim()!==""?{goal:p.trim()}:{})},"beforePersist")),i=await L(n,{...r.kind!==void 0?{kind:d}:{},...r.mode!==void 0?{mode:a}:{},...r.lifecycle!==void 0?{lifecycle:c}:{}},l)}return r.name!==void 0&&(i=$(n,{name:r.name}),i.window&&De(i.window,He(i))),{status:200,body:y(n)}}s(Cn,"handleConfig");async function Y(e){const t=Object.keys((await j(process.cwd(),X()||null)).kinds);if(!t.includes(e))throw u(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${t.sort().join(", ")}.`})}s(Y,"assertKindServer");const Pt=[{method:"POST",pattern:"/v1/nodes",handler:un},{method:"GET",pattern:"/v1/nodes",handler:mn},{method:"POST",pattern:"/v1/nodes/revive-all",handler:s(()=>Dn(),"handler")},{method:"GET",pattern:"/v1/nodes/:id",handler:pn},{method:"GET",pattern:"/v1/nodes/:id/snapshot",handler:hn},{method:"GET",pattern:"/v1/nodes/:id/subject",handler:wn},{method:"GET",pattern:"/v1/nodes/:id/messages",handler:_n},{method:"GET",pattern:"/v1/nodes/:id/session",handler:gn},{method:"GET",pattern:"/v1/nodes/:id/transcript",handler:bn},{method:"GET",pattern:"/v1/nodes/:id/context",handler:vn},{method:"GET",pattern:"/v1/nodes/:id/artifacts",handler:kn},{method:"POST",pattern:"/v1/nodes/:id/fork",handler:Sn},{method:"POST",pattern:"/v1/nodes/:id/revive",handler:On},{method:"POST",pattern:"/v1/nodes/:id/relaunch-root",handler:Nn},{method:"POST",pattern:"/v1/nodes/:id/close",handler:Tn},{method:"POST",pattern:"/v1/nodes/:id/recycle",handler:An},{method:"POST",pattern:"/v1/nodes/:id/demote",handler:$n},{method:"POST",pattern:"/v1/nodes/:id/promote",handler:Pn},{method:"POST",pattern:"/v1/nodes/:id/yield",handler:Rn},{method:"POST",pattern:"/v1/nodes/:id/wait",handler:xn},{method:"PATCH",pattern:"/v1/nodes/:id/config",handler:Cn}];export{Cn as handleConfig,un as handleCreate,Sn as handleFork,mn as handleList,Pn as handlePromote,Rn as handleYield,Pt as nodeRoutes,Dt as resolveCreateKind};
|
|
1
|
+
var X=Object.defineProperty;var s=(e,t)=>X(e,"name",{value:t,configurable:!0});import{envProfileId as Z}from"../../../shared/env.js";import{existsSync as D,readdirSync as q,statSync as ee}from"node:fs";import{basename as ne,isAbsolute as te,resolve as I}from"node:path";import{appendSituationalContext as oe,formatSituationalProse as ie}from"../../../core/runtime/situational-context.js";import{closeNode as re}from"../../../core/runtime/close.js";import{reviveNode as de}from"../../../core/runtime/revive.js";import{nowIso as T}from"../../../core/fs-utils.js";import{assertLaunchModelRegistered as $,forkNode as se,spawnChildPrepared as ae}from"../../../core/runtime/spawn.js";import{childrenOf as le,getNode as b,listNodes as M,subscribersOf as ce,subscriptionsOf as E,setMessageWait as ue,updateNode as A}from"../../../core/canvas/canvas.js";import{subtreeIds as fe}from"../../../core/canvas/nav-model.js";import{withCanvasWrite as me}from"../../../core/canvas/db.js";import{unbindSession as pe}from"../../../core/canvas/sessions.js";import{ticketCountsForNodes as he}from"../../../core/canvas/attention.js";import{contextDir as P,reportsDir as we}from"../../../core/canvas/paths.js";import{nodeArtifacts as ye}from"../../../core/canvas/history.js";import{readNodeMessagesPage as ge,readNodeSession as _e,readNodeSnapshot as be,transcriptMarkdown as ve}from"../../../core/runtime/node-read.js";import{assembleNodeSubject as ke}from"../../../core/substrate/subject.js";import{reviveAll as Se}from"../../../core/runtime/revive-all.js";import{promoteAsync as Oe,requestYieldAsync as Ne,reshapeNodeAsync as L}from"../../../core/runtime/promote.js";import{recycleNode as Te}from"../../../core/runtime/recycle.js";import{relaunchRoot as $e}from"../../../core/runtime/reset.js";import{assertReopenGate as Ae}from"../../../core/runtime/reopen.js";import{writeYieldMessage as Pe,readGoal as Re}from"../../../core/runtime/kickoff.js";import{hasRoadmap as xe,seedRoadmap as Ce}from"../../../core/runtime/roadmap.js";import{renameWindow as De}from"../../../core/runtime/placement.js";import{buildLaunchSpecAsync as Ie,isProviderPinnedModelToken as Me,normalizeModel as Ee,readMergedLaunchConfigAsync as j}from"../../../core/runtime/launch.js";import{modelRequestFromConfig as Le}from"../../../core/model-routes.js";import{BrokerUnreachableError as je}from"../../../core/runtime/broker-request.js";import{isBrokerLive as Fe,persistDormantModel as Ge,setModelLive as ze}from"../../../core/runtime/model-swap.js";import{boundFleet as We}from"../../../core/runtime/fleet.js";import{writeOutputSchema as F}from"../../../core/runtime/structured-output.js";import{OUTCOME_PAYLOAD_MAX_BYTES as G}from"../../../core/canvas/types.js";import{HUMAN_ACTION_NAME_PATTERN as Be}from"../../../core/human/action-binding.js";import{resolveHumanAction as Je}from"../../../core/human-actions.js";import{parseDurationMs as Ve}from"../../../core/wake.js";import{claimWarmNode as Ke,refillWarmPool as z,warmPoolEnabled as Ye}from"../../../core/runtime/warm-pool.js";import{resolveLaunchTarget as He}from"../../../core/runtime/launch-target.js";import{fullName as Qe}from"../../../core/canvas/labels.js";import{reportsForNode as Ue}from"./reports.js";import{getCron as Xe}from"../../../core/canvas/crons.js";import{cronWakeOrigin as Ze}from"../../../core/runtime/bearings.js";import{boundDaemonControl as qe}from"../../control.js";import{notFound as R,usage as u}from"../../../core/errors.js";import{assertScope as en,validateScopes as W}from"../../../core/scopes.js";import{scopeAllowed as B}from"../../../shared/env.js";import{toCloseResultDTO as nn,toNodeDetailDTO as x,toNodeSummaryDTO as tn,toReviveResultDTO as on}from"../map.js";import{ApiError as h}from"../../../api/index.js";import{InputError as m}from"../../../core/io.js";function f(e){const t=b(e);if(t===null)throw R(`unknown node: ${e}`,{received:e});return t}s(f,"requireMeta");function C(e){return{subscribesTo:E(e),subscribers:ce(e),children:le(e)}}s(C,"edgesFor");function y(e){const t=f(e);return x(t,C(e))}s(y,"detailOf");function J(e){let t=0;for(const n of[P(e),we(e)])try{t+=q(n).length}catch{}return t}s(J,"countFiles");function rn(e){if(typeof e!="object"||e===null)throw u("a node create requires a JSON body");const t=e;if(t.kind!==void 0&&(typeof t.kind!="string"||t.kind.trim()===""))throw u("kind must be a non-empty string when provided");if(t.description!==void 0&&(typeof t.description!="string"||t.description.trim()===""))throw u("description must be a non-empty string when provided");if(t.creator!==void 0&&(typeof t.creator!="string"||t.creator.trim()===""))throw u("creator must be a non-empty node id when provided");t.scopes!==void 0&&W(t.scopes);const n=t.root_lifecycle;if(n!==void 0&&n!=="resident"&&n!=="terminal")throw u("root_lifecycle must be 'resident' or 'terminal'");return t}s(rn,"parseCreateBody");function dn(e){if(e===void 0)return;const t=Ve(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 h(422,"invalid_deadline","`deadline` must be a positive representable duration");return n.toISOString()}s(dn,"parseDeadline");function sn(e){if(e!==void 0){if(typeof e!="object"||e===null||Array.isArray(e))throw new h(400,"invalid_request","`outcome_delivery` must be an object");if(typeof e.action!="string"||!Be.test(e.action))throw new h(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 h(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable")}if(t===void 0)throw new h(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable");if(Buffer.byteLength(t,"utf8")>G)throw new h(413,"payload_too_large",`serialized payload exceeds ${G} bytes`)}return e}}s(sn,"parseOutcomeDelivery");function an(e,t){const n=Je(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 h(422,"unknown_action",`no action named ${e.action} is declared from ${t}`):new h(422,"invalid_action",`${e.action} is declared in ${n.configOrigin} but unusable: ${n.reason}`,{reason:n.reason,configOrigin:n.configOrigin})}s(an,"resolveOutcomeDelivery");function ln(e,t,n){const o={kind:e.kind,cwd:n,prompt:e.prompt??""};return e.mode!==void 0&&(o.mode=e.mode),e.name!==void 0&&(o.name=e.name),e.description!==void 0&&(o.description=e.description),t!==void 0&&(o.parent=t),e.creator!==void 0&&(o.creator=e.creator),e.scopes!==void 0&&(o.scopes=e.scopes),e.root===!0&&(o.root=!0),e.root_lifecycle!==void 0&&(o.rootLifecycle=e.root_lifecycle),(e.worktree===!0||typeof e.worktree=="string")&&(o.worktree=!0),typeof e.worktree=="string"&&(o.worktreeBase=e.worktree),e.worktree!==void 0&&(o.worktreeCwd=I(e.pin_cwd??e.cwd??n)),e.fork_from!==void 0&&(o.forkFrom=e.fork_from),e.model!==void 0&&(o.model=e.model),e.profile!==void 0&&(o.profile=e.profile),e.situational_context!==void 0&&(o.situationalContext=e.situational_context),e.node_id!==void 0&&(o.nodeId=e.node_id),o}s(ln,"buildRecipe");function cn(e,t,n){return!Ye()||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?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}}s(cn,"warmRequestFor");import{resolveCreateKind as Dt}from"../../../core/runtime/launch-target.js";function V(e){const t=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return Le(e.model,t,e.modelExact===!0)}s(V,"requestFromLaunch");function un(e,t){if(t===null)return e;if(e.scopes===void 0)return{...e,scopes:[...t]};const n=e.scopes.filter(o=>!B(t,o));if(n.length===0)return e;throw new h(403,"scope_denied",`scopes exceed the bearer token's ceiling: ${n.join(", ")}`,{scopes:n,ceiling:t})}s(un,"withinCeiling");async function K(e,t,n){const o=(await Ie(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 $(V(o),{cwd:e.cwd,profileId:e.profile_id??null},n)}s(K,"assertNodeModelChangeRegistered");async function fn(e,t={}){const n=un(rn(e.body),e.ceiling);n.creator!==void 0&&en(f(n.creator),"act");const o=dn(n.deadline),r=sn(n.outcome_delivery),i=n.parent??void 0;if(i==null&&n.root!==!0)throw u("a node create requires a parent (or root: true for an independent root)");let d=null;if(n.output_schema!==void 0)try{d=JSON.parse(n.output_schema)}catch{throw u("output_schema must be a JSON schema string")}const{profileId:a,kind:c,cwd:l,launch:p}=await He(n,{validateKind:H}),v={...n,kind:c},g=r===void 0?void 0:an(r,l);await $(V(p),{cwd:l,profileId:a},t.modelRegistry);let _=null;{const k=cn(v,l,a);if(k!==null){const O=await Ke(k,{...o===void 0?{}:{deadlineAt:o},...g===void 0?{}:{outcomeDelivery:g}},d===null?void 0:U=>F(U,"terminal",d));if(O!==null)return z(k),{status:201,body:y(O)};_=k}const S=ln(v,i,l);o!==void 0&&(S.deadlineAt=o),g!==void 0&&(S.outcomeDelivery=g),S.readiness=n.root===!0?"await":"launch";const Q=await ae(S,d===null?void 0:O=>F(O,"terminal",d),()=>{_!==null&&z(_)});return{status:201,body:y(Q.node.node_id)}}}s(fn,"handleCreate");function w(e,t){const n=e.query.getAll(t);if(n.length>1)throw u(`${t} must appear at most once`);return n[0]}s(w,"singleQueryValue");function Y(e,t){if(e!==void 0){if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw u(`${t} must be true or false`)}}s(Y,"optionalBoolean");function N(e,t,n){if(e!==void 0){if(n.includes(e))return e;throw u(`${t} must be one of: ${n.join(", ")}`)}}s(N,"oneOf");function mn(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 u(`unknown nodes query parameter: ${_}`);const n=N(w(e,"status"),"status",["active","idle","done","dead","canceled"]),o=N(w(e,"lifecycle"),"lifecycle",["terminal","resident"]),r=w(e,"kind"),i=N(w(e,"mode"),"mode",["base","orchestrator"]),d=w(e,"profile_id"),a=w(e,"profile_prefix"),c=w(e,"parent"),l=Y(w(e,"top_level"),"top_level"),p=w(e,"under"),v=Y(w(e,"hanging"),"hanging"),g=N(w(e,"include"),"include",["activity"]);if(c!==void 0&&l===!0)throw u("parent and top_level=true cannot be combined");return{...n!==void 0?{status:n}:{},...o!==void 0?{lifecycle:o}:{},...r!==void 0?{kind:r}:{},...i!==void 0?{mode:i}:{},...d!==void 0?{profile_id:d}:{},...a!==void 0?{profile_prefix:a}:{},...c!==void 0?{parent:c}:{},...l!==void 0?{top_level:l}:{},...p!==void 0?{under:p}:{},...v!==void 0?{hanging:v}:{},...g!==void 0?{include:g}:{}}}s(mn,"parseListQuery");function pn(e){const t=mn(e);let n=t.status!==void 0?M({status:t.status}):M();if(t.lifecycle!==void 0&&(n=n.filter(i=>i.lifecycle===t.lifecycle)),t.kind!==void 0&&(n=n.filter(i=>i.kind===t.kind)),t.mode!==void 0&&(n=n.filter(i=>i.mode===t.mode)),t.profile_id!==void 0&&(n=n.filter(i=>i.profile_id===t.profile_id)),t.profile_prefix!==void 0&&(n=n.filter(i=>i.profile_id?.startsWith(t.profile_prefix))),t.parent!==void 0&&(n=n.filter(i=>i.parent===t.parent)),t.top_level===!0&&(n=n.filter(i=>i.parent===null)),t.under!==void 0){const i=new Set(fe(t.under));n=n.filter(d=>i.has(d.node_id))}t.hanging===!0&&(n=n.filter(i=>i.parent!==null&&b(i.parent)===null));const o=t.include==="activity"?he(n.map(i=>i.node_id)):null;return{status:200,body:n.map(i=>{const d=tn(i);if(o!==null){const a=Ue(i.node_id);d.activity={latest_report:a[0]??null,final_report:i.final_report===null?null:a.find(c=>ne(c.path)===i.final_report)??null,pending_human_count:o[i.node_id]??0}}return d})}}s(pn,"handleList");function hn(e){const t=e.params.id;return f(t),{status:200,body:y(t)}}s(hn,"handleDetail");async function wn(e){const t=e.params.id;f(t);const n=await be(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(r=>({name:r.name,description:r.description,source:r.source})),captured_at:T()}}}s(wn,"handleSnapshot");async function yn(e){const t=e.params.id,n=ke(t);if(n===null)throw R(`unknown node: ${t}`,{received:t});return{status:200,body:n}}s(yn,"handleSubject");function gn(e){for(const[i]of e.query)if(i!=="cursor"&&i!=="limit")throw u(`unknown messages query parameter: ${i}`);const t=e.query.getAll("cursor"),n=e.query.getAll("limit");if(t.length>1)throw u("cursor must appear at most once");if(n.length>1)throw u("limit must appear at most once");if(n.length===0)return t.length===0?{}:{cursor:t[0]};const o=n[0],r=Number(o);if(!Number.isSafeInteger(r)||o==="")throw u("limit must be an integer from 1 through 500");return t.length===0?{limit:r}:{cursor:t[0],limit:r}}s(gn,"parseMessagesQuery");async function _n(e){const t=e.params.id,n=await ge(t,gn(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:T()}}}s(_n,"handleMessages");function bn(e){const t=e.params.id;f(t);const n=_e(t);return{status:200,body:{node_id:t,session_file:n.sessionFile,session_jsonl:n.sessionJsonl,system_prompt:n.systemPrompt,captured_at:T()}}}s(bn,"handleSession");async function vn(e){const t=e.params.id;return f(t),{status:200,body:{node_id:t,markdown:await ve(t)}}}s(vn,"handleTranscript");function kn(e){const t=e.params.id;f(t);const n=[{node_id:t,label:b(t)?.name??t,dir:P(t),self:!0,files:J(t)}];for(const o of E(t))n.push({node_id:o.node_id,label:b(o.node_id)?.name??o.node_id,dir:P(o.node_id),self:!1,files:J(o.node_id)});return{status:200,body:{node_id:t,roots:n}}}s(kn,"handleContext");function Sn(e){const t=e.params.id;f(t);const n=e.query.get("type"),o=ye(t,n!==null?[n]:void 0).map(i=>({ref:i.ref,source:i.source==="report"&&i.reportKind!==void 0?`report:${i.reportKind}`:i.source,ts:i.ts,title:i.title}));return{status:200,body:{node_id:t,artifacts:o}}}s(Sn,"handleArtifacts");async function On(e){const t=await se(e.params.id,e.ceiling===null?void 0:[...e.ceiling]);return{status:201,body:y(t.node.node_id)}}s(On,"handleFork");async function Nn(e){const t=e.params.id;f(t);const n=e.body,o=n?.resume??!0,r=n?.reopen??!1;Ae(t,r);const i=!o&&n?.cron_id!==void 0?Xe(n.cron_id):null,d=await de(t,{resume:o,capacity:"refuse",...i!==null?{wakeReason:Ze(i,"schedule_revive")}:{}}),a=b(t)?.status??"active";return{status:200,body:on(t,d,a)}}s(Nn,"handleRevive");async function Tn(e){const t=e.params.id;return{status:200,body:{newNodeId:(await $e(t))?.newNodeId??null}}}s(Tn,"handleRelaunchRoot");function $n(e){const t=e.params.id;f(t);const n=e.body;if(n?.caller_pid!==void 0&&(!Number.isInteger(n.caller_pid)||n.caller_pid<=0))throw u("caller_pid must be a positive integer when provided");const o=qe(),r=re(t,{rootEvent:n?.finish===!0?"finish":"cancel",callerPid:n?.caller_pid,...o===null?{}:{registerDetached:o.registerDetached}});return{status:200,body:nn(r)}}s($n,"handleClose");async function An(e){const t=e.params.id;f(t);const n=await Te(t);return{status:200,body:{recycled:n.recycled,finalized:n.finalized,new_root:n.newRoot,delivered:n.delivered}}}s(An,"handleRecycle");async function Pn(e){const t=e.params.id;return f(t),await L(t,{lifecycle:"terminal"}),{status:200,body:y(t)}}s(Pn,"handleDemote");async function Rn(e,t={}){const n=e.params.id,o=f(n),r=e.body??{};r.model!==void 0&&await K(o,{kind:r.kind??o.kind,mode:"orchestrator",lifecycle:r.resident===!0?"resident":o.lifecycle,model:r.model},t.modelRegistry);const i=await Oe(n,{...r.kind!==void 0?{kind:r.kind}:{},...r.resident===!0?{resident:!0}:{},...r.model!==void 0?{model:r.model}:{}}),d=x(i.meta,C(n));return d.roadmap_written=i.roadmapWritten,d.roadmap_path=i.roadmapPath,d.goal_path=i.goalPath,{status:200,body:d}}s(Rn,"handlePromote");async function xn(e,t={}){const n=e.params.id,o=f(n),r=e.body??{};r.model!==void 0&&await K(o,{kind:r.kind??o.kind,mode:r.promote===!0?"orchestrator":o.mode,lifecycle:o.lifecycle,model:r.model},t.modelRegistry);const i=r.note??"Refresh: continue against your roadmap or goal.";Pe(n,i);const d=await Ne(n,{...r.promote===!0?{promote:!0}:{},...r.kind!==void 0?{kind:r.kind}:{},...r.model!==void 0?{model:r.model}:{}});return{status:200,body:x(d.meta,C(n))}}s(xn,"handleYield");function Cn(e){const t=e.params.id;f(t);const n=e.body;if(n===void 0||typeof n.controller!="string"||n.controller.trim()==="")throw u("a wait requires a controller node id");const o=b(n.controller);if(o===null)throw R(`unknown controller: ${n.controller}`,{received:n.controller});if(o.status!=="active"&&o.status!=="idle")throw new h(422,"unprocessable",`controller ${n.controller} is ${o.status}`);return ue(t,n.controller),{status:200,body:y(t)}}s(Cn,"handleWait");async function Dn(){const e=await Se();return{status:200,body:{revived:[...e.revived],failed:[...e.failed],frozen:[...e.frozen]}}}s(Dn,"handleReviveAll");async function In(e,t={}){const n=e.params.id,o=e.body;let r;if(o===void 0)r={};else if(typeof o=="object"&&o!==null&&!Array.isArray(o))r=o;else throw new m({error:"cwd_invalid",message:"cwd repair requires a non-null object with a non-empty cwd string",received:o,field:"cwd",next:"Send a config patch with a non-empty absolute cwd string."});if(Object.prototype.hasOwnProperty.call(r,"cwd")){const d=r.cwd;if(typeof d!="string"||d==="")throw new m({error:"cwd_invalid",message:"cwd must be a non-empty string",received:d,field:"cwd",next:"Send a non-empty absolute cwd string."});if(Object.keys(r).some(l=>l!=="cwd"&&r[l]!==void 0))throw new m({error:"cwd_not_exclusive",message:"cwd repair cannot be combined with another config field",received:r,field:"cwd",next:"Send cwd as the only config field."});const a=f(n);if(We().has(n)){const l=`${n} cannot repair its cwd while its broker is live`;throw new h(409,"cwd_node_live",l,{error:"cwd_node_live",message:l,received:d,field:"cwd",next:"Let the node become dormant, then retry the cwd repair."})}if(a.fork_from!=null)throw new m({error:"cwd_node_forked",message:`${n} is a fork and cannot repair its cwd; recorded cwd: ${a.cwd}`,received:d,field:"cwd",next:`Restore ${a.cwd}, then revive the fork normally.`});if(a.managed_worktree?.state==="open")throw new m({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot repair its cwd`,received:d,field:"cwd",next:"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon flow."});if(D(a.cwd))throw new m({error:"cwd_still_present",message:`${n} recorded cwd still exists: ${a.cwd}; cwd repair is not a relocation command`,received:d,field:"cwd",next:"This command only repairs a node whose recorded cwd is gone."});if(!te(d))throw new m({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${d}`,received:d,field:"cwd",next:"Send an absolute path."});const c=I(d);if(!D(c))throw new m({error:"cwd_missing",message:`cwd does not exist: ${c}`,received:d,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."});try{if(!ee(c).isDirectory())throw new m({error:"cwd_not_a_directory",message:`cwd is not a directory: ${c}`,received:d,field:"cwd",next:"Send an existing absolute directory."})}catch(l){throw l instanceof m?l:new m({error:"cwd_missing",message:`cwd does not exist: ${c}`,received:d,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."})}return me(()=>{A(n,{cwd:c}),pe(n)}),{status:200,body:y(n)}}let i=f(n);if(r.scopes!==void 0){const d=W(r.scopes);if(!d.every(a=>B(i.scopes,a)))throw new m({error:"unknown_scope",message:"scopes may only narrow the node's current list",received:d,field:"scopes",next:"Send only scopes the node already holds."});i=A(n,{scopes:d})}if(r.situational_context!==void 0&&oe(n,ie(r.situational_context)),r.model!==void 0){const d=Me(r.model),a=(await j(i.cwd,i.profile_id??null)).modelLadders,c=Ee(r.model,a);await $({kind:"concrete",spec:c},{cwd:i.cwd,profileId:i.profile_id??null},t.modelRegistry);const l=s(()=>{if(!c.includes("/"))throw u(`model must resolve to a provider/id spec: ${r.model}`);Ge(n,c,d)},"persistDormant");if(Fe(i))try{await ze(n,c,d)}catch(p){if(!(p instanceof je))throw p;l()}else l();i=f(n)}if(r.kind!==void 0||r.mode!==void 0||r.lifecycle!==void 0){r.kind!==void 0&&await H(r.kind);const d=r.kind??i.kind,a=r.mode??i.mode,c=r.lifecycle??i.lifecycle;let l;a==="orchestrator"&&!xe(n)&&(l=s(()=>{const p=Re(n);Ce(n,p!==null&&p.trim()!==""?{goal:p.trim()}:{})},"beforePersist")),i=await L(n,{...r.kind!==void 0?{kind:d}:{},...r.mode!==void 0?{mode:a}:{},...r.lifecycle!==void 0?{lifecycle:c}:{}},l)}return r.name!==void 0&&(i=A(n,{name:r.name}),i.window&&De(i.window,Qe(i))),{status:200,body:y(n)}}s(In,"handleConfig");async function H(e){const t=Object.keys((await j(process.cwd(),Z()||null)).kinds);if(!t.includes(e))throw u(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${t.sort().join(", ")}.`})}s(H,"assertKindServer");const Rt=[{method:"POST",pattern:"/v1/nodes",scope:"act",handler:fn},{method:"GET",pattern:"/v1/nodes",handler:pn},{method:"POST",pattern:"/v1/nodes/revive-all",scope:"act",handler:s(()=>Dn(),"handler")},{method:"GET",pattern:"/v1/nodes/:id",handler:hn},{method:"GET",pattern:"/v1/nodes/:id/snapshot",handler:wn},{method:"GET",pattern:"/v1/nodes/:id/subject",handler:yn},{method:"GET",pattern:"/v1/nodes/:id/messages",handler:_n},{method:"GET",pattern:"/v1/nodes/:id/session",handler:bn},{method:"GET",pattern:"/v1/nodes/:id/transcript",handler:vn},{method:"GET",pattern:"/v1/nodes/:id/context",handler:kn},{method:"GET",pattern:"/v1/nodes/:id/artifacts",handler:Sn},{method:"POST",pattern:"/v1/nodes/:id/fork",scope:"act",handler:On},{method:"POST",pattern:"/v1/nodes/:id/revive",scope:"act",handler:Nn},{method:"POST",pattern:"/v1/nodes/:id/relaunch-root",scope:"act",handler:Tn},{method:"POST",pattern:"/v1/nodes/:id/close",handler:$n},{method:"POST",pattern:"/v1/nodes/:id/recycle",scope:"act",handler:An},{method:"POST",pattern:"/v1/nodes/:id/demote",scope:"act",handler:Pn},{method:"POST",pattern:"/v1/nodes/:id/promote",scope:"act",handler:Rn},{method:"POST",pattern:"/v1/nodes/:id/yield",scope:"act",handler:xn},{method:"POST",pattern:"/v1/nodes/:id/wait",handler:Cn},{method:"PATCH",pattern:"/v1/nodes/:id/config",handler:In}];export{In as handleConfig,fn as handleCreate,On as handleFork,pn as handleList,Rn as handlePromote,xn as handleYield,Rt as nodeRoutes,Dt as resolveCreateKind};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var c=Object.defineProperty;var s=(r,e)=>c(r,"name",{value:e,configurable:!0});import{assertInstalledKind as h}from"../../../core/config.js";import{listNodesByProfile as u,shiftProfileNodeDeadlines as y}from"../../../core/canvas/canvas.js";import{shiftAutoBackgroundBashDeadlines as P}from"../../../core/bash-jobs.js";import{contextDir as _}from"../../../core/canvas/paths.js";import{boundFleet as b}from"../../../core/runtime/fleet.js";import{recordedPidLiveness as v}from"../../../core/canvas/pid.js";import{usage as
|
|
1
|
+
var c=Object.defineProperty;var s=(r,e)=>c(r,"name",{value:e,configurable:!0});import{assertInstalledKind as h}from"../../../core/config.js";import{listNodesByProfile as u,shiftProfileNodeDeadlines as y}from"../../../core/canvas/canvas.js";import{shiftAutoBackgroundBashDeadlines as P}from"../../../core/bash-jobs.js";import{contextDir as _}from"../../../core/canvas/paths.js";import{boundFleet as b}from"../../../core/runtime/fleet.js";import{recordedPidLiveness as v}from"../../../core/canvas/pid.js";import{usage as l}from"../../../core/errors.js";import{assertProfileProjects as I,createProfile as A,ensureRootProfile as O,listProfiles as p,loadProfileManifest as f,pauseProfile as D,resumeProfile as T,updateProfileMetadata as w}from"../../../core/profiles/manifest.js";import{requestProfileDeletion as E}from"../../profile-delete.js";import{toProfileDTO as i}from"../map.js";const g="root";function j(r){const e=r.params.name,t=r.body??{};if(t.projects!==void 0&&I(t.projects),e===g)return{status:200,body:i(O())};const n=p().find(o=>o.manifest.name===e);if(n!==void 0)return{status:200,body:i(n)};t.default_kind!==void 0&&h(t.default_kind);const a=A(e,t.projects??[],{defaultKind:t.default_kind,metadata:t.metadata});return{status:200,body:i(a)}}s(j,"handleEnsure");function M(r){const e=f(r.params.name),t=r.body??{};if(typeof t!="object"||t===null||Array.isArray(t))throw l("profile metadata body must be an object",{field:"body"});const n=t,a=n.unset===void 0?[]:n.unset;if(!Array.isArray(a)||a.some(m=>typeof m!="string"))throw l("profile metadata `unset` must be an array of strings",{field:"unset"});const o=n.set===void 0?{}:n.set,d=w(e.profileId,o,a);return{status:200,body:i(d)}}s(M,"handleSetMetadata");function N(r){const e=f(r.params.name),t=D(e.profileId),n=u(e.profileId).filter(o=>o.status==="active"||o.status==="idle");if(n.length===0)return{status:200,body:{profile_id:e.profileId,paused_at:t.manifest.paused_at}};const a=b();for(const o of n){const d=a.get(o.node_id);if(d!==void 0){a.interruptForProfilePause(o.node_id,d.pid);continue}o.pi_pid!=null&&v(o.pi_pid,o.pi_pid_identity)==="alive"&&a.interruptForProfilePause(o.node_id,o.pi_pid)}return{status:200,body:{profile_id:e.profileId,paused_at:t.manifest.paused_at}}}s(N,"handlePause");function R(r){const e=f(r.params.name),t=T(e.profileId);if(t.pausedAt!==null){const n=Date.parse(t.pausedAt);if(!Number.isNaN(n)){const a=Math.max(0,Date.now()-n);y(e.profileId,a);for(const o of u(e.profileId))o.status!=="dead"&&P(_(o.node_id),a)}}return{status:200,body:{profile_id:e.profileId,paused_at:t.manifest.paused_at}}}s(R,"handleResume");function k(){return{status:200,body:p().map(i)}}s(k,"handleList");function F(r){const e=r.params.name;return{status:200,body:i(f(e))}}s(F,"handleGet");async function L(r){return E(r.params.name,r.body)}s(L,"handleDelete");const Q=[{method:"PUT",pattern:"/v1/profiles/:name",handler:j},{method:"POST",pattern:"/v1/profiles/:name/pause",ownerOnly:!0,handler:N},{method:"POST",pattern:"/v1/profiles/:name/resume",ownerOnly:!0,handler:R},{method:"PATCH",pattern:"/v1/profiles/:name/metadata",ownerOnly:!0,handler:M},{method:"DELETE",pattern:"/v1/profiles/:name",ownerOnly:!0,handler:L},{method:"GET",pattern:"/v1/profiles",handler:k},{method:"GET",pattern:"/v1/profiles/:name",handler:F}];export{Q as profileRoutes};
|
|
@@ -13,4 +13,4 @@ Code: ${e.code}
|
|
|
13
13
|
Retryable: ${e.retryable?"yes":"no"}
|
|
14
14
|
|
|
15
15
|
Declined marker: ${t}
|
|
16
|
-
`}s(ee,"declineReportBody");const T=1024,N=64;function te(t){if(typeof t!="object"||t===null)throw c("a result submission requires a JSON body { value } or { decline, code, retryable }");const e=Object.hasOwn(t,"value"),r=Object.hasOwn(t,"decline");if(e&&r)throw c("a result submission carries either { value } or { decline, code, retryable }, not both");if(r){const{decline:n,code:i,retryable:o}=t;if(typeof n!="string"||n.trim()==="")throw new d({error:"missing_decline_reason",message:"A decline needs a reason.",next:'Rerun with `--decline "<one sentence on why the schema cannot be honestly satisfied>" --code <token>`.'});if(n.length>T)throw new d({error:"decline_reason_too_long",message:`A decline reason is at most ${T} characters (got ${n.length}).`,next:"Keep the reason to one plain sentence; put any detail in an artifact and name its path."});if(typeof i!="string"||i.trim()===""||/\s/.test(i.trim())||i.trim().length>N)throw new d({error:"invalid_decline_code",message:`A decline needs a code: one whitespace-free token of at most ${N} characters naming the decline class.`,next:"Rerun with `--code <token>` \u2014 the token your requester documented for this case."});if(typeof o!="boolean")throw c("a decline carries `retryable` as a boolean");return{declined:{reason:n.trim(),code:i.trim(),retryable:o}}}if(!e)throw c("a result submission requires a JSON body { value } or { decline, code, retryable }");return{value:t.value}}s(te,"parseSubmitBody");async function re(t){const e=t.params.id;g(e);const r=te(t.body),n=k(e);if(n.state==="absent")throw new d({error:"no_output_request",message:"No structured output is currently requested of this node.",next:"Nothing to submit here \u2014 continue working, or finish with `crtr push final`."});if(n.state==="invalid")throw new d({error:"invalid_output_request",message:`The structured-output request file is invalid: ${n.error}`,next:`Have the requester re-issue the request, or remove ${G(e)} and finish with \`crtr push final\`.`});const{mode:i,schema:o}=n.request;let u;if("value"in r)try{u=await K(o,r.value)}catch(h){throw new d({error:"result_schema_mismatch",message:`the submitted result does not match the requested schema: ${h.message}`,next:'Fix the listed fields and rerun `crtr push result`; if the schema cannot be honestly satisfied, rerun with `--decline "<reason>" --code <token>`.'})}const l=i==="terminal"?f(e)?.status:void 0,p=i==="terminal"?await $(e):void 0;let a,m,w;if("declined"in r){const{declined:h}=r;if(a=V(e,{mode:i,...h,at:new Date().toISOString()}),m=ee(a,h),i==="terminal"){const x={schema:"crtr.node-outcome-detail/v1",message:h.reason,declined:h};w={kind:"failure",reason:"declined",detailJson:JSON.stringify(x)}}}else a=Q(e,u),m=Z(a,u);const y=await q(e,{tier:i==="terminal"?"final":"update",body:m},w);X(e);const _=i==="terminal"&&l!==void 0?{from:l,to:f(e)?.status??"done"}:void 0,v=b(e).find(h=>h.path===y.reportPath);return v!==void 0&&O.report(e,v),{status:200,body:{mode:i,result_path:a,report_path:y.reportPath,notified:[...y.deliveredTo],..."declined"in r?{declined:r.declined}:{},..._===void 0?{}:{transitioned:_},...p===void 0?{}:{worktree_auto_dropped:!0,worktree_auto_dropped_path:p}}}}s(re,"handleSubmitResult");async function q(t,e,r){try{return await F(t,{kind:e.tier,body:e.body,...e.delivery_tier===void 0?{}:{deliveryTier:e.delivery_tier},...r===void 0?{}:{outcome:r}})}catch(n){throw n instanceof S&&n.code==="already_finalized"?new d({error:"already_finalized",message:"This node already submitted its canonical final result.",next:"Push an update with the new information, then stop."}):n instanceof S&&n.code==="finalization_forbidden"?new d({error:"finalization_forbidden",message:"A canceled or dead node cannot submit a canonical final result.",next:"Do not push final from this node."}):n}}s(q,"pushOrRethrow");function ne(t){const e=t.match(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})$/);return e===null?t:`${e[1]}-${e[2]}-${e[3]}T${e[4]}:${e[5]}:${e[6]}`}s(ne,"compactToIso");function b(t){const e=B(t);let r;try{r=E(e).filter(i=>i.endsWith(".md"))}catch{r=[]}const n=[];for(const i of r){const o=I(e,i),u=A(o,"utf8"),{data:l,body:p}=W(u),a=i.match(/^([0-9]{8}T[0-9]{6})-(\w+)\.md$/),m=(typeof l?.kind=="string"?l.kind:void 0)??(a?a[2]:"update"),w=(typeof l?.ts=="string"?l.ts:void 0)??(a?ne(a[1]):new Date(C(o).mtimeMs).toISOString());n.push({path:o,tier:m,body:p.trim(),created:w})}return n.sort((i,o)=>i.created<o.created?1:i.created>o.created?-1:0),n}s(b,"reportsForNode");function ie(t){const e=t.params.id;g(e);const r=t.query.get("tier"),n=t.query.get("limit"),i=n!==null?Number(n):void 0;let o=b(e);return r!==null&&(o=o.filter(u=>u.tier===r)),i!==void 0&&Number.isFinite(i)&&i>=0&&(o=o.slice(0,i)),{status:200,body:o}}s(ie,"handleList");const _e=[{method:"POST",pattern:"/v1/nodes/:id/reports",handler:Y},{method:"GET",pattern:"/v1/nodes/:id/reports",handler:ie},{method:"POST",pattern:"/v1/nodes/:id/result",handler:re}];export{_e as reportRoutes,b as reportsForNode};
|
|
16
|
+
`}s(ee,"declineReportBody");const T=1024,N=64;function te(t){if(typeof t!="object"||t===null)throw c("a result submission requires a JSON body { value } or { decline, code, retryable }");const e=Object.hasOwn(t,"value"),r=Object.hasOwn(t,"decline");if(e&&r)throw c("a result submission carries either { value } or { decline, code, retryable }, not both");if(r){const{decline:n,code:i,retryable:o}=t;if(typeof n!="string"||n.trim()==="")throw new d({error:"missing_decline_reason",message:"A decline needs a reason.",next:'Rerun with `--decline "<one sentence on why the schema cannot be honestly satisfied>" --code <token>`.'});if(n.length>T)throw new d({error:"decline_reason_too_long",message:`A decline reason is at most ${T} characters (got ${n.length}).`,next:"Keep the reason to one plain sentence; put any detail in an artifact and name its path."});if(typeof i!="string"||i.trim()===""||/\s/.test(i.trim())||i.trim().length>N)throw new d({error:"invalid_decline_code",message:`A decline needs a code: one whitespace-free token of at most ${N} characters naming the decline class.`,next:"Rerun with `--code <token>` \u2014 the token your requester documented for this case."});if(typeof o!="boolean")throw c("a decline carries `retryable` as a boolean");return{declined:{reason:n.trim(),code:i.trim(),retryable:o}}}if(!e)throw c("a result submission requires a JSON body { value } or { decline, code, retryable }");return{value:t.value}}s(te,"parseSubmitBody");async function re(t){const e=t.params.id;g(e);const r=te(t.body),n=k(e);if(n.state==="absent")throw new d({error:"no_output_request",message:"No structured output is currently requested of this node.",next:"Nothing to submit here \u2014 continue working, or finish with `crtr push final`."});if(n.state==="invalid")throw new d({error:"invalid_output_request",message:`The structured-output request file is invalid: ${n.error}`,next:`Have the requester re-issue the request, or remove ${G(e)} and finish with \`crtr push final\`.`});const{mode:i,schema:o}=n.request;let u;if("value"in r)try{u=await K(o,r.value)}catch(h){throw new d({error:"result_schema_mismatch",message:`the submitted result does not match the requested schema: ${h.message}`,next:'Fix the listed fields and rerun `crtr push result`; if the schema cannot be honestly satisfied, rerun with `--decline "<reason>" --code <token>`.'})}const l=i==="terminal"?f(e)?.status:void 0,p=i==="terminal"?await $(e):void 0;let a,m,w;if("declined"in r){const{declined:h}=r;if(a=V(e,{mode:i,...h,at:new Date().toISOString()}),m=ee(a,h),i==="terminal"){const x={schema:"crtr.node-outcome-detail/v1",message:h.reason,declined:h};w={kind:"failure",reason:"declined",detailJson:JSON.stringify(x)}}}else a=Q(e,u),m=Z(a,u);const y=await q(e,{tier:i==="terminal"?"final":"update",body:m},w);X(e);const _=i==="terminal"&&l!==void 0?{from:l,to:f(e)?.status??"done"}:void 0,v=b(e).find(h=>h.path===y.reportPath);return v!==void 0&&O.report(e,v),{status:200,body:{mode:i,result_path:a,report_path:y.reportPath,notified:[...y.deliveredTo],..."declined"in r?{declined:r.declined}:{},..._===void 0?{}:{transitioned:_},...p===void 0?{}:{worktree_auto_dropped:!0,worktree_auto_dropped_path:p}}}}s(re,"handleSubmitResult");async function q(t,e,r){try{return await F(t,{kind:e.tier,body:e.body,...e.delivery_tier===void 0?{}:{deliveryTier:e.delivery_tier},...r===void 0?{}:{outcome:r}})}catch(n){throw n instanceof S&&n.code==="already_finalized"?new d({error:"already_finalized",message:"This node already submitted its canonical final result.",next:"Push an update with the new information, then stop."}):n instanceof S&&n.code==="finalization_forbidden"?new d({error:"finalization_forbidden",message:"A canceled or dead node cannot submit a canonical final result.",next:"Do not push final from this node."}):n}}s(q,"pushOrRethrow");function ne(t){const e=t.match(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})$/);return e===null?t:`${e[1]}-${e[2]}-${e[3]}T${e[4]}:${e[5]}:${e[6]}`}s(ne,"compactToIso");function b(t){const e=B(t);let r;try{r=E(e).filter(i=>i.endsWith(".md"))}catch{r=[]}const n=[];for(const i of r){const o=I(e,i),u=A(o,"utf8"),{data:l,body:p}=W(u),a=i.match(/^([0-9]{8}T[0-9]{6})-(\w+)\.md$/),m=(typeof l?.kind=="string"?l.kind:void 0)??(a?a[2]:"update"),w=(typeof l?.ts=="string"?l.ts:void 0)??(a?ne(a[1]):new Date(C(o).mtimeMs).toISOString());n.push({path:o,tier:m,body:p.trim(),created:w})}return n.sort((i,o)=>i.created<o.created?1:i.created>o.created?-1:0),n}s(b,"reportsForNode");function ie(t){const e=t.params.id;g(e);const r=t.query.get("tier"),n=t.query.get("limit"),i=n!==null?Number(n):void 0;let o=b(e);return r!==null&&(o=o.filter(u=>u.tier===r)),i!==void 0&&Number.isFinite(i)&&i>=0&&(o=o.slice(0,i)),{status:200,body:o}}s(ie,"handleList");const _e=[{method:"POST",pattern:"/v1/nodes/:id/reports",ownerOnly:!0,handler:Y},{method:"GET",pattern:"/v1/nodes/:id/reports",handler:ie},{method:"POST",pattern:"/v1/nodes/:id/result",handler:re}];export{_e as reportRoutes,b as reportsForNode};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var _=Object.defineProperty;var d=(n,e)=>_(n,"name",{value:e,configurable:!0});import{isSafeNodeId as f}from"../../../core/canvas/paths.js";import{getNode as y}from"../../../core/canvas/canvas.js";import{assertScope as g}from"../../../core/scopes.js";import{createReview as
|
|
1
|
+
var _=Object.defineProperty;var d=(n,e)=>_(n,"name",{value:e,configurable:!0});import{isSafeNodeId as f}from"../../../core/canvas/paths.js";import{getNode as y}from"../../../core/canvas/canvas.js";import{assertScope as g}from"../../../core/scopes.js";import{createReview as k}from"../../../core/review/birth.js";import{readAnchorBase as R,listReviews as q,requireVisibleReview as w}from"../../../core/review/store.js";import{cancelReview as S,submitReviewApproval as E}from"../../review/finish.js";import{toFeedbackResultDTO as T,toReviewDTO as I}from"../map.js";import{invalidRequest as C,objectBody as v,optionalString as l,requireParam as D,requiredString as h}from"./validate.js";const A=new Set(["open","approved","canceled"]),O=["origin_kind","origin_node_id","file","idempotency_key","subtitle","output_path"],L=["reason","actor","disposition"];function a(n){C("review request",n)}d(a,"invalidRequest");function p(n,e){return D(n,"review_id","must be a safe review id",f,e)}d(p,"requireReviewId");function c(n){return{...I(n,n.state==="approved"?{result_path:`${n.review_dir}/result.json`}:{}),review_dir:n.review_dir}}d(c,"toReviewResponseDTO");function P(n){const e=[],i=v(n.body,O,e),o=i.origin_kind,t=o==="ticket"||o==="inline"?o:void 0;t===void 0&&e.push({field:"origin_kind",problem:"must be ticket or inline",...o===void 0?{}:{received:o}});const r=h(i,"origin_node_id",e);r!==void 0&&!f(r)&&e.push({field:"origin_node_id",problem:"must be a safe node id",received:r});const s=h(i,"file",e),u=h(i,"idempotency_key",e);u!==void 0&&u.length>128&&e.push({field:"idempotency_key",problem:"must be at most 128 characters",received:u});const m=l(i,"subtitle",e),b=l(i,"output_path",e);return t==="ticket"&&m===void 0&&i.subtitle===void 0&&e.push({field:"subtitle",problem:"is required for ticket reviews"}),t==="inline"&&i.subtitle!==void 0&&e.push({field:"subtitle",problem:"is only allowed for ticket reviews",received:i.subtitle}),t==="inline"&&i.output_path!==void 0&&e.push({field:"output_path",problem:"is only allowed for ticket reviews",received:i.output_path}),(e.length>0||t===void 0||r===void 0||!f(r)||s===void 0||u===void 0||u.length>128)&&a(e),{origin_kind:t,origin_node_id:r,file:s,idempotency_key:u,...m===void 0?{}:{subtitle:m},...b===void 0?{}:{output_path:b}}}d(P,"parseCreate");function j(n){const e=[],i={},o=new Set(["state","origin_node_id","file"]);for(const[t,r]of n.query.entries())o.has(t)||e.push({field:t,problem:"is not allowed",received:r});for(const t of o){const r=n.query.getAll(t);if(r.length>1){e.push({field:t,problem:"must appear at most once",received:r});continue}const s=r[0];s!==void 0&&(t==="state"?A.has(s)?i.state=s:e.push({field:t,problem:"must be open, approved, or canceled",received:s}):t==="origin_node_id"?f(s)?i.origin_node_id=s:e.push({field:t,problem:"must be a safe node id",received:s}):s===""?e.push({field:t,problem:"must be a non-empty string",received:s}):i.file=s)}return e.length>0&&a(e),i}d(j,"parseList");function B(n,e){const i=n.body===void 0?{}:v(n.body,L,e),o=l(i,"reason",e),t=l(i,"actor",e),r=l(i,"disposition",e);return r!==void 0&&r!=="canceled"&&r!=="dismissed"&&e.push({field:"disposition",problem:'must be "canceled" or "dismissed"',received:r}),{...o===void 0?{}:{reason:o},...t===void 0?{}:{actor:t},...r==="canceled"||r==="dismissed"?{disposition:r}:{}}}d(B,"parseCancel");function F(n,e){v(n.body,[],e)}d(F,"requireEmptyBody");async function G(n){const e=P(n),i=y(e.origin_node_id);i!==null&&g(i,"ask");const o=await k(e);return{status:200,body:c(o)}}d(G,"handleCreate");function N(n){const e=j(n);return{status:200,body:{reviews:q(e).map(c)}}}d(N,"handleList");function V(n){const e=[],i=p(n,e);return(e.length>0||i===void 0)&&a(e),{status:200,body:c(w(i))}}d(V,"handleRead");async function $(n){const e=[],i=p(n,e);F(n,e),(e.length>0||i===void 0)&&a(e);const o=await E(i);return{status:200,body:o.outcome==="awaiting_companion"?{review:c(o.record),outcome:o.outcome}:{review:c(o.record),result:T(o.result),outcome:o.outcome}}}d($,"handleSubmit");async function K(n){const e=[],i=p(n,e),o=B(n,e);(e.length>0||i===void 0)&&a(e);const t=await S(i,o);return{status:200,body:{review:c(t.record),outcome:t.outcome}}}d(K,"handleCancel");function W(n){const e=[],i=p(n,e);(e.length>0||i===void 0)&&a(e);const o=w(i),t=R(o.review_id);if(t===null)throw new Error(`review anchor base is missing: ${o.review_id}`);return{status:200,body:{review_id:o.review_id,anchor_base_sha256:t.sha256,anchor_base_text:new TextDecoder("utf-8",{fatal:!0}).decode(t.bytes),file:o.file}}}d(W,"handleDocument");const x=[{method:"POST",pattern:"/v1/human/reviews",scope:"ask",handler:G},{method:"GET",pattern:"/v1/human/reviews",handler:N},{method:"GET",pattern:"/v1/human/reviews/:review_id",handler:V},{method:"POST",pattern:"/v1/human/reviews/:review_id/submit",handler:$},{method:"POST",pattern:"/v1/human/reviews/:review_id/cancel",handler:K},{method:"GET",pattern:"/v1/human/reviews/:review_id/document",handler:W}];export{x as reviewRoutes};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type RouteTable } from '../router.js';
|
|
2
2
|
export declare const worktreeRoutes: RouteTable;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var o=Object.defineProperty;var t=(e,n)=>o(e,"name",{value:n,configurable:!0});import{closeManagedWorktreeAsync as a}from"../../../core/worktree-close.js";import{abandonManagedWorktreeAsync as d}from"../../../core/worktree-mutation-async.js";import{listQuarantinedManagedWorktrees as i}from"../../../core/worktree-quarantine.js";import{usage as s}from"../../../core/errors.js";async function y(e){const n=e.params.id;return{status:200,body:await a(n)}}t(y,"handleWorktreeClose");async function
|
|
1
|
+
var o=Object.defineProperty;var t=(e,n)=>o(e,"name",{value:n,configurable:!0});import{closeManagedWorktreeAsync as a}from"../../../core/worktree-close.js";import{abandonManagedWorktreeAsync as d}from"../../../core/worktree-mutation-async.js";import{listQuarantinedManagedWorktrees as i}from"../../../core/worktree-quarantine.js";import{usage as s}from"../../../core/errors.js";import{ownerOnly as m}from"../router.js";async function y(e){const n=e.params.id;return{status:200,body:await a(n)}}t(y,"handleWorktreeClose");async function u(e){const n=e.body?.by,r=typeof n=="string"?n.trim():"";if(r==="")throw s("abandon requires a non-empty invoking identity",{received:e.body,next:"Pass the invoking node id or human identity."});return{status:200,body:await d(e.params.id,r)}}t(u,"handleWorktreeAbandon");async function c(){return{status:200,body:await i()}}t(c,"handleQuarantinedWorktrees");const w=m([{method:"POST",pattern:"/v1/nodes/:id/worktree/close",handler:y},{method:"POST",pattern:"/v1/nodes/:id/worktree/abandon",handler:u},{method:"GET",pattern:"/v1/worktrees/quarantined",handler:c}]);export{w as worktreeRoutes};
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import { ApiError } from '../../api/errors.js';
|
|
3
|
+
/** What the caller's bearer token may reach: `null` is the owner (every scope,
|
|
4
|
+
* every route); a list is the ceiling minted by `crtr sys connect --scopes`. */
|
|
5
|
+
export type Ceiling = readonly string[] | null;
|
|
6
|
+
/** Throw the 403 `scope_denied` a scoped bearer earns when its ceiling lacks
|
|
7
|
+
* `scope`. The owner (`null`) always passes. */
|
|
8
|
+
export declare function assertCeiling(ceiling: Ceiling, scope: string): void;
|
|
9
|
+
/** The 403 `owner_only` a scoped bearer earns on a route no ceiling reaches. */
|
|
10
|
+
export declare function ownerOnlyError(): ApiError;
|
|
2
11
|
/** The request view a handler receives: the resolved route params, parsed
|
|
3
12
|
* query, parsed JSON body, and the raw req/res for the rare handler that needs
|
|
4
13
|
* them (streaming, headers). Everything a handler mutates it does through the
|
|
@@ -14,6 +23,8 @@ export interface RequestContext {
|
|
|
14
23
|
query: URLSearchParams;
|
|
15
24
|
/** Parsed JSON request body, or `undefined` when there was no body. */
|
|
16
25
|
body: unknown;
|
|
26
|
+
/** The caller's scope ceiling — `null` for the owner token or the unix socket. */
|
|
27
|
+
ceiling: Ceiling;
|
|
17
28
|
req: IncomingMessage;
|
|
18
29
|
res: ServerResponse;
|
|
19
30
|
}
|
|
@@ -36,10 +47,16 @@ export interface RouteDef {
|
|
|
36
47
|
method: string;
|
|
37
48
|
pattern: string;
|
|
38
49
|
handler: RouteHandler;
|
|
50
|
+
/** A scoped bearer token never reaches this route (403 `owner_only`). */
|
|
51
|
+
ownerOnly?: true;
|
|
52
|
+
/** The scope the caller's ceiling must hold (403 `scope_denied` otherwise). */
|
|
53
|
+
scope?: string;
|
|
39
54
|
}
|
|
40
55
|
/** The flat route table the handler authors (A-7) build up and hand to the
|
|
41
56
|
* server (A-9). */
|
|
42
57
|
export type RouteTable = RouteDef[];
|
|
58
|
+
/** Mark every route in `table` owner-only. */
|
|
59
|
+
export declare function ownerOnly(table: RouteTable): RouteTable;
|
|
43
60
|
export declare class Router {
|
|
44
61
|
private readonly routes;
|
|
45
62
|
/** Register one route. Returns `this` for chaining. */
|
|
@@ -51,10 +68,12 @@ export declare class Router {
|
|
|
51
68
|
match(method: string, path: string): {
|
|
52
69
|
handler: RouteHandler;
|
|
53
70
|
params: Record<string, string>;
|
|
71
|
+
ownerOnly: boolean;
|
|
72
|
+
scope: string | undefined;
|
|
54
73
|
} | null;
|
|
55
74
|
/** Resolve the JSON body, dispatch to the matched handler, and write the
|
|
56
75
|
* response. Every failure path — no route, bad JSON, a handler throw — is
|
|
57
76
|
* turned into a JSON `ErrorBody` (map.ts §8); this method never throws and
|
|
58
77
|
* never leaves the daemon crashed. */
|
|
59
|
-
handle(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
78
|
+
handle(req: IncomingMessage, res: ServerResponse, ceiling: Ceiling): Promise<void>;
|
|
60
79
|
}
|