@north-light/cli 0.3.531 → 0.3.533
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/api/client.d.ts +6 -3
- package/dist/api/client.js +1 -1
- package/dist/api/contract.d.ts +1 -1
- package/dist/api/contract.js +1 -1
- package/dist/api/dto/canvas.d.ts +2 -0
- package/dist/api/dto/crons.d.ts +2 -0
- package/dist/builtin-memory/crouter-sdk/release-notes.md +8 -0
- package/dist/builtin-memory/northlight-apps/providers/README.md +2 -0
- package/dist/builtin-memory/northlight-apps/providers/sms.md +2 -0
- package/dist/clients/attach/chrome/inbox-strip.d.ts +6 -1
- package/dist/clients/attach/chrome/inbox-strip.js +1 -1
- package/dist/clients/attach/chrome/roster.js +1 -1
- package/dist/clients/attach/session/chrome-refresh.d.ts +12 -3
- package/dist/clients/attach/session/chrome-refresh.js +1 -1
- package/dist/clients/attach/session/document-links.js +1 -1
- package/dist/clients/attach/viewer.js +586 -587
- package/dist/commands/api-client.js +3 -3
- package/dist/commands/node/inspect.js +6 -6
- package/dist/commands/sys/context/expose.js +2 -2
- package/dist/commands/sys/db.d.ts +1 -0
- package/dist/commands/sys/db.js +1 -0
- package/dist/commands/sys.js +1 -1
- package/dist/core/bash-guard.js +9 -3
- package/dist/core/canvas/canvas.d.ts +12 -2
- package/dist/core/canvas/canvas.js +23 -20
- package/dist/core/canvas/daemon-actions.d.ts +0 -3
- package/dist/core/canvas/daemon-actions.js +7 -24
- package/dist/core/canvas/daemon-owner.d.ts +3 -0
- package/dist/core/canvas/daemon-owner.js +1 -6
- package/dist/core/canvas/db.d.ts +28 -20
- package/dist/core/canvas/db.js +4 -3
- package/dist/core/canvas/deliveries.d.ts +5 -0
- package/dist/core/canvas/deliveries.js +25 -30
- package/dist/core/canvas/export-sqlite.d.ts +14 -0
- package/dist/core/canvas/export-sqlite.js +3 -0
- package/dist/core/canvas/import-sqlite.d.ts +44 -0
- package/dist/core/canvas/import-sqlite.js +7 -0
- package/dist/core/canvas/node-tokens.js +3 -3
- package/dist/core/canvas/outcome-actions.js +4 -4
- package/dist/core/canvas/recovery.js +1 -1
- package/dist/core/canvas/schema-pg.sql +1022 -0
- package/dist/core/canvas/schema-version.d.ts +4 -0
- package/dist/core/canvas/schema-version.js +1 -0
- package/dist/core/canvas/sessions.js +3 -3
- package/dist/core/canvas/structured-requests.js +2 -2
- package/dist/core/canvas/tree.js +6 -6
- package/dist/core/canvas/waits.js +1 -1
- package/dist/core/feed/inbox.js +1 -1
- package/dist/core/feed/messages.js +5 -5
- package/dist/core/feed/reports.js +2 -2
- package/dist/core/grants/mirror.js +2 -2
- package/dist/core/graph/access.js +7 -7
- package/dist/core/graph/custom.js +10 -10
- package/dist/core/graph/deletion.js +6 -6
- package/dist/core/graph/documents.d.ts +1 -1
- package/dist/core/graph/documents.js +9 -9
- package/dist/core/graph/edges.d.ts +3 -3
- package/dist/core/graph/edges.js +3 -1
- package/dist/core/graph/events.js +7 -7
- package/dist/core/graph/exposures.d.ts +8 -8
- package/dist/core/graph/jobs.d.ts +1 -1
- package/dist/core/graph/jobs.js +2 -2
- package/dist/core/graph/kinds/custom.js +1 -1
- package/dist/core/graph/kinds/document.js +4 -4
- package/dist/core/graph/kinds/dto.js +1 -1
- package/dist/core/graph/kinds/job.js +2 -2
- package/dist/core/graph/kinds/kind.d.ts +2 -2
- package/dist/core/graph/kinds/kind.js +1 -1
- package/dist/core/graph/kinds/live-read.d.ts +5 -0
- package/dist/core/graph/kinds/live-read.js +1 -0
- package/dist/core/graph/kinds/node.js +5 -5
- package/dist/core/graph/kinds/owner.js +2 -2
- package/dist/core/graph/names.js +3 -3
- package/dist/core/graph/objects.d.ts +5 -5
- package/dist/core/graph/objects.js +10 -10
- package/dist/core/graph/package-docs.js +6 -5
- package/dist/core/graph/reader.d.ts +1 -1
- package/dist/core/graph/reader.js +2 -2
- package/dist/core/graph/receivers.js +4 -5
- package/dist/core/graph/repo-sync/exchange.js +2 -2
- package/dist/core/graph/repo-sync/repos.js +3 -3
- package/dist/core/graph/repo-sync/sync.js +1 -1
- package/dist/core/graph/rules.d.ts +3 -4
- package/dist/core/graph/rules.js +3 -3
- package/dist/core/graph/spaces/app.js +1 -1
- package/dist/core/graph/spaces/index.d.ts +1 -1
- package/dist/core/graph/spaces/index.js +1 -1
- package/dist/core/graph/spaces/own-memory.js +1 -1
- package/dist/core/graph/spaces/person.js +3 -3
- package/dist/core/graph/spaces/repo.d.ts +1 -1
- package/dist/core/graph/spaces/repo.js +1 -1
- package/dist/core/graph/types.d.ts +4 -3
- package/dist/core/graph/watches.d.ts +2 -2
- package/dist/core/graph/watches.js +17 -17
- package/dist/core/human/page-schema.js +5 -4
- package/dist/core/human/requests.d.ts +1 -1
- package/dist/core/human/requests.js +20 -23
- package/dist/core/llm/run.js +2 -2
- package/dist/core/peer/home.d.ts +6 -0
- package/dist/core/peer/home.js +2 -2
- package/dist/core/peer/ingest.js +1 -1
- package/dist/core/peer/receiver.js +1 -1
- package/dist/core/peer/stubs.js +1 -1
- package/dist/core/providers/receipts.js +3 -2
- package/dist/core/review/comments.js +5 -4
- package/dist/core/runs/activity.js +4 -5
- package/dist/core/runs/confinement.d.ts +1 -1
- package/dist/core/runs/confinement.js +2 -2
- package/dist/core/runs/events.d.ts +1 -1
- package/dist/core/runs/events.js +5 -5
- package/dist/core/runs/operations.js +6 -4
- package/dist/core/runtime/close.d.ts +3 -0
- package/dist/core/runtime/close.js +1 -1
- package/dist/core/runtime/host.d.ts +5 -1
- package/dist/core/runtime/host.js +3 -3
- package/dist/core/runtime/launch.js +2 -2
- package/dist/core/runtime/ledger.js +3 -3
- package/dist/core/runtime/lifecycle.d.ts +9 -0
- package/dist/core/runtime/lifecycle.js +2 -2
- package/dist/core/runtime/nodes.d.ts +1 -1
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/roadmap.js +1 -1
- package/dist/core/spaces/stop.d.ts +1 -0
- package/dist/core/spaces/stop.js +2 -2
- package/dist/core/statements.d.ts +17 -0
- package/dist/core/statements.js +2 -0
- package/dist/core/substrate/delivery/corpus.js +3 -3
- package/dist/core/substrate/delivery/deliver.js +5 -5
- package/dist/core/substrate/delivery/listings.js +1 -1
- package/dist/core/substrate/delivery/match.d.ts +2 -2
- package/dist/core/substrate/delivery/match.js +1 -1
- package/dist/core/substrate/delivery/plan.js +3 -3
- package/dist/core/substrate/delivery/render-boot.js +5 -5
- package/dist/core/substrate/delivery/render-event.js +6 -6
- package/dist/core/usage/ledger.js +8 -8
- package/dist/daemon/api/bridge.js +4 -4
- package/dist/daemon/api/document-listener.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/canvas.js +1 -1
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/custom-objects.js +3 -3
- package/dist/daemon/api/handlers/docs.js +1 -1
- package/dist/daemon/api/handlers/inbox.js +1 -1
- package/dist/daemon/api/handlers/memory.js +7 -7
- package/dist/daemon/api/handlers/messages.js +1 -1
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/objects.js +3 -3
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/handlers/structured-requests.js +1 -1
- package/dist/daemon/api/reader.js +1 -1
- package/dist/daemon/broker-signals/bus.d.ts +14 -6
- package/dist/daemon/broker-signals/bus.js +1 -10
- package/dist/daemon/crtrd-cli.js +1 -1
- package/dist/daemon/crtrd.js +12 -11
- package/dist/daemon/due.js +1 -1
- package/dist/daemon/export-sqlite-run.d.ts +1 -0
- package/dist/daemon/export-sqlite-run.js +4 -0
- package/dist/daemon/fleet.d.ts +1 -0
- package/dist/daemon/fleet.js +3 -3
- package/dist/daemon/human/settle.js +1 -1
- package/dist/daemon/manage.d.ts +10 -0
- package/dist/daemon/manage.js +3 -2
- package/dist/daemon/peer/forward.d.ts +7 -0
- package/dist/daemon/peer/forward.js +1 -1
- package/dist/daemon/postgres/binary.d.ts +17 -0
- package/dist/daemon/postgres/binary.js +2 -0
- package/dist/daemon/postgres/cluster.d.ts +37 -0
- package/dist/daemon/postgres/cluster.js +6 -0
- package/dist/daemon/postgres/index.d.ts +2 -0
- package/dist/daemon/postgres/index.js +1 -0
- package/dist/daemon/postgres/pins.d.ts +7 -0
- package/dist/daemon/postgres/pins.js +1 -0
- package/dist/daemon/postgres/supervisor.d.ts +95 -0
- package/dist/daemon/postgres/supervisor.js +2 -0
- package/dist/daemon/reconcilers/bash-deadline.js +2 -2
- package/dist/daemon/reconcilers/delivery-lane.js +2 -2
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +7 -3
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +0 -6
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -8
- package/dist/daemon/runs/observer.js +5 -4
- package/dist/migrations/004-canvas-documents/index.js +1 -1
- package/dist/pi-extensions/canvas-doc-substrate.d.ts +2 -0
- package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
- package/dist/pi-extensions/envelope-merge.d.ts +3 -2
- package/dist/pi-extensions/envelope-merge.js +9 -8
- package/dist/shared/env.d.ts +3 -0
- package/dist/shared/env.js +2 -2
- package/docs/apps/providers/README.md +2 -0
- package/docs/apps/providers/sms.md +2 -0
- package/docs/public-api.md +11 -2
- package/docs/sdk/release-notes.md +8 -0
- package/package.json +6 -6
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +13 -26
- package/scripts/install-runtime.mjs +53 -3
- package/scripts/lib/isolation-env.mjs +3 -1
package/dist/core/graph/edges.js
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
var y=Object.defineProperty;var i=(t,
|
|
1
|
+
var y=Object.defineProperty;var i=(t,n)=>y(t,"name",{value:n,configurable:!0});import{canRead as f}from"./access.js";import{getById as w}from"./objects.js";import{mapAsync as N}from"../async-array.js";async function _(t,n,e){await t.prepare(`INSERT INTO edges (type, src, dst, written_as, created_at) VALUES ('acted-on', ?, ?, NULL, ?)
|
|
2
|
+
ON CONFLICT DO NOTHING`).run(n.id,e.id,new Date().toISOString())}i(_,"recordActedOn");async function k(t,n,e){const s=(await t.prepare("SELECT dst FROM edges WHERE type = 'links-to' AND src = ?").all(n.id)).map(({dst:a})=>a);await t.prepare("DELETE FROM edges WHERE type = 'links-to' AND src = ?").run(n.id);const o=t.prepare(`INSERT INTO edges (type, src, dst, written_as, created_at) VALUES ('links-to', ?, ?, ?, ?)
|
|
3
|
+
ON CONFLICT DO NOTHING`),d=new Date().toISOString();for(const a of e)await o.run(n.id,a.dst.id,a.written_as,d);const c=new Set(e.map(a=>a.dst.id));return s.filter(a=>!c.has(a))}i(k,"setLinks");async function D(t,n,e){await t.prepare("DELETE FROM unresolved_links WHERE src = ?").run(n.id);const s=t.prepare("INSERT INTO unresolved_links (src, name) VALUES (?, ?) ON CONFLICT DO NOTHING");for(const o of e)await s.run(n.id,o)}i(D,"setUnresolved");async function A(t,n,e){const s=t.prepare("DELETE FROM unresolved_links WHERE src = ? AND name = ?");for(const o of e)await s.run(n.id,o)}i(A,"dropUnresolved");async function I(t,n,e){return await t.prepare("SELECT src, name FROM unresolved_links WHERE name = ? OR name = ? OR right(name, length(CAST(? AS text)) + 1) = '/' || CAST(? AS text) ORDER BY src, name").all(n,e,n,n)}i(I,"unresolvedLinksCouldName");async function C(t,n){const e=await t.prepare("SELECT e.dst, e.written_as FROM edges e WHERE e.type = 'links-to' AND e.src = ? ORDER BY e.written_as").all(n.id);return await N(e,async s=>({written_as:s.written_as??"",dst:await w(t,s.dst)}))}i(C,"linksOf");async function g(t,n,e){return await R(t,n,e,{type:"links-to",direction:"in"})}i(g,"backlinks");async function R(t,n,e,s={}){if(!await f(t,n,e))return[];const o=s.direction??"both",d=s.type?[s.type]:["acted-on","links-to"],c=[];for(const r of d)o!=="in"&&c.push(...await t.prepare("SELECT * FROM edges WHERE type = ? AND src = ?").all(r,e.id)),o!=="out"&&c.push(...await t.prepare("SELECT * FROM edges WHERE type = ? AND dst = ?").all(r,e.id));const a=new Set,l=[];for(const r of c){const u=`${r.type}|${r.src}|${r.dst}`;if(a.has(u))continue;a.add(u);const p=r.src===e.id?e:await w(t,r.src),E=r.dst===e.id?e:await w(t,r.dst);if(!p||!E)continue;const O=p===e?E:p;O!==e&&!await f(t,n,O)||l.push({type:r.type,src:p,dst:E,written_as:r.written_as,created_at:r.created_at})}return l}i(R,"edgesOf");export{g as backlinks,A as dropUnresolved,R as edgesOf,C as linksOf,_ as recordActedOn,k as setLinks,D as setUnresolved,I as unresolvedLinksCouldName};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
var H=Object.defineProperty;var d=(n,e)=>H(n,"name",{value:e,configurable:!0});import{EventEmitter as x}from"node:events";const v=new x;v.setMaxListeners(0);async function pe(n,e){const o=d(i=>e(i),"listener");return v.on(n,o),()=>v.off(n,o)}d(pe,"subscribeDocumentEvents");import{evalCondition as $}from"../predicate.js";import{finalizeNodeMail as B,insertMessage as J}from"../feed/messages.js";import{linkAuthorizes as K,ownerChain as U,readCheck as G}from"./access.js";import{
|
|
2
|
-
AND name = ? AND
|
|
1
|
+
var H=Object.defineProperty;var d=(n,e)=>H(n,"name",{value:e,configurable:!0});import{EventEmitter as x}from"node:events";const v=new x;v.setMaxListeners(0);async function pe(n,e){const o=d(i=>e(i),"listener");return v.on(n,o),()=>v.off(n,o)}d(pe,"subscribeDocumentEvents");import{evalCondition as $}from"../predicate.js";import{finalizeNodeMail as B,insertMessage as J}from"../feed/messages.js";import{linkAuthorizes as K,ownerChain as U,readCheck as G}from"./access.js";import{getById as q}from"./objects.js";import{appScopesNow as z,publishLookups as P,readerForObject as V}from"./reader.js";import{configFromJson as k}from"./watches.js";import{CrtrError as L}from"../errors.js";import{ExitCode as A}from"../../types.js";import{eventSpec as X,kindOf as C}from"./kinds/registry.js";import{machineNameOf as M}from"../peer/names.js";import{settleObjectWaits as Y}from"../canvas/waits.js";import{RECEIVERS as F}from"./receivers.js";import{DEFAULT_LISTEN as D}from"./types.js";import{afterCommit as Q}from"../canvas/db.js";function Z(n,e){if(n.level===void 0||n.level===e.level||e.levels?.includes(n.level))return n.level??e.level;const o=[e.level,...e.levels??[]].filter((i,t,s)=>s.indexOf(i)===t).sort((i,t)=>i-t);throw new L("invalid_level",`${n.object.type} ${n.event} publishes at level ${o.join(", ")}, not ${n.level}`,A.USAGE,{kind:n.object.type,event:n.event,level:n.level,allowed:o})}d(Z,"resolveLevel");function ee(n,e){const o=n.split("."),i=e.split(".");for(let t=0;t<o.length;t++){if(o[t]===">")return t===o.length-1&&i.length>t;if(t>=i.length||o[t]!=="*"&&o[t]!==i[t])return!1}return o.length===i.length}d(ee,"matchSubject");const W={"next-turn":1,"after-turn":2,steer:3,interrupt:4};function te(n,e){let o=null;for(const i of n){let t=null;for(const s of i)s.threshold<=e&&(!t||s.threshold>t.threshold)&&(t=s);t&&(!o||W[t.delivery]>W[o])&&(o=t.delivery)}return o}d(te,"resolveDelivery");async function ve(n,e,o){if(e.config)return e.config;const i=await n.prepare("SELECT listen_json FROM objects WHERE id = ?").get(o.id);return i?.listen_json?k(i.listen_json):D}d(ve,"listenConfigFor");function ne(n,e){return e.inboxKind??(n.level>=7?"urgent":"update")}d(ne,"inboxKind");async function oe(n,e){return e.type==="node"?e.id:await n.prepare(`SELECT 1 FROM objects WHERE type IN ('person','app','repo','profile')
|
|
2
|
+
AND name = ? AND id != ? LIMIT 1`).get(e.name,e.id)?`${e.type}:${e.name}`:e.name}d(oe,"ownerHandleOf");async function ie(n,e,o){const i=e.object.owner===null?null:await n.prepare("SELECT * FROM objects WHERE id = ?").get(e.object.owner),t=i?.id??null,s=i?await oe(n,i):null;return{event:e.event,level:e.level,object:{id:e.object.id,type:e.object.type,kind:e.object.kind,owner:t,owner_handle:s,name:e.object.name,...e.object.home_machine?{machine:M(e.object.home_machine),machine_id:e.object.home_machine}:{}},actor:e.actor?.id??null,...e.actor?.home_machine?{actor_machine:M(e.actor.home_machine),actor_machine_id:e.actor.home_machine}:{},attrs:o,...e.pointer===void 0?{}:{pointer:e.pointer}}}d(ie,"pushFields");async function se(n,e,o,i){const t=await ie(n,e,i),s=e.messageBody!==void 0&&o.carriesBody===!0,f=s?typeof e.messageBody=="object"&&e.messageBody!==null&&!Array.isArray(e.messageBody)?{...e.messageBody,push:t}:{body:e.messageBody,push:t}:{push:t},c=s?e.messageBody:null,l=c?.bodyRef===void 0?null:c;return{kind:ne(e,o),label:l?.label??(typeof c?.label=="string"?c.label:e.object.type.includes(".")&&typeof e.messageBody?.summary=="string"?e.messageBody.summary.split(`
|
|
3
3
|
`)[0]:`${e.event} ${e.object.type} ${e.object.name}`),...l?.bodyRef===void 0?{}:{bodyRef:l.bodyRef},...l?.disposition===void 0?{}:{disposition:l.disposition},senderNodeId:e.actor?.type==="node"?e.actor.id:null,senderName:e.actor===null||e.actor===void 0?null:e.actor.home_machine?`${e.actor.name} on ${M(e.actor.home_machine)}`:e.actor.name,bodyJson:f}}d(se,"messageInput");async function re(n,e,o,i,t){if(!o.supersedes)return[{attrs:e.attrs,destinations:[...i]}];const s=n.prepare(`SELECT d.delivery_id, d.message_id, d.state, m.body_json FROM deliveries d
|
|
4
4
|
JOIN messages m ON m.message_id = d.message_id
|
|
5
5
|
WHERE d.destination_id = ? AND d.state IN ('pending', 'handed_off')
|
|
6
6
|
AND d.canceled_at IS NULL AND m.event = ? AND m.object_id = ?
|
|
7
|
-
ORDER BY m.seq`),f=n.prepare("DELETE FROM deliveries WHERE delivery_id = ?"),c=n.prepare("SELECT * FROM objects WHERE id = ?"),l=new Map,g=new Set;for(const m of i){const E=t(m),N=await c.get(E),
|
|
8
|
-
UNION ALL SELECT depth FROM message_causes WHERE message_id = ? LIMIT 1`).get(s,s);if(s!==null&&f===void 0)throw new
|
|
9
|
-
COALESCE(s.config_json, o.listen_json) AS config_json, w.link_app`,R=await n.prepareUncached(i.durable?`SELECT ${g} FROM watches w JOIN watch_subscriptions s ON s.watch = w.
|
|
10
|
-
JOIN objects o ON o.
|
|
11
|
-
WHERE o.reception = 2 AND w.
|
|
7
|
+
ORDER BY m.seq`),f=n.prepare("DELETE FROM deliveries WHERE delivery_id = ?"),c=n.prepare("SELECT * FROM objects WHERE id = ?"),l=new Map,g=new Set;for(const m of i){const E=t(m),N=await c.get(E),I=N===void 0?void 0:await C(n,N.type),_=await s.all(E,e.event,e.object.id),j=new Set;for(const a of _)a.state==="handed_off"?await I?.supersedeClaimed?.(n,a.delivery_id)&&j.add(a.delivery_id):(await f.run(a.delivery_id),g.add(a.message_id));const h=_.filter(a=>a.state==="pending"||j.has(a.delivery_id)).at(-1),b=h?.message_id??null,r=l.get(b)??{prior:h?.body_json?JSON.parse(h.body_json).push?.attrs??null:null,destinations:[]};r.destinations.push(m),l.set(b,r)}const R=n.prepare("DELETE FROM messages WHERE message_id = ? AND NOT EXISTS (SELECT 1 FROM deliveries WHERE message_id = ?)");for(const m of g)await R.run(m,m);return[...l.values()].map(m=>({attrs:o.merge?o.merge(m.prior,e):e.attrs,destinations:m.destinations}))}d(re,"supersede");async function ae(n,e,o,i,t){const s=await q(n,i);if(s===null||s.type!=="app")return!1;const f=await n.prepare("SELECT 1 FROM peer_stubs WHERE object = ?").get(e.id)!==void 0,c=f?null:await z(n,s,t);return(f||c!==null)&&await K(n,s,c,e,o)}d(ae,"linkDelivers");const T=8;class ce extends L{static{d(this,"HopLimitError")}constructor(e){super("hop_limit",`event depth ${e} exceeds ${T}`,A.GENERAL,{depth:e,limit:T})}}async function Ie(n,e,o=async()=>[]){const i=await X(n,e.object.type,e.event),t={...e,level:Z(e,i)};t.object.type==="document"&&(t.event==="edited"||t.event==="deleted")&&Q(()=>v.emit(t.object.id,t.event));const s=e.cause??null,f=s===null?null:await n.prepare(`SELECT depth FROM messages WHERE message_id = ?
|
|
8
|
+
UNION ALL SELECT depth FROM message_causes WHERE message_id = ? LIMIT 1`).get(s,s);if(s!==null&&f===void 0)throw new L("unknown_cause",`no message ${s}`,A.USAGE,{cause:s});const c=f===null?0:f.depth+1;if(c>T)throw new ce(c);(i.endsWait===!0||t.event==="deleted")&&await Y(n,t.object.id);const l=await U(n,t.object),g=`w.watcher, o.id AS watcher_id, o.type AS watcher_type, o.reception, s.pattern, s.filter_json,
|
|
9
|
+
COALESCE(s.config_json, o.listen_json) AS config_json, w.link_app`,R=await n.prepareUncached(i.durable?`SELECT ${g} FROM watches w JOIN watch_subscriptions s ON s.watch = w.watch_id
|
|
10
|
+
JOIN objects o ON o.id = w.watcher WHERE w.object = ? AND w.watcher != ? AND o.reception >= 1`:`SELECT ${g} FROM objects o JOIN watches w ON w.watcher = o.id JOIN watch_subscriptions s ON s.watch = w.watch_id
|
|
11
|
+
WHERE o.reception = 2 AND w.object = ? AND w.watcher != ?`).all(t.object.id,t.actor?.id??"");if(R.length===0)return{delivered:0,message_id:null,depth:c};const m={event:t.event,level:t.level,id:t.object.id,type:t.object.type,kind:t.object.kind,actor:t.actor?.id??null,...t.attrs},E=new Map;for(const r of R){if(t.onlyWatchers!==void 0&&!t.onlyWatchers.includes(r.watcher_id)||!ee(r.pattern,t.event)||r.filter_json!==null&&!$(JSON.parse(r.filter_json),m))continue;const a=E.get(r.watcher)??{id:r.watcher_id,type:r.watcher_type,reception:r.reception,configs:[],linkApp:r.link_app};a.configs.push(r.config_json?k(r.config_json):D),E.set(r.watcher,a)}const N=(l.length?l[l.length-1]:t.object).type==="repo",I=d(async()=>[],"noRepos"),_=await G(n,t.object),j=P(n),h=[];for(const r of E.values()){const a=await n.prepare("SELECT * FROM objects WHERE id = ?").get(r.id),u=await C(n,a.type),O=u.receiverFor?await u.receiverFor(n,a):u.receiver;if(O===void 0)continue;const w=te(r.configs,t.level);if(w===null)continue;const y=await V(n,a,N?o:I,j);if(y.scopes===null&&(y.class==="node"||y.owner.type!=="person"))continue;const p=r.linkApp!==null&&!await _(y)&&await ae(n,t.object,a,r.linkApp,j);!p&&!await _(y)||h.push({id:r.id,reception:r.reception,delivery:w,receiver:O,...p?{linked:p}:{}})}if(h.length===0)return{delivered:0,message_id:null,depth:c};let b=null;for(const r of await re(n,t,i,h,a=>a.id)){const a=new Map;for(const p of r.destinations)a.set(p.receiver,[...a.get(p.receiver)??[],p]);const u=await se(n,t,i,r.attrs),O=[...a].map(([p,S])=>F[p].bodyOwner(S)).find(p=>p!==null)??null,w=B({...u,urgency:"normal"},O),y=await J(n,{operationId:w.operationId,createdAt:w.createdAt,senderNodeId:u.senderNodeId,senderName:u.senderName,kind:u.kind,label:u.label,bodyRef:w.bodyRef,bodyJson:w.bodyJson,disposition:u.disposition??null,event:{event:t.event,objectId:t.object.id,level:t.level,actorId:t.actor?.id??null},causeMessageId:s,depth:c});b??=y;for(const[p,S]of a)await F[p].enqueue(n,{messageId:y,event:t.event,level:t.level,senderNodeId:u.senderNodeId,elevatesTier:i.elevatesTier===!0,...t.idempotencyKey===void 0?{}:{idempotencyKey:t.idempotencyKey}},S)}return{delivered:h.length,message_id:b,depth:c}}d(Ie,"publish");export{T as HOP_LIMIT,ce as HopLimitError,ve as listenConfigFor,ee as matchSubject,Ie as publish,te as resolveDelivery,Z as resolveLevel,pe as subscribeDocumentEvents,re as supersede};
|
|
@@ -17,27 +17,27 @@ export type Listed = {
|
|
|
17
17
|
transcript?: ExposureLevel;
|
|
18
18
|
};
|
|
19
19
|
export interface Ledger {
|
|
20
|
-
node:
|
|
20
|
+
node: string;
|
|
21
21
|
preferenceSnapshot: string | null;
|
|
22
|
-
objects: Map<
|
|
22
|
+
objects: Map<string, Held>;
|
|
23
23
|
/** key = `<owner object id>/<prefix>` */
|
|
24
24
|
listed: Map<string, Listed>;
|
|
25
25
|
}
|
|
26
26
|
export interface Exposed {
|
|
27
|
-
object:
|
|
27
|
+
object: string;
|
|
28
28
|
headsKey: string | null;
|
|
29
29
|
contentHash: string | null;
|
|
30
30
|
}
|
|
31
|
-
export declare function loadLedger(db: CanvasDb, node:
|
|
31
|
+
export declare function loadLedger(db: CanvasDb, node: string): Promise<Ledger>;
|
|
32
32
|
/** Write what changed since `loadLedger` (a ledger never loaded is written whole). */
|
|
33
33
|
export declare function saveLedger(db: CanvasDb, ledger: Ledger): Promise<void>;
|
|
34
34
|
/** Whether the node has a ledger at all (a context session or any exposure). */
|
|
35
|
-
export declare function hasLedger(db: CanvasDb, node:
|
|
35
|
+
export declare function hasLedger(db: CanvasDb, node: string): Promise<boolean>;
|
|
36
36
|
/** End the node's context session: nothing is held any more. */
|
|
37
|
-
export declare function clearLedger(db: CanvasDb, node:
|
|
37
|
+
export declare function clearLedger(db: CanvasDb, node: string): Promise<void>;
|
|
38
38
|
/** Seed a fork with what the source's transcript holds; the fork builds its own
|
|
39
39
|
* system prompt, so system rows and the preference snapshot are not copied. */
|
|
40
|
-
export declare function forkLedger(db: CanvasDb, source:
|
|
40
|
+
export declare function forkLedger(db: CanvasDb, source: string, fork: string): Promise<void>;
|
|
41
41
|
/** Held at `level` or above: this object, or any held object with the same body
|
|
42
42
|
* (content hash). The object itself counts at content level only for the same revision. */
|
|
43
43
|
export declare function heldAtOrAbove(ledger: Ledger, exposed: Exposed, level: ExposureLevel, channel?: Channel): boolean;
|
|
@@ -47,7 +47,7 @@ export declare function listedAtOrAbove(ledger: Ledger, key: string, level: Expo
|
|
|
47
47
|
export declare function holdListing(ledger: Ledger, channel: Channel, key: string, level: ExposureLevel): void;
|
|
48
48
|
/** Forget the transcript's copy of the object and of every held object with the
|
|
49
49
|
* same body (compaction dropped it); system holdings stay. */
|
|
50
|
-
export declare function demoteTranscript(ledger: Ledger, object:
|
|
50
|
+
export declare function demoteTranscript(ledger: Ledger, object: string): void;
|
|
51
51
|
/** The byte-stable preference block: the first render is kept for the session. */
|
|
52
52
|
export declare function freezePreferences(ledger: Ledger, rendered: string): string;
|
|
53
53
|
export declare function hasTranscript(ledger: Ledger): boolean;
|
|
@@ -2,7 +2,7 @@ import type { ObjectRow } from './types.js';
|
|
|
2
2
|
import type { CanvasDb } from '../canvas/db.js';
|
|
3
3
|
export type JobStatus = 'running' | 'exited' | 'killed';
|
|
4
4
|
export interface JobRow {
|
|
5
|
-
object:
|
|
5
|
+
object: string;
|
|
6
6
|
command: string;
|
|
7
7
|
status: JobStatus;
|
|
8
8
|
exit_code: number | null;
|
package/dist/core/graph/jobs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var m=Object.defineProperty;var e=(t,
|
|
2
|
-
`,1)[0].trim()}e(
|
|
1
|
+
var m=Object.defineProperty;var e=(t,i)=>m(t,"name",{value:i,configurable:!0});import{recordActedOn as s}from"./edges.js";import{publish as u}from"./events.js";import{createObject as f,getById as E}from"./objects.js";import{recordWatch as h}from"./watches.js";function d(t){return t.split(`
|
|
2
|
+
`,1)[0].trim()}e(d,"firstLine");function p(t,i){return`${d(t)} (${i})`}e(p,"previewOf");async function b(t,i){return await t.prepare("SELECT * FROM jobs WHERE object = ?").get(i.id)??null}e(b,"jobRow");async function T(t,i,r){if(i.type!=="node")throw new Error(`startJob: ${i.id} is a ${i.type}, not a node`);const a=await f(t,{...r.id===void 0?{}:{id:r.id},type:"job",kind:"bash",owner:i.id,privacy:"public",name:d(r.command)||"bash",preview:p(r.command,"running")});return await t.prepare("INSERT INTO jobs (object, command, status, exit_code, job_dir, log_path) VALUES (?, ?, 'running', NULL, ?, ?)").run(a.id,r.command,r.jobDir,r.logPath),await s(t,i,a),await h(t,i,a,"job-start"),await u(t,{event:"created",object:a,actor:i,attrs:{}}),a}e(T,"startJob");async function v(t,i,r){const a=await b(t,i);if(a===null)throw new Error(`finishJob: ${i.id} has no jobs row`);if(a.status!=="running")return i;const o="killedBy"in r,c=o?"killed":"exited",n=o?null:r.exitCode;await t.prepare("UPDATE jobs SET status = ?, exit_code = ? WHERE object = ?").run(c,n,i.id);const w=o?"killed":`exited ${n}`;await t.prepare("UPDATE objects SET preview = ? WHERE id = ?").run(p(a.command,w),i.id);const l=await E(t,i.id);return o&&r.killedBy!==null&&await s(t,r.killedBy,l),await u(t,{event:c,object:l,actor:o?r.killedBy:null,attrs:o?{"log-path":a.log_path,...r.reason===void 0?{}:{reason:r.reason}}:{"exit-code":n,"log-path":a.log_path}}),l}e(v,"finishJob");export{v as finishJob,b as jobRow,T as startJob};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var l=Object.defineProperty;var c=(s,a)=>l(s,"name",{value:a,configurable:!0});import{recordLiveRead as u}from"./
|
|
1
|
+
var l=Object.defineProperty;var c=(s,a)=>l(s,"name",{value:a,configurable:!0});import{recordLiveRead as u}from"./live-read.js";import{header as m}from"./render.js";import{objectDTO as v}from"./dto.js";import{receiverForObject as j}from"../receivers.js";function $(s,a){const d=Object.fromEntries(Object.entries(a).map(([t,{ends_wait:i,...o}])=>[`${s}.${t}`,{...o,carriesBody:!0,...i===void 0?{}:{endsWait:i}}]));return{name:s,events:{created:{level:4},read:{level:1},watched:{level:1},deleted:{level:5},configured:{level:1},...d},addressable:"name",receiverFor:j,async read(t,i,o,p){await u(t,i,o,p.reposFn);const e=await t.prepare("SELECT description, summary, state_json, published_at, receiver_json, dropped FROM custom_objects WHERE object = ?").get(o.id),n=e?.receiver_json==null?null:JSON.parse(e.receiver_json),r={object:await v(t,o),description:e?.description??"",summary:e?.summary??null,state:e?.state_json==null?null:JSON.parse(e.state_json),published_at:e?.published_at??null,receiver:typeof n=="string"?n:n&&typeof n=="object"?Object.keys(n)[0]:null,dropped:e?.dropped??0};return{data:r,text:`${m("object",r.object)}
|
|
2
2
|
Description: ${r.description}
|
|
3
3
|
Summary: ${r.summary??""}
|
|
4
4
|
State: ${JSON.stringify(r.state)}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var _=Object.defineProperty;var m=(e,t)=>_(e,"name",{value:t,configurable:!0});import{recordMemoryReadsIn as v}from"../../canvas/memory-reads.js";import{deliveryDocOf as x,nodeSubject as
|
|
2
|
-
AND substr(name, 1, ?) = ? ORDER BY name`).all(n.owner,i.length,i);return await p(await
|
|
1
|
+
var _=Object.defineProperty;var m=(e,t)=>_(e,"name",{value:t,configurable:!0});import{recordMemoryReadsIn as v}from"../../canvas/memory-reads.js";import{deliveryDocOf as x,nodeSubject as D,ownerHandle as N}from"../../substrate/delivery/corpus.js";import{recordContentDelivery as S}from"../../substrate/delivery/deliver.js";import{renderExplicitRead as $}from"../../substrate/delivery/render-event.js";import{canRead as R}from"../access.js";import{documentRecord as O,readDocument as j}from"../documents.js";import{loadLedger as k,saveLedger as A}from"../exposures.js";import{getById as E}from"../objects.js";import{rulesOf as h}from"../rules.js";import{objectDTO as d}from"./dto.js";import{withBase as I}from"./kind.js";import{attr as l,header as L,section as M}from"./render.js";import{filterAsync as T,mapAsync as p}from"../../async-array.js";async function b(e,t,n){const i=`${n.name}/`,s=await e.prepare(`SELECT * FROM objects WHERE type = 'document' AND deleted_at IS NULL AND home_machine IS NULL AND owner IS NOT DISTINCT FROM ?
|
|
2
|
+
AND substr(name, 1, ?) = ? ORDER BY name`).all(n.owner,i.length,i);return await p(await T(s,async a=>!a.name.slice(i.length).includes("/")&&await R(e,t,a)),async a=>await d(e,a))}m(b,"listingOf");async function B(e,t,n){const i=t.class==="node",s=i?await k(e,t.node.id):{node:"",preferenceSnapshot:null,objects:new Map,listed:new Map},a={db:e,reader:t,subject:i?await D(e,t):null,ledger:s,channel:"transcript"},o=await $(a,await x(e,t,n));return i&&(await S(e,t,o.delivered),await A(e,s)),{attachments:o.attachments,linked:o.linked.map(c=>c.object)}}m(B,"explicitReadAttachments");async function C(e,t,n){if(t.class!=="node"||n.kind!=="knowledge"&&n.kind!=="preference"||n.owner===null)return;const i=await E(e,n.owner);i!==null&&await v(e,t.node.id,[{name:n.name,scope:N(i),at:new Date().toISOString(),type:"read"}])}m(C,"recordExplicitMemoryRead");function W(e,t){const n=[];if(t.attachments&&n.push(t.attachments,""),n.push(L("object",e,l("privacy",e.privacy)+l("revision",t.revision))),n.push(`Preview: ${e.preview}`),t.summary&&n.push(`Summary: ${t.summary}`),t.fields!==void 0&&n.push(`<fields>
|
|
3
3
|
${JSON.stringify(t.fields,null,2)}
|
|
4
|
-
</fields>`),t.needs_merge?(t.heads.forEach((i,s)=>{n.push(`<head${l("rev",i.rev_id)}${l("number",i.number)}${l("author",i.author_id)}>`,t.bodies[s]??"","</head>")}),n.push(`This document has ${t.heads.length} heads. Your next \`crtr doc edit\` writes the merged body and joins them into one revision.`)):n.push("",t.bodies[0]??""),t.listing&&t.listing.length>0){const i=t.listing.some(o=>o.owner?.id===e.owner?.id&&o.name.startsWith(`${e.name}/`)),s=t.listing.some(o=>o.owner?.id!==e.owner?.id||!o.name.startsWith(`${e.name}/`)),
|
|
5
|
-
`)}m(
|
|
4
|
+
</fields>`),t.needs_merge?(t.heads.forEach((i,s)=>{n.push(`<head${l("rev",i.rev_id)}${l("number",i.number)}${l("author",i.author_id)}>`,t.bodies[s]??"","</head>")}),n.push(`This document has ${t.heads.length} heads. Your next \`crtr doc edit\` writes the merged body and joins them into one revision.`)):n.push("",t.bodies[0]??""),t.listing&&t.listing.length>0){const i=t.listing.some(o=>o.owner?.id===e.owner?.id&&o.name.startsWith(`${e.name}/`)),s=t.listing.some(o=>o.owner?.id!==e.owner?.id||!o.name.startsWith(`${e.name}/`)),a=i&&s?`Names under ${e.name}/ and documents it links to`:i?`Names under ${e.name}/`:"Documents it links to";n.push("",...M(a,t.listing))}return n.join(`
|
|
5
|
+
`)}m(W,"render");function F(e){const t=e.attrs.revision,n=e.attrs.from_revision??(typeof t=="number"?t-1:null),i=e.attrs.rationale;return{...e.attrs,from_revision:n,revision:t,authors:e.actor?[e.actor.id]:[],rationales:typeof i=="string"?[i]:[]}}m(F,"editAttrs");const H=m((e,t)=>{const n=F(t);if(e===null)return n;const i=e.authors??[];return{...n,from_revision:e.from_revision??null,authors:[...i,...n.authors.filter(s=>!i.includes(s))],rationales:[...e.rationales??[],...n.rationales]}},"mergeEdits"),ne={name:"document",addressable:"name",events:I({edited:{level:8,supersedes:!0,merge:H},deleted:{level:8}}),async listItem(e,t){return{summary:(await O(e,t)).summary??null,rules:(await h(e,t)).length}},async read(e,t,n,i){const s=await j(e,t,n,i.reposFn);await C(e,t,n);const a=s.record,o=await b(e,t,n),{attachments:c,linked:w}=await B(e,t,n),y=new Set(o.map(r=>r.id)),f=[...o,...await p(w.filter(r=>!y.has(r.id)),async r=>await d(e,r))],u={summary:a.summary??null,revision:a.revision,heads:s.heads.map(r=>({rev_id:r.rev_id,number:r.number,author_id:r.author,created_at:r.created_at})),bodies:s.heads.map(r=>r.body),needs_merge:s.needsMerge,...f.length>0?{listing:f}:{},...c===""?{}:{attachments:c}};return i.fields&&(u.fields={why_it_exists:a.why_it_exists??null,unlisted:a.unlisted,lint_ignore:a.lint_ignore??[],extensions:a.extensions??{},rules:(await h(e,n)).map(({matchFrontmatter:r,...g})=>({...g,...r===void 0?{}:{match_frontmatter:r}}))}),{data:u,text:W(await d(e,n),u)}}};export{ne as documentKind};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var a=Object.defineProperty;var d=(n,e)=>a(n,"name",{value:e,configurable:!0});import{
|
|
1
|
+
var a=Object.defineProperty;var d=(n,e)=>a(n,"name",{value:e,configurable:!0});import{getById as i}from"../objects.js";async function l(n,e){const t=e.owner===null?null:await i(n,e.owner),r=t?{id:t.id,type:t.type,handle:t.type==="node"?t.id:t.name}:null;return{id:e.id,type:e.type,kind:e.kind,owner:r,privacy:e.privacy,name:e.name,preview:e.preview??"",created_at:e.created_at,deleted_at:e.deleted_at}}d(l,"objectDTO");export{l as objectDTO};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jobRow as
|
|
2
|
-
`);return{data:t,text:
|
|
1
|
+
import{jobRow as d}from"../jobs.js";import{objectDTO as c}from"./dto.js";import{withBase as l}from"./kind.js";import{recordLiveRead as p}from"./live-read.js";import{attr as r,header as w}from"./render.js";const u={name:"job",addressable:"id",events:l({exited:{level:7},killed:{level:7}}),async read(a,i,e,s){const o=await d(a,e);if(!o)throw new Error(`job object ${e.id} has no jobs row`);await p(a,i,e,s.reposFn);const m=await c(a,e),t={command:o.command,status:o.status,exit_code:o.exit_code,log_path:o.log_path},n=[w("object",m,r("status",t.status)+r("exit_code",t.exit_code)),`Command: ${t.command}`,`Log: ${t.log_path}`].join(`
|
|
2
|
+
`);return{data:t,text:n}}};export{u as jobKind};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** The one interface every canvas object kind implements: its declared events, how it is
|
|
2
|
+
* addressed, and how it reads. The kind name is what `objects.type` stores. */
|
|
1
3
|
import type { ReposFn } from '../reader.js';
|
|
2
4
|
import type { ReceiverName } from '../receivers.js';
|
|
3
5
|
import type { CanvasEvent, Level, ObjectRow, Reader } from '../types.js';
|
|
@@ -63,5 +65,3 @@ export interface ObjectKind {
|
|
|
63
65
|
export declare const BASE_EVENTS: EventCatalog;
|
|
64
66
|
/** The base events with a kind's own merged over them. */
|
|
65
67
|
export declare function withBase(own?: EventCatalog): EventCatalog;
|
|
66
|
-
/** A live read of a non-document object: the reader watches it and its other watchers hear `read`. */
|
|
67
|
-
export declare function recordLiveRead(db: CanvasDb, reader: Reader, object: ObjectRow, reposFn: ReposFn): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var r=Object.defineProperty;var l=(e,t)=>r(e,"name",{value:t,configurable:!0});const d={created:{level:4},read:{level:1},watched:{level:1},deleted:{level:5},configured:{level:1}};function n(e={}){return{...d,...e}}l(n,"withBase");export{d as BASE_EVENTS,n as withBase};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ReposFn } from '../reader.js';
|
|
2
|
+
import type { ObjectRow, Reader } from '../types.js';
|
|
3
|
+
import type { CanvasDb } from '../../canvas/db.js';
|
|
4
|
+
/** A live read of a non-document object: the reader watches it and its other watchers hear `read`. */
|
|
5
|
+
export declare function recordLiveRead(db: CanvasDb, reader: Reader, object: ObjectRow, reposFn: ReposFn): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var c=Object.defineProperty;var o=(r,t)=>c(r,"name",{value:t,configurable:!0});import{actorOf as d}from"../documents.js";import{publish as f}from"../events.js";import{recordWatch as m}from"../watches.js";async function h(r,t,a,e){const i=d(t);i.id!==a.id&&(await m(r,i,a,"read"),await f(r,{event:"read",object:a,actor:i,attrs:{}},e))}o(h,"recordLiveRead");export{h as recordLiveRead};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var E=Object.defineProperty;var l=(t,r)=>E(t,"name",{value:r,configurable:!0});import{cancelCronsOnWake as _}from"../../canvas/crons.js";import{settleMatchingControllerWait as T}from"../../canvas/waits.js";import{effectiveTier as b,listenDeliveryTier as R,newId as I}from"../../feed/messages.js";import{readGoal as N}from"../../runtime/kickoff.js";import{canRead as h}from"../access.js";import{objectDTO as
|
|
2
|
-
`).map(r=>r.trim()).find(r=>r!=="")??""}l(g,"firstLine");const
|
|
3
|
-
VALUES (?, ?, ?, ?, ?, 'pending', ?, ?, ?)`);for(const e of a){const o=R(e.delivery),
|
|
4
|
-
WHERE n.parent = ? AND o.deleted_at IS NULL ORDER BY o.
|
|
5
|
-
`);return{data:i,text:w}}};export{
|
|
1
|
+
var E=Object.defineProperty;var l=(t,r)=>E(t,"name",{value:r,configurable:!0});import{cancelCronsOnWake as _}from"../../canvas/crons.js";import{settleMatchingControllerWait as T}from"../../canvas/waits.js";import{effectiveTier as b,listenDeliveryTier as R,newId as I}from"../../feed/messages.js";import{readGoal as N}from"../../runtime/kickoff.js";import{canRead as h}from"../access.js";import{objectDTO as y}from"./dto.js";import{withBase as S}from"./kind.js";import{recordLiveRead as L}from"./live-read.js";import{attr as O,header as D,section as m}from"./render.js";import{filterAsync as j,mapAsync as C}from"../../async-array.js";const p=[3,5,7];function g(t){return t?.split(`
|
|
2
|
+
`).map(r=>r.trim()).find(r=>r!=="")??""}l(g,"firstLine");const q={bodyOwner:l(t=>t[0]?.id??null,"bodyOwner"),async enqueue(t,r,a){const d=Date.now(),s=r.senderNodeId,n=a.map(e=>e.id),c=`(${n.map(()=>"?").join(",")})`,u=s===null?new Set:new Set((await t.prepareUncached(`SELECT DISTINCT node_id FROM waits WHERE kind = 'controller' AND target_id = ? AND satisfied_at IS NULL AND node_id IN ${c}`).all(s,...n)).map(e=>e.node_id)),i=new Set((await t.prepareUncached(`SELECT DISTINCT anchor_node FROM crons WHERE cancel_on_wake = 1 AND anchor_node IN ${c}`).all(...n)).map(e=>e.anchor_node)),w=t.prepare(`INSERT INTO deliveries (delivery_id, message_id, destination_id, urgency, wake, state, created_at, updated_at, idempotency_key)
|
|
3
|
+
VALUES (?, ?, ?, ?, ?, 'pending', ?, ?, ?)`);for(const e of a){const o=R(e.delivery),f=e.reception===2?o.wake:0,v=r.elevatesTier?await b(e.id,o.urgency):o.urgency;await w.run(I(),r.messageId,e.id,v,f,d,d,r.idempotencyKey===void 0?null:`${r.idempotencyKey}:${e.id}`),u.has(e.id)&&await T(e.id,s,d,t),f===1&&v!=="deferred"&&i.has(e.id)&&await _(e.id)}}},J={name:"node",addressable:"id",receiver:"inbox",receiverFor:l(async(t,r)=>await t.prepare("SELECT 1 FROM peer_stubs WHERE object = ?").get(r.id)===void 0?"inbox":"peer","receiverFor"),events:S({configured:{level:1,durable:!0},messaged:{level:2,durable:!0},sent:{level:1,durable:!0},"report.update":{level:5,levels:p,durable:!0,carriesBody:!0,elevatesTier:!0},"report.final":{level:7,durable:!0,carriesBody:!0,elevatesTier:!0,inboxKind:"final"},outcome:{level:1,durable:!0,supersedes:!0,carriesBody:!0},"report.result":{level:5,durable:!0,carriesBody:!0,elevatesTier:!0,inboxKind:"completed"},"notice.crash":{level:5,levels:p,durable:!0,carriesBody:!0,elevatesTier:!0},"notice.deadline":{level:5,levels:p,durable:!0,carriesBody:!0,elevatesTier:!0},"notice.close":{level:5,levels:p,durable:!0,carriesBody:!0,elevatesTier:!0}}),async read(t,r,a,d){const s=await t.prepare("SELECT status FROM nodes WHERE node_id = ?").get(a.id),n=l(async e=>await C(await j(e,async o=>await h(t,r,o)),async o=>await y(t,o)),"visible"),c=await t.prepare(`SELECT o.* FROM nodes n JOIN objects o ON o.id = n.node_id
|
|
4
|
+
WHERE n.parent = ? AND o.deleted_at IS NULL ORDER BY o.seq`).all(a.id),u=await t.prepare("SELECT * FROM objects WHERE owner = ? AND deleted_at IS NULL ORDER BY seq").all(a.id);await L(t,r,a,d.reposFn);const i={status:s?.status??"deleted",mandate_first_line:g(await N(a.id)),children:await n(c),owned:await n(u.filter(e=>e.type!=="job")),jobs:await n(u.filter(e=>e.type==="job"))},w=[D("object",await y(t,a),O("status",i.status)),`Mandate: ${i.mandate_first_line}`,...m("Children",i.children),...m("Owns",i.owned),...m("Jobs",i.jobs)].join(`
|
|
5
|
+
`);return{data:i,text:w}}};export{q as nodeInbox,J as nodeKind};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
`);return{data:
|
|
1
|
+
var p=Object.defineProperty;var d=(n,t)=>p(n,"name",{value:t,configurable:!0});import{objectDTO as c}from"./dto.js";import{withBase as l}from"./kind.js";import{recordLiveRead as h}from"./live-read.js";import{header as y}from"./render.js";function a(n){return{name:n,addressable:"handle",events:l(),async read(t,o,e,s){const r=await t.prepare("SELECT scheme, external_id FROM identities WHERE object = ?").get(e.id);await h(t,o,e,s.reposFn);const i={handle:e.name,display_name:e.preview||e.name,identity:{scheme:r?.scheme??"",external_id:r?.external_id??""}},m=[y("object",await c(t,e)),`Handle: ${i.handle}`,`Display name: ${i.display_name}`,`Identity: ${i.identity.scheme}:${i.identity.external_id}`].join(`
|
|
2
|
+
`);return{data:i,text:m}}}}d(a,"ownerKind");const $=[a("person"),a("app"),a("repo"),a("profile")];export{$ as ownerKinds};
|
package/dist/core/graph/names.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var $=Object.defineProperty;var s=(e,t)=>$(e,"name",{value:t,configurable:!0});import{isSafeNodeId as H}from"../canvas/paths.js";import{canRead as D,toolApps as C}from"./access.js";import{getById as M}from"./objects.js";import{filterAsync as O,findAsync as d,flatMapAsync as h}from"../async-array.js";async function S(e,t){const n=await e.prepare("SELECT * FROM objects WHERE type = 'person' AND name = 'user' AND home_machine IS NULL").get(),r=await C(e,t),o=t.class==="node"?[t.node,...t.repos,...t.projectRepos,t.profile,t.app]:t.class==="app"?[t.app]:t.class==="object"?[t.owner,...t.repos,t.app]:[],c=new Set;return[...o,n,...r].filter(a=>!!a&&!c.has(a.
|
|
2
|
-
AND deleted_at IS ${r?"NOT NULL ORDER BY deleted_at DESC":"NULL"}`).all(t.
|
|
3
|
-
OR (type IN ('person','app','repo','profile') AND (name = ? OR id = ?) AND home_machine IS NULL)`).all(t,t,t)}s(x,"ownersByHandle");async function P(e,t,n,r){let o=I(n);const c=/^([^:/]+):reports\/(.+?)(?:\.md)?$/.exec(o);c&&!j.test(o)&&(o=`${c[1]}/reports/${c[2]}`);const a=r?.readable??(async p=>await D(e,t,p)),
|
|
1
|
+
var $=Object.defineProperty;var s=(e,t)=>$(e,"name",{value:t,configurable:!0});import{isSafeNodeId as H}from"../canvas/paths.js";import{canRead as D,toolApps as C}from"./access.js";import{getById as M}from"./objects.js";import{filterAsync as O,findAsync as d,flatMapAsync as h}from"../async-array.js";async function S(e,t){const n=await e.prepare("SELECT * FROM objects WHERE type = 'person' AND name = 'user' AND home_machine IS NULL").get(),r=await C(e,t),o=t.class==="node"?[t.node,...t.repos,...t.projectRepos,t.profile,t.app]:t.class==="app"?[t.app]:t.class==="object"?[t.owner,...t.repos,t.app]:[],c=new Set;return[...o,n,...r].filter(a=>!!a&&!c.has(a.id)&&!!c.add(a.id))}s(S,"viewOf");async function m(e,t,n,r,o=!1){return await e.prepareUncached(`SELECT * FROM objects WHERE (type = 'document' OR strpos(type, '.') > 0) AND owner = ? AND name = ? AND home_machine IS ${o?"NOT NULL":"NULL"}
|
|
2
|
+
AND deleted_at IS ${r?"NOT NULL ORDER BY deleted_at DESC":"NULL"}`).all(t.id,n)}s(m,"namedObjects");const b=["person","app","repo","profile"],j=/^(person|app|repo|profile|node):([^/]+)\/(.+)$/,I=s(e=>e.trim().replace(/^\[\[(.*)\]\]$/,"$1").trim(),"unwrapRef");function g(e){const t=j.exec(e);if(t)return{type:t[1],handle:t[2],rest:t[3]};const n=e.indexOf("/");return n>0?{handle:e.slice(0,n),rest:e.slice(n+1)}:null}s(g,"splitOwnerRef");async function x(e,t,n){return n==="node"?await e.prepare("SELECT * FROM objects WHERE type = 'node' AND id = ?").all(t):n?await e.prepare("SELECT * FROM objects WHERE type = ? AND (name = ? OR id = ?) AND home_machine IS NULL").all(n,t,t):await e.prepare(`SELECT * FROM objects WHERE (type = 'node' AND id = ?)
|
|
3
|
+
OR (type IN ('person','app','repo','profile') AND (name = ? OR id = ?) AND home_machine IS NULL)`).all(t,t,t)}s(x,"ownersByHandle");async function P(e,t,n,r){let o=I(n);const c=/^([^:/]+):reports\/(.+?)(?:\.md)?$/.exec(o);c&&!j.test(o)&&(o=`${c[1]}/reports/${c[2]}`);const a=r?.readable??(async p=>await D(e,t,p)),l=await M(e,o);if(l&&await a(l))return l.deleted_at?{deleted:l}:{object:l};const y=r?.view??await S(e,t);for(const p of y){const f=await d(await m(e,p,o,!1),a);if(f)return{object:f}}const u=g(o);if(u){const{type:p,handle:f,rest:R}=u,T=p!==void 0,N=await x(e,f,p),L=s(i=>{const w=y.findIndex(_=>_.id===i.id);return w<0?1/0:w},"rank"),U=N.filter(i=>L(i)<1/0).sort((i,w)=>L(i)-L(w));for(const i of U){const w=await d(await m(e,i,R,!1),a);if(w)return{object:w}}const E=await O(await h(N,async i=>await m(e,i,R,!1)),a);if(E.length===1)return{object:E[0]};if(E.length>1)return{ambiguous:E};const A=await d(await h(N,async i=>await m(e,i,R,!0)),a);return A?{deleted:A}:!T&&N.length===0&&H(f)?{remote:o}:{missing:!0}}for(const p of y){const f=await d(await m(e,p,o,!0),a);if(f)return{deleted:f}}return{missing:!0}}s(P,"resolveName");async function V(e,t,n){const r=I(n),o=s(async(l,y)=>await O(await h(l,async u=>await m(e,u,y,!1,!0)),async u=>await D(e,t,u)),"found"),c=await o(await S(e,t),r);if(c.length)return c;const a=g(r);return a?await o(await x(e,a.handle,a.type),a.rest):[]}s(V,"stubsNamed");export{b as HANDLE_TYPES,x as ownersByHandle,P as resolveName,V as stubsNamed,I as unwrapRef,S as viewOf};
|
|
@@ -2,12 +2,11 @@ import type { ObjectRow, Privacy, Reader } from './types.js';
|
|
|
2
2
|
import type { CanvasDb } from '../canvas/db.js';
|
|
3
3
|
export type OwnerType = 'person' | 'app' | 'repo' | 'profile';
|
|
4
4
|
export declare function getById(db: CanvasDb, id: string): Promise<ObjectRow | null>;
|
|
5
|
-
export declare function getByRowid(db: CanvasDb, rowid: number): Promise<ObjectRow | null>;
|
|
6
5
|
export declare function createObject(db: CanvasDb, spec: {
|
|
7
6
|
id?: string;
|
|
8
7
|
type: string;
|
|
9
8
|
kind: string | null;
|
|
10
|
-
owner:
|
|
9
|
+
owner: string | null;
|
|
11
10
|
privacy: Privacy;
|
|
12
11
|
name: string;
|
|
13
12
|
preview: string;
|
|
@@ -28,7 +27,7 @@ export declare function renameProfileObject(db: CanvasDb, profileId: string, han
|
|
|
28
27
|
/** The owner object of a node grantee: `user:local` → person `user`; `app:<x>` → app `<x>`. */
|
|
29
28
|
export declare function ownerForGrantee(db: CanvasDb, grantee: string): Promise<ObjectRow>;
|
|
30
29
|
/** The owner's live document named `name`, or null. */
|
|
31
|
-
export declare function liveDocumentNamed(db: CanvasDb, owner:
|
|
30
|
+
export declare function liveDocumentNamed(db: CanvasDb, owner: string, name: string): Promise<ObjectRow | null>;
|
|
32
31
|
export declare function nodeObject(db: CanvasDb, nodeId: string): Promise<ObjectRow>;
|
|
33
32
|
export declare function setObjectName(db: CanvasDb, object: ObjectRow, name: string): Promise<void>;
|
|
34
33
|
export declare function setObjectKind(db: CanvasDb, object: ObjectRow, kind: string | null): Promise<void>;
|
|
@@ -40,11 +39,12 @@ export interface ObjectFilter {
|
|
|
40
39
|
name?: string;
|
|
41
40
|
deleted?: boolean;
|
|
42
41
|
}
|
|
42
|
+
/** `after_seq` is the `seq` of the last object on the previous page (the `/v1` cursor, a decimal number). */
|
|
43
43
|
export interface Page {
|
|
44
44
|
limit?: number;
|
|
45
|
-
|
|
45
|
+
after_seq?: number;
|
|
46
46
|
}
|
|
47
|
-
/** Objects the reader can read, in
|
|
47
|
+
/** Objects the reader can read, in `seq` (insertion) order. Records nothing. `limit` ≤ 100. */
|
|
48
48
|
export declare function listObjects(db: CanvasDb, reader: Reader, filter: ObjectFilter, page?: Page): Promise<ObjectRow[]>;
|
|
49
49
|
export interface SearchQuery {
|
|
50
50
|
text: string;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
var y=Object.defineProperty;var
|
|
2
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(e.id??await
|
|
3
|
-
WHERE i.scheme = ? AND i.external_id = ?`).get(t,
|
|
4
|
-
LEFT JOIN identities i ON i.object = o.
|
|
5
|
-
WHERE o.name = ? AND o.type = ? AND o.home_machine IS NULL`).get(n,e);if(
|
|
1
|
+
var y=Object.defineProperty;var s=(o,e)=>y(o,"name",{value:e,configurable:!0});import{CrtrError as N,notFound as _}from"../errors.js";import{ExitCode as L}from"../../types.js";import{newNodeId as j}from"../runtime/nodes.js";import{kindOf as I}from"./kinds/registry.js";import{canRead as l}from"./access.js";import{bodyOf as A}from"./bodies.js";const b=new Set(["person","app","repo","profile"]);function O(o){return o||null}s(O,"rowFrom");async function T(o,e){return O(await o.prepare("SELECT * FROM objects WHERE id = ?").get(e))}s(T,"getById");async function D(o,e){return await I(o,e.type),await o.prepare(`INSERT INTO objects (id, type, kind, owner, privacy, name, preview, created_at, home_machine)
|
|
2
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *`).get(e.id??await j(),e.type,e.kind,e.owner,e.privacy,e.name,e.preview,new Date().toISOString(),e.home_machine??null)}s(D,"createObject");async function R(o,e,t,r,n,i){if(!b.has(e))throw new Error(`ensureOwner: ${e} is not an owner type`);const d=await o.prepare(`SELECT o.* FROM identities i JOIN objects o ON o.id = i.object
|
|
3
|
+
WHERE i.scheme = ? AND i.external_id = ?`).get(t,r);if(d)return d;const c=await o.prepare(`SELECT o.id, o.type, i.scheme, i.external_id FROM objects o
|
|
4
|
+
LEFT JOIN identities i ON i.object = o.id
|
|
5
|
+
WHERE o.name = ? AND o.type = ? AND o.home_machine IS NULL`).get(n,e);if(c)throw new N("conflict",`handle "${n}" is held by ${c.type} ${c.id} (${c.scheme}:${c.external_id}); cannot give it to ${e} ${t}:${r}`,L.GENERAL,{handle:n,holder:c.id});const p=await D(o,{type:e,kind:null,owner:e==="profile"?i?.id??null:null,privacy:"public",name:n,preview:""});return await o.prepare("INSERT INTO identities (object, scheme, external_id) VALUES (?, ?, ?)").run(p.id,t,r),p}s(R,"ensureOwner");async function M(o,e,t){const r=await o.prepare(`SELECT o.* FROM identities i JOIN objects o ON o.id = i.object
|
|
6
6
|
WHERE i.scheme = 'profile' AND i.external_id = ? AND o.type = 'profile' AND o.deleted_at IS NULL`).get(e),n=await o.prepare(`SELECT o.id FROM objects o
|
|
7
|
-
WHERE o.name = ? AND o.type = 'profile' AND o.deleted_at IS NULL AND o.home_machine IS NULL AND o.
|
|
8
|
-
WHERE o.deleted_at IS NULL AND o.home_machine IS NULL AND (o.name
|
|
9
|
-
ORDER BY o.
|
|
10
|
-
AND NOT EXISTS (SELECT 1 FROM revision_parents p WHERE p.parent = r.
|
|
11
|
-
`),
|
|
7
|
+
WHERE o.name = ? AND o.type = 'profile' AND o.deleted_at IS NULL AND o.home_machine IS NULL AND o.id <> ?`).get(t,r?r.id:"");if(n)throw new N("conflict",`handle "${t}" is already held by profile object ${n.id}; cannot rename profile ${e} to it`,L.GENERAL,{handle:t,holder:n.id});if(!r)return!1;const i=r;return i.name===t?!1:(await x(o,i,t),!0)}s(M,"renameProfileObject");async function k(o,e){if(e==="user:local")return await R(o,"person","local-user",e,"user");if(/^app:[a-z0-9][a-z0-9._-]*$/.test(e))return await R(o,"app","app",e,e.slice(4));throw new Error(`node grantee ${JSON.stringify(e)} is neither app:<name> nor user:local`)}s(k,"ownerForGrantee");async function P(o,e,t){return O(await o.prepare("SELECT * FROM objects WHERE (type = 'document' OR strpos(type, '.') > 0) AND owner = ? AND name = ? AND deleted_at IS NULL AND home_machine IS NULL").get(e,t))}s(P,"liveDocumentNamed");async function J(o,e){const t=await T(o,e);if(!t||t.type!=="node")throw _(`no node object ${e}`);return t}s(J,"nodeObject");async function x(o,e,t){await o.prepare("UPDATE objects SET name = ? WHERE id = ?").run(t,e.id)}s(x,"setObjectName");async function B(o,e,t){await o.prepare("UPDATE objects SET kind = ? WHERE id = ?").run(t,e.id)}s(B,"setObjectKind");async function G(o,e,t,r={}){const n=["seq > ?"],i=[r.after_seq??0];return t.type!==void 0&&(n.push("type = ?"),i.push(t.type)),t.kind!==void 0&&(n.push("kind = ?"),i.push(t.kind)),t.owner!==void 0&&(n.push("owner = ?"),i.push(t.owner.id)),t.privacy!==void 0&&(n.push("privacy = ?"),i.push(t.privacy)),t.name!==void 0&&(n.push("name = ?"),i.push(t.name)),n.push("home_machine IS NULL"),n.push(t.deleted?"deleted_at IS NOT NULL":"deleted_at IS NULL"),await $(o,e,`SELECT * FROM objects WHERE ${n.join(" AND ")}`,i,Math.min(r.limit??100,100))}s(G,"listObjects");async function K(o,e,t){const n=[],i=`%${t.text.replace(/[\\%_]/g,a=>`\\${a}`)}%`;if(!t.grep){const a=await o.prepare(`SELECT o.*, d.summary AS _summary FROM objects o LEFT JOIN documents d ON d.object = o.id
|
|
8
|
+
WHERE o.deleted_at IS NULL AND o.home_machine IS NULL AND (o.name ILIKE ?1 ESCAPE '\\' OR o.preview ILIKE ?1 ESCAPE '\\' OR d.summary ILIKE ?1 ESCAPE '\\')
|
|
9
|
+
ORDER BY o.seq`).all(i),u=t.text.toLowerCase();for(const f of a){const{_summary:m,...E}=f,w=E;if(!await l(o,e,w))continue;const h=w.name.toLowerCase().includes(u)?"name":w.preview.toLowerCase().includes(u)?"preview":"summary";if(n.push({object:w,field:h,...h==="summary"?{text:String(m)}:{}}),n.length>=100)return n}}if(!t.body&&!t.grep)return n;const d=new Set(n.map(a=>a.object.id)),c=t.grep?(a=>u=>a.test(u))(new RegExp(t.text)):a=>a.includes(t.text),p=await o.prepare("SELECT * FROM objects WHERE type = 'document' AND deleted_at IS NULL ORDER BY seq").all(),S=o.prepare(`SELECT r.body_hash, d.source_path FROM revisions r JOIN documents d ON d.object = r.document WHERE r.document = ?
|
|
10
|
+
AND NOT EXISTS (SELECT 1 FROM revision_parents p WHERE p.parent = r.rev_id)`);for(const a of p)if(!(d.has(a.id)||!await l(o,e,a)))for(const{body_hash:u,source_path:f}of await S.all(a.id)){const m=A(u,f).split(`
|
|
11
|
+
`),E=m.findIndex(c);if(!(E<0)){if(n.push({object:a,field:"body",line:E+1,text:m[E]}),n.length>=100)return n;break}}return n}s(K,"searchObjects");async function $(o,e,t,r,n){const i=[],d=o.prepareUncached(`${t} ORDER BY seq LIMIT ${n*4}`);for(;;){const c=await d.all(...r);for(const p of c)if(await l(o,e,p)&&i.push(p),i.length===n)return i;if(c.length<n*4)return i;r[0]=c[c.length-1].seq}}s($,"readablePages");export{D as createObject,R as ensureOwner,T as getById,G as listObjects,P as liveDocumentNamed,J as nodeObject,k as ownerForGrantee,M as renameProfileObject,K as searchObjects,B as setObjectKind,x as setObjectName};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
var
|
|
2
|
-
WHERE o.type = 'document' AND o.deleted_at IS NULL AND d.source_path IS NOT NULL`).all();for(const{
|
|
3
|
-
WHERE o.type = 'document' AND o.owner = ? AND o.deleted_at IS NULL AND d.source_path = ?`).get(a.
|
|
4
|
-
WHERE o.type = 'document' AND o.owner = ? AND o.deleted_at IS NULL AND o.name = ? AND d.source_path IS NOT NULL`).get(a.
|
|
5
|
-
|
|
1
|
+
var S=Object.defineProperty;var u=(e,a)=>S(e,"name",{value:a,configurable:!0});import{createHash as _,randomUUID as O}from"node:crypto";import{CrtrError as g}from"../errors.js";import{emitEvent as I}from"../events/emit.js";import{quarantineBrokenPlugins as D}from"../plugin-quarantine.js";import{listInstalledPlugins as T}from"../resolver.js";import{builtinMemoryRoot as L,pluginMemoryDir as R}from"../scope.js";import{documentFields as k}from"../../migrations/004-canvas-documents/fields.js";import{applyDocumentFields as A,deleteDocument as j,documentRecord as F,heads as x,importDocument as C,linksIn as H,moveDocument as U}from"./documents.js";import{isShipped as b}from"./access.js";import{setLinks as J}from"./edges.js";import{publish as M}from"./events.js";import{resolveName as W}from"./names.js";import{packageFiles as P}from"./package-files.js";import{ensureOwner as q,getById as E,setObjectKind as B}from"./objects.js";import{checkoutsForCwd as K}from"./repo-sync/repos.js";import{rulesOf as $}from"./rules.js";function z(){return[{plugin:"crtr",dir:L()},...T("user").filter(e=>e.enabled).map(e=>({plugin:e.name,dir:R(e)}))]}u(z,"packageSources");const G=u(e=>_("sha256").update(e,"utf8").digest("hex"),"sha256");async function fe(e,a){const i={created:0,updated:0,deleted:0,conflicts:[],invalid:[],quarantined:[]};if(a===void 0){i.quarantined=D();for(const n of i.quarantined)I({level:"error",event:"daemon.plugins.quarantined",fields:{plugin:n.name,file:n.file,reason:n.reason,...n.movedTo!==void 0?{moved_to:n.movedTo}:{}}})}const l=a??z(),m=u(async n=>await K(e,n),"reposFn"),o=new Set,r=[],f=new Set;for(const n of l){let s;try{if(f.has(n.plugin))throw new g("conflict",`plugin "${n.plugin}" is already provided by another package`);f.add(n.plugin),s=await q(e,"app","app",`app:${n.plugin}`,n.plugin)}catch(p){if(!(p instanceof g)||p.code!=="conflict")throw p;i.conflicts.push({plugin:n.plugin,message:p.message});continue}o.add(s.id);const{files:d,invalid:w}=P(n.dir);i.invalid.push(...w);const h=new Set;for(const p of d){const c=await V(e,s,p,i,m);h.add(c),r.push({owner:s,id:c,body:p.body})}await v(e,s,h,i,m)}const t=await e.prepare(`SELECT DISTINCT o.owner AS id FROM objects o JOIN documents d ON d.object = o.id
|
|
2
|
+
WHERE o.type = 'document' AND o.deleted_at IS NULL AND d.source_path IS NOT NULL`).all();for(const{id:n}of t)o.has(n)||await v(e,await E(e,n),new Set,i,m);for(const{owner:n,id:s,body:d}of r)await Q(e,n,await E(e,s),d);return i}u(fe,"reconcilePackageDocuments");async function Q(e,a,i,l){if(i.deleted_at!==null)return;const m={class:"app",app:a,scopes:[]},o=[];for(const t of H(l)){const n=await W(e,m,t);"object"in n&&n.object.id!==i.id&&await b(e,n.object)&&o.push({written_as:t,dst:n.object})}const r=u(t=>JSON.stringify(t.map(n=>[n.dst,n.written_as]).sort()),"key"),f=await e.prepare("SELECT dst, written_as FROM edges WHERE type = 'links-to' AND src = ?").all(i.id);r(f)!==r(o.map(t=>({dst:t.dst.id,written_as:t.written_as})))&&await J(e,i,o)}u(Q,"deriveLinks");async function V(e,a,i,l,m){const o=k(i.frontmatter,i.body,{missingPrivacy:"public"}),r={preview:o.preview.trim()===""?i.name:o.preview,summary:o.summary,whyItExists:o.whyItExists,unlisted:o.unlisted,rules:o.rules,lintIgnore:Array.isArray(o.lintIgnore)?o.lintIgnore.filter(c=>typeof c=="string"):null,extensions:o.extensions!==null&&typeof o.extensions=="object"&&!Array.isArray(o.extensions)?o.extensions:null},f=G(i.body);let t=await e.prepare(`SELECT o.* FROM objects o JOIN documents d ON d.object = o.id
|
|
3
|
+
WHERE o.type = 'document' AND o.owner = ? AND o.deleted_at IS NULL AND d.source_path = ?`).get(a.id,i.path);if(t||(t=await e.prepare(`SELECT o.* FROM objects o JOIN documents d ON d.object = o.id
|
|
4
|
+
WHERE o.type = 'document' AND o.owner = ? AND o.deleted_at IS NULL AND o.name = ? AND d.source_path IS NOT NULL`).get(a.id,i.name),t&&await e.prepare("UPDATE documents SET source_path = ? WHERE object = ?").run(i.path,t.id)),!t){const c=await C(e,{owner:a,name:i.name,kind:o.kind,privacy:"public",...r,revisions:[{body_hash:f,author:a,rationale:null,created_at:new Date().toISOString()}]});return await e.prepare("UPDATE documents SET source_path = ? WHERE object = ?").run(i.path,c.id),l.created+=1,c.id}const n=t.name!==i.name||t.kind!==o.kind;t.name!==i.name&&(t=await U(e,null,t,{name:i.name})),t.kind!==o.kind&&(await B(e,t,o.kind),t=await E(e,t.id));const s=await F(e,t),[d]=await x(e,t),w=d?.body_hash!==f,h=t.preview!==r.preview||s.summary!==r.summary||s.why_it_exists!==r.whyItExists||s.unlisted!==r.unlisted||JSON.stringify(s.lint_ignore)!==JSON.stringify(r.lintIgnore)||JSON.stringify(s.extensions)!==JSON.stringify(r.extensions)||JSON.stringify((await $(e,t)).map(N))!==JSON.stringify(r.rules.map(N));if(!w&&!h&&!n)return t.id;const p=await A(e,t,r);if(w&&d){const c=O(),y=d.number+1;await e.prepare(`INSERT INTO revisions (rev_id, document, number, body_hash, author, rationale, verbatim, created_at)
|
|
5
|
+
SELECT ?, document, ?, ?, author, rationale, verbatim, ? FROM revisions WHERE rev_id = ?`).run(c,y,f,new Date().toISOString(),d.rev_id),await e.prepare("INSERT INTO revision_parents (child, parent) SELECT ?, parent FROM revision_parents WHERE child = ?").run(c,d.rev_id),await e.prepare("DELETE FROM revisions WHERE rev_id = ?").run(d.rev_id),await e.prepare("UPDATE documents SET heads_key = ?, revision = ? WHERE object = ?").run(c,y,p.id),await M(e,{event:"edited",object:p,actor:a,pointer:c,attrs:{revision:y,from_revision:d.number,rationale:"package file changed"}},m)}return l.updated+=1,p.id}u(V,"convergeFile");function N(e){return[e.on,e.deliver,e.match??null,e.matchFrontmatter??null,e.if??null]}u(N,"ruleKey");async function v(e,a,i,l,m){const o=await e.prepare(`SELECT o.* FROM objects o JOIN documents d ON d.object = o.id
|
|
6
|
+
WHERE o.type = 'document' AND o.owner = ? AND o.deleted_at IS NULL AND d.source_path IS NOT NULL`).all(a.id);for(const r of o)i.has(r.id)||(await j(e,null,r,m),l.deleted+=1)}u(v,"deleteMissing");export{z as packageSources,fe as reconcilePackageDocuments};
|
|
@@ -33,7 +33,7 @@ export interface ReaderLookups {
|
|
|
33
33
|
terminalHasIssuer(): boolean;
|
|
34
34
|
/** The scopes of the `crtr_app_` token a local plugin's app (`app:<plugin>`) holds, or null when it holds none. */
|
|
35
35
|
pluginScopes(grantee: string): readonly string[] | null;
|
|
36
|
-
object(
|
|
36
|
+
object(id: string): Promise<ObjectRow | null>;
|
|
37
37
|
profile(profileId: string, app: ObjectRow): Promise<ObjectRow>;
|
|
38
38
|
/** The profile's project paths in manifest order; none in a sandboxed node, whose profile store is unreadable. */
|
|
39
39
|
projectPaths(profileId: string): readonly string[];
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var F=Object.defineProperty;var p=(o,e)=>F(o,"name",{value:e,configurable:!0});import{coveredByAny as f,isSandboxedNode as x}from"../../shared/env.js";import{existsSync as H}from"node:fs";import{CrtrError as C}from"../errors.js";import{getStoredProfile as L}from"../scoped-state/profiles.js";import{userScopeRoot as A}from"../scope.js";import{parseScope as
|
|
2
|
-
sub, grant_id, scopes_json, cwd, profile_id FROM nodes WHERE node_id = ?`).get(n?.owner??null,e);if(!n||!l)throw new Error(`no node ${e}`);const{grantee:c,sub:s,grant_id:i,scopes_json:u,cwd:w,profile_id:j}=l,h=n.owner===null?null:await a.object(n.owner);if(!h)throw new Error(`node ${e} has no owner`);const S=u===null?null:JSON.parse(u);return{class:"node",node:n,app:h,scopes:await N(c,s??"",i,S,a,r),launched:S,cwd:w,...await y(w,j,t,a),profile:j===null?null:await a.profile(j,h)}}p(B,"readerForNode");async function ne(o,e,t=async()=>[],a=m(o)){const r=await o.prepare("SELECT envelope_json FROM peer_stubs WHERE object = ?").get(e.
|
|
1
|
+
var F=Object.defineProperty;var p=(o,e)=>F(o,"name",{value:e,configurable:!0});import{coveredByAny as f,isSandboxedNode as x}from"../../shared/env.js";import{existsSync as H}from"node:fs";import{CrtrError as C}from"../errors.js";import{getStoredProfile as L}from"../scoped-state/profiles.js";import{userScopeRoot as A}from"../scope.js";import{parseScope as O}from"@north-light/identity";import{activeGrant as R,grantFor as v}from"../grants/mirror.js";import{ApiError as b}from"../../api/errors.js";import{readConfig as $}from"../config.js";import{pluginAppToken as M}from"../secrets.js";import{SCOPE_VOCABULARY as d}from"../scopes.js";import{loadExactProfileManifest as T}from"../profiles/manifest.js";import{ensureOwner as _,getById as W,nodeObject as D}from"./objects.js";async function y(o,e,t,a){const r=e===null?[]:a.projectPaths(e),n=await t(o),l=new Set(n.map(s=>s.repo.id)),c=[];for(const s of r){if(!H(s))continue;let i;try{i=await t(s)}catch(u){if(u instanceof C&&u.code==="git-lookup-failed")continue;throw u}for(const u of i)l.has(u.repo.id)||(l.add(u.repo.id),c.push(u))}return{repos:n.map(s=>s.repo),checkouts:n,projectRepos:c.map(s=>s.repo),projectCheckouts:c}}p(y,"viewRepos");async function re(o,e,t){if(e.class==="anonymous")throw new Error("a publish token cannot read as a principal");if(e.class==="person")return{class:"person",person:await E(o)};if(e.class==="app")return{class:"app",app:await g(o,e.app),scopes:e.scopes};if(e.class==="machine")throw new Error("a machine token cannot read as a principal");if(e.class==="forwarded"){if(e.actor.kind==="person")return{class:"person",person:await E(o)};const c=await v(e.actor.app,e.sub);if(!c)throw new b(403,"app_not_granted",`${e.actor.app} holds no active grant for ${e.sub} on this machine`);const s=e.actor.node_scopes;return{class:"app",app:await g(o,e.actor.app),place:e.actor.place,launched:s,scopes:s===null?c.resolved:s.filter(i=>f(c.resolved,i))}}if(e.class==="cron"){const c=e.grant?(await R(e.grant))?.resolved??[]:d,s=e.scopes;return{class:"app",app:await g(o,e.app),scopes:s===null?c:s.filter(i=>f(c,i)),launched:s,place:{run:e.origin_run??"",isolated:e.isolated}}}const a=m(o),r=await D(o,e.node),n=r.owner===null?null:await a.object(r.owner);if(!n)throw new Error(`node ${e.node} has no owner`);const l=await o.prepare("SELECT cwd, profile_id FROM nodes WHERE node_id = ?").get(e.node);return{class:"node",node:r,app:n,scopes:await N(e.app,e.sub,e.grant,e.scopes,a),launched:e.scopes,cwd:l.cwd,...await y(l.cwd,l.profile_id,t,a),profile:l.profile_id===null?null:await a.profile(l.profile_id,n)}}p(re,"readerFor");async function B(o,e,t,a=m(o),r=!1){const n=await o.prepare("SELECT o.* FROM objects o WHERE o.id = ? AND o.type = 'node'").get(e),l=await o.prepare(`SELECT (SELECT external_id FROM identities WHERE object = ?) AS grantee,
|
|
2
|
+
sub, grant_id, scopes_json, cwd, profile_id FROM nodes WHERE node_id = ?`).get(n?.owner??null,e);if(!n||!l)throw new Error(`no node ${e}`);const{grantee:c,sub:s,grant_id:i,scopes_json:u,cwd:w,profile_id:j}=l,h=n.owner===null?null:await a.object(n.owner);if(!h)throw new Error(`node ${e} has no owner`);const S=u===null?null:JSON.parse(u);return{class:"node",node:n,app:h,scopes:await N(c,s??"",i,S,a,r),launched:S,cwd:w,...await y(w,j,t,a),profile:j===null?null:await a.profile(j,h)}}p(B,"readerForNode");async function ne(o,e,t=async()=>[],a=m(o)){const r=await o.prepare("SELECT envelope_json FROM peer_stubs WHERE object = ?").get(e.id);if(r!==void 0)return await P(o,e,r.envelope_json===null?null:JSON.parse(r.envelope_json),a);if(e.type==="node")return await B(o,e.id,t,a,!0);const n=e.owner===null?null:await a.object(e.owner);if(!n)throw new Error(`watcher ${e.id} has no owner`);const c=(n.type==="app"?n:n.type==="profile"&&n.owner!==null?await a.object(n.owner):null)??await o.prepare("SELECT o.* FROM identities i JOIN objects o ON o.id = i.object WHERE i.external_id = 'app:terminal' AND i.scheme = 'app'").get()??await o.prepare("SELECT * FROM objects WHERE type = 'person' AND name = 'user' AND home_machine IS NULL").get();if(!c)throw new Error("no terminal app or person object");const s=(await o.prepare("SELECT external_id FROM identities WHERE object = ? AND scheme = 'app'").get(c.id))?.external_id??"app:terminal",i=await o.prepare("SELECT resolved_scopes_json FROM grants WHERE grantee = ? AND status = 'active'").all(s),u=n.type==="person"?null:i.length===0?s==="app:terminal"&&!a.terminalHasIssuer()?d:a.pluginScopes(s):i.length===1?JSON.parse(i[0].resolved_scopes_json).filter(w=>w.mode==="always").map(w=>O(w.scope)):null;return{class:"object",object:e,node:e,owner:n,app:c,scopes:u,repos:n.type==="repo"?[n]:[]}}p(ne,"readerForObject");async function te(o,e,t){const a=(await o.prepare("SELECT external_id FROM identities WHERE object = ? AND scheme = 'app'").get(e.id))?.external_id;if(a===void 0)return null;const r=await o.prepare("SELECT resolved_scopes_json FROM grants WHERE grantee = ? AND status = 'active'").all(a);return r.length===0?a==="app:terminal"&&!t.terminalHasIssuer()?d:t.pluginScopes(a):r.length>1?null:JSON.parse(r[0].resolved_scopes_json).filter(n=>n.mode==="always").map(n=>O(n.scope))}p(te,"appScopesNow");async function P(o,e,t,a){const r=await E(o);if(t!==null&&t.app===null)return{class:"object",object:e,node:e,owner:r,app:r,scopes:null,repos:[]};const n=t?.app==null?null:await g(o,t.app),l=t?.app==null?null:await a.grantFor(t.app,t.sub),c=t===null||l===null?null:t.node_scopes===null?l.resolved:t.node_scopes.filter(i=>f(l.resolved,i)),s=n??(e.owner===null?r:await a.object(e.owner)??r);return{class:"object",object:e,node:e,owner:s,app:s,scopes:c,launched:t?.node_scopes??null,repos:[],...t?.place==null?{}:{place:t.place}}}p(P,"readerForStub");function m(o){return{grantById:R,grantFor:v,terminalHasIssuer:p(()=>!!$("user").runtime?.issuer,"terminalHasIssuer"),pluginScopes:p(e=>M(e.replace(/^app:/,""))?.scopes??null,"pluginScopes"),object:p(async e=>await W(o,e),"object"),profile:p(async(e,t)=>await I(o,e,t),"profile"),projectPaths:p(e=>x()?[]:L(A(),e)?.manifest.projects.map(t=>t.path)??[],"projectPaths")}}p(m,"liveLookups");function ae(o){const e=m(o),t=new Map,a=p((r,n)=>(t.has(r)||t.set(r,n()),t.get(r)),"memo");return{grantById:p(r=>a(`g\0${r}`,()=>e.grantById(r)),"grantById"),grantFor:p((r,n)=>a(`a\0${r}\0${n}`,()=>e.grantFor(r,n)),"grantFor"),terminalHasIssuer:p(()=>a("issuer",()=>e.terminalHasIssuer()),"terminalHasIssuer"),pluginScopes:p(r=>a(`t\0${r}`,()=>e.pluginScopes(r)),"pluginScopes"),object:p(async r=>await a(`o\0${r}`,async()=>await e.object(r)),"object"),profile:p(async(r,n)=>await a(`p\0${r}\0${n.id}`,async()=>await e.profile(r,n)),"profile"),projectPaths:p(r=>a(`j\0${r}`,()=>e.projectPaths(r)),"projectPaths")}}p(ae,"publishLookups");async function N(o,e,t,a,r,n=!1){const l=t?await r.grantById(t):await r.grantFor(o,e),c=l&&l.grantee===o?l.resolved:o==="app:terminal"&&!r.terminalHasIssuer()?d:null;if(c===null){if(n)return null;throw new Error(`the grant of ${o} is not active`)}return a===null?c:a.filter(s=>f(c,s))}p(N,"nodeScopes");async function E(o){return await _(o,"person","local-user","user:local","user")}p(E,"personObject");async function g(o,e){return e==="user:local"?await E(o):await _(o,"app","app",e,e.replace(/^app:/,""))}p(g,"appObject");async function I(o,e,t){return await o.prepare(`SELECT o.* FROM identities i JOIN objects o ON o.id = i.object
|
|
3
3
|
WHERE i.scheme = 'profile' AND i.external_id = ?`).get(e)??await _(o,"profile","profile",e,T(e).manifest.name,t)}p(I,"profileObject");export{te as appScopesNow,m as liveLookups,I as profileObject,ae as publishLookups,re as readerFor,B as readerForNode,ne as readerForObject,y as viewRepos};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
var
|
|
2
|
-
AND state = 'pending' AND canceled_at IS NULL`).get(
|
|
1
|
+
var E=Object.defineProperty;var i=(e,t)=>E(e,"name",{value:t,configurable:!0});import{randomBytes as l}from"node:crypto";import{nodeInbox as f}from"./kinds/node.js";import{peerReceiver as g}from"../peer/receiver.js";async function O(e,t){const r=await e.prepare("SELECT receiver_json FROM custom_objects WHERE object = ?").get(t.id);if(!r?.receiver_json)return;const n=JSON.parse(r.receiver_json);if(n==="queue")return"queue";if(n&&typeof n=="object"&&!Array.isArray(n)){if("url"in n)return"url";if("argv"in n)return"argv"}}i(O,"receiverForObject");const u=1e3,s=new Map;async function T(e,t){const r=s.get(e)??new Set;return r.add(t),s.set(e,r),()=>{r.delete(t),r.size===0&&s.delete(e)}}i(T,"onQueueSignal");function _(e){setImmediate(()=>{for(const t of s.get(e)??[])t()})}i(_,"signalQueue");async function m(e,t){const r=(await e.prepare(`SELECT COUNT(*) AS n FROM deliveries WHERE destination_id = ?
|
|
2
|
+
AND state = 'pending' AND canceled_at IS NULL`).get(t)).n;if(r<=u)return;const n=await e.prepare(`SELECT delivery_id, message_id FROM deliveries
|
|
3
3
|
WHERE destination_id = ? AND state = 'pending' AND canceled_at IS NULL
|
|
4
|
-
ORDER BY created_at,
|
|
5
|
-
(SELECT rowid FROM objects WHERE id = ?)`).run(n.length,r)}i(R,"cap");function c(e,r){return{bodyOwner:i(()=>null,"bodyOwner"),async enqueue(t,n,a){const o=Date.now(),E=t.prepare(`INSERT INTO deliveries
|
|
4
|
+
ORDER BY created_at, seq LIMIT ?`).all(t,r-u);for(const a of n)await e.prepare("DELETE FROM deliveries WHERE delivery_id = ?").run(a.delivery_id),await e.prepare("DELETE FROM messages WHERE message_id = ? AND NOT EXISTS (SELECT 1 FROM deliveries WHERE message_id = ?)").run(a.message_id,a.message_id);n.length&&await e.prepare("UPDATE custom_objects SET dropped = dropped + ? WHERE object = ?").run(n.length,t)}i(m,"cap");function c(e,t){return{bodyOwner:i(()=>null,"bodyOwner"),async enqueue(r,n,a){const o=Date.now(),p=r.prepare(`INSERT INTO deliveries
|
|
6
5
|
(delivery_id, message_id, destination_id, urgency, wake, state, next_attempt_at, created_at, updated_at)
|
|
7
|
-
VALUES (?, ?, ?, 'normal', 0, 'pending', ?, ?, ?)`);for(const d of a)await
|
|
6
|
+
VALUES (?, ?, ?, 'normal', 0, 'pending', ?, ?, ?)`);for(const d of a)await p.run(l(16).toString("hex"),n.messageId,d.id,e?o:null,o,o),await m(r,d.id),t&&_(d.id)}}}i(c,"pushReceiver");const v=c(!0,!1),L={inbox:f,argv:v,url:c(!0,!1),queue:c(!1,!0),peer:g};export{u as BACKLOG_CAP,L as RECEIVERS,v as argvReceiver,T as onQueueSignal,O as receiverForObject,_ as signalQueue};
|