@vornicx/origin 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 vornicx / Archic
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,238 @@
1
+ # Origin
2
+
3
+ **A system of context, memory & action.**
4
+
5
+ Origin is a personal intelligence layer: it understands the work around you,
6
+ remembers what matters, reasons from goals, and acts through **human-directed
7
+ agents** — with every decision traceable. Reasoning and action run on a pluggable
8
+ runtime: the built-in reference runner, or [Apollo](https://github.com/vornicx/apollo-agent).
9
+
10
+ > Intelligence is incomplete until it can act.
11
+
12
+ ```ts
13
+ import { Origin, ApolloAgent, humanDirected } from "@vornicx/origin";
14
+
15
+ const origin = await Origin.open();
16
+
17
+ const agent = new ApolloAgent({
18
+ memory: origin.memory,
19
+ tools: [calendar, mail, browser],
20
+ policy: humanDirected(),
21
+ });
22
+
23
+ await agent.run("Prepare my launch plan");
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ npm install @vornicx/origin
32
+ ```
33
+
34
+ Requires Node ≥ 22. Ships ESM + types. The only required runtime dependency is `zod`.
35
+ **BYOK** — bring your own model key (OpenRouter, OpenAI, Anthropic, Google,
36
+ Groq, Mistral); nothing is sent anywhere you don't configure.
37
+
38
+ ---
39
+
40
+ ## Principles
41
+
42
+ | | Principle | What it means |
43
+ |--|-----------|----------------|
44
+ | **Ⅰ** | First principles | Context, memory, reasoning, tools and control are designed as one system — not bolted together. |
45
+ | **Ⅱ** | Human agency | Agents amplify judgment, never replace it by default. |
46
+ | **Ⅲ** | Context as interface | The best intelligence understands the work around you before it acts. |
47
+ | **Ⅳ** | Action matters | Intelligence is incomplete until it can help you do something meaningful — with you, not without you. |
48
+
49
+ They're exported, too: `import { PRINCIPLES } from "@vornicx/origin"`.
50
+
51
+ ---
52
+
53
+ ## The cycle
54
+
55
+ Every run is one turn of **understand → remember → reason → act → learn**:
56
+
57
+ ```
58
+ context → recall → plan → (gate → act → trace)* → synthesize → verify → remember
59
+ ```
60
+
61
+ - **Context** — scans the work around the goal (files, tools, intent).
62
+ - **Memory (Atlas)** — recalls what's relevant; saves the mission afterward.
63
+ - **Reasoning** — decomposes the goal into executable steps.
64
+ - **Action** — every change passes the **policy gate** first (approve / deny / ask).
65
+ - **Verification** — runs a success **contract** and issues a tamper-evident **certificate**.
66
+ - **Observability** — every decision is recorded; replay any run.
67
+
68
+ ---
69
+
70
+ ## Tools
71
+
72
+ A tool is anything the agent can call. Inputs are validated by the tool itself.
73
+
74
+ ```ts
75
+ import { defineTool } from "@vornicx/origin";
76
+
77
+ const calendar = defineTool({
78
+ name: "calendar",
79
+ description: "read the user's calendar",
80
+ run: (input) => readCalendar(input),
81
+ });
82
+
83
+ // Mutating tools are gated more strictly by policy:
84
+ const sendMail = defineTool({
85
+ name: "send_mail",
86
+ description: "send an email",
87
+ mutating: true,
88
+ kind: "network",
89
+ run: (input) => smtp.send(input),
90
+ });
91
+ ```
92
+
93
+ ---
94
+
95
+ ## Human agency (policy)
96
+
97
+ Policies map to Apollo's execution modes and decide, per action, whether to
98
+ **allow**, **deny**, or **ask** a human.
99
+
100
+ ```ts
101
+ import { humanDirected, reviewOnly, autonomous, autoApprove } from "@vornicx/origin";
102
+
103
+ humanDirected(); // default — read freely, ask before any change
104
+ reviewOnly(); // plan only, never act
105
+ autonomous({ fullAuto: true }); // act without prompts (use deliberately)
106
+ ```
107
+
108
+ The approval handler is yours to implement (CLI prompt by default):
109
+
110
+ ```ts
111
+ const agent = new ApolloAgent({
112
+ memory: origin.memory,
113
+ tools: [sendMail],
114
+ policy: humanDirected(),
115
+ approver: async (req) => ({ approved: await askHuman(req.reason) }),
116
+ });
117
+ ```
118
+
119
+ Non-interactive? Use `autoApprove` / `denyAll`, or supply your own.
120
+
121
+ ---
122
+
123
+ ## Memory — Atlas
124
+
125
+ Persistent across sessions, decisions and workflows. Recall is ranked by
126
+ **relevance × importance × recency**, and shares Apollo's memory model
127
+ (`note · chat · mission · fact · preference`, importance 1–5).
128
+
129
+ ```ts
130
+ import { Memory, JsonStore } from "@vornicx/origin";
131
+
132
+ const memory = new Memory({ store: new JsonStore({ file: ".origin/atlas.json" }) });
133
+
134
+ await memory.remember({ content: "Launch is June 12.", kind: "fact", importance: 5 });
135
+ const hits = await memory.recall("when is the launch?");
136
+ ```
137
+
138
+ Stores: `InMemoryStore` (default), `JsonStore` (file), or `SupabaseStore`
139
+ (cloud — see below). Bring your own by implementing `MemoryStore`.
140
+
141
+ ---
142
+
143
+ ## Verification — contracts & certificates
144
+
145
+ Done is provable, not vibes. A contract verifies a goal via commands, HTTP
146
+ checks, regex over output, and human criteria, producing a hashed certificate.
147
+
148
+ ```ts
149
+ import { evaluateContract } from "@vornicx/origin";
150
+
151
+ const cert = await evaluateContract({
152
+ commands: [{ cmd: "npm test" }],
153
+ http: [{ url: "http://localhost:3000/health", expectStatus: 200 }],
154
+ criteria: ["no console.log left behind"],
155
+ });
156
+
157
+ cert.ok; // true if every check passed
158
+ cert.hash; // sha256 fingerprint, stable across time
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Observability
164
+
165
+ ```ts
166
+ const result = await agent.run("Prepare my launch plan");
167
+
168
+ const trace = await origin.observability.replay(result.traceId);
169
+ console.log(trace.events.map((e) => e.kind).join(" → "));
170
+ // mission_start → plan → approval → tool_call → verify → mission_end
171
+ ```
172
+
173
+ Sinks: in-memory (default) or JSONL on disk. Sensitive values are redacted by a
174
+ configurable redactor before anything is written.
175
+
176
+ ---
177
+
178
+ ## Apollo — the agent runtime
179
+
180
+ Use the real [Apollo](https://github.com/vornicx/apollo-agent) CLI as Origin's
181
+ reasoning runtime, and persist Atlas to the same Supabase cloud Apollo syncs to.
182
+
183
+ ```bash
184
+ npm i -g @vornicx/apollo-agent && apollo setup
185
+ ```
186
+
187
+ ```ts
188
+ import { Origin } from "@vornicx/origin";
189
+ import { ApolloAgent, ApolloRuntime, SupabaseStore } from "@vornicx/origin/apollo";
190
+
191
+ const origin = await Origin.open();
192
+
193
+ const agent = new ApolloAgent({
194
+ memory: origin.memory,
195
+ policy: humanDirected(),
196
+ runtime: new ApolloRuntime(), // drives `apollo run …`
197
+ });
198
+ ```
199
+
200
+ ```ts
201
+ // Atlas in the cloud (run SUPABASE_ATLAS_DDL once in your project):
202
+ const memory = new Memory({
203
+ store: new SupabaseStore({ url: process.env.SUPABASE_URL!, key: process.env.SUPABASE_KEY! }),
204
+ });
205
+ ```
206
+
207
+ ---
208
+
209
+ ## Ecosystem
210
+
211
+ One foundation. Multiple layers.
212
+
213
+ | Layer | Name | This package |
214
+ |-------|------|--------------|
215
+ | Foundation | **Archic** | — |
216
+ | Personal intelligence | **Origin** | `Origin` |
217
+ | Agent runtime | **Apollo** | `ApolloAgent`, `ApolloRuntime` |
218
+ | Memory layer | **Atlas** | `Memory`, `*Store` |
219
+ | Integrations | **Nexus** | _planned_ |
220
+ | — | **Forge** | _coming soon_ |
221
+
222
+ ---
223
+
224
+ ## Examples
225
+
226
+ ```bash
227
+ npm run example:launch # the snippet above, end to end
228
+ npm run example:apollo # drive the Apollo CLI as the runtime
229
+ npm run example:memory # Atlas: remember & recall
230
+ ```
231
+
232
+ See [`examples/`](./examples).
233
+
234
+ ---
235
+
236
+ ## License
237
+
238
+ MIT © [vornicx](https://github.com/vornicx) · [archic.es](https://archic.es)
@@ -0,0 +1,87 @@
1
+ import { W as Runtime, c as ApolloMode, X as RuntimeContext, y as Plan, x as Observation, u as MemoryStore, s as MemoryRecord } from '../policy-KjPvxtus.js';
2
+ export { a as ApolloAgent, b as ApolloAgentOptions, v as MissionResult, $ as Tool, a7 as autonomous, ad as defineTool, ag as humanDirected, an as reviewOnly } from '../policy-KjPvxtus.js';
3
+ import 'zod';
4
+
5
+ interface ApolloExecResult {
6
+ code: number;
7
+ stdout: string;
8
+ stderr: string;
9
+ }
10
+ type ApolloExec = (args: string[], opts: {
11
+ cwd?: string;
12
+ timeoutMs?: number;
13
+ input?: string;
14
+ }) => Promise<ApolloExecResult>;
15
+ interface ApolloRuntimeOptions {
16
+ /** CLI binary. Defaults to `apollo` (`apollo.cmd` on Windows). */
17
+ bin?: string;
18
+ /** Force an Apollo execution mode (`--mode`). Default: let Apollo choose by complexity. */
19
+ mode?: ApolloMode;
20
+ cwd?: string;
21
+ /** Per-invocation timeout. Default 120s. */
22
+ timeoutMs?: number;
23
+ /** Injectable process runner (tests). Defaults to spawning the CLI. */
24
+ exec?: ApolloExec;
25
+ /** Extra CLI args appended to every invocation. */
26
+ extraArgs?: string[];
27
+ }
28
+ /**
29
+ * Drives the real Apollo CLI (`@vornicx/apollo-agent`) as Origin's reasoning
30
+ * runtime. `plan()` asks Apollo to plan the goal (`apollo run <goal> --json
31
+ * --dry-run`); Origin then gates and executes the steps with *your* tools,
32
+ * keeping humans in control. If the CLI is missing or errors, planning degrades
33
+ * to a legible empty plan rather than throwing.
34
+ *
35
+ * Install Apollo first: `npm i -g @vornicx/apollo-agent && apollo setup`.
36
+ */
37
+ declare class ApolloRuntime implements Runtime {
38
+ readonly name = "apollo";
39
+ private readonly bin;
40
+ private readonly mode?;
41
+ private readonly cwd?;
42
+ private readonly timeoutMs;
43
+ private readonly extraArgs;
44
+ private readonly exec;
45
+ constructor(options?: ApolloRuntimeOptions);
46
+ plan(ctx: RuntimeContext): Promise<Plan>;
47
+ synthesize(ctx: RuntimeContext, observations: Observation[]): Promise<string>;
48
+ }
49
+
50
+ interface SupabaseStoreOptions {
51
+ /** Supabase project URL, e.g. `https://abcd.supabase.co`. */
52
+ url: string;
53
+ /** Supabase API key (anon or service-role). */
54
+ key: string;
55
+ /** Table name. Default `atlas_memories`. */
56
+ table?: string;
57
+ /** Injectable fetch (tests). Defaults to global `fetch`. */
58
+ fetchImpl?: typeof fetch;
59
+ }
60
+ /** Run this once in your Supabase project to create the Atlas table. */
61
+ declare const SUPABASE_ATLAS_DDL = "create table if not exists atlas_memories (\n id uuid primary key,\n data jsonb not null,\n created_at timestamptz not null default now()\n);";
62
+ /**
63
+ * Persists Atlas memory to Supabase via its REST (PostgREST) API — the same
64
+ * cloud Apollo syncs to. Each memory is stored as `{ id, data: <record> }`, so
65
+ * the schema is migration-proof. Pure `fetch`, no SDK dependency. Create the
66
+ * table once with {@link SUPABASE_ATLAS_DDL}.
67
+ *
68
+ * ```ts
69
+ * const memory = new Memory({
70
+ * store: new SupabaseStore({ url: process.env.SUPABASE_URL!, key: process.env.SUPABASE_KEY! }),
71
+ * });
72
+ * ```
73
+ */
74
+ declare class SupabaseStore implements MemoryStore {
75
+ private readonly base;
76
+ private readonly key;
77
+ private readonly fetchImpl;
78
+ constructor(options: SupabaseStoreOptions);
79
+ private req;
80
+ all(): Promise<MemoryRecord[]>;
81
+ get(id: string): Promise<MemoryRecord | null>;
82
+ put(record: MemoryRecord): Promise<void>;
83
+ delete(id: string): Promise<boolean>;
84
+ clear(): Promise<void>;
85
+ }
86
+
87
+ export { type ApolloExec, type ApolloExecResult, ApolloRuntime, type ApolloRuntimeOptions, SUPABASE_ATLAS_DDL, SupabaseStore, type SupabaseStoreOptions };
@@ -0,0 +1,140 @@
1
+ import { parsePlan } from '../chunk-77G3SI57.js';
2
+ export { ApolloAgent, autonomous, defineTool, humanDirected, reviewOnly } from '../chunk-77G3SI57.js';
3
+ import { spawn } from 'child_process';
4
+
5
+ var ApolloRuntime = class {
6
+ name = "apollo";
7
+ bin;
8
+ mode;
9
+ cwd;
10
+ timeoutMs;
11
+ extraArgs;
12
+ exec;
13
+ constructor(options = {}) {
14
+ this.bin = options.bin ?? "apollo";
15
+ if (options.mode) this.mode = options.mode;
16
+ if (options.cwd) this.cwd = options.cwd;
17
+ this.timeoutMs = options.timeoutMs ?? 12e4;
18
+ this.extraArgs = options.extraArgs ?? [];
19
+ this.exec = options.exec ?? makeSpawnExec(this.bin);
20
+ }
21
+ async plan(ctx) {
22
+ const args = ["run", ctx.goal, "--json", "--dry-run"];
23
+ if (this.mode) args.push("--mode", this.mode);
24
+ args.push(...this.extraArgs);
25
+ const res = await this.exec(args, {
26
+ ...this.cwd ? { cwd: this.cwd } : {},
27
+ timeoutMs: this.timeoutMs
28
+ });
29
+ if (res.code !== 0) {
30
+ const detail = res.stderr.trim().slice(0, 200);
31
+ return { steps: [], rationale: `apollo exited ${res.code}${detail ? `: ${detail}` : ""}` };
32
+ }
33
+ return parsePlan(res.stdout, ctx.tools);
34
+ }
35
+ async synthesize(ctx, observations) {
36
+ const lines = observations.map(
37
+ (o) => `- ${o.stepId}: ${o.skipped ? "skipped" : o.ok ? "ok" : "failed"}${o.error ? ` (${o.error})` : ""}`
38
+ );
39
+ const body = lines.length ? `
40
+ ${lines.join("\n")}` : " (no steps)";
41
+ return `Apollo planned and Origin executed "${ctx.goal}".${body}`;
42
+ }
43
+ };
44
+ function makeSpawnExec(bin) {
45
+ const useShell = process.platform === "win32";
46
+ return (args, opts) => new Promise((resolve) => {
47
+ let child;
48
+ try {
49
+ child = useShell ? spawn([bin, ...args.map(quoteForShell)].join(" "), {
50
+ ...opts.cwd ? { cwd: opts.cwd } : {},
51
+ windowsHide: true,
52
+ shell: true
53
+ }) : spawn(bin, args, { ...opts.cwd ? { cwd: opts.cwd } : {}, windowsHide: true });
54
+ } catch (e) {
55
+ resolve({ code: 127, stdout: "", stderr: e instanceof Error ? e.message : String(e) });
56
+ return;
57
+ }
58
+ let stdout = "";
59
+ let stderr = "";
60
+ const timer = opts.timeoutMs ? setTimeout(() => child.kill(), opts.timeoutMs) : void 0;
61
+ child.stdout?.on("data", (d) => stdout += d.toString());
62
+ child.stderr?.on("data", (d) => stderr += d.toString());
63
+ if (opts.input) child.stdin?.end(opts.input);
64
+ child.on("error", (e) => {
65
+ if (timer) clearTimeout(timer);
66
+ resolve({ code: 127, stdout, stderr: stderr || e.message });
67
+ });
68
+ child.on("close", (code) => {
69
+ if (timer) clearTimeout(timer);
70
+ resolve({ code: code ?? 0, stdout, stderr });
71
+ });
72
+ });
73
+ }
74
+ function quoteForShell(arg) {
75
+ return /[\s"&|<>^()%]/.test(arg) ? `"${arg.replace(/"/g, '\\"')}"` : arg;
76
+ }
77
+
78
+ // src/apollo/supabase-store.ts
79
+ var SUPABASE_ATLAS_DDL = `create table if not exists atlas_memories (
80
+ id uuid primary key,
81
+ data jsonb not null,
82
+ created_at timestamptz not null default now()
83
+ );`;
84
+ var SupabaseStore = class {
85
+ base;
86
+ key;
87
+ fetchImpl;
88
+ constructor(options) {
89
+ const table = options.table ?? "atlas_memories";
90
+ this.base = `${options.url.replace(/\/+$/, "")}/rest/v1/${table}`;
91
+ this.key = options.key;
92
+ this.fetchImpl = options.fetchImpl ?? fetch;
93
+ }
94
+ async req(method, query, init) {
95
+ const headers = {
96
+ apikey: this.key,
97
+ Authorization: `Bearer ${this.key}`,
98
+ "Content-Type": "application/json",
99
+ ...init?.prefer ? { Prefer: init.prefer } : {}
100
+ };
101
+ const res = await this.fetchImpl(`${this.base}${query}`, {
102
+ method,
103
+ headers,
104
+ ...init?.body !== void 0 ? { body: JSON.stringify(init.body) } : {}
105
+ });
106
+ if (!res.ok) {
107
+ const text = await res.text().catch(() => "");
108
+ throw new Error(`SupabaseStore ${method} ${query} -> ${res.status} ${res.statusText} ${text}`.trim());
109
+ }
110
+ return res;
111
+ }
112
+ async all() {
113
+ const res = await this.req("GET", "?select=id,data");
114
+ const rows = await res.json();
115
+ return rows.map((r) => r.data);
116
+ }
117
+ async get(id) {
118
+ const res = await this.req("GET", `?id=eq.${encodeURIComponent(id)}&select=id,data&limit=1`);
119
+ const rows = await res.json();
120
+ return rows[0]?.data ?? null;
121
+ }
122
+ async put(record) {
123
+ await this.req("POST", "", {
124
+ body: [{ id: record.id, data: record }],
125
+ prefer: "resolution=merge-duplicates,return=minimal"
126
+ });
127
+ }
128
+ async delete(id) {
129
+ const res = await this.req("DELETE", `?id=eq.${encodeURIComponent(id)}`, { prefer: "return=representation" });
130
+ const rows = await res.json();
131
+ return rows.length > 0;
132
+ }
133
+ async clear() {
134
+ await this.req("DELETE", "?id=not.is.null", { prefer: "return=minimal" });
135
+ }
136
+ };
137
+
138
+ export { ApolloRuntime, SUPABASE_ATLAS_DDL, SupabaseStore };
139
+ //# sourceMappingURL=index.js.map
140
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/apollo/apollo-runtime.ts","../../src/apollo/supabase-store.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { parsePlan } from \"../agent/plan-parse\";\nimport type { Observation, Plan, Runtime, RuntimeContext } from \"../agent/runtime\";\nimport type { ApolloMode } from \"../policy/types\";\n\nexport interface ApolloExecResult {\n code: number;\n stdout: string;\n stderr: string;\n}\n\nexport type ApolloExec = (\n args: string[],\n opts: { cwd?: string; timeoutMs?: number; input?: string },\n) => Promise<ApolloExecResult>;\n\nexport interface ApolloRuntimeOptions {\n /** CLI binary. Defaults to `apollo` (`apollo.cmd` on Windows). */\n bin?: string;\n /** Force an Apollo execution mode (`--mode`). Default: let Apollo choose by complexity. */\n mode?: ApolloMode;\n cwd?: string;\n /** Per-invocation timeout. Default 120s. */\n timeoutMs?: number;\n /** Injectable process runner (tests). Defaults to spawning the CLI. */\n exec?: ApolloExec;\n /** Extra CLI args appended to every invocation. */\n extraArgs?: string[];\n}\n\n/**\n * Drives the real Apollo CLI (`@vornicx/apollo-agent`) as Origin's reasoning\n * runtime. `plan()` asks Apollo to plan the goal (`apollo run <goal> --json\n * --dry-run`); Origin then gates and executes the steps with *your* tools,\n * keeping humans in control. If the CLI is missing or errors, planning degrades\n * to a legible empty plan rather than throwing.\n *\n * Install Apollo first: `npm i -g @vornicx/apollo-agent && apollo setup`.\n */\nexport class ApolloRuntime implements Runtime {\n readonly name = \"apollo\";\n private readonly bin: string;\n private readonly mode?: ApolloMode;\n private readonly cwd?: string;\n private readonly timeoutMs: number;\n private readonly extraArgs: string[];\n private readonly exec: ApolloExec;\n\n constructor(options: ApolloRuntimeOptions = {}) {\n this.bin = options.bin ?? \"apollo\";\n if (options.mode) this.mode = options.mode;\n if (options.cwd) this.cwd = options.cwd;\n this.timeoutMs = options.timeoutMs ?? 120_000;\n this.extraArgs = options.extraArgs ?? [];\n this.exec = options.exec ?? makeSpawnExec(this.bin);\n }\n\n async plan(ctx: RuntimeContext): Promise<Plan> {\n const args = [\"run\", ctx.goal, \"--json\", \"--dry-run\"];\n if (this.mode) args.push(\"--mode\", this.mode);\n args.push(...this.extraArgs);\n const res = await this.exec(args, {\n ...(this.cwd ? { cwd: this.cwd } : {}),\n timeoutMs: this.timeoutMs,\n });\n if (res.code !== 0) {\n const detail = res.stderr.trim().slice(0, 200);\n return { steps: [], rationale: `apollo exited ${res.code}${detail ? `: ${detail}` : \"\"}` };\n }\n return parsePlan(res.stdout, ctx.tools);\n }\n\n async synthesize(ctx: RuntimeContext, observations: Observation[]): Promise<string> {\n const lines = observations.map(\n (o) =>\n `- ${o.stepId}: ${o.skipped ? \"skipped\" : o.ok ? \"ok\" : \"failed\"}${o.error ? ` (${o.error})` : \"\"}`,\n );\n const body = lines.length ? `\\n${lines.join(\"\\n\")}` : \" (no steps)\";\n return `Apollo planned and Origin executed \"${ctx.goal}\".${body}`;\n }\n}\n\nfunction makeSpawnExec(bin: string): ApolloExec {\n // On Windows the global `apollo` shim is a `.cmd`, which Node refuses to spawn\n // without a shell (EINVAL, post CVE-2024-27980). Use a shell there and quote\n // args; elsewhere spawn directly (no shell = no injection surface).\n const useShell = process.platform === \"win32\";\n return (args, opts) =>\n new Promise<ApolloExecResult>((resolve) => {\n let child: ReturnType<typeof spawn>;\n try {\n // With shell:true, pass one command string (not an args array) — both to\n // control quoting and to avoid Node's DEP0190 warning.\n child = useShell\n ? spawn([bin, ...args.map(quoteForShell)].join(\" \"), {\n ...(opts.cwd ? { cwd: opts.cwd } : {}),\n windowsHide: true,\n shell: true,\n })\n : spawn(bin, args, { ...(opts.cwd ? { cwd: opts.cwd } : {}), windowsHide: true });\n } catch (e) {\n resolve({ code: 127, stdout: \"\", stderr: e instanceof Error ? e.message : String(e) });\n return;\n }\n let stdout = \"\";\n let stderr = \"\";\n const timer = opts.timeoutMs ? setTimeout(() => child.kill(), opts.timeoutMs) : undefined;\n child.stdout?.on(\"data\", (d: Buffer) => (stdout += d.toString()));\n child.stderr?.on(\"data\", (d: Buffer) => (stderr += d.toString()));\n if (opts.input) child.stdin?.end(opts.input);\n child.on(\"error\", (e: Error) => {\n if (timer) clearTimeout(timer);\n resolve({ code: 127, stdout, stderr: stderr || e.message });\n });\n child.on(\"close\", (code: number | null) => {\n if (timer) clearTimeout(timer);\n resolve({ code: code ?? 0, stdout, stderr });\n });\n });\n}\n\n/** Minimal cmd.exe-safe quoting for args passed through a shell. */\nfunction quoteForShell(arg: string): string {\n return /[\\s\"&|<>^()%]/.test(arg) ? `\"${arg.replace(/\"/g, '\\\\\"')}\"` : arg;\n}\n","import type { MemoryStore } from \"../memory/store\";\nimport type { MemoryRecord } from \"../memory/types\";\n\nexport interface SupabaseStoreOptions {\n /** Supabase project URL, e.g. `https://abcd.supabase.co`. */\n url: string;\n /** Supabase API key (anon or service-role). */\n key: string;\n /** Table name. Default `atlas_memories`. */\n table?: string;\n /** Injectable fetch (tests). Defaults to global `fetch`. */\n fetchImpl?: typeof fetch;\n}\n\n/** Run this once in your Supabase project to create the Atlas table. */\nexport const SUPABASE_ATLAS_DDL = `create table if not exists atlas_memories (\n id uuid primary key,\n data jsonb not null,\n created_at timestamptz not null default now()\n);`;\n\ninterface Row {\n id: string;\n data: MemoryRecord;\n}\n\n/**\n * Persists Atlas memory to Supabase via its REST (PostgREST) API — the same\n * cloud Apollo syncs to. Each memory is stored as `{ id, data: <record> }`, so\n * the schema is migration-proof. Pure `fetch`, no SDK dependency. Create the\n * table once with {@link SUPABASE_ATLAS_DDL}.\n *\n * ```ts\n * const memory = new Memory({\n * store: new SupabaseStore({ url: process.env.SUPABASE_URL!, key: process.env.SUPABASE_KEY! }),\n * });\n * ```\n */\nexport class SupabaseStore implements MemoryStore {\n private readonly base: string;\n private readonly key: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(options: SupabaseStoreOptions) {\n const table = options.table ?? \"atlas_memories\";\n this.base = `${options.url.replace(/\\/+$/, \"\")}/rest/v1/${table}`;\n this.key = options.key;\n this.fetchImpl = options.fetchImpl ?? fetch;\n }\n\n private async req(method: string, query: string, init?: { body?: unknown; prefer?: string }): Promise<Response> {\n const headers: Record<string, string> = {\n apikey: this.key,\n Authorization: `Bearer ${this.key}`,\n \"Content-Type\": \"application/json\",\n ...(init?.prefer ? { Prefer: init.prefer } : {}),\n };\n const res = await this.fetchImpl(`${this.base}${query}`, {\n method,\n headers,\n ...(init?.body !== undefined ? { body: JSON.stringify(init.body) } : {}),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`SupabaseStore ${method} ${query} -> ${res.status} ${res.statusText} ${text}`.trim());\n }\n return res;\n }\n\n async all(): Promise<MemoryRecord[]> {\n const res = await this.req(\"GET\", \"?select=id,data\");\n const rows = (await res.json()) as Row[];\n return rows.map((r) => r.data);\n }\n\n async get(id: string): Promise<MemoryRecord | null> {\n const res = await this.req(\"GET\", `?id=eq.${encodeURIComponent(id)}&select=id,data&limit=1`);\n const rows = (await res.json()) as Row[];\n return rows[0]?.data ?? null;\n }\n\n async put(record: MemoryRecord): Promise<void> {\n await this.req(\"POST\", \"\", {\n body: [{ id: record.id, data: record }],\n prefer: \"resolution=merge-duplicates,return=minimal\",\n });\n }\n\n async delete(id: string): Promise<boolean> {\n const res = await this.req(\"DELETE\", `?id=eq.${encodeURIComponent(id)}`, { prefer: \"return=representation\" });\n const rows = (await res.json()) as Row[];\n return rows.length > 0;\n }\n\n async clear(): Promise<void> {\n await this.req(\"DELETE\", \"?id=not.is.null\", { prefer: \"return=minimal\" });\n }\n}\n"]}