@probnaya/057-cli 1.0.1 → 1.1.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/NOTICE.md +2 -1
- package/README.md +15 -7
- package/dist-server/057.mjs +1 -1
- package/package.json +1 -1
package/NOTICE.md
CHANGED
|
@@ -29,12 +29,13 @@ falls through to the system monospace when it is not installed locally, so no fo
|
|
|
29
29
|
and no font licence applies.
|
|
30
30
|
|
|
31
31
|
**057 Desktop** (`057.app`, built by `desktop/app/bundle.sh`; not part of the npm package)
|
|
32
|
-
redistributes
|
|
32
|
+
redistributes three further components, each with its licence inside the app bundle:
|
|
33
33
|
|
|
34
34
|
| Component | Version | License | Copyright | In the bundle |
|
|
35
35
|
| --- | --- | --- | --- | --- |
|
|
36
36
|
| IBM Plex Mono, Regular and Medium (WOFF2, unmodified) | 2.5.0 | SIL Open Font License 1.1 | © 2017 IBM Corp., Reserved Font Name "Plex" | `Contents/Resources/Fonts/IBMPlexMono-LICENSE.txt` |
|
|
37
37
|
| Node.js (official darwin-arm64 build, re-signed as the Core helper) | 24.14.0 | MIT, with the third-party licences Node lists | Node.js contributors and others | `Contents/Resources/Licenses/Node-LICENSE.txt` |
|
|
38
|
+
| Sparkle (the update framework; arm64 slices only, without its XPC services, re-signed) | 2.10.0 | MIT, with the external licences Sparkle lists | © 2006–2013 Andy Matuschak and the Sparkle contributors | `Contents/Resources/Licenses/Sparkle-LICENSE.txt` |
|
|
38
39
|
|
|
39
40
|
---
|
|
40
41
|
|
package/README.md
CHANGED
|
@@ -49,9 +49,10 @@ and open it. The app carries its own Core — no Node, npm or terminal — and s
|
|
|
49
49
|
opens. Closing the window leaves it observing from the menu bar; quitting the app stops it. It is
|
|
50
50
|
signed with Developer ID and notarized by Apple.
|
|
51
51
|
|
|
52
|
-
**Open in Browser** (the menu-bar menu, or View) opens the browser surface its Core serves.
|
|
53
|
-
|
|
54
|
-
source has failed for ten minutes.
|
|
52
|
+
**Open in Browser** (the menu-bar menu, or View) opens the browser surface its Core serves. At its
|
|
53
|
+
first launch 057 asks, the way Mac apps do, whether it may send notifications: allowed, it tells you
|
|
54
|
+
only when its Core fails or a source has failed for ten minutes, silently. **Notifications** in the
|
|
55
|
+
**057** menu switches them afterwards.
|
|
55
56
|
|
|
56
57
|
### The web / CLI surface
|
|
57
58
|
|
|
@@ -109,10 +110,17 @@ pointer to the record it read a fact from, never a copy of it.
|
|
|
109
110
|
**Where:** one SQLite database at `~/.057/events.db`, created owner-only (`0700`/`0600`). Nowhere
|
|
110
111
|
else. `O57_STORE` overrides it; `057 status` prints the path, size and permissions.
|
|
111
112
|
|
|
112
|
-
**Sent:** nothing. No account, no cloud, no synchronisation, no product
|
|
113
|
-
reporting, no update check. The interface fetches nothing but its own local API —
|
|
114
|
-
font. The only connection is the loopback socket between your browser and the local
|
|
115
|
-
057's own behaviour; the runtimes it observes talk to their providers on their own
|
|
113
|
+
**Sent:** by the web / CLI surface, nothing. No account, no cloud, no synchronisation, no product
|
|
114
|
+
analytics, no crash reporting, no update check. The interface fetches nothing but its own local API —
|
|
115
|
+
not even a web font. The only connection is the loopback socket between your browser and the local
|
|
116
|
+
server. This is 057's own behaviour; the runtimes it observes talk to their providers on their own
|
|
117
|
+
terms.
|
|
118
|
+
|
|
119
|
+
The macOS app adds exactly one request: **an update check**, to
|
|
120
|
+
`https://057.probnaya.work/appcast.xml`, about once a day — on by default, and off with *Check for
|
|
121
|
+
Updates Automatically* in the 057 menu (*Check for Updates…* beside it checks at once). The request
|
|
122
|
+
carries the app's version and nothing else — no system profile, none of your telemetry. An update is
|
|
123
|
+
installed only when you choose to, and only if it carries 057's signature.
|
|
116
124
|
|
|
117
125
|
**Kept:** process observations 7 days, sessions and executions 90 days, machine identity forever.
|
|
118
126
|
Both windows are configurable. Deleting rows lets SQLite reuse the pages, so the store plateaus
|
package/dist-server/057.mjs
CHANGED
|
@@ -74,7 +74,7 @@ CREATE INDEX IF NOT EXISTS claims_event ON claims(event_id);
|
|
|
74
74
|
(SELECT id FROM events WHERE subject_type = ? AND subject_id = ?)`),$=t.prepare("DELETE FROM events WHERE subject_type = ? AND subject_id = ?");let O=0,U=0,X=0;t.exec("BEGIN");try{for(const{type:j,id:N}of l.values()){X+=Number(_.run(j,N).changes);const V=Number($.run(j,N).changes);ms.includes(j)?O+=V:U+=V}t.exec("COMMIT")}catch(j){throw t.exec("ROLLBACK"),j}return O+U>0&&w.checkpoint(),{processEvents:O,otherEvents:U,claims:X,subjects:l.size,retainedByDependents:C,processBefore:v,otherBefore:d}},checkpoint(){try{t.exec("PRAGMA wal_checkpoint(TRUNCATE)")}catch{}},sizeBytes(){const[p,m,v]=ze(e).map(yi);return{db:p,wal:m,shm:v,total:p+m+v}},health(){const p=o.size;return p===0?{ok:!0,malformedRows:0,columns:[],since:null}:{ok:!1,malformedRows:p,columns:[...r].sort(),since:a,remedy:`${p} stored row(s) could not be read as JSON and lost their ${[...r].sort().join("/")} channel. Everything else is being used normally and nothing has been deleted. Run \`057 compact\` to rewrite the store; if the count keeps growing, back the store up and run \`057 reset\` to start a new one.`}},compact(){t.exec("VACUUM"),w.checkpoint(),lt(e)},close(){w.checkpoint(),t.close()}};return w}function yi(e){try{return qe(e).size}catch{return 0}}function Pe(e,t,s){if(e!=null)try{const n=JSON.parse(String(e));if(n&&typeof n=="object")return n;t&&s?.(t);return}catch{t&&s?.(t);return}}function wi(e,t){const s=e,n=t?o=>t(o,String(s.id)):void 0;return{id:String(s.id),source:{id:String(s.source_id),instance:String(s.source_instance)},occurredAt:Number(s.occurred_at),observedAt:Number(s.observed_at),clock:s.clock,kind:s.kind,subject:{type:s.subject_type,id:String(s.subject_id)},core:Pe(s.core,"core",n),attrs:Pe(s.attrs,"attrs",n),basis:s.basis,assumption:s.assumption?String(s.assumption):void 0,stratum:s.stratum?s.stratum:void 0,provenance:Pe(s.provenance,"provenance",n)}}const Ai=Fn(Dn);function Si(){return $s()}function Ei(e){const t=[];for(const s of e.split(`
|
|
75
75
|
`)){const n=s.trim();if(!n)continue;const o=n.match(/^(\d+)\s+(\d+)\s+(\w{3}\s+\w{3}\s+\d+\s+[\d:]+\s+\d{4})\s+([\d:.]+)\s+(\d+)\s+(.*)$/);if(!o)continue;const[,r,a,i,c,u,h]=o,f=Date.parse(i);Number.isFinite(f)&&t.push({pid:Number(r),ppid:Number(a),startedAt:f,cpuMs:ki(c),rssBytes:Number(u)*1024,command:h.trim()})}return t}function ki(e){const[t,s]=e.includes("-")?e.split("-"):["0",e],n=s.split(":").map(Number);let o=0;for(const r of n)o=o*60+(Number.isFinite(r)?r:0);return Math.round((o+Number(t)*86400)*1e3)}async function Ii(){const{stdout:e}=await Ai("ps",["-Ao","pid=,ppid=,lstart=,time=,rss=,comm="],{maxBuffer:8388608});return Ei(e)}const bs=5e3;function Ti(e,t){const s=Si();let n=new Map,o=null,r=0,a=null,i,c=!1;async function u(){if(c)return[];c=!0;try{const h=await Ii(),f=Date.now(),{envelopes:E,next:b}=pr(n,h,{machineId:t,host:s,observedAt:f,intervalMs:bs}),w=E.map(se);return e.append(w),n=b,r++,a=f,i=void 0,w}catch(h){return i=h instanceof Error?h.message:String(h),[]}finally{c=!1}}return{sample:u,start(){o||(u(),o=setInterval(()=>{u()},bs),o.unref?.())},stop(){o&&clearInterval(o),o=null},get running(){return o!==null},stats(){return{samples:r,tracked:n.size,lastSampleAt:a,lastError:i}}}}const fn={info:e=>console.log(e),warn:e=>console.warn(e),error:e=>console.error(e)},Mi=36e5,Oi=15e3,$i=3;function It(e={}){const t=e.log??fn,s=e.path??Ve(),n=e.retention??un(),o=vi(s),r=o.stats();t.info(r.events>0?`[057] store ${s}: opened with ${r.events} events`:`[057] store ${s}: NEW EMPTY STORE — if history existed before, it was lost, not carried`);const a=pn();a&&t.warn(`[057] a store from a previous layout exists at ${a} and is NOT in use. Run 057 with O57_STORE=${a} to keep using it, or move it to ${s}.`);const i=ge();o.append([se({source:{id:"host",instance:i.id},occurredAt:0,observedAt:Date.now(),clock:"wall",kind:"began",stratum:"machine",subject:{type:"machine",id:i.id},basis:"measured",core:{machineName:i.name,machineKind:i.kind},seq:"host"})]);const c=Ti(o,i.id),u=new Map;function h(d){for(const A of d){const g=u.get(A.id)??{consecutiveFailures:0,totalFailures:0,failing:!1};A.ok?(g.consecutiveFailures=0,g.failing=!1,g.failingSince=void 0,g.lastSuccessAt=Date.now()):(g.consecutiveFailures===0&&(g.failingSince=Date.now()),g.consecutiveFailures++,g.totalFailures++,g.lastFailureAt=Date.now(),g.lastError=A.error,g.consecutiveFailures>=$i&&!g.failing&&(g.failing=!0,t.warn(`[057] source ${A.id} has failed ${g.consecutiveFailures} collection rounds in a row: ${A.error??"unknown error"}`))),u.set(A.id,g)}}const f=vs(s);let E=null;function b(d){return E||(E=d,t.error(`[057] ${d.message} — ${d.remedy}`),c.stop()),E}function w(){if(E)return E;if(s===":memory:")return null;if(!L(s))return b({kind:"unlinked",message:`the store at ${s} no longer exists on disk; captured events are going to an orphaned file and will be lost`,remedy:"Stop 057 and start it again. It will open a new store at the same path.",since:Date.now()});const d=vs(s);return f!==null&&d!==null&&d!==f?b({kind:"replaced",message:`the store at ${s} was replaced by a different file while 057 was running; captured events are going to the old one`,remedy:"Stop 057 and start it again so it opens the file that is actually there.",since:Date.now()}):null}e.observe!==!1&&c.start();const p=o.sweep(n);p.processEvents+p.otherEvents>0&&t.info(`[057] retention: removed ${p.processEvents} process and ${p.otherEvents} semantic events (${Ye(n)})`);const m=setInterval(()=>{if(!E)try{o.sweep(n),lt(s)}catch(d){t.warn(`[057] retention sweep failed: ${String(d)}`)}},Mi);m.unref?.();const v=setInterval(()=>{w()},Oi);return v.unref?.(),{store:o,machine:i,os:c,path:s,retention:n,fault:()=>E,sweep:d=>o.sweep(n,d),checkStore:w,recordCollection:h,collectionHealth:()=>Object.fromEntries(u),stop(){clearInterval(m),clearInterval(v),c.stop(),o.close()}}}function vs(e){try{return qe(e).ino}catch{return null}}const pt=[{id:Os,collect:(e,t)=>ao(e,t)},{id:rt,collect:(e,t)=>Ao(e,t)},{id:Se,collect:(e,t)=>No(e,t)},{id:De,collect:(e,t)=>Bo(e,t)},{id:Oe,collect:(e,t)=>zo(e,t)},{id:Le,collect:(e,t)=>ir(e,t)}],ys=[...pt.map(e=>e.id),pe],ws=10*365*24*36e5,je=2e5,Ri=24*36e5,xi=72*36e5;function As(e){const t=new Date(e);return t.setHours(0,0,0,0),{from:t.getTime(),to:e}}function Ss(e){const t=e.collectionHealth(),s=Object.entries(t).filter(([,i])=>i.failing).map(([i])=>i),n=e.store.health(),o=e.os.stats(),r=e.fault();let a=null;for(const i of Object.values(t))i.lastSuccessAt&&(a===null||i.lastSuccessAt>a)&&(a=i.lastSuccessAt);return{ok:s.length===0&&n.ok&&!r&&!o.lastError,fault:r??void 0,failingSources:s,errors:Object.fromEntries(Object.entries(t).filter(([,i])=>i.failing).map(([i,c])=>[i,c.lastError??"failing"])),failing:Object.fromEntries(Object.entries(t).filter(([,i])=>i.failing).map(([i,c])=>[i,{since:c.failingSince??null,rounds:c.consecutiveFailures}])),store:{ok:n.ok,remedy:n.remedy},os:{running:e.os.running,lastSampleAt:o.lastSampleAt,lastError:o.lastError},lastCollectionAt:a,sources:{total:ys.length,reported:ys.filter(i=>t[i]!==void 0).length}}}function Ni(e,t,s){const n=t.startsWith("/api/");if(s){const i=(e.headers.host??"").toLowerCase(),c=i.startsWith("[")?i.slice(0,i.indexOf("]")+1):i.split(":")[0];if(!s.includes(c))return`refusing a request for host "${i}"; 057 answers only on ${s.join(", ")}`}const o=e.headers.origin;if(typeof o=="string"&&o!=="null"){const i=(e.headers.host??"").toLowerCase();let c="";try{c=new URL(o).host.toLowerCase()}catch{return"refusing a request with an unparseable Origin"}if(c!==i)return`refusing a cross-origin request from ${o}`}const r=e.headers["sec-fetch-site"],a=String(e.headers["sec-fetch-dest"]??"");if(Ci.has(a))return`refusing to be embedded as ${a}`;if(typeof r=="string"&&r!==""){if(r!=="same-origin"&&r!=="none")return`refusing a ${r} request`;if(r==="none"&&n)return"refusing a directly-navigated API request"}else if(n&&t==="/api/collect"&&!e.headers[_i])return"refusing a state-changing request that carries no fetch metadata";return null}const _i="x-057-client",Ci=new Set(["iframe","frame","embed","object","fencedframe"]);function Tt(e){e.setHeader("x-frame-options","DENY"),e.setHeader("content-security-policy","frame-ancestors 'none'")}function ji(e,t){const s=(r,a)=>{const i=e.get(r);if(i===null||i==="")return a;const c=Number(i);return Number.isSafeInteger(c)?c:null},n=s("from",t-864e5),o=s("to",t);return n===null||o===null?{error:"from and to must be integer epoch millis"}:o<n?{error:"to must not precede from"}:o>t+Ri?{error:"to is too far in the future"}:o-n>ws?{error:`window must not exceed ${ws} ms`}:{from:n,to:o}}function B(e,t,s){e.statusCode=t,e.setHeader("content-type","application/json"),e.setHeader("cache-control","no-store"),e.setHeader("x-content-type-options","nosniff"),Tt(e),e.end(JSON.stringify(s))}function mn(e,t,s,n,o){const r=o?Di(o):void 0,a=r?Es(e.query(t,s,n),r):e.query(t,s,n),i=new Set,c=new Set,u=E=>{const b=`${E.subject.type}:${E.subject.id}`;E.kind==="began"?i.add(b):c.add(b),E.core?.sessionId&&c.add(`session:${E.core.sessionId}`),E.core?.machineId&&c.add(`machine:${E.core.machineId}`)};for(const E of a)u(E);const h=[];for(let E=0;E<4;E++){const b=[...c].filter(p=>!i.has(p));if(b.length===0)break;const w=r?Es(e.begansFor(b),r):e.begansFor(b);if(w.length===0)break;for(const p of w)h.push(p.occurredAt<t?{...p,occurredAt:t}:p),u(p),i.add(`${p.subject.type}:${p.subject.id}`)}return{events:[...h,...a].sort((E,b)=>E.occurredAt-b.occurredAt||ks(E)-ks(b)),relationships:Vn(e,t,s).relationships}}function Di(e){const t=to(e);return s=>{if(s.subject.type==="machine")return s.subject.id!==e&&jt(s.subject.id)?null:s;const n=s.core?.machineId;if(!n||n===e||!jt(n))return s;const o=s.subject.type==="process"&&t?cr(s.subject.id,t):void 0;return{...s,...o?{subject:{...s.subject,id:o}}:{},core:{...s.core,machineId:e}}}}function Es(e,t){const s=[];for(const n of e){const o=t(n);o&&s.push(o)}return s}function Ie(e,t,s,n){const o=performance.now(),{events:r,relationships:a}=mn(e,t,s,void 0,n),i=performance.now()-o,c=performance.now(),u=tn(t,s);Ar(u,r),Sr(u,s);const h=performance.now()-c,f=performance.now(),E=Ir(u,a),b=performance.now()-f;return{world:E,meta:{events:r.length,readMs:Math.round(i*10)/10,deriveMs:Math.round(h*10)/10,serializeMs:Math.round(b*10)/10}}}function ks(e){if(e.kind==="ended")return 5;switch(e.subject.type){case"machine":return 0;case"session":return 1;case"execution":case"process":return e.kind==="began"?2:3;default:return 4}}function Fi(e){const t=e.problems.filter(s=>s.path.includes("/sessions/")).length;return{identity:e.identityAvailable?t===0?"available":e.registryEntries>0?"partial":"failed":"unavailable","stored-semantics":e.storedAvailable?e.transcriptsFailed===0?"available":e.transcriptsRead>0?"partial":"failed":"unavailable","live-semantics":"unavailable"}}function ot(e){return{"stored-semantics":e.storedAvailable?e.failed===0?"available":e.read>0?"partial":"failed":"unavailable","live-semantics":"unavailable"}}function Li(e){return e.error?"failed":e.available?"observing":e.present?"installed-no-data":"not-installed"}function Ui(e){const t=e.home??e.globalStorage;if(typeof t=="string")return t;const s=e.roots;return Array.isArray(s)?s.join(", "):void 0}function le(e){return{available:e.available,present:e.present??!1,presence:Li(e),origin:Ui(e),error:e.error}}function Pi(e){const{runtime:t,log:s}=e;let n=null;function o(r){if(!n||r-n.at>6e4){const a=As(r),i=ts(Ie(t.store,a.from,a.to,t.machine.id).world);n={at:r,label:"TODAY",world:i,landscape:ls(i)}}return n}return async function(a,i){const c=a.url??"";if(!c.startsWith("/api/"))return!1;const u=new URL(c,"http://localhost"),h=Ni(a,u.pathname,e.allowedHosts);if(h)return s.warn(`[057] ${h}`),B(i,403,{error:h}),!0;const f=t.store,E=Date.now(),b=ji(u.searchParams,E);if("error"in b)return B(i,400,{error:b.error}),!0;const{from:w,to:p}=b;try{if(u.pathname==="/api/state"){const[m,v,d,A,g,y]=await Promise.all([Ft().catch(N=>({available:!1,error:String(N)})),Ht().catch(N=>({available:!1,error:String(N)})),Xt().catch(N=>({available:!1,error:String(N)})),qt().catch(N=>({available:!1,error:String(N)})),Kt().catch(N=>({available:!1,error:String(N)})),Qt().catch(N=>({available:!1,error:String(N)}))]),[M,l,S,k]=await Promise.all([Us(w,p).catch(()=>null),Ws(w,p).catch(()=>null),qs(w,p).catch(()=>null),Ks(w,p).catch(()=>null)]),T={strata:{"stored-semantics":"failed"}},I={"claude-code":M?{strata:Fi(M),registryEntries:M.registryEntries,transcriptsRead:M.transcriptsRead,transcriptsFailed:M.transcriptsFailed,problems:M.problems.slice(0,20)}:{strata:{identity:"failed"}},codex:l?{strata:ot({storedAvailable:l.storedAvailable,read:l.rolloutsRead,failed:l.rolloutsFailed}),rolloutsRead:l.rolloutsRead,rolloutsFailed:l.rolloutsFailed,problems:l.problems.slice(0,20)}:T,cursor:S?{strata:ot({storedAvailable:S.storedAvailable,read:S.composersRead,failed:S.composersFailed}),composersRead:S.composersRead,composersFailed:S.composersFailed,problems:S.problems.slice(0,20)}:T,gemini:k?{strata:ot({storedAvailable:k.storedAvailable,read:k.sessionsRead,failed:k.sessionsFailed}),sessionsRead:k.sessionsRead,sessionsFailed:k.sessionsFailed,problems:k.problems.slice(0,20)}:T},x={deepseek:le(m),"0x2f":le(v),"claude-code":le(d),codex:le(A),cursor:le(g),gemini:le(y)},C=t.collectionHealth();for(const[N,V]of Object.entries(x)){const K=C[N];K?.failing&&(V.presence="failed",V.error??=K.lastError)}const _=t.os.stats(),O=Object.values(x).filter(N=>N.available).length>0?"observing":_.samples>0?"os-only":"empty",U=Object.entries(C).filter(([,N])=>N.failing).map(([N])=>N),X=f.health(),j={ok:U.length===0&&X.ok&&!t.fault()&&!_.lastError,failingSources:U,collection:C,store:X,os:_.lastError?{failing:!0,lastError:_.lastError}:{failing:!1}};return B(i,200,{machine:t.machine,mode:O,fault:t.fault()??void 0,health:j,store:{...f.stats(),path:f.path,schemaVersion:f.schemaVersion,bytes:f.sizeBytes(),retention:{...t.retention,description:Ye(t.retention)}},os:{..._,running:t.os.running,source:pe},sources:x,observation:I}),!0}if(u.pathname==="/api/collect"){const m=t.checkStore();if(m)return B(i,503,{error:m.message,fault:m}),!0;const v=await Yn(f,pt,w,p,A=>t.recordCollection([A])),d=await t.os.sample();return t.recordCollection([{id:pe,ok:!t.os.stats().lastError,error:t.os.stats().lastError}]),B(i,200,{...v,sources:[...v.sources,{id:pe,ok:!t.os.stats().lastError,collected:d.length,inserted:d.length,duplicate:0,error:t.os.stats().lastError,ms:0}]}),!0}if(u.pathname==="/api/world")return B(i,200,{from:w,to:p,now:E,...Ie(f,w,p,t.machine.id)}),!0;if(u.pathname==="/api/health")return B(i,200,{pid:process.pid,version:e.version??"dev",contract:At,store:t.path,health:Ss(t)}),!0;if(u.pathname==="/api/landscape"){let m={from:w,to:p},v="WINDOW",d;if(u.searchParams.get("window")==="live"){if(m=As(E),v="TODAY",d=Ie(f,m.from,m.to,t.machine.id),d.world.executions.length===0&&d.world.sessions.length===0){const y={from:E-xi,to:E},M=Ie(f,y.from,y.to,t.machine.id);(M.world.executions.length>0||M.world.sessions.length>0)&&(m=y,v="LAST 72H",d=M)}}else d=Ie(f,w,p,t.machine.id);const A=ts(d.world),g=ls(A);return u.searchParams.get("window")==="live"&&(n={at:E,label:v,world:A,landscape:g}),B(i,200,{...m,now:E,window:v,meta:d.meta,health:Ss(t),...Lr(g)}),!0}if(u.pathname==="/api/today"||u.pathname==="/api/log"){const m=o(E);return B(i,200,u.pathname==="/api/today"?{window:m.label,...ii(m.world)}:{window:m.label,...ai(m.world,m.landscape)}),!0}if(u.pathname==="/api/inspect"){const m=u.searchParams.get("kind")??"",v=u.searchParams.get("id")??"";if(!["disturbance","stratum","mass","coupling"].includes(m)||!v||v.length>512)return B(i,400,{error:"inspect needs kind=disturbance|stratum|mass|coupling and an id"}),!0;if(o(E),!n)return!0;const d=(g,y)=>{for(const M of f.subjectEvents(g,y))if(M.provenance?.path)return M.provenance.path},A=Pr(n.world,n.landscape,m,v,d);return A?(B(i,200,A),!0):(B(i,404,{error:"not in the current world"}),!0)}if(u.pathname==="/api/sources"){const m=await Promise.all([Ft().catch(g=>({available:!1,error:String(g)})),Ht().catch(g=>({available:!1,error:String(g)})),Xt().catch(g=>({available:!1,error:String(g)})),qt().catch(g=>({available:!1,error:String(g)})),Kt().catch(g=>({available:!1,error:String(g)})),Qt().catch(g=>({available:!1,error:String(g)}))]),v=t.collectionHealth(),d=t.os.stats(),A=pt.map((g,y)=>{const M=le(m[y]),l=v[g.id];return{id:g.id,presence:l?.failing?"failed":M.presence,origin:M.origin,error:l?.failing?l.lastError??M.error:M.error,consecutiveFailures:l?.consecutiveFailures??0,lastSuccessAt:l?.lastSuccessAt}});return A.push({id:pe,presence:d.lastError?"failed":d.samples>0?"observing":"installed-no-data",origin:void 0,error:d.lastError,consecutiveFailures:v[pe]?.consecutiveFailures??0,lastSuccessAt:d.lastSampleAt??void 0}),B(i,200,{sources:A}),!0}if(u.pathname==="/api/detail"){const m=u.searchParams.get("type")??"",v=u.searchParams.get("id")??"";if(!Nt.includes(m)||!v)return B(i,400,{error:"detail needs type=<entity type> and id"}),!0;if(v.length>512)return B(i,400,{error:"id is too long"}),!0;const d=f.subjectEvents(m,v);return B(i,200,{type:m,id:v,events:d.slice(0,je),truncated:d.length>je}),!0}if(u.pathname==="/api/events"){const m=u.searchParams.get("subject"),v=m?m.split(",").filter(A=>Nt.includes(A)):void 0,d=mn(f,w,p,v,t.machine.id);return B(i,200,{from:w,to:p,now:E,events:d.events.slice(0,je),truncated:d.events.length>je,relationships:d.relationships}),!0}return B(i,404,{error:"unknown endpoint"}),!0}catch(m){return s.error(`[057] ${String(m)}`),B(i,500,{error:String(m)}),!0}}}const Mt=5057,ce="127.0.0.1",Bi=["localhost","127.0.0.1","[::1]","::1"],Hi=10,Wi={".html":"text/html; charset=utf-8",".js":"text/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json; charset=utf-8",".svg":"image/svg+xml",".woff2":"font/woff2",".png":"image/png",".ico":"image/vnd.microsoft.icon"};function Is(e,t,s){let n;try{n=decodeURIComponent(t)}catch{return!1}if(n.includes("\0"))return!1;const o=Re(e,`.${On(n)}`);if(o!==e&&!o.startsWith(e+$n)||!L(o)||!qe(o).isFile())return!1;const r=Wi[Rn(o).toLowerCase()]??"application/octet-stream";return s.statusCode=200,s.setHeader("content-type",r),s.setHeader("x-content-type-options","nosniff"),Tt(s),s.setHeader("cache-control",t.startsWith("/assets/")?"public, max-age=31536000, immutable":"no-store"),En(o).pipe(s),!0}function Xi(e,t,s,n){return new Promise((o,r)=>{let a=n,i=t;const c=u=>{if(u.code==="EADDRINUSE"&&a>1){a--,i++,e.listen(i,s);return}e.off("error",c),r(u)};e.on("error",c),e.once("listening",()=>{e.off("error",c);const u=e.address();o(typeof u=="object"&&u?u.port:i)}),e.listen(i,s)})}function Gi(e,t){const s=String(e.headers["sec-fetch-dest"]??"");if(qi.has(s))return`refusing to be embedded as ${s}`;const n=e.headers["sec-fetch-site"];return typeof n=="string"&&n!==""&&n!=="same-origin"&&n!=="none"?`refusing a ${n} request for ${t}`:null}const qi=new Set(["iframe","frame","embed","object","fencedframe"]);async function hn(e){const t=e.log??fn,s=Re(e.root),n=e.host??ce,o=n===ce||n==="::1"||n==="localhost",r=e.runtime?.path??e.storePath??Ve();if(!e.runtime){const f=await ui(r);if(f)throw new Et(f)}const a=e.runtime??It({path:e.storePath,log:t,retention:e.retention,observe:e.observe}),i=Pi({runtime:a,log:t,version:e.version,allowedHosts:o?Bi:null}),c=In((f,E)=>{(async()=>{try{if(await i(f,E))return;if(f.method!=="GET"&&f.method!=="HEAD"){E.statusCode=405,E.setHeader("allow","GET, HEAD"),E.end();return}const b=new URL(f.url??"/","http://localhost").pathname,w=Gi(f,b);if(w){t.warn(`[057] ${w}`),E.statusCode=403,E.setHeader("content-type","text/plain; charset=utf-8"),Tt(E),E.end(`${w}
|
|
76
76
|
`);return}if(Is(s,b==="/"?"/index.html":b,E)||!b.startsWith("/assets/")&&Is(s,"/index.html",E))return;E.statusCode=404,E.setHeader("content-type","text/plain; charset=utf-8"),E.end(`not found
|
|
77
|
-
`)}catch(b){t.error(`[057] request failed: ${String(b)}`),E.headersSent||(E.statusCode=500),E.end()}})()}),u=await Xi(c,e.port??Mt,n,Hi).catch(f=>{throw a.stop(),f}),h=o?"localhost":n;return di(a.path,{pid:process.pid,url:`http://${o?ce:n}:${u}`,version:e.version??"dev",contract:At,store:a.path,startedAt:Date.now(),owner:e.owner??"cli"}),{url:`http://${h}:${u}`,port:u,host:n,runtime:a,server:c,close(){return new Promise(f=>{li(a.path),c.close(()=>{a.stop(),f()}),c.closeAllConnections?.()})}}}function Yi(e){return Re(xn(new URL(".",e)),"..","dist")}const $e="1.
|
|
77
|
+
`)}catch(b){t.error(`[057] request failed: ${String(b)}`),E.headersSent||(E.statusCode=500),E.end()}})()}),u=await Xi(c,e.port??Mt,n,Hi).catch(f=>{throw a.stop(),f}),h=o?"localhost":n;return di(a.path,{pid:process.pid,url:`http://${o?ce:n}:${u}`,version:e.version??"dev",contract:At,store:a.path,startedAt:Date.now(),owner:e.owner??"cli"}),{url:`http://${h}:${u}`,port:u,host:n,runtime:a,server:c,close(){return new Promise(f=>{li(a.path),c.close(()=>{a.stop(),f()}),c.closeAllConnections?.()})}}}function Yi(e){return Re(xn(new URL(".",e)),"..","dist")}const $e="1.1.1";function Vi(e){const t={command:"serve",open:!1,yes:!1,desktop:!1},s=[...e],n=s[0];if(n&&!n.startsWith("-"))if(n==="status"||n==="compact"||n==="reset")t.command=n,s.shift();else return{...t,command:"help",error:`unknown command: ${n}`};for(;s.length;){const o=s.shift(),[r,a]=o.includes("=")?zi(o,"="):[o,void 0],i=()=>a??s.shift();switch(r){case"-h":case"--help":t.command="help";break;case"-v":case"--version":t.command="version";break;case"--open":t.open=!0;break;case"--yes":case"-y":t.yes=!0;break;case"--desktop":t.desktop=!0;break;case"--port":{const c=i(),u=Number(c);if(!Number.isInteger(u)||u<0||u>65535)return{...t,command:"help",error:`--port needs a port number, got ${c}`};t.port=u;break}case"--host":{const c=i();if(!c)return{...t,command:"help",error:"--host needs a value"};t.host=c;break}case"--store":{const c=i();if(!c)return{...t,command:"help",error:"--store needs a path"};t.store=c;break}default:return{...t,command:"help",error:`unknown option: ${r}`}}}return t}function zi(e,t){const s=e.indexOf(t);return[e.slice(0,s),e.slice(s+1)]}const Ki=`057 — a spatial interface for observing the shape of a computational workday
|
|
78
78
|
|
|
79
79
|
057 observe this machine and serve the interface
|
|
80
80
|
057 status where the store is, what it holds, what is observed
|