agentix-cli 0.111.0 → 0.111.1
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/{board-dashboard-3TVUCOSI.js → board-dashboard-MZVUQ2YO.js} +2 -2
- package/dist/{board-dashboard-3TVUCOSI.js.map → board-dashboard-MZVUQ2YO.js.map} +1 -1
- package/dist/{chunk-DUBCOGQB.js → chunk-3RHFEKFX.js} +2 -2
- package/dist/{chunk-DUBCOGQB.js.map → chunk-3RHFEKFX.js.map} +1 -1
- package/dist/chunk-3RTOS727.js +482 -0
- package/dist/chunk-3RTOS727.js.map +1 -0
- package/dist/chunk-JIT5GPTX.js +4 -0
- package/dist/chunk-JIT5GPTX.js.map +1 -0
- package/dist/{chunk-KDD6FPQ6.js → chunk-K24MYJFP.js} +6 -6
- package/dist/{chunk-KDD6FPQ6.js.map → chunk-K24MYJFP.js.map} +1 -1
- package/dist/chunk-QLWGLRT5.js +3 -0
- package/dist/chunk-QLWGLRT5.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/{grants-M4K6WXOO.js → grants-BRAVOGBP.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{program-EZLJIVQX.js → program-YK3YR2CQ.js} +5 -5
- package/package.json +1 -1
- package/dist/chunk-RXLU6HJ6.js +0 -4
- package/dist/chunk-RXLU6HJ6.js.map +0 -1
- package/dist/chunk-WYSNRZV4.js +0 -482
- package/dist/chunk-WYSNRZV4.js.map +0 -1
- package/dist/chunk-XF26QNAW.js +0 -3
- package/dist/chunk-XF26QNAW.js.map +0 -1
- /package/dist/{grants-M4K6WXOO.js.map → grants-BRAVOGBP.js.map} +0 -0
- /package/dist/{program-EZLJIVQX.js.map → program-YK3YR2CQ.js.map} +0 -0
package/dist/chunk-XF26QNAW.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{e as A,g as x,p as G}from"./chunk-RXLU6HJ6.js";import{a as w,e as b}from"./chunk-2QNT5JDS.js";b();var h="guest:",P="guests",_=7,y=365,T=400;function $(e){let t=e.scopes.find(n=>n.startsWith(h));return t?t.slice(h.length):null}function R(e){return`g-${e.toString(36)}-${Math.random().toString(36).slice(2,6)}`}var l=e=>(Array.isArray(e)?e:typeof e=="string"?e.split(","):[]).map(t=>String(t).trim()).filter(Boolean).slice(0,50);function Y(e,t){let n=(e.now??Date.now)(),r=String(t.name??"").trim().slice(0,120),s=String(t.guest??"").trim().slice(0,80);if(!r)return{ok:!1,error:'name is required: what you call this grant, e.g. "Support session for company X"'};if(!s)return{ok:!1,error:"guest is required: the other organisation's name"};if(!t.agentId||!e.hasAgent(t.agentId))return{ok:!1,error:`agent must be an agent on this node, got "${t.agentId??""}"`};let a=w.safeParse(t.level??"propose");if(!a.success)return{ok:!1,error:"level must be report, propose or act"};let o=t.days===void 0?_:Number(t.days);if(!Number.isFinite(o)||o<1||o>y)return{ok:!1,error:`days must be between 1 and ${y}`};let d=R(n),{token:u,record:g}=e.tokens.create({name:`guest ${s} (${r})`,scopes:[`${h}${d}`],expiresInDays:Math.ceil(o)}),{code:i,expiresAt:p}=e.codes.create({token:u,tokenId:g.id,name:d}),c={id:d,name:r,guest:s,agentId:t.agentId,folders:l(t.folders),skills:l(t.skills),commands:l(t.commands),level:a.data,state:"pending",tokenId:g.id,createdAt:new Date(n).toISOString(),expiresAt:new Date(n+o*864e5).toISOString(),usage:{turns:0,tokens:0}};return e.guests.add(c),e.guests.log({grant:d,event:"invited",detail:`${s}: ${r}`}),{ok:!0,code:i,codeExpiresAt:p,grant:c}}var J="That code didn't work. Ask the host for a new one.";async function q(e,t,n){let r=Date.now(),s=n.now??Date.now,a=n.log??(f=>console.log(f)),o=n.limiter.retryAfter(t);if(o>0)return a(`[guests] join refused from ${t}: locked out for ${o}s more`),{status:429,body:{error:"too many attempts",retryAfter:o},retryAfter:o};let d=n.codes.redeem(e.code),u=d?n.tokens.verify(d.token):null,g=u?$(u):null,i=g?n.guests.get(g):null;if(await L(r,n.minMs??T),!d||!u||!i||i.tokenId!==u.id||i.state==="ended")return n.limiter.fail(t),a(`[guests] join failed from ${t}`),{status:401,body:{error:G}};n.limiter.succeed(t);let p=e.node&&typeof e.node=="object"?e.node:{},c=(f,S)=>typeof f=="string"&&f.trim()?f.replace(/\s+/g," ").trim().slice(0,S):void 0,m={id:c(p.id,80),name:c(p.name,80),address:t},D=i.expiresAt.slice(0,10),k=x(n.root,{title:`Guest mesh: ${i.guest} wants to join`,ask:`Let "${m.name??m.id??"a node"}" at ${t} use ${i.agentId} inside "${i.name}" (${i.level}, until ${D})?`,recommend:`Yes if ${i.guest} told you they are joining now. No if you did not expect it.`,if_silent:"discard",raised_by:P},{now:s()});return k.ok?(n.guests.update(i.id,{guestNode:m,cardId:k.card.id}),n.guests.log({grant:i.id,event:"joined",address:t,detail:m.name??m.id}),a(`[guests] ${i.id}: ${i.guest} joined from ${t}; waiting for the owner (card ${k.card.id})`),{status:200,body:{grant:i.id,name:i.name,agentId:i.agentId,level:i.level,expiresAt:i.expiresAt,state:"pending"},token:d.token}):(a(`[guests] ${i.id}: join from ${t} could not raise a card: ${k.error}`),{status:403,body:{error:"The host cannot take a join right now. Try again later."}})}var v="no grant opens this",j="waiting for the host to approve the join",O="the host paused this grant";function N(e,t){let n=e.now??Date.now,r=e.log??(o=>console.log(o));if(t.state==="ended")return t;if(Date.parse(t.expiresAt)<=n())return r(`[guests] ${t.id}: expired`),I({tokens:e.tokens,guests:e.guests,now:n},t.id,"expired")??t;if(t.state!=="pending")return t;let s=t.cardId?A(e.root,t.cardId):null,a=s?s.status==="decided"?s.verdict:s.status==="expired"?"no":null:null;if(a==="yes"){let o=e.guests.update(t.id,{state:"active",approvedAt:new Date(n()).toISOString()})??t;return e.guests.log({grant:t.id,event:"approved",detail:s?.decided_by}),r(`[guests] ${t.id}: join approved`),o}if(a==="no"){let o=s?.status==="expired"?"the host did not answer in time":"the host said no",d=I({tokens:e.tokens,guests:e.guests,now:n},t.id,o)??t;return e.guests.log({grant:t.id,event:"refused",detail:o}),r(`[guests] ${t.id}: join refused: ${o}`),d}return t}function B(e,t){let n=e?t.tokens.verify(e):null,r=n?$(n):null,s=r?t.guests.get(r):null;if(!n||!s||s.tokenId!==n.id)return{ok:!1,status:401,error:v};let a=N(t,s);return a.state==="ended"?{ok:!1,status:401,error:v}:a.state==="pending"?{ok:!1,status:403,error:j,waiting:!0}:a.state==="paused"?{ok:!1,status:403,error:O,paused:!0}:{ok:!0,grant:a}}function C(e){let t=(r,s)=>r.length?r.join(", "):`none named: do not touch ${s} unless the owner's own instructions already allow it for this work`,n=e.level==="report"?"report: read and answer only; change nothing":e.level==="propose"?"propose: you may prepare changes and open a merge request or draft; never merge, deploy or delete":"act: you may act inside the grant without asking";return[`[Guest mesh] You are working for a guest organisation, "${e.guest}", under the grant "${e.name}" that the owner of this node opened.`,`Stay inside it. Folders: ${t(e.folders,"files")}. Skills: ${t(e.skills,"skills")}. Commands: ${t(e.commands,"commands")}. Freedom: ${n}. The grant ends on ${e.expiresAt.slice(0,10)}.`,"Anything outside the grant: say it is not covered and stop. The guest sees only your answers: never reveal other chats, agents, people or files of this node."].join(`
|
|
2
|
-
`)}function U(e,t){return{agentId:e.agentId,message:t,context:{channel:"guest",chatId:`guest:${e.id}`,sender:`guest:${e.guest}`},systemPromptAppend:C(e),...e.level==="act"?{}:{autonomy:e.level}}}function X(e,t){let n=e.guests.get(t);if(!n||n.state!=="active")return null;let r=e.guests.update(t,{state:"paused",pausedAt:new Date((e.now??Date.now)()).toISOString()});return e.guests.log({grant:t,event:"paused"}),r}function W(e,t){let n=e.guests.get(t);if(!n||n.state!=="paused")return null;let r=e.guests.update(t,{state:"active",pausedAt:void 0});return e.guests.log({grant:t,event:"resumed"}),r}function I(e,t,n="ended by the host"){let r=e.guests.get(t);if(!r||r.state==="ended")return null;e.tokens.revoke(r.tokenId);let s=e.guests.update(t,{state:"ended",endedAt:new Date((e.now??Date.now)()).toISOString(),endedReason:n});return e.guests.log({grant:t,event:n==="expired"?"expired":"ended",detail:n}),s}function H(e,t,n){let r=e.guests.get(t);if(!r||r.state==="ended")return{ok:!1,error:`no open grant "${t}"`};let s={};if(n.folders!==void 0&&(s.folders=l(n.folders)),n.skills!==void 0&&(s.skills=l(n.skills)),n.commands!==void 0&&(s.commands=l(n.commands)),n.level!==void 0){let u=w.safeParse(n.level);if(!u.success)return{ok:!1,error:"level must be report, propose or act"};s.level=u.data}if(n.days!==void 0){let u=Number(n.days);if(!Number.isFinite(u)||u<1||u>y)return{ok:!1,error:`days must be between 1 and ${y}`};s.expiresAt=new Date((e.now??Date.now)()+u*864e5).toISOString()}let a=e.guests.update(t,s),o=["report","propose","act"],d=s.level&&o.indexOf(s.level)>o.indexOf(r.level)||s.folders&&s.folders.length>r.folders.length||s.skills&&s.skills.length>r.skills.length||s.commands&&s.commands.length>r.commands.length||s.expiresAt&&s.expiresAt>r.expiresAt;return e.guests.log({grant:t,event:d?"widened":"narrowed",detail:Object.keys(s).join(", ")}),{ok:!0,grant:a}}function z(e){return{grant:e.id,name:e.name,agentId:e.agentId,level:e.level,folders:e.folders,skills:e.skills,commands:e.commands,state:e.state,expiresAt:e.expiresAt,usage:e.usage}}async function L(e,t){let n=e+t-Date.now();n>0&&await new Promise(r=>setTimeout(r,n))}export{h as a,P as b,_ as c,y as d,$ as e,R as f,Y as g,J as h,q as i,v as j,j as k,O as l,N as m,B as n,C as o,U as p,X as q,W as r,I as s,H as t,z as u};
|
|
3
|
-
//# sourceMappingURL=chunk-XF26QNAW.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/guests/grants.ts"],"sourcesContent":["import { TokenStore, type TokenRecord } from \"@/daemon/token-store\"\nimport { PairCodeStore } from \"@/daemon/pair-codes\"\nimport { PAIR_CODE_FAILED, type PairAttemptLimiter } from \"@/daemon/app-pair-code\"\nimport { createCard, readCard } from \"@/approvals/cards\"\nimport { autonomyLevelSchema, type AutonomyLevel } from \"@/guard/autonomy\"\nimport { GuestStore, type GuestGrant } from \"./store\"\n\n// --- Opening part of a mesh to a guest, and keeping it in hand (#380) ---\n//\n// Two roles. The host opens a grant: one of its agents, named folders,\n// skills and commands, a freedom level and an end date. The guest is the\n// other organisation's mesh. Access goes one way per grant.\n//\n// The guest asks, the host's agent acts. The guest never gets a shell or\n// a session on the host's machine: its messages run as turns of the host\n// agent, under the host's rules and in the host's log, with the routine\n// autonomy levels of #80 enforced on the run (report: read-only;\n// propose: no merge, deploy or delete; act: inside the grant, no question\n// asked). What the grant names is put in front of the agent on every turn.\n//\n// Joining is a one-time code, like phone pairing; the join arrives as a\n// decision card in the host's Approvals inbox. No yes, no join. The host\n// can pause, widen, narrow or end the grant while it is in use.\n\nexport const GUEST_SCOPE_PREFIX = \"guest:\"\n/** Who the join card is raised by: not an agent, so no agent is told the\n * verdict; the guest routes read it instead. */\nexport const JOIN_CARD_BY = \"guests\"\nexport const DEFAULT_GRANT_DAYS = 7\nexport const MAX_GRANT_DAYS = 365\nconst MIN_MS = 400\n\nexport interface GrantInput {\n name: string\n guest: string\n agentId: string\n folders?: string[]\n skills?: string[]\n commands?: string[]\n level?: string\n days?: number\n}\n\nexport interface GuestDeps {\n tokens: TokenStore\n codes: PairCodeStore\n guests: GuestStore\n hasAgent: (agentId: string) => boolean\n /** The install folder: where decision cards live. */\n root: string\n limiter: PairAttemptLimiter\n now?: () => number\n minMs?: number\n log?: (line: string) => void\n}\n\nexport function grantIdOf(rec: TokenRecord): string | null {\n const scope = rec.scopes.find((s) => s.startsWith(GUEST_SCOPE_PREFIX))\n return scope ? scope.slice(GUEST_SCOPE_PREFIX.length) : null\n}\n\nexport function newGrantId(now: number): string {\n return `g-${now.toString(36)}-${Math.random().toString(36).slice(2, 6)}`\n}\n\nconst list = (v: unknown): string[] =>\n (Array.isArray(v) ? v : typeof v === \"string\" ? v.split(\",\") : []).map((s) => String(s).trim()).filter(Boolean).slice(0, 50)\n\nexport type InviteResult =\n | { ok: true; code: string; codeExpiresAt: string; grant: GuestGrant }\n | { ok: false; error: string }\n\n/** Open a grant and mint the one-time code the guest joins with. */\nexport function inviteGuest(deps: Pick<GuestDeps, \"tokens\" | \"codes\" | \"guests\" | \"hasAgent\" | \"now\">, input: GrantInput): InviteResult {\n const now = (deps.now ?? Date.now)()\n const name = String(input.name ?? \"\").trim().slice(0, 120)\n const guest = String(input.guest ?? \"\").trim().slice(0, 80)\n if (!name) return { ok: false, error: \"name is required: what you call this grant, e.g. \\\"Support session for company X\\\"\" }\n if (!guest) return { ok: false, error: \"guest is required: the other organisation's name\" }\n if (!input.agentId || !deps.hasAgent(input.agentId)) return { ok: false, error: `agent must be an agent on this node, got \"${input.agentId ?? \"\"}\"` }\n const level = autonomyLevelSchema.safeParse(input.level ?? \"propose\")\n if (!level.success) return { ok: false, error: \"level must be report, propose or act\" }\n const days = input.days === undefined ? DEFAULT_GRANT_DAYS : Number(input.days)\n if (!Number.isFinite(days) || days < 1 || days > MAX_GRANT_DAYS) return { ok: false, error: `days must be between 1 and ${MAX_GRANT_DAYS}` }\n const id = newGrantId(now)\n const { token, record } = deps.tokens.create({ name: `guest ${guest} (${name})`, scopes: [`${GUEST_SCOPE_PREFIX}${id}`], expiresInDays: Math.ceil(days) })\n const { code, expiresAt: codeExpiresAt } = deps.codes.create({ token, tokenId: record.id, name: id })\n const grant: GuestGrant = {\n id, name, guest, agentId: input.agentId,\n folders: list(input.folders), skills: list(input.skills), commands: list(input.commands),\n level: level.data, state: \"pending\", tokenId: record.id,\n createdAt: new Date(now).toISOString(), expiresAt: new Date(now + days * 86_400_000).toISOString(),\n usage: { turns: 0, tokens: 0 },\n }\n deps.guests.add(grant)\n deps.guests.log({ grant: id, event: \"invited\", detail: `${guest}: ${name}` })\n return { ok: true, code, codeExpiresAt, grant }\n}\n\nexport type JoinResult =\n | { status: 200; body: { grant: string; name: string; agentId: string; level: AutonomyLevel; expiresAt: string; state: \"pending\" }; token: string }\n | { status: 401 | 403; body: { error: string } }\n | { status: 429; body: { error: string; retryAfter: number }; retryAfter: number }\n\nexport const JOIN_FAILED = \"That code didn't work. Ask the host for a new one.\"\n\n/** POST /mesh/guest/join: the guest trades the code for its key and asks\n * the host to approve the join. */\nexport async function joinGuest(\n body: Record<string, unknown>,\n client: string,\n deps: GuestDeps,\n): Promise<JoinResult> {\n const started = Date.now()\n const now = deps.now ?? Date.now\n const log = deps.log ?? ((line: string) => console.log(line))\n const wait = deps.limiter.retryAfter(client)\n if (wait > 0) {\n log(`[guests] join refused from ${client}: locked out for ${wait}s more`)\n return { status: 429, body: { error: \"too many attempts\", retryAfter: wait }, retryAfter: wait }\n }\n const redeemed = deps.codes.redeem(body.code)\n const rec = redeemed ? deps.tokens.verify(redeemed.token) : null\n const grantId = rec ? grantIdOf(rec) : null\n const grant = grantId ? deps.guests.get(grantId) : null\n await padTo(started, deps.minMs ?? MIN_MS)\n if (!redeemed || !rec || !grant || grant.tokenId !== rec.id || grant.state === \"ended\") {\n deps.limiter.fail(client)\n log(`[guests] join failed from ${client}`)\n return { status: 401, body: { error: PAIR_CODE_FAILED } }\n }\n deps.limiter.succeed(client)\n const node = (body.node && typeof body.node === \"object\" ? body.node : {}) as Record<string, unknown>\n const str = (v: unknown, n: number) => (typeof v === \"string\" && v.trim() ? v.replace(/\\s+/g, \" \").trim().slice(0, n) : undefined)\n const guestNode = { id: str(node.id, 80), name: str(node.name, 80), address: client }\n const until = grant.expiresAt.slice(0, 10)\n const card = createCard(deps.root, {\n title: `Guest mesh: ${grant.guest} wants to join`,\n ask: `Let \"${guestNode.name ?? guestNode.id ?? \"a node\"}\" at ${client} use ${grant.agentId} inside \"${grant.name}\" (${grant.level}, until ${until})?`,\n recommend: `Yes if ${grant.guest} told you they are joining now. No if you did not expect it.`,\n if_silent: \"discard\",\n raised_by: JOIN_CARD_BY,\n }, { now: now() })\n if (!card.ok) {\n log(`[guests] ${grant.id}: join from ${client} could not raise a card: ${card.error}`)\n return { status: 403, body: { error: \"The host cannot take a join right now. Try again later.\" } }\n }\n deps.guests.update(grant.id, { guestNode, cardId: card.card.id })\n deps.guests.log({ grant: grant.id, event: \"joined\", address: client, detail: guestNode.name ?? guestNode.id })\n log(`[guests] ${grant.id}: ${grant.guest} joined from ${client}; waiting for the owner (card ${card.card.id})`)\n return {\n status: 200,\n body: { grant: grant.id, name: grant.name, agentId: grant.agentId, level: grant.level, expiresAt: grant.expiresAt, state: \"pending\" },\n token: redeemed.token,\n }\n}\n\nexport type AccessResult =\n | { ok: true; grant: GuestGrant }\n | { ok: false; status: 401; error: string }\n | { ok: false; status: 403; error: string; waiting?: true; paused?: true }\n\nexport const NO_GRANT = \"no grant opens this\"\nexport const WAITING_HOST = \"waiting for the host to approve the join\"\nexport const PAUSED = \"the host paused this grant\"\n\ntype SettleDeps = Pick<GuestDeps, \"tokens\" | \"guests\" | \"root\" | \"now\" | \"log\">\n\n/** Applies what time and the host's card say: an expired grant ends, a\n * decided join card activates or ends the grant. Returns the grant as it\n * stands now. Both sides call this: the guest on every request, the host\n * before listing or acting, so a yes on the card counts at once. */\nexport function settleGrant(deps: SettleDeps, grant: GuestGrant): GuestGrant {\n const now = deps.now ?? Date.now\n const log = deps.log ?? ((line: string) => console.log(line))\n if (grant.state === \"ended\") return grant\n if (Date.parse(grant.expiresAt) <= now()) {\n log(`[guests] ${grant.id}: expired`)\n return endGrant({ tokens: deps.tokens, guests: deps.guests, now }, grant.id, \"expired\") ?? grant\n }\n if (grant.state !== \"pending\") return grant\n const card = grant.cardId ? readCard(deps.root, grant.cardId) : null\n const answer = !card ? null : card.status === \"decided\" ? card.verdict : card.status === \"expired\" ? \"no\" : null\n if (answer === \"yes\") {\n const out = deps.guests.update(grant.id, { state: \"active\", approvedAt: new Date(now()).toISOString() }) ?? grant\n deps.guests.log({ grant: grant.id, event: \"approved\", detail: card?.decided_by })\n log(`[guests] ${grant.id}: join approved`)\n return out\n }\n if (answer === \"no\") {\n const reason = card?.status === \"expired\" ? \"the host did not answer in time\" : \"the host said no\"\n const out = endGrant({ tokens: deps.tokens, guests: deps.guests, now }, grant.id, reason) ?? grant\n deps.guests.log({ grant: grant.id, event: \"refused\", detail: reason })\n log(`[guests] ${grant.id}: join refused: ${reason}`)\n return out\n }\n return grant\n}\n\n/** Whether `token` opens a grant right now. */\nexport function guestAccess(token: string | null, deps: SettleDeps): AccessResult {\n const rec = token ? deps.tokens.verify(token) : null\n const grantId = rec ? grantIdOf(rec) : null\n const found = grantId ? deps.guests.get(grantId) : null\n if (!rec || !found || found.tokenId !== rec.id) return { ok: false, status: 401, error: NO_GRANT }\n const grant = settleGrant(deps, found)\n if (grant.state === \"ended\") return { ok: false, status: 401, error: NO_GRANT }\n if (grant.state === \"pending\") return { ok: false, status: 403, error: WAITING_HOST, waiting: true }\n if (grant.state === \"paused\") return { ok: false, status: 403, error: PAUSED, paused: true }\n return { ok: true, grant }\n}\n\n/** What the host agent is told on every guest turn. */\nexport function grantBrief(grant: GuestGrant): string {\n const none = (xs: string[], word: string) => xs.length ? xs.join(\", \") : `none named: do not touch ${word} unless the owner's own instructions already allow it for this work`\n const level =\n grant.level === \"report\" ? \"report: read and answer only; change nothing\" :\n grant.level === \"propose\" ? \"propose: you may prepare changes and open a merge request or draft; never merge, deploy or delete\" :\n \"act: you may act inside the grant without asking\"\n return [\n `[Guest mesh] You are working for a guest organisation, \"${grant.guest}\", under the grant \"${grant.name}\" that the owner of this node opened.`,\n `Stay inside it. Folders: ${none(grant.folders, \"files\")}. Skills: ${none(grant.skills, \"skills\")}. Commands: ${none(grant.commands, \"commands\")}. Freedom: ${level}. The grant ends on ${grant.expiresAt.slice(0, 10)}.`,\n `Anything outside the grant: say it is not covered and stop. The guest sees only your answers: never reveal other chats, agents, people or files of this node.`,\n ].join(\"\\n\")\n}\n\n/** A guest's message as a turn of the host agent. */\nexport function guestTask(grant: GuestGrant, message: string): {\n agentId: string\n message: string\n context: { channel: \"guest\"; chatId: string; sender: string }\n systemPromptAppend: string\n autonomy?: AutonomyLevel\n} {\n return {\n agentId: grant.agentId,\n message,\n context: { channel: \"guest\", chatId: `guest:${grant.id}`, sender: `guest:${grant.guest}` },\n systemPromptAppend: grantBrief(grant),\n ...(grant.level === \"act\" ? {} : { autonomy: grant.level }),\n }\n}\n\ntype ControlDeps = Pick<GuestDeps, \"tokens\" | \"guests\" | \"now\">\n\nexport function pauseGrant(deps: ControlDeps, id: string): GuestGrant | null {\n const grant = deps.guests.get(id)\n if (!grant || grant.state !== \"active\") return null\n const out = deps.guests.update(id, { state: \"paused\", pausedAt: new Date((deps.now ?? Date.now)()).toISOString() })\n deps.guests.log({ grant: id, event: \"paused\" })\n return out\n}\n\nexport function resumeGrant(deps: ControlDeps, id: string): GuestGrant | null {\n const grant = deps.guests.get(id)\n if (!grant || grant.state !== \"paused\") return null\n const out = deps.guests.update(id, { state: \"active\", pausedAt: undefined })\n deps.guests.log({ grant: id, event: \"resumed\" })\n return out\n}\n\n/** Ends the grant: its key stops at once. */\nexport function endGrant(deps: ControlDeps, id: string, reason = \"ended by the host\"): GuestGrant | null {\n const grant = deps.guests.get(id)\n if (!grant || grant.state === \"ended\") return null\n deps.tokens.revoke(grant.tokenId)\n const out = deps.guests.update(id, { state: \"ended\", endedAt: new Date((deps.now ?? Date.now)()).toISOString(), endedReason: reason })\n deps.guests.log({ grant: id, event: reason === \"expired\" ? \"expired\" : \"ended\", detail: reason })\n return out\n}\n\nexport interface GrantPatch { folders?: unknown; skills?: unknown; commands?: unknown; level?: unknown; days?: unknown }\n\n/** Widen or narrow a grant while it is in use. */\nexport function updateGrant(deps: ControlDeps, id: string, patch: GrantPatch): { ok: true; grant: GuestGrant } | { ok: false; error: string } {\n const grant = deps.guests.get(id)\n if (!grant || grant.state === \"ended\") return { ok: false, error: `no open grant \"${id}\"` }\n const next: Partial<GuestGrant> = {}\n if (patch.folders !== undefined) next.folders = list(patch.folders)\n if (patch.skills !== undefined) next.skills = list(patch.skills)\n if (patch.commands !== undefined) next.commands = list(patch.commands)\n if (patch.level !== undefined) {\n const level = autonomyLevelSchema.safeParse(patch.level)\n if (!level.success) return { ok: false, error: \"level must be report, propose or act\" }\n next.level = level.data\n }\n if (patch.days !== undefined) {\n const days = Number(patch.days)\n if (!Number.isFinite(days) || days < 1 || days > MAX_GRANT_DAYS) return { ok: false, error: `days must be between 1 and ${MAX_GRANT_DAYS}` }\n next.expiresAt = new Date((deps.now ?? Date.now)() + days * 86_400_000).toISOString()\n }\n const out = deps.guests.update(id, next)!\n const order: AutonomyLevel[] = [\"report\", \"propose\", \"act\"]\n const wider = (next.level && order.indexOf(next.level) > order.indexOf(grant.level))\n || (next.folders && next.folders.length > grant.folders.length)\n || (next.skills && next.skills.length > grant.skills.length)\n || (next.commands && next.commands.length > grant.commands.length)\n || (next.expiresAt && next.expiresAt > grant.expiresAt)\n deps.guests.log({ grant: id, event: wider ? \"widened\" : \"narrowed\", detail: Object.keys(next).join(\", \") })\n return { ok: true, grant: out }\n}\n\n/** What the guest may know about its grant. */\nexport function grantForGuest(grant: GuestGrant): Record<string, unknown> {\n return {\n grant: grant.id, name: grant.name, agentId: grant.agentId, level: grant.level,\n folders: grant.folders, skills: grant.skills, commands: grant.commands,\n state: grant.state, expiresAt: grant.expiresAt, usage: grant.usage,\n }\n}\n\nasync function padTo(started: number, minMs: number): Promise<void> {\n const left = started + minMs - Date.now()\n if (left > 0) await new Promise((r) => setTimeout(r, left))\n}\n"],"mappings":"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","names":["init_autonomy","GUEST_SCOPE_PREFIX","JOIN_CARD_BY","DEFAULT_GRANT_DAYS","MAX_GRANT_DAYS","MIN_MS","grantIdOf","rec","scope","s","newGrantId","now","list","v","inviteGuest","deps","input","name","guest","level","autonomyLevelSchema","days","id","token","record","code","codeExpiresAt","grant","JOIN_FAILED","joinGuest","body","client","started","log","line","wait","redeemed","grantId","padTo","PAIR_CODE_FAILED","node","str","n","guestNode","until","card","createCard","NO_GRANT","WAITING_HOST","PAUSED","settleGrant","endGrant","readCard","answer","out","reason","guestAccess","found","grantBrief","none","xs","word","guestTask","message","pauseGrant","resumeGrant","updateGrant","patch","next","order","wider","grantForGuest","minMs","left"]}
|
|
File without changes
|
|
File without changes
|