@abaigram/abaikit 0.1.0 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"learnabai.js","sourceRoot":"","sources":["../src/learnabai.ts"],"names":[],"mappings":"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","sourcesContent":["// abaikit learnabai: the guide an agent reads before it creates or\n// retrofits an abaigram. One text, `abai/learnabai.md`, delivered three\n// ways: printed by the verb (whole, one section, or as JSON), returned by\n// the `learnabai` capability to an agent on the MCP front end, and written\n// as a Claude Code skill by `--skill`. The text names this machine's way\n// to install the packages and the stub's own deviations, filled in here,\n// so it is never out of step with what is installed.\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { basename, join, resolve } from \"node:path\";\nimport {\n\tABAI_STUB_VERSION,\n\tABAIGRAMMAR_VERSION,\n\tINSTANTIATION_DEVIATIONS,\n\tSIDECAR_DEVIATION,\n} from \"@abaigram/abai-stub\";\nimport { PACKAGE_ROOT } from \"./abaigram.ts\";\nimport type { ParsedArgs } from \"./bin.ts\";\nimport { type AbaikitIo, UsageError } from \"./io.ts\";\nimport { ABAIKIT_VERSION } from \"./version.ts\";\n\nexport const GUIDE_FILE = join(PACKAGE_ROOT, \"abai\", \"learnabai.md\");\nexport const SKILL_NAME = \"learnabai\";\n\nexport interface GuideSection {\n\tid: string;\n\ttitle: string;\n\ttext: string;\n}\n\nexport interface PackageSpecs {\n\t/** `npm install` arguments: `file:` paths, or `name@^version`. */\n\tabai: string;\n\tharness: string;\n\t/** The same packages as package.json values: `file:` paths, or `^version`; abaikit itself for a devDependency. */\n\tdependency: { abai: string; harness: string; abaikit: string };\n\t/** The specs are `file:` paths into a workspace checkout, not published versions. */\n\tfromWorkspace: boolean;\n\t/** Workspace checkouts only: both packages have their `dist/` built, so `npm install` of them works now. */\n\tbuilt: boolean;\n}\n\nexport interface Guide {\n\tabaigrammar: string;\n\tstub: string;\n\tabaikit: string;\n\t/** How this machine installs the stub and the harness. */\n\tpackages: PackageSpecs;\n\theader: string;\n\tsections: GuideSection[];\n\ttext: string;\n}\n\nconst require = createRequire(import.meta.url);\n\nfunction readPackage(dir: string): { name?: unknown; workspaces?: unknown } | undefined {\n\tconst path = join(dir, \"package.json\");\n\tif (!existsSync(path)) return undefined;\n\ttry {\n\t\treturn JSON.parse(readFileSync(path, \"utf8\")) as { name?: unknown; workspaces?: unknown };\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * The specs `npm install` takes for the two packages an abaigram needs, as\n * this abaikit can reach them. Inside the workspace checkout (the parent\n * is the workspace root whose `workspaces` name abaikit, not some\n * `node_modules` where hoisted siblings happen to sit) they are `file:`\n * paths to the sibling packages; anywhere else, the published versions.\n */\nexport function packageSpecs(packageRoot: string = PACKAGE_ROOT): PackageSpecs {\n\tconst workspace = resolve(packageRoot, \"..\");\n\tconst root = readPackage(workspace);\n\tconst workspaces = Array.isArray(root?.workspaces) ? (root.workspaces as unknown[]) : [];\n\tconst inWorkspace = basename(workspace) !== \"node_modules\" && workspaces.includes(basename(packageRoot));\n\tconst abai = join(workspace, \"abai-stub\");\n\tconst harness = join(workspace, \"abai-embedded-harness\");\n\tif (\n\t\tinWorkspace &&\n\t\treadPackage(abai)?.name === \"@abaigram/abai-stub\" &&\n\t\treadPackage(harness)?.name === \"@abaigram/abai-embedded-harness\"\n\t) {\n\t\tconst built = existsSync(join(abai, \"dist\", \"index.js\")) && existsSync(join(harness, \"dist\", \"index.js\"));\n\t\treturn {\n\t\t\tabai: `file:${abai}`,\n\t\t\tharness: `file:${harness}`,\n\t\t\tdependency: { abai: `file:${abai}`, harness: `file:${harness}`, abaikit: `file:${resolve(packageRoot)}` },\n\t\t\tfromWorkspace: true,\n\t\t\tbuilt,\n\t\t};\n\t}\n\tconst harnessVersion = (require(\"@abaigram/abai-embedded-harness/package.json\") as { version: string }).version;\n\treturn {\n\t\tabai: `@abaigram/abai-stub@^${ABAI_STUB_VERSION}`,\n\t\tharness: `@abaigram/abai-embedded-harness@^${harnessVersion}`,\n\t\tdependency: { abai: `^${ABAI_STUB_VERSION}`, harness: `^${harnessVersion}`, abaikit: `^${ABAIKIT_VERSION}` },\n\t\tfromWorkspace: false,\n\t\tbuilt: true,\n\t};\n}\n\n/** The text with every fenced block blanked, so a heading inside one is not a section. */\nfunction outsideFences(text: string): string {\n\treturn text.replace(/^```[a-z]*\\n[\\s\\S]*?^```$/gm, (block) => block.replace(/[^\\n]/g, \" \"));\n}\n\n/** The guide, filled in and split into its sections. */\nexport function loadGuide(file: string = GUIDE_FILE, packageRoot: string = PACKAGE_ROOT): Guide {\n\tconst packages = packageSpecs(packageRoot);\n\tconst deviations = [...INSTANTIATION_DEVIATIONS, SIDECAR_DEVIATION].map((d) => `- ${d}`).join(\"\\n\");\n\tlet workspaceNote = \"\";\n\tif (packages.fromWorkspace && !packages.built) {\n\t\tworkspaceNote =\n\t\t\t\"\\nThese are workspace checkouts whose `dist/` is not built yet: run `npm run build` in the workspace first, or the packages install with nothing to import.\\n\";\n\t} else if (packages.fromWorkspace) {\n\t\tworkspaceNote = \"\\n(These are the workspace's own checkouts, built; `npm install` links them.)\\n\";\n\t}\n\tconst values: Record<string, string> = {\n\t\tabaigrammar: ABAIGRAMMAR_VERSION,\n\t\tstub: ABAI_STUB_VERSION,\n\t\tabaikit: ABAIKIT_VERSION,\n\t\tabai_spec: packages.abai,\n\t\tharness_spec: packages.harness,\n\t\tworkspace_note: workspaceNote,\n\t\tdeviations,\n\t};\n\tconst text = readFileSync(file, \"utf8\").replace(/\\{\\{([a-z_]+)\\}\\}/g, (whole, key: string) => {\n\t\tconst value = values[key];\n\t\tif (value === undefined) throw new Error(`${file} names an unknown value ${whole}`);\n\t\treturn value;\n\t});\n\t// sections are the level-two headings outside fenced blocks, each ending in its id in parentheses\n\tconst scan = outsideFences(text);\n\tconst sections: GuideSection[] = [];\n\tlet header = text;\n\tlet previous: { id: string; title: string; start: number } | undefined;\n\tfor (const match of scan.matchAll(/^## (.*)$/gm)) {\n\t\tconst titled = /^(.+?) \\(([a-z]+)\\)$/.exec(match[1]);\n\t\tif (!titled) throw new Error(`${file}: the heading \"## ${match[1]}\" ends in no (id)`);\n\t\tconst [, title, id] = titled;\n\t\tif (sections.some((s) => s.id === id) || previous?.id === id) {\n\t\t\tthrow new Error(`${file}: two sections are named (${id})`);\n\t\t}\n\t\tconst start = match.index;\n\t\tif (previous) {\n\t\t\tsections.push({ id: previous.id, title: previous.title, text: text.slice(previous.start, start).trimEnd() });\n\t\t} else header = text.slice(0, start).trimEnd();\n\t\tprevious = { id, title, start };\n\t}\n\tif (previous) sections.push({ id: previous.id, title: previous.title, text: text.slice(previous.start).trimEnd() });\n\treturn {\n\t\tabaigrammar: ABAIGRAMMAR_VERSION,\n\t\tstub: ABAI_STUB_VERSION,\n\t\tabaikit: ABAIKIT_VERSION,\n\t\tpackages,\n\t\theader,\n\t\tsections,\n\t\ttext,\n\t};\n}\n\n/** One section by id; an unknown id names the ids there are. */\nexport function findSection(guide: Guide, id: string): GuideSection {\n\tconst found = guide.sections.find((s) => s.id === id);\n\tif (!found) throw new UsageError(`no section ${id}; the sections are ${guide.sections.map((s) => s.id).join(\", \")}`);\n\treturn found;\n}\n\n/** The whole guide, or one section, as printed. */\nexport function guideText(section?: string): string {\n\tconst guide = loadGuide();\n\tif (section === undefined || section === \"\") return guide.text;\n\treturn `${findSection(guide, section).text}\\n`;\n}\n\n/** The `learnabai` capability: the guide for an agent, one section or all. */\nexport const learnabaiHandler = (params: Record<string, unknown>): { text: string } => {\n\tconst section = typeof params.section === \"string\" ? params.section : undefined;\n\treturn { text: guideText(section) };\n};\n\n/** The skill file Claude Code loads as `/learnabai`: the whole guide, with its source named. */\nexport function skillText(guide: Guide): string {\n\treturn [\n\t\t\"---\",\n\t\t`name: ${SKILL_NAME}`,\n\t\t\"description: How to create an abaigram or retrofit a repository into one with abai (the stub, the standard entry, the conformance levels, the step-by-step retrofit, and what never to do). Use when asked to abaify a repository, add abai to a program, or check an abaigram's conformance.\",\n\t\t\"---\",\n\t\t\"\",\n\t\t`This is the output of \\`abaikit learnabai\\` for abaikit ${guide.abaikit}; run that command for the current text and \\`abaikit learnabai --section <id>\\` for one section.`,\n\t\t\"\",\n\t\tguide.text.trimEnd(),\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\n/** Where `--skill` writes: `<dir>/learnabai/SKILL.md`, the dir defaulting to Claude Code's user skills. */\nexport function skillPath(io: AbaikitIo, dir?: string): string {\n\tif (dir !== undefined) return join(resolve(io.cwd, dir), SKILL_NAME, \"SKILL.md\");\n\tconst home = io.env.HOME;\n\tif (!home) throw new UsageError(\"--skill needs HOME, or --skill-dir <dir>, to know where Claude Code's skills live\");\n\treturn join(home, \".claude\", \"skills\", SKILL_NAME, \"SKILL.md\");\n}\n\nexport async function runLearnabai(parsed: Extract<ParsedArgs, { verb: \"learnabai\" }>, io: AbaikitIo): Promise<number> {\n\tif (parsed.skill) {\n\t\tconst path = skillPath(io, parsed.skillDir);\n\t\tmkdirSync(join(path, \"..\"), { recursive: true });\n\t\twriteFileSync(path, skillText(loadGuide()));\n\t\tio.out(`${path}\\n`);\n\t\treturn 0;\n\t}\n\tif (parsed.json) {\n\t\tconst guide = loadGuide();\n\t\tconst sections: Record<string, string> = {};\n\t\tconst picked = parsed.section === undefined ? guide.sections : [findSection(guide, parsed.section)];\n\t\tfor (const s of picked) sections[s.id] = s.text;\n\t\tconst json = {\n\t\t\tabaigrammar: guide.abaigrammar,\n\t\t\tstub: guide.stub,\n\t\t\tabaikit: guide.abaikit,\n\t\t\tpackages: guide.packages,\n\t\t\tsections,\n\t\t};\n\t\tio.out(`${JSON.stringify(json, null, 2)}\\n`);\n\t\treturn 0;\n\t}\n\tio.out(guideText(parsed.section));\n\treturn 0;\n}\n"]}
1
+ {"version":3,"file":"learnabai.js","sourceRoot":"","sources":["../src/learnabai.ts"],"names":[],"mappings":"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","sourcesContent":["// abaikit learnabai: the guide an agent reads before it creates or\n// retrofits an abaigram. One text, `abai/learnabai.md`, delivered three\n// ways: printed by the verb (whole, one section, or as JSON), returned by\n// the `learnabai` capability to an agent on the MCP front end, and written\n// as a Claude Code skill by `--skill`. The text names this machine's way\n// to install the packages and the stub's own deviations, filled in here,\n// so it is never out of step with what is installed.\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { basename, join, resolve } from \"node:path\";\nimport {\n\tABAI_STUB_VERSION,\n\tABAIGRAMMAR_VERSION,\n\tINSTANTIATION_DEVIATIONS,\n\tSIDECAR_DEVIATION,\n\tTHREAD_DEVIATION,\n} from \"@abaigram/abai-stub\";\nimport { PACKAGE_ROOT } from \"./abaigram.ts\";\nimport type { ParsedArgs } from \"./bin.ts\";\nimport { type AbaikitIo, UsageError } from \"./io.ts\";\nimport { ABAIKIT_VERSION } from \"./version.ts\";\n\nexport const GUIDE_FILE = join(PACKAGE_ROOT, \"abai\", \"learnabai.md\");\nexport const SKILL_NAME = \"learnabai\";\n\nexport interface GuideSection {\n\tid: string;\n\ttitle: string;\n\ttext: string;\n}\n\nexport interface PackageSpecs {\n\t/** `npm install` arguments: `file:` paths, or `name@^version`. */\n\tabai: string;\n\tharness: string;\n\t/** The same packages as package.json values: `file:` paths, or `^version`; abaikit itself for a devDependency. */\n\tdependency: { abai: string; harness: string; abaikit: string };\n\t/** The specs are `file:` paths into a workspace checkout, not published versions. */\n\tfromWorkspace: boolean;\n\t/** Workspace checkouts only: both packages have their `dist/` built, so `npm install` of them works now. */\n\tbuilt: boolean;\n}\n\nexport interface Guide {\n\tabaigrammar: string;\n\tstub: string;\n\tabaikit: string;\n\t/** How this machine installs the stub and the harness. */\n\tpackages: PackageSpecs;\n\theader: string;\n\tsections: GuideSection[];\n\ttext: string;\n}\n\nconst require = createRequire(import.meta.url);\n\nfunction readPackage(dir: string): { name?: unknown; workspaces?: unknown } | undefined {\n\tconst path = join(dir, \"package.json\");\n\tif (!existsSync(path)) return undefined;\n\ttry {\n\t\treturn JSON.parse(readFileSync(path, \"utf8\")) as { name?: unknown; workspaces?: unknown };\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * The specs `npm install` takes for the two packages an abaigram needs, as\n * this abaikit can reach them. Inside the workspace checkout (the parent\n * is the workspace root whose `workspaces` name abaikit, not some\n * `node_modules` where hoisted siblings happen to sit) they are `file:`\n * paths to the sibling packages; anywhere else, the published versions.\n */\nexport function packageSpecs(packageRoot: string = PACKAGE_ROOT): PackageSpecs {\n\tconst workspace = resolve(packageRoot, \"..\");\n\tconst root = readPackage(workspace);\n\tconst workspaces = Array.isArray(root?.workspaces) ? (root.workspaces as unknown[]) : [];\n\tconst inWorkspace = basename(workspace) !== \"node_modules\" && workspaces.includes(basename(packageRoot));\n\tconst abai = join(workspace, \"abai-stub\");\n\tconst harness = join(workspace, \"abai-embedded-harness\");\n\tif (\n\t\tinWorkspace &&\n\t\treadPackage(abai)?.name === \"@abaigram/abai-stub\" &&\n\t\treadPackage(harness)?.name === \"@abaigram/abai-embedded-harness\"\n\t) {\n\t\tconst built = existsSync(join(abai, \"dist\", \"index.js\")) && existsSync(join(harness, \"dist\", \"index.js\"));\n\t\treturn {\n\t\t\tabai: `file:${abai}`,\n\t\t\tharness: `file:${harness}`,\n\t\t\tdependency: { abai: `file:${abai}`, harness: `file:${harness}`, abaikit: `file:${resolve(packageRoot)}` },\n\t\t\tfromWorkspace: true,\n\t\t\tbuilt,\n\t\t};\n\t}\n\tconst harnessVersion = (require(\"@abaigram/abai-embedded-harness/package.json\") as { version: string }).version;\n\treturn {\n\t\tabai: `@abaigram/abai-stub@^${ABAI_STUB_VERSION}`,\n\t\tharness: `@abaigram/abai-embedded-harness@^${harnessVersion}`,\n\t\tdependency: { abai: `^${ABAI_STUB_VERSION}`, harness: `^${harnessVersion}`, abaikit: `^${ABAIKIT_VERSION}` },\n\t\tfromWorkspace: false,\n\t\tbuilt: true,\n\t};\n}\n\n/** The text with every fenced block blanked, so a heading inside one is not a section. */\nfunction outsideFences(text: string): string {\n\treturn text.replace(/^```[a-z]*\\n[\\s\\S]*?^```$/gm, (block) => block.replace(/[^\\n]/g, \" \"));\n}\n\n/** The guide, filled in and split into its sections. */\nexport function loadGuide(file: string = GUIDE_FILE, packageRoot: string = PACKAGE_ROOT): Guide {\n\tconst packages = packageSpecs(packageRoot);\n\tconst deviations = [...INSTANTIATION_DEVIATIONS, THREAD_DEVIATION, SIDECAR_DEVIATION]\n\t\t.map((d) => `- ${d}`)\n\t\t.join(\"\\n\");\n\tlet workspaceNote = \"\";\n\tif (packages.fromWorkspace && !packages.built) {\n\t\tworkspaceNote =\n\t\t\t\"\\nThese are workspace checkouts whose `dist/` is not built yet: run `npm run build` in the workspace first, or the packages install with nothing to import.\\n\";\n\t} else if (packages.fromWorkspace) {\n\t\tworkspaceNote = \"\\n(These are the workspace's own checkouts, built; `npm install` links them.)\\n\";\n\t}\n\tconst values: Record<string, string> = {\n\t\tabaigrammar: ABAIGRAMMAR_VERSION,\n\t\tstub: ABAI_STUB_VERSION,\n\t\tabaikit: ABAIKIT_VERSION,\n\t\tabai_spec: packages.abai,\n\t\tharness_spec: packages.harness,\n\t\tworkspace_note: workspaceNote,\n\t\tdeviations,\n\t};\n\tconst text = readFileSync(file, \"utf8\").replace(/\\{\\{([a-z_]+)\\}\\}/g, (whole, key: string) => {\n\t\tconst value = values[key];\n\t\tif (value === undefined) throw new Error(`${file} names an unknown value ${whole}`);\n\t\treturn value;\n\t});\n\t// sections are the level-two headings outside fenced blocks, each ending in its id in parentheses\n\tconst scan = outsideFences(text);\n\tconst sections: GuideSection[] = [];\n\tlet header = text;\n\tlet previous: { id: string; title: string; start: number } | undefined;\n\tfor (const match of scan.matchAll(/^## (.*)$/gm)) {\n\t\tconst titled = /^(.+?) \\(([a-z]+)\\)$/.exec(match[1]);\n\t\tif (!titled) throw new Error(`${file}: the heading \"## ${match[1]}\" ends in no (id)`);\n\t\tconst [, title, id] = titled;\n\t\tif (sections.some((s) => s.id === id) || previous?.id === id) {\n\t\t\tthrow new Error(`${file}: two sections are named (${id})`);\n\t\t}\n\t\tconst start = match.index;\n\t\tif (previous) {\n\t\t\tsections.push({ id: previous.id, title: previous.title, text: text.slice(previous.start, start).trimEnd() });\n\t\t} else header = text.slice(0, start).trimEnd();\n\t\tprevious = { id, title, start };\n\t}\n\tif (previous) sections.push({ id: previous.id, title: previous.title, text: text.slice(previous.start).trimEnd() });\n\treturn {\n\t\tabaigrammar: ABAIGRAMMAR_VERSION,\n\t\tstub: ABAI_STUB_VERSION,\n\t\tabaikit: ABAIKIT_VERSION,\n\t\tpackages,\n\t\theader,\n\t\tsections,\n\t\ttext,\n\t};\n}\n\n/** One section by id; an unknown id names the ids there are. */\nexport function findSection(guide: Guide, id: string): GuideSection {\n\tconst found = guide.sections.find((s) => s.id === id);\n\tif (!found) throw new UsageError(`no section ${id}; the sections are ${guide.sections.map((s) => s.id).join(\", \")}`);\n\treturn found;\n}\n\n/** The whole guide, or one section, as printed. */\nexport function guideText(section?: string): string {\n\tconst guide = loadGuide();\n\tif (section === undefined || section === \"\") return guide.text;\n\treturn `${findSection(guide, section).text}\\n`;\n}\n\n/** The `learnabai` capability: the guide for an agent, one section or all. */\nexport const learnabaiHandler = (params: Record<string, unknown>): { text: string } => {\n\tconst section = typeof params.section === \"string\" ? params.section : undefined;\n\treturn { text: guideText(section) };\n};\n\n/** The skill file Claude Code loads as `/learnabai`: the whole guide, with its source named. */\nexport function skillText(guide: Guide): string {\n\treturn [\n\t\t\"---\",\n\t\t`name: ${SKILL_NAME}`,\n\t\t\"description: How to create an abaigram or retrofit a repository into one with abai (the stub, the standard entry, the conformance levels, the step-by-step retrofit, and what never to do). Use when asked to abaify a repository, add abai to a program, or check an abaigram's conformance.\",\n\t\t\"---\",\n\t\t\"\",\n\t\t`This is the output of \\`abaikit learnabai\\` for abaikit ${guide.abaikit}; run that command for the current text and \\`abaikit learnabai --section <id>\\` for one section.`,\n\t\t\"\",\n\t\tguide.text.trimEnd(),\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\n/** Where `--skill` writes: `<dir>/learnabai/SKILL.md`, the dir defaulting to Claude Code's user skills. */\nexport function skillPath(io: AbaikitIo, dir?: string): string {\n\tif (dir !== undefined) return join(resolve(io.cwd, dir), SKILL_NAME, \"SKILL.md\");\n\tconst home = io.env.HOME;\n\tif (!home) throw new UsageError(\"--skill needs HOME, or --skill-dir <dir>, to know where Claude Code's skills live\");\n\treturn join(home, \".claude\", \"skills\", SKILL_NAME, \"SKILL.md\");\n}\n\nexport async function runLearnabai(parsed: Extract<ParsedArgs, { verb: \"learnabai\" }>, io: AbaikitIo): Promise<number> {\n\tif (parsed.skill) {\n\t\tconst path = skillPath(io, parsed.skillDir);\n\t\tmkdirSync(join(path, \"..\"), { recursive: true });\n\t\twriteFileSync(path, skillText(loadGuide()));\n\t\tio.out(`${path}\\n`);\n\t\treturn 0;\n\t}\n\tif (parsed.json) {\n\t\tconst guide = loadGuide();\n\t\tconst sections: Record<string, string> = {};\n\t\tconst picked = parsed.section === undefined ? guide.sections : [findSection(guide, parsed.section)];\n\t\tfor (const s of picked) sections[s.id] = s.text;\n\t\tconst json = {\n\t\t\tabaigrammar: guide.abaigrammar,\n\t\t\tstub: guide.stub,\n\t\t\tabaikit: guide.abaikit,\n\t\t\tpackages: guide.packages,\n\t\t\tsections,\n\t\t};\n\t\tio.out(`${JSON.stringify(json, null, 2)}\\n`);\n\t\treturn 0;\n\t}\n\tio.out(guideText(parsed.section));\n\treturn 0;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"template-ts.d.ts","sourceRoot":"","sources":["../src/template-ts.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,qBAAqB,CAAC;AAE9E,MAAM,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAElC,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,sHAAsH;IACtH,UAAU,EAAE,MAAM,CAAC;IACnB,oHAAoH;IACpH,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;CACrG;AAkDD,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,eAAe,CA+BrE;AAgPD,2GAA2G;AAC3G,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqB1E","sourcesContent":["// The TypeScript template behind `abaikit new`: one declaration, as data,\n// rendered twice. Into the new project's `src/abai.ts` as source, and\n// through the stub's `buildManifest` into its `abaigram.yaml`, so file and\n// code agree without running the program. The program is a small loop\n// that works through a number of steps; at each level the declarations it\n// needs are live and the loop uses them, so `abaikit check` reaches that\n// level out of the box. Below its level every declaration kind is present\n// once, commented, as section 13 asks, and uncommenting one is all it\n// takes to make it live.\nimport type { AbaigramOptions, CapabilityOptions } from \"@abaigram/abai-stub\";\n\nexport type Level = 1 | 2 | 3 | 4;\n\nexport interface TemplateInput {\n\tname: string;\n\tlevel: Level;\n\t/** The specifier the generated code imports the stub by; `@abaigram/abai-stub` unless a test points at the source. */\n\tabaiImport: string;\n\t/** What `package.json` depends on, in package.json form, and whether the packages are built workspace checkouts. */\n\tpackages: { abai: string; harness: string; abaikit: string; fromWorkspace: boolean; built: boolean };\n}\n\n// The declaration's constants, each written once and read by both renderings.\nconst ENTRY = \"node src/main.ts abai\";\nconst MODES = [\"turns\", \"sidecar\"] as const;\nconst CONTENT = { identity: \"abai/identity.md\", use: \"abai/use.md\" };\nconst AUDIT = { path: \"./abai-audit.log\" };\nconst CHECK = { run: \"node src/main.ts 4\" };\nconst CELL_DONE = { type: \"int\", access: \"read\", doc: \"Steps finished so far.\" } as const;\nconst KNOB_PACE = {\n\ttype: \"int\",\n\taccess: \"readwrite\",\n\tdefault: 10,\n\trange: [1, 1000],\n\tdoc: \"Milliseconds a step takes; the agent may slow or hasten the work.\",\n} as const;\nconst EVENT_STEP = { payload: { n: \"int\" }, wakes: \"never\", doc: \"A step finished.\" } as const;\nconst CAPABILITY_SKIP: Omit<CapabilityOptions, \"handler\"> = {\n\tparams: { n: \"int\" },\n\tresult: { ok: \"bool\" },\n\teffect: \"mutate\",\n\tpolicy: \"confirm\",\n\tdispatch: \"immediate\",\n\t// step 2: the exercise's call lands while step 1 already runs, so this one is seen skipped under check\n\texample: { n: 2 },\n\tdoc: \"Skip step n when the loop reaches it.\",\n};\n/** The handler as source, indented from column zero; the renderer places it. */\nconst SKIP_HANDLER = \"({ n }) => {\\n\\tskipped.add(Number(n));\\n\\treturn { ok: true };\\n}\";\nconst DECISION_HALFWAY = {\n\tcontext: { done: \"int\", total: \"int\" },\n\toptions: [\"continue\", \"stop\"],\n\tdefault: \"continue\",\n\t// long enough for an agent to answer under `abai run`; past it the default applies\n\ttimeout: \"15s\",\n\tdoc: \"Asked halfway through the work: go on, or stop here.\",\n} as const;\nconst TURN_STEP = { timeout: \"5s\", doc: \"After each step. The agent may skip a step or change the pace.\" } as const;\n\n/** The level each declaration becomes live at. */\nconst LIVE_FROM = {\n\tcheck: 2,\n\t\"work.done\": 2,\n\t\"work.step\": 2,\n\tend_of_step: 2,\n\t\"work.pace_ms\": 3,\n\t\"work.skip\": 3,\n\ton_halfway: 4,\n} as const;\n\n/** The declaration the program makes at this level, as the stub takes it. */\nexport function declarationsFor(input: TemplateInput): AbaigramOptions {\n\tconst { name, level } = input;\n\tconst options: AbaigramOptions = {\n\t\tname,\n\t\tentry: ENTRY,\n\t\tmodes: [...MODES],\n\t\tcontent: { ...CONTENT },\n\t\taudit: { ...AUDIT },\n\t};\n\tif (level >= LIVE_FROM.check) options.check = { ...CHECK };\n\tconst cells: NonNullable<AbaigramOptions[\"cells\"]> = {};\n\tif (level >= LIVE_FROM[\"work.done\"]) cells[\"work.done\"] = { ...CELL_DONE };\n\tif (level >= LIVE_FROM[\"work.pace_ms\"]) cells[\"work.pace_ms\"] = { ...KNOB_PACE, range: [...KNOB_PACE.range] };\n\tif (Object.keys(cells).length > 0) options.cells = cells;\n\tif (level >= LIVE_FROM[\"work.step\"])\n\t\toptions.events = { \"work.step\": { ...EVENT_STEP, payload: { ...EVENT_STEP.payload } } };\n\tif (level >= LIVE_FROM[\"work.skip\"]) {\n\t\t// the handler here is a stand-in: the manifest never sees it, and the generated module has the real one\n\t\toptions.capabilities = { \"work.skip\": { ...CAPABILITY_SKIP, handler: () => ({ ok: true }) } };\n\t}\n\tif (level >= LIVE_FROM.on_halfway) {\n\t\toptions.decisions = {\n\t\t\ton_halfway: {\n\t\t\t\t...DECISION_HALFWAY,\n\t\t\t\toptions: [...DECISION_HALFWAY.options],\n\t\t\t\tcontext: { ...DECISION_HALFWAY.context },\n\t\t\t},\n\t\t};\n\t}\n\tif (level >= LIVE_FROM.end_of_step) options.turns = { end_of_step: { ...TURN_STEP } };\n\treturn options;\n}\n\n// ---------------------------------------------------------------------------\n// Rendering source\n// ---------------------------------------------------------------------------\n\nconst IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst WIDTH = 110;\n\n/** A value rendered verbatim, at the current indent: a handler's source. */\nclass Raw {\n\treadonly source: string;\n\tconstructor(source: string) {\n\t\tthis.source = source;\n\t}\n}\n\nfunction key(k: string): string {\n\treturn IDENT.test(k) ? k : JSON.stringify(k);\n}\n\n/** A value as a TypeScript literal, on one line when it fits in `room` columns, else nested by `indent` tabs. */\nfunction literal(value: unknown, indent: number, room: number): string {\n\tif (value instanceof Raw) {\n\t\tconst pad = \"\\t\".repeat(indent);\n\t\treturn value.source\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line, i) => (i === 0 ? line : `${pad}${line}`))\n\t\t\t.join(\"\\n\");\n\t}\n\tif (Array.isArray(value)) return `[${value.map((v) => literal(v, indent, room)).join(\", \")}]`;\n\tif (typeof value === \"object\" && value !== null) {\n\t\tconst entries = Object.entries(value);\n\t\tif (entries.length === 0) return \"{}\";\n\t\tconst inline = entries.map(([k, v]) => `${key(k)}: ${literal(v, indent, room)}`).join(\", \");\n\t\tif (!inline.includes(\"\\n\") && inline.length + 4 <= room) return `{ ${inline} }`;\n\t\tconst pad = \"\\t\".repeat(indent + 1);\n\t\tconst lines = entries.map(([k, v]) => {\n\t\t\tconst head = `${pad}${key(k)}: `;\n\t\t\treturn `${head}${literal(v, indent + 1, WIDTH - head.length * 2)},`;\n\t\t});\n\t\treturn `{\\n${lines.join(\"\\n\")}\\n${\"\\t\".repeat(indent)}}`;\n\t}\n\treturn JSON.stringify(value);\n}\n\n/** Comment out a rendered piece, every line. */\nfunction commented(text: string, indent: number): string {\n\tconst pad = \"\\t\".repeat(indent);\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.map((line) => (line.startsWith(pad) ? `${pad}// ${line.slice(pad.length)}` : `${pad}// ${line.trimStart()}`))\n\t\t.join(\"\\n\");\n}\n\n/**\n * One declaration block, `cells: { ... },` with each entry live or\n * commented on its own, so uncommenting an entry is all it takes; a block\n * with no live entry is commented whole, as the example of its kind.\n */\nfunction block(name: string, entries: Array<{ key: string; value: unknown; live: boolean }>, indent: number): string {\n\tconst pad = \"\\t\".repeat(indent);\n\tconst inner = \"\\t\".repeat(indent + 1);\n\tconst raw = entries.map((e) => {\n\t\tconst head = `${inner}${key(e.key)}: `;\n\t\treturn { text: `${head}${literal(e.value, indent + 1, WIDTH - head.length * 2)},`, live: e.live };\n\t});\n\tif (!raw.some((e) => e.live)) {\n\t\t// no live entry: the whole block is the example, commented once\n\t\treturn commented(`${pad}${name}: {\\n${raw.map((e) => e.text).join(\"\\n\")}\\n${pad}},`, indent);\n\t}\n\tconst rendered = raw.map((e) => (e.live ? e.text : commented(e.text, indent + 1)));\n\treturn `${pad}${name}: {\\n${rendered.join(\"\\n\")}\\n${pad}},`;\n}\n\nfunction declarationModule(input: TemplateInput): string {\n\tconst { name, level, abaiImport } = input;\n\tconst live = (from: number) => level >= from;\n\tconst lines: string[] = [];\n\tlines.push(`// ${name} as an abaigram: what the agent may observe and steer, declared once.`);\n\tlines.push(\"// The manifest (abaigram.yaml) is generated from this: after a change, run\");\n\tlines.push(\"// node src/main.ts abai manifest > abaigram.yaml\");\n\tlines.push(\"// and check it with: abaikit check .\");\n\tif (level < 4) {\n\t\tlines.push(\"// A commented declaration is the example of its kind: uncomment it (and the lines\");\n\t\tlines.push(\"// in src/main.ts that use it) when the program has the fact or the fork.\");\n\t}\n\tlines.push('import { fileURLToPath } from \"node:url\";');\n\tlines.push(`import { createAbaigram } from ${JSON.stringify(abaiImport)};`);\n\tlines.push(\"\");\n\tlines.push(\"/** Steps the agent asked to skip (work.skip); the loop in main.ts honours it. */\");\n\tlines.push(\n\t\tlive(LIVE_FROM[\"work.skip\"])\n\t\t\t? \"export const skipped = new Set<number>();\"\n\t\t\t: \"// export const skipped = new Set<number>();\",\n\t);\n\tlines.push(\"\");\n\tlines.push(\"export const app = createAbaigram(\");\n\tlines.push(\"\\t{\");\n\tlines.push(`\\t\\tname: ${JSON.stringify(name)},`);\n\tlines.push(\"\\t\\t// a runnable entry: the tools reach the program through it, in this directory\");\n\tlines.push(`\\t\\tentry: ${JSON.stringify(ENTRY)},`);\n\tlines.push(`\\t\\tmodes: ${literal([...MODES], 2, WIDTH)},`);\n\tlines.push(`\\t\\tcontent: ${literal(CONTENT, 2, WIDTH)},`);\n\tlines.push(`\\t\\taudit: ${literal(AUDIT, 2, WIDTH)},`);\n\tlines.push(\"\\t\\t// a short run that exercises every channel: what abaikit check runs for the levels above 1\");\n\tconst checkLine = `\\t\\tcheck: ${literal(CHECK, 2, WIDTH)},`;\n\tlines.push(live(LIVE_FROM.check) ? checkLine : commented(checkLine, 2));\n\tlines.push(\"\\t\\t// cells the program writes; a readwrite cell is a knob the agent may set within its range\");\n\tlines.push(\n\t\tblock(\n\t\t\t\"cells\",\n\t\t\t[\n\t\t\t\t{ key: \"work.done\", value: CELL_DONE, live: live(LIVE_FROM[\"work.done\"]) },\n\t\t\t\t{ key: \"work.pace_ms\", value: KNOB_PACE, live: live(LIVE_FROM[\"work.pace_ms\"]) },\n\t\t\t],\n\t\t\t2,\n\t\t),\n\t);\n\tlines.push(\"\\t\\t// events the program emits; wakes says when one wakes the agent\");\n\tlines.push(block(\"events\", [{ key: \"work.step\", value: EVENT_STEP, live: live(LIVE_FROM[\"work.step\"]) }], 2));\n\tlines.push(\"\\t\\t// capabilities the agent may call. dispatch immediate runs the handler at once; the default\");\n\tlines.push(\"\\t\\t// (safepoint) waits for app.safepoint(). check calls the example, so keep it harmless\");\n\tlines.push(\n\t\tblock(\n\t\t\t\"capabilities\",\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tkey: \"work.skip\",\n\t\t\t\t\tvalue: { ...CAPABILITY_SKIP, handler: new Raw(SKIP_HANDLER) },\n\t\t\t\t\tlive: live(LIVE_FROM[\"work.skip\"]),\n\t\t\t\t},\n\t\t\t],\n\t\t\t2,\n\t\t),\n\t);\n\tlines.push(\"\\t\\t// decisions the program asks at a real fork; the default is what it does when nobody answers\");\n\tlines.push(\n\t\tblock(\"decisions\", [{ key: \"on_halfway\", value: DECISION_HALFWAY, live: live(LIVE_FROM.on_halfway) }], 2),\n\t);\n\tlines.push(\"\\t\\t// turns: bounded moments the program hands the agent\");\n\tlines.push(block(\"turns\", [{ key: \"end_of_step\", value: TURN_STEP, live: live(LIVE_FROM.end_of_step) }], 2));\n\tlines.push(\"\\t},\");\n\tlines.push(\"\\t// the directory holding abaigram.yaml and abai/: one level up from this file\");\n\tlines.push('\\t{ root: fileURLToPath(new URL(\"..\", import.meta.url)) },');\n\tlines.push(\");\");\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction mainModule(input: TemplateInput): string {\n\tconst { name, level, abaiImport } = input;\n\tconst live = (from: number) => level >= from;\n\tconst lines: string[] = [];\n\tlines.push(`// ${name}: works through a number of steps and prints each. Node 22.19 and`);\n\tlines.push(\"// later run this file as it is (node src/main.ts 5); the first lines hand the\");\n\tlines.push(\"// standard agent entry to the stub, and the program's own run follows.\");\n\tlines.push(`import { runEntry } from ${JSON.stringify(abaiImport)};`);\n\tlines.push(\n\t\tlive(LIVE_FROM[\"work.skip\"]) ? 'import { app, skipped } from \"./abai.ts\";' : 'import { app } from \"./abai.ts\";',\n\t);\n\tlines.push(\"\");\n\tlines.push(\"const code = await runEntry(app, process.argv.slice(2));\");\n\tlines.push(\"if (code >= 0) process.exit(code); // an abai verb ran; otherwise the program's own run begins\");\n\tlines.push(\"\");\n\tlines.push(\"const total = Number(process.argv[2] ?? 5);\");\n\tlines.push(\"const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\");\n\tif (live(LIVE_FROM[\"work.done\"])) {\n\t\tlines.push(\"// handles once, at startup; set and emit are the cheap calls\");\n\t\tlines.push('const done = app.cell<number>(\"work.done\");');\n\t\tlines.push('const step = app.event(\"work.step\");');\n\t}\n\tif (live(LIVE_FROM[\"work.pace_ms\"])) lines.push('const pace = app.knob<number>(\"work.pace_ms\");');\n\tlines.push(\"\");\n\tlines.push(\"for (let n = 1; n <= total; n++) {\");\n\tif (live(LIVE_FROM.on_halfway)) {\n\t\tlines.push(\"\\tif (n === Math.ceil(total / 2)) {\");\n\t\tlines.push(\"\\t\\t// a real fork: the default is what the program did before it was an abaigram\");\n\t\tlines.push('\\t\\tconst choice = await app.decide<string>(\"on_halfway\", { done: n - 1, total });');\n\t\tlines.push('\\t\\tif (choice === \"stop\") {');\n\t\tlines.push(`\\t\\t\\tconsole.log(\"${name}: stopped halfway, as asked\");`);\n\t\tlines.push(\"\\t\\t\\tbreak;\");\n\t\tlines.push(\"\\t\\t}\");\n\t\tlines.push(\"\\t}\");\n\t}\n\tif (live(LIVE_FROM[\"work.skip\"])) {\n\t\tlines.push(\"\\tif (skipped.has(n)) {\");\n\t\t// biome-ignore lint/suspicious/noTemplateCurlyInString: this is the generated program's source, a template literal in it\n\t\tlines.push(\"\\t\\tconsole.log(`step ${n} skipped`);\");\n\t\tlines.push(\"\\t\\tcontinue;\");\n\t\tlines.push(\"\\t}\");\n\t\tlines.push(\"\\tawait sleep(pace.get());\");\n\t} else {\n\t\tlines.push(\"\\tawait sleep(10);\");\n\t}\n\tif (live(LIVE_FROM[\"work.done\"])) {\n\t\tlines.push(\"\\tdone.set(n);\");\n\t\tlines.push(\"\\tstep.emit({ n });\");\n\t}\n\t// biome-ignore lint/suspicious/noTemplateCurlyInString: this is the generated program's source, a template literal in it\n\tlines.push(\"\\tconsole.log(`step ${n} of ${total}`);\");\n\tlines.push(\"\\tapp.safepoint();\");\n\tif (live(LIVE_FROM.end_of_step)) lines.push('\\tawait app.turn(\"end_of_step\");');\n\tlines.push(\"}\");\n\tlines.push(\n\t\tlive(LIVE_FROM[\"work.done\"])\n\t\t\t? `console.log(\\`${name}: \\${done.get()} steps done\\`);`\n\t\t\t: `console.log(\"${name}: done\");`,\n\t);\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction readme(input: TemplateInput): string {\n\tconst { name, level, packages } = input;\n\tconst where = packages.fromWorkspace\n\t\t? `The two packages come from the abai workspace checkout (\\`file:\\` dependencies)${packages.built ? \"\" : \", which is not built yet: run `npm run build` there first\"}; abaikit itself is a devDependency, so \\`npm run check\\` finds it.`\n\t\t: \"The packages come from npm; abaikit itself is a devDependency, so `npm run check` finds it.\";\n\treturn [\n\t\t`# ${name}`,\n\t\t\"\",\n\t\t`An abaigram at level ${level}, made by \\`abaikit new\\`: a small program that works through a number of steps,`,\n\t\t\"with an agent fused in through the abai stub. Node 22.19 or later runs the TypeScript as it is.\",\n\t\t\"\",\n\t\t\"```\",\n\t\t\"npm install # the stub, the harness, and abaikit for check\",\n\t\t\"node src/main.ts 5 # the program, as itself\",\n\t\t\"node src/main.ts abai doctor --offline # the manifest, the content, the modes\",\n\t\t\"npm run check # abaikit check .: the conformance level, with no model\",\n\t\t\"node src/main.ts abai # a session with the agent about the program (needs a model: node src/main.ts abai config)\",\n\t\t\"node src/main.ts abai run -- 5 # the harness starts the program as its child; the loop meets the agent here\",\n\t\t\"```\",\n\t\t\"\",\n\t\twhere,\n\t\t\"\",\n\t\t\"`src/abai.ts` declares what the agent may observe and steer; `src/main.ts` is the program. After a change to\",\n\t\t\"the declaration, regenerate the manifest: `node src/main.ts abai manifest > abaigram.yaml`. The agent's prompt is\",\n\t\t\"`abai/identity.md`. For the next level, `abaikit learnabai --section retrofit` says what to add.\",\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\n/** Every file of the new project, by path relative to its root. The manifest is rendered by the caller. */\nexport function templateFiles(input: TemplateInput): Record<string, string> {\n\tconst { name, packages } = input;\n\tconst pkg = {\n\t\tname,\n\t\tversion: \"0.1.0\",\n\t\tprivate: true,\n\t\ttype: \"module\",\n\t\tscripts: { start: \"node src/main.ts\", abai: \"node src/main.ts abai\", check: \"abaikit check .\" },\n\t\tdependencies: { \"@abaigram/abai-embedded-harness\": packages.harness, \"@abaigram/abai-stub\": packages.abai },\n\t\tdevDependencies: { \"@abaigram/abaikit\": packages.abaikit },\n\t\tengines: { node: \">=22.19.0\" },\n\t};\n\treturn {\n\t\t\"package.json\": `${JSON.stringify(pkg, null, 2)}\\n`,\n\t\t\"src/abai.ts\": declarationModule(input),\n\t\t\"src/main.ts\": mainModule(input),\n\t\t\"abai/identity.md\": `You are the agent fused into ${name}, a small program that works through a number of steps and prints each. Watch its progress, skip or pace steps only when that serves the person, and say why in every act.\\n`,\n\t\t\"abai/use.md\": `<!-- The use slot (abaigrammar section 8): what the agent should know during sessions and live operation, beyond its identity. -->\\nUnder \\`node src/main.ts abai\\` the program opens a session before its loop: answer about the manifest and the plan. Under \\`node src/main.ts abai run -- N\\` the loop runs while you watch: read the cells before you act, and prefer watching to steering.\\n`,\n\t\t\"README.md\": readme(input),\n\t\t\".gitignore\": \"node_modules/\\nabai-audit.log\\n\",\n\t};\n}\n"]}
1
+ {"version":3,"file":"template-ts.d.ts","sourceRoot":"","sources":["../src/template-ts.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,qBAAqB,CAAC;AAE9E,MAAM,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAElC,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,sHAAsH;IACtH,UAAU,EAAE,MAAM,CAAC;IACnB,oHAAoH;IACpH,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;CACrG;AAkDD,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,eAAe,CA+BrE;AAgPD,2GAA2G;AAC3G,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqB1E","sourcesContent":["// The TypeScript template behind `abaikit new`: one declaration, as data,\n// rendered twice. Into the new project's `src/abai.ts` as source, and\n// through the stub's `buildManifest` into its `abaigram.yaml`, so file and\n// code agree without running the program. The program is a small loop\n// that works through a number of steps; at each level the declarations it\n// needs are live and the loop uses them, so `abaikit check` reaches that\n// level out of the box. Below its level every declaration kind is present\n// once, commented, as section 13 asks, and uncommenting one is all it\n// takes to make it live.\nimport type { AbaigramOptions, CapabilityOptions } from \"@abaigram/abai-stub\";\n\nexport type Level = 1 | 2 | 3 | 4;\n\nexport interface TemplateInput {\n\tname: string;\n\tlevel: Level;\n\t/** The specifier the generated code imports the stub by; `@abaigram/abai-stub` unless a test points at the source. */\n\tabaiImport: string;\n\t/** What `package.json` depends on, in package.json form, and whether the packages are built workspace checkouts. */\n\tpackages: { abai: string; harness: string; abaikit: string; fromWorkspace: boolean; built: boolean };\n}\n\n// The declaration's constants, each written once and read by both renderings.\nconst ENTRY = \"node src/main.ts abai\";\nconst MODES = [\"turns\", \"thread\", \"sidecar\"] as const;\nconst CONTENT = { identity: \"abai/identity.md\", use: \"abai/use.md\" };\nconst AUDIT = { path: \"./abai-audit.log\" };\nconst CHECK = { run: \"node src/main.ts 4\" };\nconst CELL_DONE = { type: \"int\", access: \"read\", doc: \"Steps finished so far.\" } as const;\nconst KNOB_PACE = {\n\ttype: \"int\",\n\taccess: \"readwrite\",\n\tdefault: 10,\n\trange: [1, 1000],\n\tdoc: \"Milliseconds a step takes; the agent may slow or hasten the work.\",\n} as const;\nconst EVENT_STEP = { payload: { n: \"int\" }, wakes: \"never\", doc: \"A step finished.\" } as const;\nconst CAPABILITY_SKIP: Omit<CapabilityOptions, \"handler\"> = {\n\tparams: { n: \"int\" },\n\tresult: { ok: \"bool\" },\n\teffect: \"mutate\",\n\tpolicy: \"confirm\",\n\tdispatch: \"immediate\",\n\t// step 2: the exercise's call lands while step 1 already runs, so this one is seen skipped under check\n\texample: { n: 2 },\n\tdoc: \"Skip step n when the loop reaches it.\",\n};\n/** The handler as source, indented from column zero; the renderer places it. */\nconst SKIP_HANDLER = \"({ n }) => {\\n\\tskipped.add(Number(n));\\n\\treturn { ok: true };\\n}\";\nconst DECISION_HALFWAY = {\n\tcontext: { done: \"int\", total: \"int\" },\n\toptions: [\"continue\", \"stop\"],\n\tdefault: \"continue\",\n\t// long enough for an agent to answer under `abai run`; past it the default applies\n\ttimeout: \"15s\",\n\tdoc: \"Asked halfway through the work: go on, or stop here.\",\n} as const;\nconst TURN_STEP = { timeout: \"5s\", doc: \"After each step. The agent may skip a step or change the pace.\" } as const;\n\n/** The level each declaration becomes live at. */\nconst LIVE_FROM = {\n\tcheck: 2,\n\t\"work.done\": 2,\n\t\"work.step\": 2,\n\tend_of_step: 2,\n\t\"work.pace_ms\": 3,\n\t\"work.skip\": 3,\n\ton_halfway: 4,\n} as const;\n\n/** The declaration the program makes at this level, as the stub takes it. */\nexport function declarationsFor(input: TemplateInput): AbaigramOptions {\n\tconst { name, level } = input;\n\tconst options: AbaigramOptions = {\n\t\tname,\n\t\tentry: ENTRY,\n\t\tmodes: [...MODES],\n\t\tcontent: { ...CONTENT },\n\t\taudit: { ...AUDIT },\n\t};\n\tif (level >= LIVE_FROM.check) options.check = { ...CHECK };\n\tconst cells: NonNullable<AbaigramOptions[\"cells\"]> = {};\n\tif (level >= LIVE_FROM[\"work.done\"]) cells[\"work.done\"] = { ...CELL_DONE };\n\tif (level >= LIVE_FROM[\"work.pace_ms\"]) cells[\"work.pace_ms\"] = { ...KNOB_PACE, range: [...KNOB_PACE.range] };\n\tif (Object.keys(cells).length > 0) options.cells = cells;\n\tif (level >= LIVE_FROM[\"work.step\"])\n\t\toptions.events = { \"work.step\": { ...EVENT_STEP, payload: { ...EVENT_STEP.payload } } };\n\tif (level >= LIVE_FROM[\"work.skip\"]) {\n\t\t// the handler here is a stand-in: the manifest never sees it, and the generated module has the real one\n\t\toptions.capabilities = { \"work.skip\": { ...CAPABILITY_SKIP, handler: () => ({ ok: true }) } };\n\t}\n\tif (level >= LIVE_FROM.on_halfway) {\n\t\toptions.decisions = {\n\t\t\ton_halfway: {\n\t\t\t\t...DECISION_HALFWAY,\n\t\t\t\toptions: [...DECISION_HALFWAY.options],\n\t\t\t\tcontext: { ...DECISION_HALFWAY.context },\n\t\t\t},\n\t\t};\n\t}\n\tif (level >= LIVE_FROM.end_of_step) options.turns = { end_of_step: { ...TURN_STEP } };\n\treturn options;\n}\n\n// ---------------------------------------------------------------------------\n// Rendering source\n// ---------------------------------------------------------------------------\n\nconst IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst WIDTH = 110;\n\n/** A value rendered verbatim, at the current indent: a handler's source. */\nclass Raw {\n\treadonly source: string;\n\tconstructor(source: string) {\n\t\tthis.source = source;\n\t}\n}\n\nfunction key(k: string): string {\n\treturn IDENT.test(k) ? k : JSON.stringify(k);\n}\n\n/** A value as a TypeScript literal, on one line when it fits in `room` columns, else nested by `indent` tabs. */\nfunction literal(value: unknown, indent: number, room: number): string {\n\tif (value instanceof Raw) {\n\t\tconst pad = \"\\t\".repeat(indent);\n\t\treturn value.source\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line, i) => (i === 0 ? line : `${pad}${line}`))\n\t\t\t.join(\"\\n\");\n\t}\n\tif (Array.isArray(value)) return `[${value.map((v) => literal(v, indent, room)).join(\", \")}]`;\n\tif (typeof value === \"object\" && value !== null) {\n\t\tconst entries = Object.entries(value);\n\t\tif (entries.length === 0) return \"{}\";\n\t\tconst inline = entries.map(([k, v]) => `${key(k)}: ${literal(v, indent, room)}`).join(\", \");\n\t\tif (!inline.includes(\"\\n\") && inline.length + 4 <= room) return `{ ${inline} }`;\n\t\tconst pad = \"\\t\".repeat(indent + 1);\n\t\tconst lines = entries.map(([k, v]) => {\n\t\t\tconst head = `${pad}${key(k)}: `;\n\t\t\treturn `${head}${literal(v, indent + 1, WIDTH - head.length * 2)},`;\n\t\t});\n\t\treturn `{\\n${lines.join(\"\\n\")}\\n${\"\\t\".repeat(indent)}}`;\n\t}\n\treturn JSON.stringify(value);\n}\n\n/** Comment out a rendered piece, every line. */\nfunction commented(text: string, indent: number): string {\n\tconst pad = \"\\t\".repeat(indent);\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.map((line) => (line.startsWith(pad) ? `${pad}// ${line.slice(pad.length)}` : `${pad}// ${line.trimStart()}`))\n\t\t.join(\"\\n\");\n}\n\n/**\n * One declaration block, `cells: { ... },` with each entry live or\n * commented on its own, so uncommenting an entry is all it takes; a block\n * with no live entry is commented whole, as the example of its kind.\n */\nfunction block(name: string, entries: Array<{ key: string; value: unknown; live: boolean }>, indent: number): string {\n\tconst pad = \"\\t\".repeat(indent);\n\tconst inner = \"\\t\".repeat(indent + 1);\n\tconst raw = entries.map((e) => {\n\t\tconst head = `${inner}${key(e.key)}: `;\n\t\treturn { text: `${head}${literal(e.value, indent + 1, WIDTH - head.length * 2)},`, live: e.live };\n\t});\n\tif (!raw.some((e) => e.live)) {\n\t\t// no live entry: the whole block is the example, commented once\n\t\treturn commented(`${pad}${name}: {\\n${raw.map((e) => e.text).join(\"\\n\")}\\n${pad}},`, indent);\n\t}\n\tconst rendered = raw.map((e) => (e.live ? e.text : commented(e.text, indent + 1)));\n\treturn `${pad}${name}: {\\n${rendered.join(\"\\n\")}\\n${pad}},`;\n}\n\nfunction declarationModule(input: TemplateInput): string {\n\tconst { name, level, abaiImport } = input;\n\tconst live = (from: number) => level >= from;\n\tconst lines: string[] = [];\n\tlines.push(`// ${name} as an abaigram: what the agent may observe and steer, declared once.`);\n\tlines.push(\"// The manifest (abaigram.yaml) is generated from this: after a change, run\");\n\tlines.push(\"// node src/main.ts abai manifest > abaigram.yaml\");\n\tlines.push(\"// and check it with: abaikit check .\");\n\tif (level < 4) {\n\t\tlines.push(\"// A commented declaration is the example of its kind: uncomment it (and the lines\");\n\t\tlines.push(\"// in src/main.ts that use it) when the program has the fact or the fork.\");\n\t}\n\tlines.push('import { fileURLToPath } from \"node:url\";');\n\tlines.push(`import { createAbaigram } from ${JSON.stringify(abaiImport)};`);\n\tlines.push(\"\");\n\tlines.push(\"/** Steps the agent asked to skip (work.skip); the loop in main.ts honours it. */\");\n\tlines.push(\n\t\tlive(LIVE_FROM[\"work.skip\"])\n\t\t\t? \"export const skipped = new Set<number>();\"\n\t\t\t: \"// export const skipped = new Set<number>();\",\n\t);\n\tlines.push(\"\");\n\tlines.push(\"export const app = createAbaigram(\");\n\tlines.push(\"\\t{\");\n\tlines.push(`\\t\\tname: ${JSON.stringify(name)},`);\n\tlines.push(\"\\t\\t// a runnable entry: the tools reach the program through it, in this directory\");\n\tlines.push(`\\t\\tentry: ${JSON.stringify(ENTRY)},`);\n\tlines.push(`\\t\\tmodes: ${literal([...MODES], 2, WIDTH)},`);\n\tlines.push(`\\t\\tcontent: ${literal(CONTENT, 2, WIDTH)},`);\n\tlines.push(`\\t\\taudit: ${literal(AUDIT, 2, WIDTH)},`);\n\tlines.push(\"\\t\\t// a short run that exercises every channel: what abaikit check runs for the levels above 1\");\n\tconst checkLine = `\\t\\tcheck: ${literal(CHECK, 2, WIDTH)},`;\n\tlines.push(live(LIVE_FROM.check) ? checkLine : commented(checkLine, 2));\n\tlines.push(\"\\t\\t// cells the program writes; a readwrite cell is a knob the agent may set within its range\");\n\tlines.push(\n\t\tblock(\n\t\t\t\"cells\",\n\t\t\t[\n\t\t\t\t{ key: \"work.done\", value: CELL_DONE, live: live(LIVE_FROM[\"work.done\"]) },\n\t\t\t\t{ key: \"work.pace_ms\", value: KNOB_PACE, live: live(LIVE_FROM[\"work.pace_ms\"]) },\n\t\t\t],\n\t\t\t2,\n\t\t),\n\t);\n\tlines.push(\"\\t\\t// events the program emits; wakes says when one wakes the agent\");\n\tlines.push(block(\"events\", [{ key: \"work.step\", value: EVENT_STEP, live: live(LIVE_FROM[\"work.step\"]) }], 2));\n\tlines.push(\"\\t\\t// capabilities the agent may call. dispatch immediate runs the handler at once; the default\");\n\tlines.push(\"\\t\\t// (safepoint) waits for app.safepoint(). check calls the example, so keep it harmless\");\n\tlines.push(\n\t\tblock(\n\t\t\t\"capabilities\",\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tkey: \"work.skip\",\n\t\t\t\t\tvalue: { ...CAPABILITY_SKIP, handler: new Raw(SKIP_HANDLER) },\n\t\t\t\t\tlive: live(LIVE_FROM[\"work.skip\"]),\n\t\t\t\t},\n\t\t\t],\n\t\t\t2,\n\t\t),\n\t);\n\tlines.push(\"\\t\\t// decisions the program asks at a real fork; the default is what it does when nobody answers\");\n\tlines.push(\n\t\tblock(\"decisions\", [{ key: \"on_halfway\", value: DECISION_HALFWAY, live: live(LIVE_FROM.on_halfway) }], 2),\n\t);\n\tlines.push(\"\\t\\t// turns: bounded moments the program hands the agent\");\n\tlines.push(block(\"turns\", [{ key: \"end_of_step\", value: TURN_STEP, live: live(LIVE_FROM.end_of_step) }], 2));\n\tlines.push(\"\\t},\");\n\tlines.push(\"\\t// the directory holding abaigram.yaml and abai/: one level up from this file\");\n\tlines.push('\\t{ root: fileURLToPath(new URL(\"..\", import.meta.url)) },');\n\tlines.push(\");\");\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction mainModule(input: TemplateInput): string {\n\tconst { name, level, abaiImport } = input;\n\tconst live = (from: number) => level >= from;\n\tconst lines: string[] = [];\n\tlines.push(`// ${name}: works through a number of steps and prints each. Node 22.19 and`);\n\tlines.push(\"// later run this file as it is (node src/main.ts 5); the first lines hand the\");\n\tlines.push(\"// standard agent entry to the stub, and the program's own run follows.\");\n\tlines.push(`import { runEntry } from ${JSON.stringify(abaiImport)};`);\n\tlines.push(\n\t\tlive(LIVE_FROM[\"work.skip\"]) ? 'import { app, skipped } from \"./abai.ts\";' : 'import { app } from \"./abai.ts\";',\n\t);\n\tlines.push(\"\");\n\tlines.push(\"const code = await runEntry(app, process.argv.slice(2));\");\n\tlines.push(\"if (code >= 0) process.exit(code); // an abai verb ran; otherwise the program's own run begins\");\n\tlines.push(\"\");\n\tlines.push(\"const total = Number(process.argv[2] ?? 5);\");\n\tlines.push(\"const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\");\n\tif (live(LIVE_FROM[\"work.done\"])) {\n\t\tlines.push(\"// handles once, at startup; set and emit are the cheap calls\");\n\t\tlines.push('const done = app.cell<number>(\"work.done\");');\n\t\tlines.push('const step = app.event(\"work.step\");');\n\t}\n\tif (live(LIVE_FROM[\"work.pace_ms\"])) lines.push('const pace = app.knob<number>(\"work.pace_ms\");');\n\tlines.push(\"\");\n\tlines.push(\"for (let n = 1; n <= total; n++) {\");\n\tif (live(LIVE_FROM.on_halfway)) {\n\t\tlines.push(\"\\tif (n === Math.ceil(total / 2)) {\");\n\t\tlines.push(\"\\t\\t// a real fork: the default is what the program did before it was an abaigram\");\n\t\tlines.push('\\t\\tconst choice = await app.decide<string>(\"on_halfway\", { done: n - 1, total });');\n\t\tlines.push('\\t\\tif (choice === \"stop\") {');\n\t\tlines.push(`\\t\\t\\tconsole.log(\"${name}: stopped halfway, as asked\");`);\n\t\tlines.push(\"\\t\\t\\tbreak;\");\n\t\tlines.push(\"\\t\\t}\");\n\t\tlines.push(\"\\t}\");\n\t}\n\tif (live(LIVE_FROM[\"work.skip\"])) {\n\t\tlines.push(\"\\tif (skipped.has(n)) {\");\n\t\t// biome-ignore lint/suspicious/noTemplateCurlyInString: this is the generated program's source, a template literal in it\n\t\tlines.push(\"\\t\\tconsole.log(`step ${n} skipped`);\");\n\t\tlines.push(\"\\t\\tcontinue;\");\n\t\tlines.push(\"\\t}\");\n\t\tlines.push(\"\\tawait sleep(pace.get());\");\n\t} else {\n\t\tlines.push(\"\\tawait sleep(10);\");\n\t}\n\tif (live(LIVE_FROM[\"work.done\"])) {\n\t\tlines.push(\"\\tdone.set(n);\");\n\t\tlines.push(\"\\tstep.emit({ n });\");\n\t}\n\t// biome-ignore lint/suspicious/noTemplateCurlyInString: this is the generated program's source, a template literal in it\n\tlines.push(\"\\tconsole.log(`step ${n} of ${total}`);\");\n\tlines.push(\"\\tapp.safepoint();\");\n\tif (live(LIVE_FROM.end_of_step)) lines.push('\\tawait app.turn(\"end_of_step\");');\n\tlines.push(\"}\");\n\tlines.push(\n\t\tlive(LIVE_FROM[\"work.done\"])\n\t\t\t? `console.log(\\`${name}: \\${done.get()} steps done\\`);`\n\t\t\t: `console.log(\"${name}: done\");`,\n\t);\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction readme(input: TemplateInput): string {\n\tconst { name, level, packages } = input;\n\tconst where = packages.fromWorkspace\n\t\t? `The two packages come from the abai workspace checkout (\\`file:\\` dependencies)${packages.built ? \"\" : \", which is not built yet: run `npm run build` there first\"}; abaikit itself is a devDependency, so \\`npm run check\\` finds it.`\n\t\t: \"The packages come from npm; abaikit itself is a devDependency, so `npm run check` finds it.\";\n\treturn [\n\t\t`# ${name}`,\n\t\t\"\",\n\t\t`An abaigram at level ${level}, made by \\`abaikit new\\`: a small program that works through a number of steps,`,\n\t\t\"with an agent fused in through the abai stub. Node 22.19 or later runs the TypeScript as it is.\",\n\t\t\"\",\n\t\t\"```\",\n\t\t\"npm install # the stub, the harness, and abaikit for check\",\n\t\t\"node src/main.ts 5 # the program, as itself\",\n\t\t\"node src/main.ts abai doctor --offline # the manifest, the content, the modes\",\n\t\t\"npm run check # abaikit check .: the conformance level, with no model\",\n\t\t\"node src/main.ts abai # a session with the agent about the program (needs a model: node src/main.ts abai config)\",\n\t\t\"node src/main.ts abai run -- 5 # the harness starts the program as its child; the loop meets the agent here\",\n\t\t\"```\",\n\t\t\"\",\n\t\twhere,\n\t\t\"\",\n\t\t\"`src/abai.ts` declares what the agent may observe and steer; `src/main.ts` is the program. After a change to\",\n\t\t\"the declaration, regenerate the manifest: `node src/main.ts abai manifest > abaigram.yaml`. The agent's prompt is\",\n\t\t\"`abai/identity.md`. For the next level, `abaikit learnabai --section retrofit` says what to add.\",\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\n/** Every file of the new project, by path relative to its root. The manifest is rendered by the caller. */\nexport function templateFiles(input: TemplateInput): Record<string, string> {\n\tconst { name, packages } = input;\n\tconst pkg = {\n\t\tname,\n\t\tversion: \"0.1.0\",\n\t\tprivate: true,\n\t\ttype: \"module\",\n\t\tscripts: { start: \"node src/main.ts\", abai: \"node src/main.ts abai\", check: \"abaikit check .\" },\n\t\tdependencies: { \"@abaigram/abai-embedded-harness\": packages.harness, \"@abaigram/abai-stub\": packages.abai },\n\t\tdevDependencies: { \"@abaigram/abaikit\": packages.abaikit },\n\t\tengines: { node: \">=22.19.0\" },\n\t};\n\treturn {\n\t\t\"package.json\": `${JSON.stringify(pkg, null, 2)}\\n`,\n\t\t\"src/abai.ts\": declarationModule(input),\n\t\t\"src/main.ts\": mainModule(input),\n\t\t\"abai/identity.md\": `You are the agent fused into ${name}, a small program that works through a number of steps and prints each. Watch its progress, skip or pace steps only when that serves the person, and say why in every act.\\n`,\n\t\t\"abai/use.md\": `<!-- The use slot (abaigrammar section 8): what the agent should know during sessions and live operation, beyond its identity. -->\\nUnder \\`node src/main.ts abai\\` the program opens a session before its loop: answer about the manifest and the plan. Under \\`node src/main.ts abai run -- N\\` the loop runs while you watch: read the cells before you act, and prefer watching to steering.\\n`,\n\t\t\"README.md\": readme(input),\n\t\t\".gitignore\": \"node_modules/\\nabai-audit.log\\n\",\n\t};\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  // The declaration's constants, each written once and read by both renderings.
2
2
  const ENTRY = "node src/main.ts abai";
3
- const MODES = ["turns", "sidecar"];
3
+ const MODES = ["turns", "thread", "sidecar"];
4
4
  const CONTENT = { identity: "abai/identity.md", use: "abai/use.md" };
5
5
  const AUDIT = { path: "./abai-audit.log" };
6
6
  const CHECK = { run: "node src/main.ts 4" };
@@ -1 +1 @@
1
- {"version":3,"file":"template-ts.js","sourceRoot":"","sources":["../src/template-ts.ts"],"names":[],"mappings":"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","sourcesContent":["// The TypeScript template behind `abaikit new`: one declaration, as data,\n// rendered twice. Into the new project's `src/abai.ts` as source, and\n// through the stub's `buildManifest` into its `abaigram.yaml`, so file and\n// code agree without running the program. The program is a small loop\n// that works through a number of steps; at each level the declarations it\n// needs are live and the loop uses them, so `abaikit check` reaches that\n// level out of the box. Below its level every declaration kind is present\n// once, commented, as section 13 asks, and uncommenting one is all it\n// takes to make it live.\nimport type { AbaigramOptions, CapabilityOptions } from \"@abaigram/abai-stub\";\n\nexport type Level = 1 | 2 | 3 | 4;\n\nexport interface TemplateInput {\n\tname: string;\n\tlevel: Level;\n\t/** The specifier the generated code imports the stub by; `@abaigram/abai-stub` unless a test points at the source. */\n\tabaiImport: string;\n\t/** What `package.json` depends on, in package.json form, and whether the packages are built workspace checkouts. */\n\tpackages: { abai: string; harness: string; abaikit: string; fromWorkspace: boolean; built: boolean };\n}\n\n// The declaration's constants, each written once and read by both renderings.\nconst ENTRY = \"node src/main.ts abai\";\nconst MODES = [\"turns\", \"sidecar\"] as const;\nconst CONTENT = { identity: \"abai/identity.md\", use: \"abai/use.md\" };\nconst AUDIT = { path: \"./abai-audit.log\" };\nconst CHECK = { run: \"node src/main.ts 4\" };\nconst CELL_DONE = { type: \"int\", access: \"read\", doc: \"Steps finished so far.\" } as const;\nconst KNOB_PACE = {\n\ttype: \"int\",\n\taccess: \"readwrite\",\n\tdefault: 10,\n\trange: [1, 1000],\n\tdoc: \"Milliseconds a step takes; the agent may slow or hasten the work.\",\n} as const;\nconst EVENT_STEP = { payload: { n: \"int\" }, wakes: \"never\", doc: \"A step finished.\" } as const;\nconst CAPABILITY_SKIP: Omit<CapabilityOptions, \"handler\"> = {\n\tparams: { n: \"int\" },\n\tresult: { ok: \"bool\" },\n\teffect: \"mutate\",\n\tpolicy: \"confirm\",\n\tdispatch: \"immediate\",\n\t// step 2: the exercise's call lands while step 1 already runs, so this one is seen skipped under check\n\texample: { n: 2 },\n\tdoc: \"Skip step n when the loop reaches it.\",\n};\n/** The handler as source, indented from column zero; the renderer places it. */\nconst SKIP_HANDLER = \"({ n }) => {\\n\\tskipped.add(Number(n));\\n\\treturn { ok: true };\\n}\";\nconst DECISION_HALFWAY = {\n\tcontext: { done: \"int\", total: \"int\" },\n\toptions: [\"continue\", \"stop\"],\n\tdefault: \"continue\",\n\t// long enough for an agent to answer under `abai run`; past it the default applies\n\ttimeout: \"15s\",\n\tdoc: \"Asked halfway through the work: go on, or stop here.\",\n} as const;\nconst TURN_STEP = { timeout: \"5s\", doc: \"After each step. The agent may skip a step or change the pace.\" } as const;\n\n/** The level each declaration becomes live at. */\nconst LIVE_FROM = {\n\tcheck: 2,\n\t\"work.done\": 2,\n\t\"work.step\": 2,\n\tend_of_step: 2,\n\t\"work.pace_ms\": 3,\n\t\"work.skip\": 3,\n\ton_halfway: 4,\n} as const;\n\n/** The declaration the program makes at this level, as the stub takes it. */\nexport function declarationsFor(input: TemplateInput): AbaigramOptions {\n\tconst { name, level } = input;\n\tconst options: AbaigramOptions = {\n\t\tname,\n\t\tentry: ENTRY,\n\t\tmodes: [...MODES],\n\t\tcontent: { ...CONTENT },\n\t\taudit: { ...AUDIT },\n\t};\n\tif (level >= LIVE_FROM.check) options.check = { ...CHECK };\n\tconst cells: NonNullable<AbaigramOptions[\"cells\"]> = {};\n\tif (level >= LIVE_FROM[\"work.done\"]) cells[\"work.done\"] = { ...CELL_DONE };\n\tif (level >= LIVE_FROM[\"work.pace_ms\"]) cells[\"work.pace_ms\"] = { ...KNOB_PACE, range: [...KNOB_PACE.range] };\n\tif (Object.keys(cells).length > 0) options.cells = cells;\n\tif (level >= LIVE_FROM[\"work.step\"])\n\t\toptions.events = { \"work.step\": { ...EVENT_STEP, payload: { ...EVENT_STEP.payload } } };\n\tif (level >= LIVE_FROM[\"work.skip\"]) {\n\t\t// the handler here is a stand-in: the manifest never sees it, and the generated module has the real one\n\t\toptions.capabilities = { \"work.skip\": { ...CAPABILITY_SKIP, handler: () => ({ ok: true }) } };\n\t}\n\tif (level >= LIVE_FROM.on_halfway) {\n\t\toptions.decisions = {\n\t\t\ton_halfway: {\n\t\t\t\t...DECISION_HALFWAY,\n\t\t\t\toptions: [...DECISION_HALFWAY.options],\n\t\t\t\tcontext: { ...DECISION_HALFWAY.context },\n\t\t\t},\n\t\t};\n\t}\n\tif (level >= LIVE_FROM.end_of_step) options.turns = { end_of_step: { ...TURN_STEP } };\n\treturn options;\n}\n\n// ---------------------------------------------------------------------------\n// Rendering source\n// ---------------------------------------------------------------------------\n\nconst IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst WIDTH = 110;\n\n/** A value rendered verbatim, at the current indent: a handler's source. */\nclass Raw {\n\treadonly source: string;\n\tconstructor(source: string) {\n\t\tthis.source = source;\n\t}\n}\n\nfunction key(k: string): string {\n\treturn IDENT.test(k) ? k : JSON.stringify(k);\n}\n\n/** A value as a TypeScript literal, on one line when it fits in `room` columns, else nested by `indent` tabs. */\nfunction literal(value: unknown, indent: number, room: number): string {\n\tif (value instanceof Raw) {\n\t\tconst pad = \"\\t\".repeat(indent);\n\t\treturn value.source\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line, i) => (i === 0 ? line : `${pad}${line}`))\n\t\t\t.join(\"\\n\");\n\t}\n\tif (Array.isArray(value)) return `[${value.map((v) => literal(v, indent, room)).join(\", \")}]`;\n\tif (typeof value === \"object\" && value !== null) {\n\t\tconst entries = Object.entries(value);\n\t\tif (entries.length === 0) return \"{}\";\n\t\tconst inline = entries.map(([k, v]) => `${key(k)}: ${literal(v, indent, room)}`).join(\", \");\n\t\tif (!inline.includes(\"\\n\") && inline.length + 4 <= room) return `{ ${inline} }`;\n\t\tconst pad = \"\\t\".repeat(indent + 1);\n\t\tconst lines = entries.map(([k, v]) => {\n\t\t\tconst head = `${pad}${key(k)}: `;\n\t\t\treturn `${head}${literal(v, indent + 1, WIDTH - head.length * 2)},`;\n\t\t});\n\t\treturn `{\\n${lines.join(\"\\n\")}\\n${\"\\t\".repeat(indent)}}`;\n\t}\n\treturn JSON.stringify(value);\n}\n\n/** Comment out a rendered piece, every line. */\nfunction commented(text: string, indent: number): string {\n\tconst pad = \"\\t\".repeat(indent);\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.map((line) => (line.startsWith(pad) ? `${pad}// ${line.slice(pad.length)}` : `${pad}// ${line.trimStart()}`))\n\t\t.join(\"\\n\");\n}\n\n/**\n * One declaration block, `cells: { ... },` with each entry live or\n * commented on its own, so uncommenting an entry is all it takes; a block\n * with no live entry is commented whole, as the example of its kind.\n */\nfunction block(name: string, entries: Array<{ key: string; value: unknown; live: boolean }>, indent: number): string {\n\tconst pad = \"\\t\".repeat(indent);\n\tconst inner = \"\\t\".repeat(indent + 1);\n\tconst raw = entries.map((e) => {\n\t\tconst head = `${inner}${key(e.key)}: `;\n\t\treturn { text: `${head}${literal(e.value, indent + 1, WIDTH - head.length * 2)},`, live: e.live };\n\t});\n\tif (!raw.some((e) => e.live)) {\n\t\t// no live entry: the whole block is the example, commented once\n\t\treturn commented(`${pad}${name}: {\\n${raw.map((e) => e.text).join(\"\\n\")}\\n${pad}},`, indent);\n\t}\n\tconst rendered = raw.map((e) => (e.live ? e.text : commented(e.text, indent + 1)));\n\treturn `${pad}${name}: {\\n${rendered.join(\"\\n\")}\\n${pad}},`;\n}\n\nfunction declarationModule(input: TemplateInput): string {\n\tconst { name, level, abaiImport } = input;\n\tconst live = (from: number) => level >= from;\n\tconst lines: string[] = [];\n\tlines.push(`// ${name} as an abaigram: what the agent may observe and steer, declared once.`);\n\tlines.push(\"// The manifest (abaigram.yaml) is generated from this: after a change, run\");\n\tlines.push(\"// node src/main.ts abai manifest > abaigram.yaml\");\n\tlines.push(\"// and check it with: abaikit check .\");\n\tif (level < 4) {\n\t\tlines.push(\"// A commented declaration is the example of its kind: uncomment it (and the lines\");\n\t\tlines.push(\"// in src/main.ts that use it) when the program has the fact or the fork.\");\n\t}\n\tlines.push('import { fileURLToPath } from \"node:url\";');\n\tlines.push(`import { createAbaigram } from ${JSON.stringify(abaiImport)};`);\n\tlines.push(\"\");\n\tlines.push(\"/** Steps the agent asked to skip (work.skip); the loop in main.ts honours it. */\");\n\tlines.push(\n\t\tlive(LIVE_FROM[\"work.skip\"])\n\t\t\t? \"export const skipped = new Set<number>();\"\n\t\t\t: \"// export const skipped = new Set<number>();\",\n\t);\n\tlines.push(\"\");\n\tlines.push(\"export const app = createAbaigram(\");\n\tlines.push(\"\\t{\");\n\tlines.push(`\\t\\tname: ${JSON.stringify(name)},`);\n\tlines.push(\"\\t\\t// a runnable entry: the tools reach the program through it, in this directory\");\n\tlines.push(`\\t\\tentry: ${JSON.stringify(ENTRY)},`);\n\tlines.push(`\\t\\tmodes: ${literal([...MODES], 2, WIDTH)},`);\n\tlines.push(`\\t\\tcontent: ${literal(CONTENT, 2, WIDTH)},`);\n\tlines.push(`\\t\\taudit: ${literal(AUDIT, 2, WIDTH)},`);\n\tlines.push(\"\\t\\t// a short run that exercises every channel: what abaikit check runs for the levels above 1\");\n\tconst checkLine = `\\t\\tcheck: ${literal(CHECK, 2, WIDTH)},`;\n\tlines.push(live(LIVE_FROM.check) ? checkLine : commented(checkLine, 2));\n\tlines.push(\"\\t\\t// cells the program writes; a readwrite cell is a knob the agent may set within its range\");\n\tlines.push(\n\t\tblock(\n\t\t\t\"cells\",\n\t\t\t[\n\t\t\t\t{ key: \"work.done\", value: CELL_DONE, live: live(LIVE_FROM[\"work.done\"]) },\n\t\t\t\t{ key: \"work.pace_ms\", value: KNOB_PACE, live: live(LIVE_FROM[\"work.pace_ms\"]) },\n\t\t\t],\n\t\t\t2,\n\t\t),\n\t);\n\tlines.push(\"\\t\\t// events the program emits; wakes says when one wakes the agent\");\n\tlines.push(block(\"events\", [{ key: \"work.step\", value: EVENT_STEP, live: live(LIVE_FROM[\"work.step\"]) }], 2));\n\tlines.push(\"\\t\\t// capabilities the agent may call. dispatch immediate runs the handler at once; the default\");\n\tlines.push(\"\\t\\t// (safepoint) waits for app.safepoint(). check calls the example, so keep it harmless\");\n\tlines.push(\n\t\tblock(\n\t\t\t\"capabilities\",\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tkey: \"work.skip\",\n\t\t\t\t\tvalue: { ...CAPABILITY_SKIP, handler: new Raw(SKIP_HANDLER) },\n\t\t\t\t\tlive: live(LIVE_FROM[\"work.skip\"]),\n\t\t\t\t},\n\t\t\t],\n\t\t\t2,\n\t\t),\n\t);\n\tlines.push(\"\\t\\t// decisions the program asks at a real fork; the default is what it does when nobody answers\");\n\tlines.push(\n\t\tblock(\"decisions\", [{ key: \"on_halfway\", value: DECISION_HALFWAY, live: live(LIVE_FROM.on_halfway) }], 2),\n\t);\n\tlines.push(\"\\t\\t// turns: bounded moments the program hands the agent\");\n\tlines.push(block(\"turns\", [{ key: \"end_of_step\", value: TURN_STEP, live: live(LIVE_FROM.end_of_step) }], 2));\n\tlines.push(\"\\t},\");\n\tlines.push(\"\\t// the directory holding abaigram.yaml and abai/: one level up from this file\");\n\tlines.push('\\t{ root: fileURLToPath(new URL(\"..\", import.meta.url)) },');\n\tlines.push(\");\");\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction mainModule(input: TemplateInput): string {\n\tconst { name, level, abaiImport } = input;\n\tconst live = (from: number) => level >= from;\n\tconst lines: string[] = [];\n\tlines.push(`// ${name}: works through a number of steps and prints each. Node 22.19 and`);\n\tlines.push(\"// later run this file as it is (node src/main.ts 5); the first lines hand the\");\n\tlines.push(\"// standard agent entry to the stub, and the program's own run follows.\");\n\tlines.push(`import { runEntry } from ${JSON.stringify(abaiImport)};`);\n\tlines.push(\n\t\tlive(LIVE_FROM[\"work.skip\"]) ? 'import { app, skipped } from \"./abai.ts\";' : 'import { app } from \"./abai.ts\";',\n\t);\n\tlines.push(\"\");\n\tlines.push(\"const code = await runEntry(app, process.argv.slice(2));\");\n\tlines.push(\"if (code >= 0) process.exit(code); // an abai verb ran; otherwise the program's own run begins\");\n\tlines.push(\"\");\n\tlines.push(\"const total = Number(process.argv[2] ?? 5);\");\n\tlines.push(\"const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\");\n\tif (live(LIVE_FROM[\"work.done\"])) {\n\t\tlines.push(\"// handles once, at startup; set and emit are the cheap calls\");\n\t\tlines.push('const done = app.cell<number>(\"work.done\");');\n\t\tlines.push('const step = app.event(\"work.step\");');\n\t}\n\tif (live(LIVE_FROM[\"work.pace_ms\"])) lines.push('const pace = app.knob<number>(\"work.pace_ms\");');\n\tlines.push(\"\");\n\tlines.push(\"for (let n = 1; n <= total; n++) {\");\n\tif (live(LIVE_FROM.on_halfway)) {\n\t\tlines.push(\"\\tif (n === Math.ceil(total / 2)) {\");\n\t\tlines.push(\"\\t\\t// a real fork: the default is what the program did before it was an abaigram\");\n\t\tlines.push('\\t\\tconst choice = await app.decide<string>(\"on_halfway\", { done: n - 1, total });');\n\t\tlines.push('\\t\\tif (choice === \"stop\") {');\n\t\tlines.push(`\\t\\t\\tconsole.log(\"${name}: stopped halfway, as asked\");`);\n\t\tlines.push(\"\\t\\t\\tbreak;\");\n\t\tlines.push(\"\\t\\t}\");\n\t\tlines.push(\"\\t}\");\n\t}\n\tif (live(LIVE_FROM[\"work.skip\"])) {\n\t\tlines.push(\"\\tif (skipped.has(n)) {\");\n\t\t// biome-ignore lint/suspicious/noTemplateCurlyInString: this is the generated program's source, a template literal in it\n\t\tlines.push(\"\\t\\tconsole.log(`step ${n} skipped`);\");\n\t\tlines.push(\"\\t\\tcontinue;\");\n\t\tlines.push(\"\\t}\");\n\t\tlines.push(\"\\tawait sleep(pace.get());\");\n\t} else {\n\t\tlines.push(\"\\tawait sleep(10);\");\n\t}\n\tif (live(LIVE_FROM[\"work.done\"])) {\n\t\tlines.push(\"\\tdone.set(n);\");\n\t\tlines.push(\"\\tstep.emit({ n });\");\n\t}\n\t// biome-ignore lint/suspicious/noTemplateCurlyInString: this is the generated program's source, a template literal in it\n\tlines.push(\"\\tconsole.log(`step ${n} of ${total}`);\");\n\tlines.push(\"\\tapp.safepoint();\");\n\tif (live(LIVE_FROM.end_of_step)) lines.push('\\tawait app.turn(\"end_of_step\");');\n\tlines.push(\"}\");\n\tlines.push(\n\t\tlive(LIVE_FROM[\"work.done\"])\n\t\t\t? `console.log(\\`${name}: \\${done.get()} steps done\\`);`\n\t\t\t: `console.log(\"${name}: done\");`,\n\t);\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction readme(input: TemplateInput): string {\n\tconst { name, level, packages } = input;\n\tconst where = packages.fromWorkspace\n\t\t? `The two packages come from the abai workspace checkout (\\`file:\\` dependencies)${packages.built ? \"\" : \", which is not built yet: run `npm run build` there first\"}; abaikit itself is a devDependency, so \\`npm run check\\` finds it.`\n\t\t: \"The packages come from npm; abaikit itself is a devDependency, so `npm run check` finds it.\";\n\treturn [\n\t\t`# ${name}`,\n\t\t\"\",\n\t\t`An abaigram at level ${level}, made by \\`abaikit new\\`: a small program that works through a number of steps,`,\n\t\t\"with an agent fused in through the abai stub. Node 22.19 or later runs the TypeScript as it is.\",\n\t\t\"\",\n\t\t\"```\",\n\t\t\"npm install # the stub, the harness, and abaikit for check\",\n\t\t\"node src/main.ts 5 # the program, as itself\",\n\t\t\"node src/main.ts abai doctor --offline # the manifest, the content, the modes\",\n\t\t\"npm run check # abaikit check .: the conformance level, with no model\",\n\t\t\"node src/main.ts abai # a session with the agent about the program (needs a model: node src/main.ts abai config)\",\n\t\t\"node src/main.ts abai run -- 5 # the harness starts the program as its child; the loop meets the agent here\",\n\t\t\"```\",\n\t\t\"\",\n\t\twhere,\n\t\t\"\",\n\t\t\"`src/abai.ts` declares what the agent may observe and steer; `src/main.ts` is the program. After a change to\",\n\t\t\"the declaration, regenerate the manifest: `node src/main.ts abai manifest > abaigram.yaml`. The agent's prompt is\",\n\t\t\"`abai/identity.md`. For the next level, `abaikit learnabai --section retrofit` says what to add.\",\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\n/** Every file of the new project, by path relative to its root. The manifest is rendered by the caller. */\nexport function templateFiles(input: TemplateInput): Record<string, string> {\n\tconst { name, packages } = input;\n\tconst pkg = {\n\t\tname,\n\t\tversion: \"0.1.0\",\n\t\tprivate: true,\n\t\ttype: \"module\",\n\t\tscripts: { start: \"node src/main.ts\", abai: \"node src/main.ts abai\", check: \"abaikit check .\" },\n\t\tdependencies: { \"@abaigram/abai-embedded-harness\": packages.harness, \"@abaigram/abai-stub\": packages.abai },\n\t\tdevDependencies: { \"@abaigram/abaikit\": packages.abaikit },\n\t\tengines: { node: \">=22.19.0\" },\n\t};\n\treturn {\n\t\t\"package.json\": `${JSON.stringify(pkg, null, 2)}\\n`,\n\t\t\"src/abai.ts\": declarationModule(input),\n\t\t\"src/main.ts\": mainModule(input),\n\t\t\"abai/identity.md\": `You are the agent fused into ${name}, a small program that works through a number of steps and prints each. Watch its progress, skip or pace steps only when that serves the person, and say why in every act.\\n`,\n\t\t\"abai/use.md\": `<!-- The use slot (abaigrammar section 8): what the agent should know during sessions and live operation, beyond its identity. -->\\nUnder \\`node src/main.ts abai\\` the program opens a session before its loop: answer about the manifest and the plan. Under \\`node src/main.ts abai run -- N\\` the loop runs while you watch: read the cells before you act, and prefer watching to steering.\\n`,\n\t\t\"README.md\": readme(input),\n\t\t\".gitignore\": \"node_modules/\\nabai-audit.log\\n\",\n\t};\n}\n"]}
1
+ {"version":3,"file":"template-ts.js","sourceRoot":"","sources":["../src/template-ts.ts"],"names":[],"mappings":"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","sourcesContent":["// The TypeScript template behind `abaikit new`: one declaration, as data,\n// rendered twice. Into the new project's `src/abai.ts` as source, and\n// through the stub's `buildManifest` into its `abaigram.yaml`, so file and\n// code agree without running the program. The program is a small loop\n// that works through a number of steps; at each level the declarations it\n// needs are live and the loop uses them, so `abaikit check` reaches that\n// level out of the box. Below its level every declaration kind is present\n// once, commented, as section 13 asks, and uncommenting one is all it\n// takes to make it live.\nimport type { AbaigramOptions, CapabilityOptions } from \"@abaigram/abai-stub\";\n\nexport type Level = 1 | 2 | 3 | 4;\n\nexport interface TemplateInput {\n\tname: string;\n\tlevel: Level;\n\t/** The specifier the generated code imports the stub by; `@abaigram/abai-stub` unless a test points at the source. */\n\tabaiImport: string;\n\t/** What `package.json` depends on, in package.json form, and whether the packages are built workspace checkouts. */\n\tpackages: { abai: string; harness: string; abaikit: string; fromWorkspace: boolean; built: boolean };\n}\n\n// The declaration's constants, each written once and read by both renderings.\nconst ENTRY = \"node src/main.ts abai\";\nconst MODES = [\"turns\", \"thread\", \"sidecar\"] as const;\nconst CONTENT = { identity: \"abai/identity.md\", use: \"abai/use.md\" };\nconst AUDIT = { path: \"./abai-audit.log\" };\nconst CHECK = { run: \"node src/main.ts 4\" };\nconst CELL_DONE = { type: \"int\", access: \"read\", doc: \"Steps finished so far.\" } as const;\nconst KNOB_PACE = {\n\ttype: \"int\",\n\taccess: \"readwrite\",\n\tdefault: 10,\n\trange: [1, 1000],\n\tdoc: \"Milliseconds a step takes; the agent may slow or hasten the work.\",\n} as const;\nconst EVENT_STEP = { payload: { n: \"int\" }, wakes: \"never\", doc: \"A step finished.\" } as const;\nconst CAPABILITY_SKIP: Omit<CapabilityOptions, \"handler\"> = {\n\tparams: { n: \"int\" },\n\tresult: { ok: \"bool\" },\n\teffect: \"mutate\",\n\tpolicy: \"confirm\",\n\tdispatch: \"immediate\",\n\t// step 2: the exercise's call lands while step 1 already runs, so this one is seen skipped under check\n\texample: { n: 2 },\n\tdoc: \"Skip step n when the loop reaches it.\",\n};\n/** The handler as source, indented from column zero; the renderer places it. */\nconst SKIP_HANDLER = \"({ n }) => {\\n\\tskipped.add(Number(n));\\n\\treturn { ok: true };\\n}\";\nconst DECISION_HALFWAY = {\n\tcontext: { done: \"int\", total: \"int\" },\n\toptions: [\"continue\", \"stop\"],\n\tdefault: \"continue\",\n\t// long enough for an agent to answer under `abai run`; past it the default applies\n\ttimeout: \"15s\",\n\tdoc: \"Asked halfway through the work: go on, or stop here.\",\n} as const;\nconst TURN_STEP = { timeout: \"5s\", doc: \"After each step. The agent may skip a step or change the pace.\" } as const;\n\n/** The level each declaration becomes live at. */\nconst LIVE_FROM = {\n\tcheck: 2,\n\t\"work.done\": 2,\n\t\"work.step\": 2,\n\tend_of_step: 2,\n\t\"work.pace_ms\": 3,\n\t\"work.skip\": 3,\n\ton_halfway: 4,\n} as const;\n\n/** The declaration the program makes at this level, as the stub takes it. */\nexport function declarationsFor(input: TemplateInput): AbaigramOptions {\n\tconst { name, level } = input;\n\tconst options: AbaigramOptions = {\n\t\tname,\n\t\tentry: ENTRY,\n\t\tmodes: [...MODES],\n\t\tcontent: { ...CONTENT },\n\t\taudit: { ...AUDIT },\n\t};\n\tif (level >= LIVE_FROM.check) options.check = { ...CHECK };\n\tconst cells: NonNullable<AbaigramOptions[\"cells\"]> = {};\n\tif (level >= LIVE_FROM[\"work.done\"]) cells[\"work.done\"] = { ...CELL_DONE };\n\tif (level >= LIVE_FROM[\"work.pace_ms\"]) cells[\"work.pace_ms\"] = { ...KNOB_PACE, range: [...KNOB_PACE.range] };\n\tif (Object.keys(cells).length > 0) options.cells = cells;\n\tif (level >= LIVE_FROM[\"work.step\"])\n\t\toptions.events = { \"work.step\": { ...EVENT_STEP, payload: { ...EVENT_STEP.payload } } };\n\tif (level >= LIVE_FROM[\"work.skip\"]) {\n\t\t// the handler here is a stand-in: the manifest never sees it, and the generated module has the real one\n\t\toptions.capabilities = { \"work.skip\": { ...CAPABILITY_SKIP, handler: () => ({ ok: true }) } };\n\t}\n\tif (level >= LIVE_FROM.on_halfway) {\n\t\toptions.decisions = {\n\t\t\ton_halfway: {\n\t\t\t\t...DECISION_HALFWAY,\n\t\t\t\toptions: [...DECISION_HALFWAY.options],\n\t\t\t\tcontext: { ...DECISION_HALFWAY.context },\n\t\t\t},\n\t\t};\n\t}\n\tif (level >= LIVE_FROM.end_of_step) options.turns = { end_of_step: { ...TURN_STEP } };\n\treturn options;\n}\n\n// ---------------------------------------------------------------------------\n// Rendering source\n// ---------------------------------------------------------------------------\n\nconst IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst WIDTH = 110;\n\n/** A value rendered verbatim, at the current indent: a handler's source. */\nclass Raw {\n\treadonly source: string;\n\tconstructor(source: string) {\n\t\tthis.source = source;\n\t}\n}\n\nfunction key(k: string): string {\n\treturn IDENT.test(k) ? k : JSON.stringify(k);\n}\n\n/** A value as a TypeScript literal, on one line when it fits in `room` columns, else nested by `indent` tabs. */\nfunction literal(value: unknown, indent: number, room: number): string {\n\tif (value instanceof Raw) {\n\t\tconst pad = \"\\t\".repeat(indent);\n\t\treturn value.source\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line, i) => (i === 0 ? line : `${pad}${line}`))\n\t\t\t.join(\"\\n\");\n\t}\n\tif (Array.isArray(value)) return `[${value.map((v) => literal(v, indent, room)).join(\", \")}]`;\n\tif (typeof value === \"object\" && value !== null) {\n\t\tconst entries = Object.entries(value);\n\t\tif (entries.length === 0) return \"{}\";\n\t\tconst inline = entries.map(([k, v]) => `${key(k)}: ${literal(v, indent, room)}`).join(\", \");\n\t\tif (!inline.includes(\"\\n\") && inline.length + 4 <= room) return `{ ${inline} }`;\n\t\tconst pad = \"\\t\".repeat(indent + 1);\n\t\tconst lines = entries.map(([k, v]) => {\n\t\t\tconst head = `${pad}${key(k)}: `;\n\t\t\treturn `${head}${literal(v, indent + 1, WIDTH - head.length * 2)},`;\n\t\t});\n\t\treturn `{\\n${lines.join(\"\\n\")}\\n${\"\\t\".repeat(indent)}}`;\n\t}\n\treturn JSON.stringify(value);\n}\n\n/** Comment out a rendered piece, every line. */\nfunction commented(text: string, indent: number): string {\n\tconst pad = \"\\t\".repeat(indent);\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.map((line) => (line.startsWith(pad) ? `${pad}// ${line.slice(pad.length)}` : `${pad}// ${line.trimStart()}`))\n\t\t.join(\"\\n\");\n}\n\n/**\n * One declaration block, `cells: { ... },` with each entry live or\n * commented on its own, so uncommenting an entry is all it takes; a block\n * with no live entry is commented whole, as the example of its kind.\n */\nfunction block(name: string, entries: Array<{ key: string; value: unknown; live: boolean }>, indent: number): string {\n\tconst pad = \"\\t\".repeat(indent);\n\tconst inner = \"\\t\".repeat(indent + 1);\n\tconst raw = entries.map((e) => {\n\t\tconst head = `${inner}${key(e.key)}: `;\n\t\treturn { text: `${head}${literal(e.value, indent + 1, WIDTH - head.length * 2)},`, live: e.live };\n\t});\n\tif (!raw.some((e) => e.live)) {\n\t\t// no live entry: the whole block is the example, commented once\n\t\treturn commented(`${pad}${name}: {\\n${raw.map((e) => e.text).join(\"\\n\")}\\n${pad}},`, indent);\n\t}\n\tconst rendered = raw.map((e) => (e.live ? e.text : commented(e.text, indent + 1)));\n\treturn `${pad}${name}: {\\n${rendered.join(\"\\n\")}\\n${pad}},`;\n}\n\nfunction declarationModule(input: TemplateInput): string {\n\tconst { name, level, abaiImport } = input;\n\tconst live = (from: number) => level >= from;\n\tconst lines: string[] = [];\n\tlines.push(`// ${name} as an abaigram: what the agent may observe and steer, declared once.`);\n\tlines.push(\"// The manifest (abaigram.yaml) is generated from this: after a change, run\");\n\tlines.push(\"// node src/main.ts abai manifest > abaigram.yaml\");\n\tlines.push(\"// and check it with: abaikit check .\");\n\tif (level < 4) {\n\t\tlines.push(\"// A commented declaration is the example of its kind: uncomment it (and the lines\");\n\t\tlines.push(\"// in src/main.ts that use it) when the program has the fact or the fork.\");\n\t}\n\tlines.push('import { fileURLToPath } from \"node:url\";');\n\tlines.push(`import { createAbaigram } from ${JSON.stringify(abaiImport)};`);\n\tlines.push(\"\");\n\tlines.push(\"/** Steps the agent asked to skip (work.skip); the loop in main.ts honours it. */\");\n\tlines.push(\n\t\tlive(LIVE_FROM[\"work.skip\"])\n\t\t\t? \"export const skipped = new Set<number>();\"\n\t\t\t: \"// export const skipped = new Set<number>();\",\n\t);\n\tlines.push(\"\");\n\tlines.push(\"export const app = createAbaigram(\");\n\tlines.push(\"\\t{\");\n\tlines.push(`\\t\\tname: ${JSON.stringify(name)},`);\n\tlines.push(\"\\t\\t// a runnable entry: the tools reach the program through it, in this directory\");\n\tlines.push(`\\t\\tentry: ${JSON.stringify(ENTRY)},`);\n\tlines.push(`\\t\\tmodes: ${literal([...MODES], 2, WIDTH)},`);\n\tlines.push(`\\t\\tcontent: ${literal(CONTENT, 2, WIDTH)},`);\n\tlines.push(`\\t\\taudit: ${literal(AUDIT, 2, WIDTH)},`);\n\tlines.push(\"\\t\\t// a short run that exercises every channel: what abaikit check runs for the levels above 1\");\n\tconst checkLine = `\\t\\tcheck: ${literal(CHECK, 2, WIDTH)},`;\n\tlines.push(live(LIVE_FROM.check) ? checkLine : commented(checkLine, 2));\n\tlines.push(\"\\t\\t// cells the program writes; a readwrite cell is a knob the agent may set within its range\");\n\tlines.push(\n\t\tblock(\n\t\t\t\"cells\",\n\t\t\t[\n\t\t\t\t{ key: \"work.done\", value: CELL_DONE, live: live(LIVE_FROM[\"work.done\"]) },\n\t\t\t\t{ key: \"work.pace_ms\", value: KNOB_PACE, live: live(LIVE_FROM[\"work.pace_ms\"]) },\n\t\t\t],\n\t\t\t2,\n\t\t),\n\t);\n\tlines.push(\"\\t\\t// events the program emits; wakes says when one wakes the agent\");\n\tlines.push(block(\"events\", [{ key: \"work.step\", value: EVENT_STEP, live: live(LIVE_FROM[\"work.step\"]) }], 2));\n\tlines.push(\"\\t\\t// capabilities the agent may call. dispatch immediate runs the handler at once; the default\");\n\tlines.push(\"\\t\\t// (safepoint) waits for app.safepoint(). check calls the example, so keep it harmless\");\n\tlines.push(\n\t\tblock(\n\t\t\t\"capabilities\",\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tkey: \"work.skip\",\n\t\t\t\t\tvalue: { ...CAPABILITY_SKIP, handler: new Raw(SKIP_HANDLER) },\n\t\t\t\t\tlive: live(LIVE_FROM[\"work.skip\"]),\n\t\t\t\t},\n\t\t\t],\n\t\t\t2,\n\t\t),\n\t);\n\tlines.push(\"\\t\\t// decisions the program asks at a real fork; the default is what it does when nobody answers\");\n\tlines.push(\n\t\tblock(\"decisions\", [{ key: \"on_halfway\", value: DECISION_HALFWAY, live: live(LIVE_FROM.on_halfway) }], 2),\n\t);\n\tlines.push(\"\\t\\t// turns: bounded moments the program hands the agent\");\n\tlines.push(block(\"turns\", [{ key: \"end_of_step\", value: TURN_STEP, live: live(LIVE_FROM.end_of_step) }], 2));\n\tlines.push(\"\\t},\");\n\tlines.push(\"\\t// the directory holding abaigram.yaml and abai/: one level up from this file\");\n\tlines.push('\\t{ root: fileURLToPath(new URL(\"..\", import.meta.url)) },');\n\tlines.push(\");\");\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction mainModule(input: TemplateInput): string {\n\tconst { name, level, abaiImport } = input;\n\tconst live = (from: number) => level >= from;\n\tconst lines: string[] = [];\n\tlines.push(`// ${name}: works through a number of steps and prints each. Node 22.19 and`);\n\tlines.push(\"// later run this file as it is (node src/main.ts 5); the first lines hand the\");\n\tlines.push(\"// standard agent entry to the stub, and the program's own run follows.\");\n\tlines.push(`import { runEntry } from ${JSON.stringify(abaiImport)};`);\n\tlines.push(\n\t\tlive(LIVE_FROM[\"work.skip\"]) ? 'import { app, skipped } from \"./abai.ts\";' : 'import { app } from \"./abai.ts\";',\n\t);\n\tlines.push(\"\");\n\tlines.push(\"const code = await runEntry(app, process.argv.slice(2));\");\n\tlines.push(\"if (code >= 0) process.exit(code); // an abai verb ran; otherwise the program's own run begins\");\n\tlines.push(\"\");\n\tlines.push(\"const total = Number(process.argv[2] ?? 5);\");\n\tlines.push(\"const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\");\n\tif (live(LIVE_FROM[\"work.done\"])) {\n\t\tlines.push(\"// handles once, at startup; set and emit are the cheap calls\");\n\t\tlines.push('const done = app.cell<number>(\"work.done\");');\n\t\tlines.push('const step = app.event(\"work.step\");');\n\t}\n\tif (live(LIVE_FROM[\"work.pace_ms\"])) lines.push('const pace = app.knob<number>(\"work.pace_ms\");');\n\tlines.push(\"\");\n\tlines.push(\"for (let n = 1; n <= total; n++) {\");\n\tif (live(LIVE_FROM.on_halfway)) {\n\t\tlines.push(\"\\tif (n === Math.ceil(total / 2)) {\");\n\t\tlines.push(\"\\t\\t// a real fork: the default is what the program did before it was an abaigram\");\n\t\tlines.push('\\t\\tconst choice = await app.decide<string>(\"on_halfway\", { done: n - 1, total });');\n\t\tlines.push('\\t\\tif (choice === \"stop\") {');\n\t\tlines.push(`\\t\\t\\tconsole.log(\"${name}: stopped halfway, as asked\");`);\n\t\tlines.push(\"\\t\\t\\tbreak;\");\n\t\tlines.push(\"\\t\\t}\");\n\t\tlines.push(\"\\t}\");\n\t}\n\tif (live(LIVE_FROM[\"work.skip\"])) {\n\t\tlines.push(\"\\tif (skipped.has(n)) {\");\n\t\t// biome-ignore lint/suspicious/noTemplateCurlyInString: this is the generated program's source, a template literal in it\n\t\tlines.push(\"\\t\\tconsole.log(`step ${n} skipped`);\");\n\t\tlines.push(\"\\t\\tcontinue;\");\n\t\tlines.push(\"\\t}\");\n\t\tlines.push(\"\\tawait sleep(pace.get());\");\n\t} else {\n\t\tlines.push(\"\\tawait sleep(10);\");\n\t}\n\tif (live(LIVE_FROM[\"work.done\"])) {\n\t\tlines.push(\"\\tdone.set(n);\");\n\t\tlines.push(\"\\tstep.emit({ n });\");\n\t}\n\t// biome-ignore lint/suspicious/noTemplateCurlyInString: this is the generated program's source, a template literal in it\n\tlines.push(\"\\tconsole.log(`step ${n} of ${total}`);\");\n\tlines.push(\"\\tapp.safepoint();\");\n\tif (live(LIVE_FROM.end_of_step)) lines.push('\\tawait app.turn(\"end_of_step\");');\n\tlines.push(\"}\");\n\tlines.push(\n\t\tlive(LIVE_FROM[\"work.done\"])\n\t\t\t? `console.log(\\`${name}: \\${done.get()} steps done\\`);`\n\t\t\t: `console.log(\"${name}: done\");`,\n\t);\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction readme(input: TemplateInput): string {\n\tconst { name, level, packages } = input;\n\tconst where = packages.fromWorkspace\n\t\t? `The two packages come from the abai workspace checkout (\\`file:\\` dependencies)${packages.built ? \"\" : \", which is not built yet: run `npm run build` there first\"}; abaikit itself is a devDependency, so \\`npm run check\\` finds it.`\n\t\t: \"The packages come from npm; abaikit itself is a devDependency, so `npm run check` finds it.\";\n\treturn [\n\t\t`# ${name}`,\n\t\t\"\",\n\t\t`An abaigram at level ${level}, made by \\`abaikit new\\`: a small program that works through a number of steps,`,\n\t\t\"with an agent fused in through the abai stub. Node 22.19 or later runs the TypeScript as it is.\",\n\t\t\"\",\n\t\t\"```\",\n\t\t\"npm install # the stub, the harness, and abaikit for check\",\n\t\t\"node src/main.ts 5 # the program, as itself\",\n\t\t\"node src/main.ts abai doctor --offline # the manifest, the content, the modes\",\n\t\t\"npm run check # abaikit check .: the conformance level, with no model\",\n\t\t\"node src/main.ts abai # a session with the agent about the program (needs a model: node src/main.ts abai config)\",\n\t\t\"node src/main.ts abai run -- 5 # the harness starts the program as its child; the loop meets the agent here\",\n\t\t\"```\",\n\t\t\"\",\n\t\twhere,\n\t\t\"\",\n\t\t\"`src/abai.ts` declares what the agent may observe and steer; `src/main.ts` is the program. After a change to\",\n\t\t\"the declaration, regenerate the manifest: `node src/main.ts abai manifest > abaigram.yaml`. The agent's prompt is\",\n\t\t\"`abai/identity.md`. For the next level, `abaikit learnabai --section retrofit` says what to add.\",\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\n/** Every file of the new project, by path relative to its root. The manifest is rendered by the caller. */\nexport function templateFiles(input: TemplateInput): Record<string, string> {\n\tconst { name, packages } = input;\n\tconst pkg = {\n\t\tname,\n\t\tversion: \"0.1.0\",\n\t\tprivate: true,\n\t\ttype: \"module\",\n\t\tscripts: { start: \"node src/main.ts\", abai: \"node src/main.ts abai\", check: \"abaikit check .\" },\n\t\tdependencies: { \"@abaigram/abai-embedded-harness\": packages.harness, \"@abaigram/abai-stub\": packages.abai },\n\t\tdevDependencies: { \"@abaigram/abaikit\": packages.abaikit },\n\t\tengines: { node: \">=22.19.0\" },\n\t};\n\treturn {\n\t\t\"package.json\": `${JSON.stringify(pkg, null, 2)}\\n`,\n\t\t\"src/abai.ts\": declarationModule(input),\n\t\t\"src/main.ts\": mainModule(input),\n\t\t\"abai/identity.md\": `You are the agent fused into ${name}, a small program that works through a number of steps and prints each. Watch its progress, skip or pace steps only when that serves the person, and say why in every act.\\n`,\n\t\t\"abai/use.md\": `<!-- The use slot (abaigrammar section 8): what the agent should know during sessions and live operation, beyond its identity. -->\\nUnder \\`node src/main.ts abai\\` the program opens a session before its loop: answer about the manifest and the plan. Under \\`node src/main.ts abai run -- N\\` the loop runs while you watch: read the cells before you act, and prefer watching to steering.\\n`,\n\t\t\"README.md\": readme(input),\n\t\t\".gitignore\": \"node_modules/\\nabai-audit.log\\n\",\n\t};\n}\n"]}
package/dist/version.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  /** The abaikit package's own version. */
2
- export declare const ABAIKIT_VERSION = "0.1.0";
2
+ export declare const ABAIKIT_VERSION = "0.2.0";
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,eAAO,MAAM,eAAe,UAAU,CAAC","sourcesContent":["/** The abaikit package's own version. */\nexport const ABAIKIT_VERSION = \"0.1.0\";\n"]}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,eAAO,MAAM,eAAe,UAAU,CAAC","sourcesContent":["/** The abaikit package's own version. */\nexport const ABAIKIT_VERSION = \"0.2.0\";\n"]}
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  /** The abaikit package's own version. */
2
- export const ABAIKIT_VERSION = "0.1.0";
2
+ export const ABAIKIT_VERSION = "0.2.0";
3
3
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC","sourcesContent":["/** The abaikit package's own version. */\nexport const ABAIKIT_VERSION = \"0.1.0\";\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC","sourcesContent":["/** The abaikit package's own version. */\nexport const ABAIKIT_VERSION = \"0.2.0\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaigram/abaikit",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -32,8 +32,8 @@
32
32
  "test": "vitest --run"
33
33
  },
34
34
  "dependencies": {
35
- "@abaigram/abai-embedded-harness": "0.1.0",
36
- "@abaigram/abai-stub": "0.1.0"
35
+ "@abaigram/abai-embedded-harness": "0.2.0",
36
+ "@abaigram/abai-stub": "0.2.0"
37
37
  },
38
38
  "engines": {
39
39
  "node": ">=22.19.0"