babavoss 0.12.5 → 0.13.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.
Files changed (52) hide show
  1. package/gui/babavoss-web.js +234 -0
  2. package/gui/chunk-5hpp1ypv.js +11710 -0
  3. package/gui/chunk-a20zfekq.js +8639 -0
  4. package/gui/chunk-k3cm8j6r.js +433 -0
  5. package/gui/chunk-pk09y98y.js +50 -0
  6. package/gui/chunk-smz02qa6.js +186 -0
  7. package/gui/chunk-wwqypxre.js +49 -0
  8. package/gui/gui.js +2015 -0
  9. package/gui/react-compiler-runtime.js +39 -0
  10. package/gui/react-dom-client.js +21 -0
  11. package/gui/react-dom.js +44 -0
  12. package/gui/react-jsx-runtime.js +19 -0
  13. package/gui/react.js +105 -0
  14. package/gui/theme.css +3053 -0
  15. package/index.ts +1 -1
  16. package/package.json +8 -6
  17. package/src/{promptware → agents}/compile.ts +12 -12
  18. package/src/{promptware → agents}/define.ts +2 -2
  19. package/src/{promptware → agents}/disk.ts +7 -4
  20. package/src/{promptware → agents}/sync.ts +2 -2
  21. package/src/{promptware → agents}/system.ts +17 -17
  22. package/src/baba/check.ts +3 -3
  23. package/src/baba/config.ts +5 -2
  24. package/src/baba/init.ts +13 -18
  25. package/src/baba/node.ts +2 -2
  26. package/src/baba/worker.ts +13 -5
  27. package/src/build/mdx.ts +4 -4
  28. package/src/build/project.ts +6 -1
  29. package/src/build/views.ts +3 -3
  30. package/src/desktop/index.ts +1 -1
  31. package/src/door/core.ts +2 -2
  32. package/src/ecs/baba.ts +27 -17
  33. package/src/generated/build.ts +1 -1
  34. package/src/gui/gui.tsx +3 -3
  35. package/src/gui/{promptware.tsx → instructions.tsx} +12 -12
  36. package/src/gui/theme.css +1 -1
  37. package/src/guide/add-a-desktop.mdx +2 -2
  38. package/src/guide/index.ts +4 -4
  39. package/src/guide/write-a-system.mdx +3 -3
  40. package/src/guide/{write-promptware.mdx → write-agentic-instructions.mdx} +17 -24
  41. package/src/{prompt → instructions}/evals.ts +1 -1
  42. package/src/{prompt → instructions}/index.ts +9 -8
  43. package/src/{prompt → instructions}/jsx-runtime.ts +3 -3
  44. package/src/mcp/main.ts +3 -3
  45. package/src/mcp/tools.ts +4 -4
  46. package/src/runtime/harness.ts +2 -2
  47. package/src/shell/run.ts +18 -18
  48. package/src/spec/index.ts +1 -1
  49. package/src/web/core.tsx +2 -2
  50. /package/src/{promptware → agents}/markdown.d.ts +0 -0
  51. /package/src/{prompt → instructions}/jsx-dev-runtime.ts +0 -0
  52. /package/src/{prompt → instructions}/mdx.d.ts +0 -0
package/src/ecs/baba.ts CHANGED
@@ -9,7 +9,7 @@ import type { Context } from "../kernel/context.ts";
9
9
  import { keyFields, keyField } from "./handles.ts";
10
10
  import { State, type Component, type Ask, type Resource, type Effect, type Model, type Entity, type Args, type Result, type MirrorEvent } from "./state.ts";
11
11
  import { checkPositional } from "../shell/positional.ts";
12
- import { render, type InterpretationSuite, type Prompt } from "../prompt/index.ts";
12
+ import { render, type InterpretationSuite, type Prompt } from "../instructions/index.ts";
13
13
  import { routesError } from "../desktop/routes.ts";
14
14
 
15
15
  // ---- shapes --------------------------------------------------------------
@@ -105,7 +105,7 @@ export function query<const S extends Shape = {}, R = unknown, X = any>(def: { s
105
105
  /** A skill as the manifest carries it, rendered: what an agent reads when it opens it, and the calls it uses, by name. */
106
106
  export interface SkillDef { description: string; body: string; uses?: string[]; eval?: InterpretationSuite }
107
107
  /** What the baba tells agents, as the manifest carries it: its section of the context file, its skills, its hooks; the Markdown rendered. */
108
- export interface Promptware { context: string | null; contextEval?: InterpretationSuite; skills: Record<string, SkillDef>; hooks: HookDef[] }
108
+ export interface Instructions { context: string | null; contextEval?: InterpretationSuite; skills: Record<string, SkillDef>; hooks: HookDef[] }
109
109
 
110
110
  /** Which harnesses get the baba's files, and Claude Code's permissions; `table` renders the contract as a table of calls; `auto` writes the files on every change. */
111
111
  export interface Harness { claude: { enabled: boolean; permissions: string[] }; codex: { enabled: boolean }; table: boolean; auto: boolean }
@@ -197,7 +197,7 @@ export const nameOf = (v: unknown): string => dataOf(v).name;
197
197
  const NAME = /^[a-z][a-zA-Z0-9-]*$/;
198
198
  const SYSTEM_NAME = /^[a-z][a-z0-9-]*$/;
199
199
  /** Words the shell keeps for itself: an action or a query may not take them. */
200
- export const RESERVED = new Set(["start", "stop", "status", "state", "follow", "run", "raw", "secret", "help", "mcp", "check", "install", "add-system", "serve", "promptware", "init", "babas", "service", "gui"]);
200
+ export const RESERVED = new Set(["start", "stop", "status", "state", "follow", "run", "raw", "secret", "help", "mcp", "check", "install", "add-system", "serve", "agents", "init", "babas", "service", "gui"]);
201
201
 
202
202
  /** What a declaration makes: its handles by name, on an object with no prototype, and the model they form. */
203
203
  export interface Declared { readonly name: string; readonly refs: Readonly<Record<string, Component | Resource | Effect>>; readonly model: Model }
@@ -313,8 +313,8 @@ export interface Baba<Ss extends readonly System[] = readonly System[], K extend
313
313
  readonly $app: K;
314
314
  /** The routes of each app, as a type: what `compose<typeof baba>` asks a table of components for. */
315
315
  readonly $routes: R;
316
- /** What the baba tells agents: `context(...)`, `skill(...)` and `hook(...)` from babavoss/prompt, in order. */
317
- readonly promptware: readonly Prompt[];
316
+ /** What the baba tells agents: `context(...)`, `skill(...)` and `hook(...)` from babavoss/instructions, in order. */
317
+ readonly instructions: readonly Prompt[];
318
318
  /** Which harnesses get the files, and how. */
319
319
  readonly harness: Harness;
320
320
  /** Milliseconds between rounds the runtime causes on its own, for steps that need time to pass; null for a baba moved by actions and jobs. */
@@ -324,7 +324,8 @@ export interface Baba<Ss extends readonly System[] = readonly System[], K extend
324
324
  readonly queries: Record<string, QueryDef & { owner: string }>;
325
325
  }
326
326
 
327
- export function baba<const Ss extends readonly System[], const Sc extends readonly AppSpec[] = readonly []>(def: { systems: Ss; apps?: Sc; tick?: number; promptware?: readonly Prompt[]; harness?: HarnessInput }): Baba<Ss, Sc[number]["key"], RoutesOf<Sc>> {
327
+ export function baba<const Ss extends readonly System[], const Sc extends readonly AppSpec[] = readonly []>(def: { systems: Ss; apps?: Sc; tick?: number; instructions?: readonly Prompt[]; harness?: HarnessInput }): Baba<Ss, Sc[number]["key"], RoutesOf<Sc>> {
328
+ if ("promptware" in def) throw new Error("baba({ promptware }) is gone: the agentic instructions are the .mdx files under .baba/agents/, which voss reads on its own; see the write-agentic-instructions skill");
328
329
  const harness = harnessOf(def.harness);
329
330
  if (def.tick !== undefined && !(Number.isInteger(def.tick) && def.tick > 0)) throw new Error("baba: tick is whole milliseconds, above zero");
330
331
  const model: Model = { components: [], resources: [], effects: [] };
@@ -367,7 +368,7 @@ export function baba<const Ss extends readonly System[], const Sc extends readon
367
368
  if (new Set(apps.map((v) => v.key)).size !== apps.length || apps.some((v) => !/^[a-z][a-z0-9-]*$/.test(v.key))) throw new Error("baba: app keys must be unique lowercase names");
368
369
  for (const v of apps) for (const n of v.systems ?? []) if (!systemNames.has(n)) throw new Error(`app ${v.key} shows ${n}, which is not one of the baba's systems`);
369
370
  for (const v of apps) { const e = v.routes && routesError(v.routes); if (e) throw new Error(`app ${v.key}: ${e}`); }
370
- return Object.freeze({ kind: "baba", systems: def.systems, apps: apps.map((v) => ({ ...v, ...(v.systems ? { systems: [...v.systems] } : {}), ...(v.routes ? { routes: [...v.routes] } : {}) })), $app: undefined as never, $routes: undefined as never, tick: def.tick ?? null, promptware: [...(def.promptware ?? [])], harness, model, actions, queries });
371
+ return Object.freeze({ kind: "baba", systems: def.systems, apps: apps.map((v) => ({ ...v, ...(v.systems ? { systems: [...v.systems] } : {}), ...(v.routes ? { routes: [...v.routes] } : {}) })), $app: undefined as never, $routes: undefined as never, tick: def.tick ?? null, instructions: [...(def.instructions ?? [])], harness, model, actions, queries });
371
372
  }
372
373
 
373
374
  export function isBaba(v: unknown): v is Baba {
@@ -387,7 +388,7 @@ export function ofSystem(c: System): Baba { return baba({ systems: closureOf([c]
387
388
  export interface Manifest {
388
389
  systems: { name: string }[];
389
390
  /** What the baba tells agents, rendered: its context, its skills, its hooks; voss's own skills after the baba's. */
390
- promptware: Promptware;
391
+ instructions: Instructions;
391
392
  harness: Harness;
392
393
  components: Record<string, { owner: string; schema: Json; accept?: true }>;
393
394
  resources: Record<string, { owner: string; schema: Json }>;
@@ -403,29 +404,38 @@ export interface Manifest {
403
404
  export interface Call { owner: string; summary: string; args: Json; positional?: string[]; result: Json }
404
405
 
405
406
  export function manifestOf(v: Baba, program = "voss baba"): Manifest {
406
- const m: Manifest = { systems: v.systems.map((c) => ({ name: nameOf(c) })), promptware: { context: null, skills: {}, hooks: [] }, harness: v.harness, components: {}, resources: {}, effects: {}, actions: {}, queries: {}, tick: v.tick, apps: v.apps.map((x) => ({ ...x })) };
407
+ const m: Manifest = { systems: v.systems.map((c) => ({ name: nameOf(c) })), instructions: { context: null, skills: {}, hooks: [] }, harness: v.harness, components: {}, resources: {}, effects: {}, actions: {}, queries: {}, tick: v.tick, apps: v.apps.map((x) => ({ ...x })) };
407
408
  for (const c of v.model.components) m.components[c.name] = { owner: c.owner, schema: c.schema.json, ...(c.accept ? { accept: true as const } : {}) };
408
409
  for (const r of v.model.resources) m.resources[r.name] = { owner: r.owner, schema: r.schema.json };
409
410
  for (const e of v.model.effects) m.effects[e.name] = { owner: e.owner, summary: e.summary, args: e.args.json, result: e.result.json, retry: e.retry, every: e.every, repeat: e.repeat, shape: e.shape, ...(e.mirror ? { mirror: e.mirror } : {}), ...(e.event ? { event: e.event.json } : {}) };
410
411
  const call = (d: (ActionDef | QueryDef) & { owner: string }): Call => ({ owner: d.owner, summary: d.summary, args: d.args.json, ...(d.positional ? { positional: d.positional } : {}), result: d.result.json });
411
412
  for (const [n, a] of Object.entries(v.actions)) m.actions[n] = call(a);
412
413
  for (const [n, q] of Object.entries(v.queries)) m.queries[n] = call(q);
413
- // The promptware renders once the contract is in the manifest, since it may refer to it.
414
+ // The agentic instructions renders once the contract is in the manifest, since it may refer to it.
414
415
  const refs: string[] = [];
415
- m.promptware = renderPromptware(v.promptware, { manifest: m, program, refs });
416
- for (const r of refs) if (!(r in m.promptware.skills)) throw new Error(`a skill says "see ${r}", which is not a skill of the baba`);
417
- for (const [n, sk] of Object.entries(m.promptware.skills)) for (const u of sk.uses ?? []) if (!(u in m.actions) && !(u in m.queries)) throw new Error(`skill ${n} uses ${u}, which is not an action or query of the baba`);
418
- for (const h of m.promptware.hooks) if (!(h.action in m.actions)) throw new Error(`hook on ${h.on} calls ${h.action}, which is not an action of the baba`);
416
+ m.instructions = renderInstructions(v.instructions, { manifest: m, program, refs });
417
+ for (const r of refs) if (!(r in m.instructions.skills)) throw new Error(`a skill says "see ${r}", which is not a skill of the baba`);
418
+ for (const [n, sk] of Object.entries(m.instructions.skills)) for (const u of sk.uses ?? []) if (!(u in m.actions) && !(u in m.queries)) throw new Error(`skill ${n} uses ${u}, which is not an action or query of the baba`);
419
+ for (const h of m.instructions.hooks) if (!(h.action in m.actions)) throw new Error(`hook on ${h.on} calls ${h.action}, which is not an action of the baba`);
419
420
  return m;
420
421
  }
421
422
 
422
- /** The baba's promptware as Markdown: the one context, each skill by name, the hooks. */
423
- export function renderPromptware(ps: readonly Prompt[], context: { manifest: Manifest; program: string; refs?: string[] }): Promptware {
423
+ /** The baba with the documents voss found under .baba/agents/, after any it declares itself: what the builder hands the runtime. */
424
+ export function instructed(v: Baba, docs: readonly Prompt[]): Baba {
425
+ if (!docs.length) return v;
426
+ return Object.freeze({ ...v, instructions: [...v.instructions, ...docs] }) as Baba;
427
+ }
428
+
429
+ /** The baba's agentic instructions as Markdown: the one context, each skill by name, the hooks. */
430
+ export function renderInstructions(ps: readonly Prompt[], context: { manifest: Manifest; program: string; refs?: string[] }): Instructions {
424
431
  const contexts = ps.filter((p) => p.kind === "context");
425
432
  if (contexts.length > 1) throw new Error("a baba has one context(...); put every paragraph in it");
426
433
  const text = contexts[0] ? render(contexts[0].body, context) : "";
427
434
  const skills: Record<string, SkillDef> = {};
428
435
  for (const p of ps) if (p.kind === "skill") { if (p.name in skills) throw new Error(`two skills are named ${p.name}`); skills[p.name] = { description: p.description, body: render(p.body, context), uses: p.uses, ...(p.eval ? { eval: p.eval } : {}) }; }
429
- const hooks = ps.filter((p) => p.kind === "hook").map((p) => ({ on: p.on, match: p.match, action: p.action, strict: p.strict }));
436
+ const hooks = [
437
+ ...(contexts[0]?.hooks ?? []).map((h) => ({ on: h.on, match: h.match ?? null, action: h.action, strict: h.strict === true })),
438
+ ...ps.filter((p) => p.kind === "hook").map((p) => ({ on: p.on, match: p.match, action: p.action, strict: p.strict })),
439
+ ];
430
440
  return { context: text || null, skills, hooks, ...(contexts[0]?.eval ? { contextEval: contexts[0].eval } : {}) };
431
441
  }
@@ -1,4 +1,4 @@
1
1
  // The commit and the moment a package was built from, stamped by the pack
2
2
  // of a release (tools/release/pack.ts) and restored after it. From a
3
3
  // checkout both are empty: the tree is the build.
4
- export const build = { sha: "", at: "" };
4
+ export const build = {"sha":"ff74ab0","at":"2026-10-08T22:02:34.371Z"};
package/src/gui/gui.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  // voss's GUI: voss's shell at every level. At the root, over page state: the
2
2
  // babas and the New baba wizard. At /NAME/ over the baba,
3
3
  // its apps and voss's own, the Maker, the state, the contract, the
4
- // promptware and the settings, as windows. One bundle, one React, served by the
4
+ // agentic instructions and the settings, as windows. One bundle, one React, served by the
5
5
  // kernel's server child.
6
6
  import "./theme.css";
7
7
  import { Component, StrictMode, useEffect, useMemo, useState, type ComponentType, type ReactNode } from "react";
@@ -13,7 +13,7 @@ import type { AppSpec } from "../ecs/baba.ts";
13
13
  import type { Described } from "../baba/node.ts";
14
14
  import { Inspector } from "./inspector.tsx";
15
15
  import { Runner } from "./runner.tsx";
16
- import { Promptware } from "./promptware.tsx";
16
+ import { Instructions } from "./instructions.tsx";
17
17
  import { Button } from "../web/ui.tsx";
18
18
  import { Root } from "./levels.tsx";
19
19
  import type { Voss } from "../server/messages.ts";
@@ -188,7 +188,7 @@ function ShellPage({ d }: { d: Described }) {
188
188
  maker: ({ path, navigate, setTitle }) => <Maker specs={[]} title={d.title} path={path} navigate={navigate} setTitle={setTitle} />,
189
189
  state: () => <section className="gui-app">{d.error && <p className="bv-error">The code did not load; the last generation serves: {d.error}</p>}<Inspector manifest={manifest} /></section>,
190
190
  contract: () => <section className="gui-app"><Runner manifest={manifest} /></section>,
191
- promptware: () => <section className="gui-app"><Promptware manifest={manifest} /></section>,
191
+ instructions: () => <section className="gui-app"><Instructions manifest={manifest} /></section>,
192
192
  settings: Settings,
193
193
  };
194
194
  for (const sc of manifest.apps ?? []) {
@@ -1,6 +1,6 @@
1
- // The promptware drawer: the baba's know-how for agents as it declares it,
1
+ // The agentic instructions drawer: the baba's know-how for agents as it declares it,
2
2
  // the harness as the baba declares it, the plan of each output, and a sync.
3
- // Read from the state by the promptware system's names.
3
+ // Read from the state by the agents system's names.
4
4
  import { useEffect, useState } from "react";
5
5
  import type { Manifest } from "../ecs/baba.ts";
6
6
  import { useBabaState } from "../web/state.tsx";
@@ -9,12 +9,12 @@ import { ErrorText } from "./runner.tsx";
9
9
 
10
10
  interface Plan { auto: boolean; lastSync: number | null; pending: number; error: string | null; outputs: { path: string; harness: string; status: string; action: string | null; reason: string }[] }
11
11
 
12
- export function Promptware({ manifest }: { manifest: Manifest }) {
12
+ export function Instructions({ manifest }: { manifest: Manifest }) {
13
13
  const { fire, read, ready, round } = useBabaState();
14
14
  const [plan, setPlan] = useState<Plan | null>(null);
15
15
  const [error, setError] = useState<unknown>(null);
16
- useEffect(() => { if (ready) read("promptware-plan").then((p) => setPlan(p as Plan), setError); }, [ready, round]);
17
- if (!("pwStatus" in manifest.resources)) return <p className="bv-muted">This baba has no promptware system.</p>;
16
+ useEffect(() => { if (ready) read("agents-plan").then((p) => setPlan(p as Plan), setError); }, [ready, round]);
17
+ if (!("pwStatus" in manifest.resources)) return <p className="bv-muted">This baba has no agents system.</p>;
18
18
  if (!ready) return <p className="bv-muted">Reading the state…</p>;
19
19
  const act = (name: string, args: unknown) => { setError(null); return fire(name, args as never).catch((e: unknown) => { setError(e); throw e; }); };
20
20
  return (
@@ -24,7 +24,7 @@ export function Promptware({ manifest }: { manifest: Manifest }) {
24
24
  <section className="gui-section">
25
25
  <h2>Outputs</h2>
26
26
  <div className="bv-form-actions">
27
- <Button variant="primary" onClick={() => void act("promptware-sync", {}).catch(() => {})}>Sync now</Button>
27
+ <Button variant="primary" onClick={() => void act("agents-sync", {}).catch(() => {})}>Sync now</Button>
28
28
  {plan && <span className="bv-muted">{plan.pending ? `${plan.pending} to write` : "up to date"} · {plan.auto ? "writes on every change" : "writes on sync"}{plan.lastSync ? ` · synced ${new Date(plan.lastSync).toLocaleTimeString()}` : ""}</span>}
29
29
  </div>
30
30
  {plan?.error && <p className="bv-error">{plan.error}</p>}
@@ -35,18 +35,18 @@ export function Promptware({ manifest }: { manifest: Manifest }) {
35
35
  );
36
36
  }
37
37
 
38
- /** What the baba tells agents, read-only here: it is code under .baba/promptware/. */
38
+ /** What the baba tells agents, read-only here: it is code under .baba/agents/. */
39
39
  function Declared({ manifest }: { manifest: Manifest }) {
40
- const pw = manifest.promptware;
40
+ const pw = manifest.instructions;
41
41
  const skills = Object.entries(pw.skills);
42
42
  return (
43
43
  <section className="gui-section">
44
- <h2>Promptware</h2>
45
- {!pw.context && skills.length === 0 && pw.hooks.length === 0 && <p className="bv-muted">Nothing declared yet: give the baba a `context(...)`, a `skill(...)` or a `hook(...)` under `promptware`.</p>}
44
+ <h2>Instructions</h2>
45
+ {!pw.context && skills.length === 0 && pw.hooks.length === 0 && <p className="bv-muted">Nothing declared yet: give the baba a `context(...)`, a `skill(...)` or a `hook(...)` under `.baba/agents/`.</p>}
46
46
  {pw.context && <p className="bv-muted">{pw.context.length} characters of context, {pw.hooks.length} hook{pw.hooks.length === 1 ? "" : "s"}.</p>}
47
47
  {pw.hooks.length > 0 && <Rows>{pw.hooks.map((h, i) => <Row key={i} hint={`${h.on}${h.match ? ` on ${h.match}` : ""}${h.strict ? " · strict" : ""}`}><code>{h.action}</code></Row>)}</Rows>}
48
48
  {skills.length > 0 && <Rows>{skills.map(([k, sk]) => <Row key={k} hint={sk.description}><code>{k}</code></Row>)}</Rows>}
49
- <p className="bv-muted">The promptware is the baba's code: edit it under .baba/promptware/; the files below follow.</p>
49
+ <p className="bv-muted">The agentic instructions is the baba's code: edit it under .baba/agents/; the files below follow.</p>
50
50
  </section>
51
51
  );
52
52
  }
@@ -62,7 +62,7 @@ function Harness({ manifest }: { manifest: Manifest }) {
62
62
  <Row hint={h.codex.enabled ? "on" : "off"}><code>codex</code></Row>
63
63
  <Row hint={`${h.auto ? "writes on every change" : "writes on sync"}${h.table ? " · the contract as a table" : ""}`}><code>files</code></Row>
64
64
  </Rows>
65
- <p className="bv-muted">Declared in .baba/index.ts: <code>{"baba({ systems, promptware, harness })"}</code>.</p>
65
+ <p className="bv-muted">The .mdx files under .baba/agents/, each <code>{'export const prompt = { kind: "context" | "skill", … }'}</code>; voss reads them on its own.</p>
66
66
  </section>
67
67
  );
68
68
  }
package/src/gui/theme.css CHANGED
@@ -295,7 +295,7 @@ button.pk-crumb:hover { background: var(--accent); color: var(--foreground); }
295
295
  @keyframes gui-appear { from { opacity: 0 } to { opacity: 1 } }
296
296
  @media (prefers-reduced-motion: reduce) { .gui-fade { animation: none; } }
297
297
 
298
- /* ---- voss's apps, in the shell's windows: the state, the contract, the promptware, the settings, with a page's gutters; the Maker edge to edge ---- */
298
+ /* ---- voss's apps, in the shell's windows: the state, the contract, the agentic instructions, the settings, with a page's gutters; the Maker edge to edge ---- */
299
299
  .gui-app { max-width: 1100px; padding: 16px 20px 32px; }
300
300
  .gui-app > h2 { margin: 16px 0 4px; font-size: 13px; }
301
301
  .gui-choices { display: flex; gap: 6px; margin-top: 8px; }
@@ -2,7 +2,7 @@ export const prompt = { kind: "skill", name: "add-a-desktop", description: "Give
2
2
 
3
3
  # Add a desktop
4
4
 
5
- Every baba runs voss's shell: the desktop system, which voss adds to every baba as it adds `maker` and `promptware`, over the apps the baba declares in `baba({ apps })`. The interface gives each app its component; the page is voss's. Three nouns and one verb: a **app** is a kind the baba registers; a **window** is one instance of it in a session, at a path; the **session** shows one window, or nothing. The verb is `desktop-open`: it brings the window at that path to the front, else the app's current window, else makes one; asked for a `fresh` window, an app declared `many` gets another, any other app gives the one it has. The launcher, a link in an app, the page's address, the CLI and another system's ask all go through it.
5
+ Every baba runs voss's shell: the desktop system, which voss adds to every baba as it adds `maker` and `agents`, over the apps the baba declares in `baba({ apps })`. The interface gives each app its component; the page is voss's. Three nouns and one verb: a **app** is a kind the baba registers; a **window** is one instance of it in a session, at a path; the **session** shows one window, or nothing. The verb is `desktop-open`: it brings the window at that path to the front, else the app's current window, else makes one; asked for a `fresh` window, an app declared `many` gets another, any other app gives the one it has. The launcher, a link in an app, the page's address, the CLI and another system's ask all go through it.
6
6
 
7
7
  The page is a bar over one app. At the bar's far left the mark, the two eyes, opens the launcher; then a pill per open window, its icon at the left and the one in front filled; pointing at a pill turns its icon into the × that closes it, and a middle click closes it too, as it closes a browser tab; closing the one in front brings the pill to its left forward, else the one to its right. The launcher is the page's, not the state's: it shows while its search has focus, and while nothing is in front, since there is nothing else to show. The mark or Cmd/Ctrl K gives the search focus; a click on the launcher's empty space keeps it; choosing a row, Escape or the mark again takes it, and the launcher goes. It covers the page and changes nothing beneath: the bar's row becomes the search, and below it one column of rows, a palette: the icon, beginning where the search begins, then the label; what is open first, then every app under its group. One dot under the mark says which row is chosen, by the keys or the pointer, and glides between them. Typing ranks both by the words, a word at the start of a name first, and drops the groups. An app's row opens a fresh window of it, or brings the one it has to the front; a window's row brings it to the front, and pointing at it turns its icon into its ×. A browser tab shows one window at a time: a pill on the bar brings an open one to the front, the mark then a row opens another. Below the apps, under Sessions, the tab's other sessions and New session. A page inside a baba is that baba only; the last row, Leave, and the `voss` link before the title on the bar go back to the picker, voss's root page, which has no state: it lists the babas voss knows, one inside another under its parent, and New baba, the wizard that makes a baba in a folder or remembers one already there.
8
8
 
@@ -30,7 +30,7 @@ import { Tasks } from "./apps/tasks.tsx";
30
30
  export default compose<typeof baba>({ apps: { tasks: Tasks } });
31
31
  ```
32
32
 
33
- An app missing from `compose`, or a component for an app the baba does not declare, is a type error. After the baba's apps come voss's own, under Voss: `maker` the specs run live, `state` the entities and resources, `contract` the actions and queries as forms, `promptware` the know-how, `settings` the theme. A baba never declares them; its interface may give one a component of its own to draw it otherwise, `compose<typeof baba>({ apps: { …, promptware: Mine } })`. A baba that declares no apps has one, `view`, which draws its interface whole. A baba whose interface fails to build or load still has its shell: its apps say why, voss's work. The old addresses, `/NAME/run`, `/inspect`, `/proofs`, open the app they became, unless the baba has an app by that name. The old form, `compose({ shell })`, still loads for one release, in the `view` app; a baba cannot declare apps and keep a desktop system of its own.
33
+ An app missing from `compose`, or a component for an app the baba does not declare, is a type error. After the baba's apps come voss's own, under Voss: `maker` the specs run live, `state` the entities and resources, `contract` the actions and queries as forms, `agentic instructions` the know-how, `settings` the theme. A baba never declares them; its interface may give one a component of its own to draw it otherwise, `compose<typeof baba>({ apps: { …, agentic instructions: Mine } })`. A baba that declares no apps has one, `view`, which draws its interface whole. A baba whose interface fails to build or load still has its shell: its apps say why, voss's work. The old addresses, `/NAME/run`, `/inspect`, `/proofs`, open the app they became, unless the baba has an app by that name. The old form, `compose({ shell })`, still loads for one release, in the `view` app; a baba cannot declare apps and keep a desktop system of its own.
34
34
 
35
35
  An app's component receives `AppProps`: `{ session, window, path, route, params, active, memory, navigate, open, setTitle, remember }`. It never names an action: `navigate(path)` moves its own window, `open(app, path)` opens any app by the one rule, `setTitle(title)` names its window after what it shows, the pill's tooltip, `remember(key, value)` keeps a filter, a selection or a fold on its window, in the state, and `memory` reads it back. Windows stay mounted when hidden. A path begins with one `/`.
36
36
 
@@ -1,13 +1,13 @@
1
1
  // voss's own know-how for agents, given to every baba after its own: how to
2
2
  // write, prove and compose systems, how to draw the page as apps and give it
3
- // a desktop, and how to write promptware.
4
- import type { Prompt } from "../prompt/index.ts";
3
+ // a desktop, and how to write agentic instructions.
4
+ import type { Prompt } from "../instructions/index.ts";
5
5
  import writeASystem from "./write-a-system.mdx";
6
6
  import reachOutside from "./reach-outside.mdx";
7
7
  import systemsTogether from "./systems-together.mdx";
8
8
  import composeAnInterface from "./compose-an-interface.mdx";
9
9
  import addADesktop from "./add-a-desktop.mdx";
10
- import writePromptware from "./write-promptware.mdx";
10
+ import writeInstructions from "./write-agentic-instructions.mdx";
11
11
  import specASystem from "./spec-a-system.mdx";
12
12
 
13
- export const guide: readonly Prompt[] = [writeASystem, reachOutside, systemsTogether, specASystem, composeAnInterface, addADesktop, writePromptware];
13
+ export const guide: readonly Prompt[] = [writeASystem, reachOutside, systemsTogether, specASystem, composeAnInterface, addADesktop, writeInstructions];
@@ -164,11 +164,11 @@ p.query("pond", {
164
164
  - A fire may carry an idempotency key (`--key K` at the shell, `key` by MCP): the baba remembers the answer for a day, so a retry answers the same without running again. Make actions safe to repeat anyway.
165
165
  - `w.transaction(fn)` gives any code what an action has: a throw undoes every write inside it.
166
166
  - Validation is at the boundary: args and results are checked; your writes inside are trusted, so write what the schema says.
167
- - Reserved names, not for actions or queries: start, stop, status, state, follow, run, raw, secret, help, mcp, check, install, add-system, serve, promptware, init, babas, service, gui.
167
+ - Reserved names, not for actions or queries: start, stop, status, state, follow, run, raw, secret, help, mcp, check, install, add-system, serve, agents, init, babas, service, gui.
168
168
 
169
169
  ## The baba
170
170
 
171
- `.baba/index.ts` lists every system, in the order their steps run: `baba({ systems: [tasks, pond], apps, promptware, harness, tick })`. A system that reads another goes after it, so it sees this round's writes.
171
+ `.baba/index.ts` lists every system, in the order their steps run: `baba({ systems: [tasks, pond], apps, harness, tick })`. A system that reads another goes after it, so it sees this round's writes.
172
172
 
173
173
  ## Schemas
174
174
 
@@ -179,5 +179,5 @@ p.query("pond", {
179
179
  1. Every component and resource the system writes is in its `model`; every other system it reads or asks of is in its `reads`, and none of those reads it back.
180
180
  2. Steps are ordered on purpose; the hot ones use `w.each`; the reactive ones use change terms.
181
181
  3. Every piece is made with this system's `p` and listed once; actions answer data; queries change nothing; names are flat and not reserved.
182
- 4. The baba's promptware says in a line what the system is for (see `write-promptware`); its `spec.ts` beside it proves it, a scenario for each thing it must do (see `spec-a-system`); an app in `.baba/apps/` that names it in `systems` shows it, live and in the Maker (see `compose-an-interface`).
182
+ 4. The baba's context, an `.mdx` under `.baba/agents/`, says in a line what the system is for (see `write-agentic-instructions`); its `spec.ts` beside it proves it, a scenario for each thing it must do (see `spec-a-system`); an app in `.baba/apps/` that names it in `systems` shows it, live and in the Maker (see `compose-an-interface`).
183
183
  5. `bun test` (the runner `.baba/spec.test.ts` proves every spec) and the type-check are green; the running baba reloads on save and `voss baba` shows the new contract.
@@ -1,10 +1,10 @@
1
- export const prompt = { kind: "skill", name: "write-promptware",
2
- description: "Write or change what a baba tells agents: its context, skills and hooks, as code under .baba/promptware/. Use before writing any promptware, in any baba, including skills like this one.",
1
+ export const prompt = { kind: "skill", name: "write-agentic-instructions",
2
+ description: "Write or change what a baba tells agents: its context, skills and hooks, each an .mdx file under .baba/agents/. Use before writing any agentic instructions, in any baba, including skills like this one.",
3
3
  };
4
4
 
5
- # Write promptware
5
+ # Write agentic instructions
6
6
 
7
- A promptware file an agent can act on at first read: one trigger, steps in order, one example, claims it can check, rules it cannot break.
7
+ An instruction file an agent can act on at first read: one trigger, steps in order, one example, claims it can check, rules it cannot break. The agentic instructions of a baba are the `.mdx` files under `.baba/agents/`; voss reads every one of them, in name order, and there is no list to keep.
8
8
 
9
9
  ## When
10
10
 
@@ -14,17 +14,17 @@ A promptware file an agent can act on at first read: one trigger, steps in order
14
14
 
15
15
  ## Do
16
16
 
17
- 1. Pick the kind. `context`: the baba's section of the context file, read by every session; what the project is, how it is worked on, its rules; one per baba, in `promptware/index.ts`. `skill`: a file read when its description fits; how to do one thing; one `.mdx` per skill beside it. `hook`: a harness moment handed to an action; what the harness may not do.
17
+ 1. Pick the kind. `context`: the baba's section of the context file, read by every session; what the project is, how it is worked on, its rules; one per baba, `export const prompt = { kind: "context" }`. `skill`: a file read when its description fits; how to do one thing; `export const prompt = { kind: "skill", name, description, uses }`, one `.mdx` per skill. A hook, a harness moment handed to an action, is `hooks: [{ on, match, action }]` on the context's `prompt`.
18
18
  2. Write the description as the trigger: `Use when …`, the situations, the files, the words an agent would be thinking. The description decides whether the skill is read; the body decides whether it works.
19
- 3. Write Markdown directly in an MDX file. Export a `prompt` metadata object with `kind: "skill"`, name, description, and optional uses/eval; for context use `kind: "context"`. An `eval` is the owner's golden interpretation, run on demand from the Trials app to score readers of the text; it gates nothing. Changing a skill, leave its eval alone unless the owner asks. Import contract components and embed them as JSX. MDX expressions are JavaScript; keep typed helpers in imported .ts files. Existing TSX and `md` templates remain supported.
19
+ 3. Write Markdown in the `.mdx` file; `import { Call } from "babavoss/instructions"` for the tags below. Export the `prompt` metadata object with `kind: "skill"`, name, description, and optional uses/eval; for the context, `kind: "context"` with optional hooks/eval. An `eval` is the owner's golden interpretation, run on demand from the Trials app to score readers of the text; it gates nothing. Changing a skill, leave its eval alone unless the owner asks. Import contract components and embed them as JSX. MDX expressions are JavaScript; keep typed helpers in imported .ts files. Existing TSX and `md` templates remain supported.
20
20
  4. Reference the contract, never restate it: `<Call of="feed" />` for a call with its example and summary, `<Calls of="pond" />` for a system's calls, `<Schema of>` for args, `<Usage of>` for the shell's spelling, `<See skills={[…]} />` for the skills to read next. A name that does not exist refuses to load.
21
- 5. List the file in `promptware/index.ts`, which `baba({ systems, promptware, harness })` declares; `harness` says which harnesses get the files and Claude Code's permissions.
21
+ 5. Save it under `.baba/agents/`: voss finds it there. `baba({ harness })` says which harnesses get the files and Claude Code's permissions.
22
22
  6. Read the output: `CLAUDE.md` and `.claude/skills/NAME/SKILL.md` after the sync. Cut every sentence that does not change what an agent does.
23
23
 
24
24
  ## Example
25
25
 
26
26
  ```mdx
27
- import { Call, See } from "babavoss/prompt";
27
+ import { Call, See } from "babavoss/instructions";
28
28
 
29
29
  export const prompt = {
30
30
  kind: "skill",
@@ -48,22 +48,15 @@ Do not add or remove fish with raw writes.
48
48
  <See skills={["write-a-system"]} />
49
49
  ```
50
50
 
51
- ```ts
52
- // .baba/promptware/index.ts
53
- import { context, hook, md } from "babavoss/prompt";
54
- import feedThePond from "./feed-the-pond.mdx";
51
+ ```mdx
52
+ {/* .baba/agents/context.mdx */}
53
+ export const prompt = { kind: "context", hooks: [{ on: "PreToolUse", match: "Bash", action: "guard-raw" }] };
55
54
 
56
- export default [
57
- context(md\`
58
- The demo: an example baba. It shows what a baba is; it is not a product.
55
+ The demo: an example baba. It shows what a baba is; it is not a product.
59
56
 
60
- ## Rules
57
+ ## Rules
61
58
 
62
- - Keep each system small and proved by its scenarios.
63
- \`),
64
- feedThePond,
65
- hook({ on: "PreToolUse", match: "Bash", action: "guard-raw" }),
66
- ];
59
+ - Keep each system small and proved by its scenarios.
67
60
  ```
68
61
 
69
62
  ## Check
@@ -76,15 +69,15 @@ export default [
76
69
 
77
70
  ## Never
78
71
 
79
- - Read the state in promptware: it is static, rendered from the manifest once per generation.
72
+ - Read the state in agentic instructions: it is static, rendered from the manifest once per generation.
80
73
  - Explain why in a step; put reasons in the context if they are needed at all.
81
74
  - Write `simply`, `just`, `easily`, `should`, or a synonym for a term that has one name: system, app, spec, step, state, round, action, query, effect, source, mirror, context, skill, hook, baba, voss.
82
- - Edit `CLAUDE.md`, `AGENTS.md`, a `SKILL.md` or `.claude/settings.local.json`: they are outputs. Git keeps none of them: voss writes its lines of the project's `.gitignore`, and a checkout makes its own with `voss baba promptware sync`.
75
+ - Edit `CLAUDE.md`, `AGENTS.md`, a `SKILL.md` or `.claude/settings.local.json`: they are outputs. Git keeps none of them: voss writes its lines of the project's `.gitignore`, and a checkout makes its own with `voss baba agents sync`.
83
76
  - Commit an output. A hand-written `.claude/settings.json` beside the made `settings.local.json` is the place for what the repository itself tells Claude Code, a `SessionStart` hook that runs the sync, say.
84
77
 
85
78
  ## Hooks
86
79
 
87
- A hook hands a harness moment to an action: `hook({ on, match?, action, strict? })` with `on` one of PreToolUse, PostToolUse, UserPromptSubmit, Stop, SubagentStop, SessionStart, PreCompact, Notification, and `match` a tool-name regex for the two tool events. The action takes `hookArgs(EVENT)` and answers `hookResult()`: `{ decision: "block", reason }` stops the tool call and the agent reads the reason; `{ context }` is told to the agent; `{}` lets it through. Voss compiles it into `.claude/settings.local.json` as `voss baba ACTION @- --hook EVENT`; a baba that is down lets through with a note, `strict: true` blocks. Prove a hook with a scenario: `fire` the action with an event, `check` the decision.
80
+ A hook hands a harness moment to an action: `{ on, match?, action, strict? }` in the context's `hooks`, with `on` one of PreToolUse, PostToolUse, UserPromptSubmit, Stop, SubagentStop, SessionStart, PreCompact, Notification, and `match` a tool-name regex for the two tool events. The action takes `hookArgs(EVENT)` and answers `hookResult()`: `{ decision: "block", reason }` stops the tool call and the agent reads the reason; `{ context }` is told to the agent; `{}` lets it through. Voss compiles it into `.claude/settings.local.json` as `voss baba ACTION @- --hook EVENT`; a baba that is down lets through with a note, `strict: true` blocks. Prove a hook with a scenario: `fire` the action with an event, `check` the decision.
88
81
 
89
82
  ## Voice
90
83
 
@@ -1,4 +1,4 @@
1
- // The golden interpretation of a piece of promptware: situations a fresh
1
+ // The golden interpretation of a piece of agentic instructions: situations a fresh
2
2
  // reader must decide from the text alone. Authored as givens, each with the
3
3
  // cases under it: when (the moment of decision) and then (the right move, a
4
4
  // few words). A situation the text never mentions, decided by what the text
@@ -1,4 +1,4 @@
1
- // babavoss/prompt: promptware as code. What a baba tells agents, written in
1
+ // babavoss/instructions: agentic instructions as code. What a baba tells agents, written in
2
2
  // MDX (or TSX) that renders to Markdown: `context(...)` for the baba's section of the
3
3
  // context file, `skill({ name, description }, ...)` for a skill file,
4
4
  // `hook(...)` for a moment of the harness; `md` for raw Markdown; `<Call
@@ -15,9 +15,9 @@ import { isElement, jsx, Fragment, type PromptNode, type PromptElement, type Pro
15
15
 
16
16
  export { Fragment, type PromptNode, type PromptElement, type PromptComponent, type JSX } from "./jsx-runtime.ts";
17
17
 
18
- /** What a baba declares under `promptware`. */
18
+ /** What a baba declares under `.baba/agents/`. */
19
19
  export type Prompt =
20
- | { kind: "context"; body: PromptNode; eval?: InterpretationSuite }
20
+ | { kind: "context"; body: PromptNode; eval?: InterpretationSuite; hooks?: HookDef[] }
21
21
  | { kind: "skill"; name: string; description: string; uses: string[]; body: PromptNode; eval?: InterpretationSuite }
22
22
  | { kind: "hook"; on: HookEvent; match: string | null; action: string; strict: boolean };
23
23
 
@@ -33,7 +33,8 @@ export type HookEvent = (typeof HOOK_EVENTS)[number];
33
33
  * PostToolUse to tool names, a regex. With `strict`, a baba that does not
34
34
  * answer blocks; otherwise it lets through.
35
35
  */
36
- export function hook(def: { on: HookEvent; match?: string; action: string; strict?: boolean }): Prompt {
36
+ export interface HookDef { on: HookEvent; match?: string; action: string; strict?: boolean }
37
+ export function hook(def: HookDef): Prompt {
37
38
  if (!HOOK_EVENTS.includes(def.on)) throw new Error(`hook: on is one of ${HOOK_EVENTS.join(", ")}, not ${JSON.stringify(def.on)}`);
38
39
  if (def.match !== undefined && def.on !== "PreToolUse" && def.on !== "PostToolUse") throw new Error(`hook on ${def.on}: match is for PreToolUse and PostToolUse`);
39
40
  return { kind: "hook", on: def.on, match: def.match ?? null, action: def.action, strict: def.strict === true };
@@ -72,7 +73,7 @@ export const hookResult = (): Schema<HookAnswer> => s.object({ decision: s.optio
72
73
  const WORD = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
73
74
 
74
75
  /** The baba's section of the context file, CLAUDE.md and AGENTS.md: what the project is and how it is worked on, in any Markdown; one per baba. Voss wraps it with the doors and the skills. */
75
- export const context = (body: PromptNode, options?: { eval?: InterpretationSuite }): Prompt => ({ kind: "context", body, ...(options?.eval ? { eval: options.eval } : {}) });
76
+ export const context = (body: PromptNode, options?: { eval?: InterpretationSuite; hooks?: HookDef[] }): Prompt => ({ kind: "context", body, ...(options?.eval ? { eval: options.eval } : {}), ...(options?.hooks?.length ? { hooks: options.hooks.map((h) => { hook(h); return h; }) } : {}) });
76
77
 
77
78
  /** A skill: a file an agent opens when the description fits what it is doing. `uses` names the calls it is about, checked against the contract. The body is any Markdown node. */
78
79
  export function skill(head: { name: string; description: string; uses?: string[]; eval?: InterpretationSuite }, body: PromptNode): Prompt {
@@ -82,11 +83,11 @@ export function skill(head: { name: string; description: string; uses?: string[]
82
83
  }
83
84
 
84
85
  /** MDX's metadata and lazy document component become the same prompt as TSX. */
85
- export function mdxDocument(meta: { kind: "context"; eval?: InterpretationSuite } | { kind: "skill"; name: string; description: string; uses?: string[]; eval?: InterpretationSuite }, Content: PromptComponent): Prompt {
86
+ export function mdxDocument(meta: { kind: "context"; eval?: InterpretationSuite; hooks?: HookDef[] } | { kind: "skill"; name: string; description: string; uses?: string[]; eval?: InterpretationSuite }, Content: PromptComponent): Prompt {
86
87
  const body = jsx(Content, {});
87
88
  if (meta?.kind === "context") return context(body, meta);
88
89
  if (meta?.kind === "skill") return skill(meta, body);
89
- throw new Error('MDX promptware needs export const prompt = { kind: "context" | "skill", ... }');
90
+ throw new Error('an MDX instruction file needs export const prompt = { kind: "context" | "skill", ... }');
90
91
  }
91
92
 
92
93
  /** Raw Markdown, verbatim, with the common indentation removed: for prose longer than a line. */
@@ -172,7 +173,7 @@ function block(node: PromptNode): string {
172
173
  case "table": return table(kids) + "\n";
173
174
  case "strong": case "em": case "del": case "img": case "input": case "code": case "b": case "i": case "a": case "br": return inline(node) + "\n\n";
174
175
  case "tr": case "th": case "td": return inline(kids);
175
- default: throw new Error(`promptware: no such tag <${String(type)}>`);
176
+ default: throw new Error(`instructions: no such tag <${String(type)}>`);
176
177
  }
177
178
  }
178
179
 
@@ -1,5 +1,5 @@
1
- // The JSX runtime for promptware: elements that render to Markdown, not to
2
- // the DOM. A file says `/** @jsxImportSource babavoss/prompt */` and writes
1
+ // The JSX runtime for agentic instructions: elements that render to Markdown, not to
2
+ // the DOM. A file says `/** @jsxImportSource babavoss/instructions */` and writes
3
3
  // `<p>`, `<ul>`, `<pre lang="ts">`, `<Call of="feed" />`; `render` turns the
4
4
  // tree into text. Pure, no React.
5
5
  export interface PromptElement { readonly $prompt: true; type: string | PromptComponent; props: Record<string, unknown> }
@@ -18,7 +18,7 @@ export const isElement = (v: unknown): v is PromptElement => typeof v === "objec
18
18
 
19
19
  type Children = { children?: PromptNode };
20
20
 
21
- // What TypeScript admits in a promptware file: the Markdown tags, each with the props it renders.
21
+ // What TypeScript admits in an instruction file: the Markdown tags, each with the props it renders.
22
22
  export namespace JSX {
23
23
  export type Element = PromptElement;
24
24
  /** What a tag may be: a Markdown tag, or a component answering any node, text and lists included, not only an element. */
package/src/mcp/main.ts CHANGED
@@ -17,7 +17,7 @@ import { toolsOf, callName, promptsOf, promptText, type Tools } from "./tools.ts
17
17
  import { BUDGET, DoorError, budget, errorOf, index, schemaOf, followEntity, watchQuery, stateOf, untilOf, byKey, isTruncated, type Outcome } from "../door/core.ts";
18
18
 
19
19
  const VERSIONS = ["2025-06-18", "2025-03-26", "2024-11-05"];
20
- const empty: Manifest = { systems: [], promptware: { context: null, skills: {}, hooks: [] }, harness: defaultHarness, components: {}, resources: {}, effects: {}, actions: {}, queries: {}, tick: null };
20
+ const empty: Manifest = { systems: [], instructions: { context: null, skills: {}, hooks: [] }, harness: defaultHarness, components: {}, resources: {}, effects: {}, actions: {}, queries: {}, tick: null };
21
21
 
22
22
  const log = (l: string) => process.stderr.write(`voss mcp: ${l}\n`);
23
23
  const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
@@ -159,13 +159,13 @@ export async function runMcp(project: Project, rootDir: string): Promise<number>
159
159
  }
160
160
  case "resources/list": return {
161
161
  resources: [
162
- ...(m.promptware.context ? [{ uri: "baba://context", name: "context", description: "what the baba tells agents", mimeType: "text/markdown" }] : []),
162
+ ...(m.instructions.context ? [{ uri: "baba://context", name: "context", description: "what the baba tells agents", mimeType: "text/markdown" }] : []),
163
163
  ...[...outs.keys()].map((f) => ({ uri: `baba://out/${f}`, name: f, description: "an answer over the output budget", mimeType: "application/json" })),
164
164
  ],
165
165
  };
166
166
  case "resources/read": {
167
167
  const uri = String(p.uri ?? "");
168
- const context = uri === "baba://context" ? m.promptware.context : null;
168
+ const context = uri === "baba://context" ? m.instructions.context : null;
169
169
  if (context) return { contents: [{ uri, mimeType: "text/markdown", text: context }] };
170
170
  const out = uri.startsWith("baba://out/") ? outs.get(basename(uri.slice(11))) : undefined;
171
171
  if (out) return { contents: [{ uri, mimeType: "application/json", text: await readFile(out, "utf8") }] };
package/src/mcp/tools.ts CHANGED
@@ -16,12 +16,12 @@ export interface Target { kind: "action" | "query"; name: string; system: string
16
16
 
17
17
  export interface Tools { tools: Tool[]; targets: Map<string, Target>; generic: boolean }
18
18
 
19
- /** The promptware's threshold for describing the contract as `call`/`read`; the server itself is generic unless VOSS_MCP_TOOLS=1. */
19
+ /** The agentic instructions's threshold for describing the contract as `call`/`read`; the server itself is generic unless VOSS_MCP_TOOLS=1. */
20
20
 
21
21
  /** How an agent learns the contract: said in every tool that takes a call's name. */
22
22
  const LEARN = "`manifest` lists every call with an example; `manifest` with a name gives its schemas.";
23
23
 
24
- /** `<system>_<name>`; a name that already starts with its system's, as voss's own do (`promptware-sync`), is not prefixed twice: `promptware_sync`. */
24
+ /** `<system>_<name>`; a name that already starts with its system's, as voss's own do (`agents-sync`), is not prefixed twice: `agents_sync`. */
25
25
  export const toolName = (system: string, name: string) => name.startsWith(`${system}-`) ? `${system}_${name.slice(system.length + 1)}` : `${system}_${name}`;
26
26
 
27
27
  const isObj = (v: unknown): v is Obj => typeof v === "object" && v !== null && !Array.isArray(v);
@@ -107,12 +107,12 @@ export function callName(m: Manifest, n: string): { kind: "action" | "query"; na
107
107
 
108
108
  /** One prompt per skill, by its name. */
109
109
  export function promptsOf(m: Manifest): { name: string; description: string; skill: string }[] {
110
- return Object.entries(m.promptware.skills).map(([k, sk]) => ({ name: k, description: sk.description, skill: k }));
110
+ return Object.entries(m.instructions.skills).map(([k, sk]) => ({ name: k, description: sk.description, skill: k }));
111
111
  }
112
112
 
113
113
  /** A skill's prompt text: its body, then the tools it uses. */
114
114
  export function promptText(m: Manifest, skill: string, generic: boolean): string | null {
115
- const sk = m.promptware.skills[skill];
115
+ const sk = m.instructions.skills[skill];
116
116
  if (!sk) return null;
117
117
  const uses = (sk.uses ?? []).map((n) => {
118
118
  const c = m.actions[n] ?? m.queries[n];
@@ -6,7 +6,7 @@ import { manifestOf, type Baba } from "../ecs/baba.ts";
6
6
  import { Runtime, ContractError } from "../ecs/runtime.ts";
7
7
  import { StateError, type Snapshot } from "../ecs/state.ts";
8
8
  import { makeBridge, portOver } from "./bridge.ts";
9
- import { withPromptware } from "../promptware/system.ts";
9
+ import { withInstructions } from "../agents/system.ts";
10
10
 
11
11
  /** How long a `state` read waits for the round past `since` before answering the state as it is. */
12
12
  export const STATE_WAIT_MS = 25_000;
@@ -23,7 +23,7 @@ export class Harness {
23
23
  /** Loads the baba over the snapshot given; answers `loaded`, or throws for `failed`. */
24
24
  load(own: Baba, project: { name: string; dir: string; baba: string }, env: Record<string, string>, snapshot: Snapshot | null, prepare = false): void {
25
25
  // Voss's own systems join every baba after its own.
26
- const v = withPromptware(own);
26
+ const v = withInstructions(own);
27
27
  const manifest = manifestOf(v);
28
28
  const make = (snapshot: Snapshot | null, auto: boolean) => new Runtime(v, {
29
29
  auto,