@abaigram/abaikit 0.0.0-stage → 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.
Files changed (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +15 -2
  3. package/abai/identity.md +1 -0
  4. package/abai/learnabai.md +546 -0
  5. package/abai/use.md +1 -0
  6. package/abaigram.yaml +208 -0
  7. package/dist/abaify.d.ts +68 -0
  8. package/dist/abaify.d.ts.map +1 -0
  9. package/dist/abaify.js +310 -0
  10. package/dist/abaify.js.map +1 -0
  11. package/dist/abaigram.d.ts +18 -0
  12. package/dist/abaigram.d.ts.map +1 -0
  13. package/dist/abaigram.js +153 -0
  14. package/dist/abaigram.js.map +1 -0
  15. package/dist/app.d.ts +19 -0
  16. package/dist/app.d.ts.map +1 -0
  17. package/dist/app.js +29 -0
  18. package/dist/app.js.map +1 -0
  19. package/dist/bin.d.ts +46 -0
  20. package/dist/bin.d.ts.map +1 -0
  21. package/dist/bin.js +274 -0
  22. package/dist/bin.js.map +1 -0
  23. package/dist/check.d.ts +119 -0
  24. package/dist/check.d.ts.map +1 -0
  25. package/dist/check.js +416 -0
  26. package/dist/check.js.map +1 -0
  27. package/dist/command.d.ts +41 -0
  28. package/dist/command.d.ts.map +1 -0
  29. package/dist/command.js +179 -0
  30. package/dist/command.js.map +1 -0
  31. package/dist/index.d.ts +5 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +5 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/io.d.ts +12 -0
  36. package/dist/io.d.ts.map +1 -0
  37. package/dist/io.js +20 -0
  38. package/dist/io.js.map +1 -0
  39. package/dist/learnabai.d.ts +60 -0
  40. package/dist/learnabai.d.ts.map +1 -0
  41. package/dist/learnabai.js +199 -0
  42. package/dist/learnabai.js.map +1 -0
  43. package/dist/new.d.ts +26 -0
  44. package/dist/new.d.ts.map +1 -0
  45. package/dist/new.js +87 -0
  46. package/dist/new.js.map +1 -0
  47. package/dist/repo.d.ts +99 -0
  48. package/dist/repo.d.ts.map +1 -0
  49. package/dist/repo.js +482 -0
  50. package/dist/repo.js.map +1 -0
  51. package/dist/run.d.ts +6 -0
  52. package/dist/run.d.ts.map +1 -0
  53. package/dist/run.js +47 -0
  54. package/dist/run.js.map +1 -0
  55. package/dist/subject.d.ts +15 -0
  56. package/dist/subject.d.ts.map +1 -0
  57. package/dist/subject.js +53 -0
  58. package/dist/subject.js.map +1 -0
  59. package/dist/template-ts.d.ts +21 -0
  60. package/dist/template-ts.d.ts.map +1 -0
  61. package/dist/template-ts.js +322 -0
  62. package/dist/template-ts.js.map +1 -0
  63. package/dist/version.d.ts +3 -0
  64. package/dist/version.d.ts.map +1 -0
  65. package/dist/version.js +3 -0
  66. package/dist/version.js.map +1 -0
  67. package/examples/hello/abai/identity.md +1 -0
  68. package/examples/hello/abaigram.yaml +24 -0
  69. package/examples/hello/hello.ts +18 -0
  70. package/package.json +40 -5
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abaify.js","sourceRoot":"","sources":["../src/abaify.ts"],"names":[],"mappings":"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","sourcesContent":["// abaikit abaify: the agent-driven retrofit (section 13). abaikit's own\n// agent, with the configured model, works through the repo.* capabilities\n// and nothing else: no source line the repository had is ever removed or\n// reordered, and the three files structured tools rewrite (package.json,\n// abaigram.yaml, the lock file) are named as such. The person's invocation\n// is the consent for its writes, said at the start and in the report. Each\n// round the agent works until it stops, then abaikit runs check itself;\n// the level reached ends the loop, anything short of it is the next\n// prompt, up to the abaify.max_rounds knob. A model that cannot be reached\n// ends the run at once, and the report of what changed and why is left in\n// the repository whatever happened.\nimport { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { AgentModel, SessionForm, UserChannel } from \"@abaigram/abai-embedded-harness\";\nimport type { Mode } from \"@abaigram/abai-stub\";\nimport type { AbaikitApp } from \"./app.ts\";\nimport type { ParsedArgs } from \"./bin.ts\";\nimport { type CheckReport, checkRepository, recordCheck, renderReport } from \"./check.ts\";\nimport { type AbaikitIo, errorMessage, UsageError } from \"./io.ts\";\nimport { findSection, loadGuide } from \"./learnabai.ts\";\nimport { type Change, readRepo, summarizeRepo } from \"./repo.ts\";\n\nexport const REPORT_FILE = \"abai/abaify-report.md\";\n/** Lines of the entry file the brief quotes: enough to see where a launcher checks or imports its build. */\nconst HEAD_LINES = 80;\n/** The brief is thousands of tokens: the model's first answer may take minutes, which is not unreachability. */\nexport const FIRST_CONTACT_MS = 180_000;\n/** Scripts a brief names first, when the package has them. */\nconst KNOWN_SCRIPTS = [\"start\", \"build\", \"compile\", \"dev\", \"test\", \"check\", \"lint\", \"typecheck\"];\n\nexport interface AbaifyOptions {\n\trepo: string;\n\tlevel?: number;\n\tmode?: Mode;\n\trounds?: number;\n\tdryRun: boolean;\n\t/** A model for the agent; the machine's configured one otherwise. */\n\tmodel?: AgentModel;\n}\n\nexport interface Round {\n\tnumber: number;\n\tanswer: string;\n\tcheck: CheckReport | undefined;\n\t/** When check could not run: why (no abaigram.yaml yet, for one). */\n\tcheckError?: string;\n}\n\nexport interface AbaifyResult {\n\troot: string;\n\trequested: number;\n\tlevel: number;\n\tpassed: boolean;\n\tdryRun: boolean;\n\trounds: Round[];\n\tchanges: Change[];\n\t/** Why the run ended short, when it did: the model gone, an error. */\n\tfailure?: string;\n\treportPath?: string;\n\treport: string;\n}\n\ninterface Inventory {\n\tpackageJson: Record<string, unknown> | undefined;\n\tentryFile?: { path: string; head: string; to: number; total: number };\n\tguidelines?: { path: string; head: string };\n\tsummary: string;\n\ttotal: number;\n\t/** Build output present at the root (`dist/`, `build/`, `out/`), so the agent knows whether built paths run. */\n\tbuildOutput: string[];\n}\n\nfunction inventory(root: string): Inventory {\n\tlet packageJson: Record<string, unknown> | undefined;\n\ttry {\n\t\tpackageJson = JSON.parse(readFileSync(join(root, \"package.json\"), \"utf8\")) as Record<string, unknown>;\n\t} catch {\n\t\tpackageJson = undefined;\n\t}\n\tconst { total, summary } = summarizeRepo(root);\n\tconst buildOutput = [\"dist\", \"build\", \"out\"].filter(\n\t\t(d) => existsSync(join(root, d)) && statSync(join(root, d)).isDirectory(),\n\t);\n\tconst result: Inventory = { packageJson, summary, total, buildOutput };\n\tconst bin = packageJson?.bin;\n\tconst binTarget =\n\t\ttypeof bin === \"string\"\n\t\t\t? bin\n\t\t\t: bin && typeof bin === \"object\"\n\t\t\t\t? (Object.values(bin as Record<string, string>)[0] ?? undefined)\n\t\t\t\t: undefined;\n\tconst main = typeof packageJson?.main === \"string\" ? packageJson.main : undefined;\n\tfor (const candidate of [\n\t\tbinTarget,\n\t\tmain,\n\t\t\"src/main.ts\",\n\t\t\"src/main.js\",\n\t\t\"src/index.ts\",\n\t\t\"src/index.js\",\n\t\t\"index.js\",\n\t]) {\n\t\tif (candidate && existsSync(join(root, candidate))) {\n\t\t\tconst { text, to, total_lines } = readRepo(root, candidate, 1, HEAD_LINES);\n\t\t\tresult.entryFile = { path: candidate, head: text, to, total: total_lines };\n\t\t\tbreak;\n\t\t}\n\t}\n\tfor (const candidate of [\"AGENTS.md\", \"CONTRIBUTING.md\", \"CLAUDE.md\"]) {\n\t\tif (existsSync(join(root, candidate))) {\n\t\t\tconst { text } = readRepo(root, candidate, 1, 40);\n\t\t\tresult.guidelines = { path: candidate, head: text };\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction pickedScripts(scripts: Record<string, string>): Record<string, string> {\n\tconst picked: Record<string, string> = {};\n\tfor (const name of KNOWN_SCRIPTS) if (scripts[name] !== undefined) picked[name] = scripts[name];\n\tfor (const [name, value] of Object.entries(scripts)) {\n\t\tif (Object.keys(picked).length >= 15) break;\n\t\tif (picked[name] === undefined) picked[name] = value;\n\t}\n\treturn picked;\n}\n\n/** The first prompt: the task, the repository as it is, the procedure mapped onto the capabilities, the API, the rules. */\nexport function brief(root: string, level: number, mode: Mode | undefined, inv: Inventory, dryRun: boolean): string {\n\tconst guide = loadGuide();\n\tconst pkg = inv.packageJson;\n\tconst picked = pkg\n\t\t? JSON.stringify(\n\t\t\t\t{\n\t\t\t\t\tname: pkg.name,\n\t\t\t\t\ttype: pkg.type,\n\t\t\t\t\tbin: pkg.bin,\n\t\t\t\t\tmain: pkg.main,\n\t\t\t\t\tscripts: pickedScripts((pkg.scripts as Record<string, string>) ?? {}),\n\t\t\t\t},\n\t\t\t\tnull,\n\t\t\t\t2,\n\t\t\t)\n\t\t: \"(no package.json)\";\n\tconst lines = [\n\t\t`Retrofit the repository at ${root} into an abaigram at level ${level}${mode ? ` in ${mode} mode: declare \"${mode}\" among the modes, since the check runs under it` : \"\"}.`,\n\t\t\"\",\n\t\t\"You work only through abaikit's capabilities (the abai_call tool), with `repo` set to exactly the path above:\",\n\t\t\"- repo.list (glob narrows: `*.json` by name anywhere, `src/**` or `scripts/*.mjs` by path; the listing is bounded and says so first), repo.read (a window of lines; the result says `from` and `to`).\",\n\t\t\"- repo.write makes a new file only. repo.insert puts text before or after one unique anchor line of an existing file; no line the repository had is ever removed or reordered. repo.add_dependency adds to package.json (a structured edit that re-serializes the file). repo.manifest runs the entry's `manifest` and writes abaigram.yaml: never write that file yourself. repo.install runs npm install (the lock file and node_modules are rewritten). check gives the conformance report.\",\n\t\t\"- You cannot run shell commands or build the repository. Where the procedure below says `npm install`, call repo.add_dependency for both `@abaigram/abai-stub` and `@abaigram/abai-embedded-harness`, then repo.install once. Where it says `<entry> manifest > abaigram.yaml`, call repo.manifest with the entry. Where it says `abaikit check`, call check. Where it says build: \" +\n\t\t\t(inv.buildOutput.length > 0\n\t\t\t\t? `the build output is present (${inv.buildOutput.map((d) => `${d}/`).join(\", \")}), so the built program runs; prefer a cell or event at a real boundary of the program and a check.run that is a real command of it, over a synthetic mode.`\n\t\t\t\t: \"there is no build output, so choose a path that needs no build: a plain `.mjs` module beside a launcher, a cell or event set in code that runs unbuilt.\"),\n\t\t\"- The `entry` you declare must end with the word `abai` (such as `node scripts/x.mjs abai` or `node dist/main.js abai`): the tools append `manifest`, `doctor` and `run` to it, and the stub's runEntry answers only when `abai` comes first. A file you wrote in this run you may write again with repo.write; a file the repository had you may only insert into.\",\n\t\t\"- You have the person's consent for this run; do not ask them.\",\n\t\tdryRun\n\t\t\t? \"- This is a dry run: call the capabilities as you would; nothing is written, repo.manifest and check cannot succeed on files that are not on disk, so propose the whole retrofit and stop.\"\n\t\t\t: \"\",\n\t\t\"\",\n\t\t`Repository shape (${inv.total} files after skipping dependencies, build output and ignored trees; directories with their counts, use repo.list with a glob to see inside one):`,\n\t\t\"```\",\n\t\tinv.summary,\n\t\t\"```\",\n\t\t\"package.json (the known scripts first):\",\n\t\t\"```json\",\n\t\tpicked,\n\t\t\"```\",\n\t];\n\tif (inv.entryFile) {\n\t\tlines.push(\n\t\t\t`The entry file ${inv.entryFile.path}, lines 1 to ${inv.entryFile.to} of ${inv.entryFile.total}:`,\n\t\t\t\"```\",\n\t\t\tinv.entryFile.head,\n\t\t\t\"```\",\n\t\t);\n\t}\n\tif (inv.guidelines) {\n\t\tlines.push(`The repository's own guidelines, ${inv.guidelines.path}, head:`, \"```\", inv.guidelines.head, \"```\");\n\t}\n\tlines.push(\n\t\t\"\",\n\t\t\"The procedure, from abaikit learnabai (read it with the mapping above):\",\n\t\tfindSection(guide, \"retrofit\").text,\n\t\t\"\",\n\t\t\"The declaration API:\",\n\t\tfindSection(guide, \"declare\").text,\n\t\t\"\",\n\t\t\"What never to do:\",\n\t\tfindSection(guide, \"never\").text,\n\t\t\"\",\n\t\t`When you believe level ${level} is reached, call check once; when it reports level ${level} with no violation, answer with the word DONE on its own line followed by a short summary of what you added and why. If you cannot go on, say why.`,\n\t);\n\treturn lines.filter((l) => l !== undefined).join(\"\\n\");\n}\n\nfunction followUp(round: Round, level: number): string {\n\tconst status = round.check ? renderReport(round.check) : `check could not run: ${round.checkError}`;\n\treturn `abaikit ran check after your last round. Level ${level} is not reached yet. The report:\\n\\n${status}\\nFix what it names, through the capabilities, then call check again. Answer DONE with a summary when level ${level} holds with no violation.`;\n}\n\nfunction consentLine(root: string, level: number, dryRun: boolean): string {\n\treturn dryRun\n\t\t? `abaify: dry run on ${root}: the agent proposes a retrofit to level ${level}; nothing is written, though the repository's entry may be run read-only`\n\t\t: `abaify: ${root} to level ${level}, with your consent for this run: the agent may add files, insert lines, add dependencies, run npm install (network, the repository's own install scripts), run the repository's entry and its check.run under the null harness`;\n}\n\n/** The report left in the repository: every change with its why, the rounds, the last check. */\nexport function renderAbaifyReport(result: AbaifyResult, run: number): string {\n\tconst lines = [\n\t\t`# abaify report: ${result.root} (run ${run}, ${new Date().toISOString()})`,\n\t\t\"\",\n\t\tresult.dryRun\n\t\t\t? `Dry run to level ${result.requested}: ${result.changes.length} change${result.changes.length === 1 ? \"\" : \"s\"} proposed, nothing written, no check run.`\n\t\t\t: `Requested level ${result.requested}; reached level ${result.level}; ${result.passed ? \"passed\" : \"not passed\"} after ${result.rounds.length} round${result.rounds.length === 1 ? \"\" : \"s\"}.`,\n\t\tconsentLine(result.root, result.requested, result.dryRun).replace(/^abaify: /, \"Consent: \"),\n\t\t\"\",\n\t];\n\tif (result.failure) lines.push(`The run ended short: ${result.failure}`, \"\");\n\tconst added = result.changes.filter((c) => c.kind === \"added\");\n\tconst rewritten = result.changes.filter((c) => c.kind === \"rewritten\");\n\tlines.push(\"## Added (new files and inserted lines; nothing the repository had was removed or reordered)\", \"\");\n\tlines.push(\n\t\t...(added.length === 0 ? [\"(none)\"] : added.map((c) => `- ${c.how} ${c.path}: ${c.detail}. Why: ${c.why}`)),\n\t);\n\tlines.push(\"\", \"## Rewritten in place by a structured tool\", \"\");\n\tlines.push(\n\t\t...(rewritten.length === 0\n\t\t\t? [\"(none)\"]\n\t\t\t: rewritten.map((c) => `- ${c.how} ${c.path}: ${c.detail}. Why: ${c.why}`)),\n\t);\n\tlines.push(\"\", \"## Rounds\", \"\");\n\tfor (const r of result.rounds) {\n\t\tlines.push(`### Round ${r.number}`, \"\", \"The agent said:\", \"\", r.answer.trim() || \"(nothing)\", \"\");\n\t\tif (!result.dryRun) {\n\t\t\tlines.push(\n\t\t\t\tr.check\n\t\t\t\t\t? `check after the round: level ${r.check.level}, ${r.check.passed ? \"passed\" : \"not passed\"}`\n\t\t\t\t\t: `check could not run: ${r.checkError ?? \"unknown\"}`,\n\t\t\t\t\"\",\n\t\t\t);\n\t\t}\n\t}\n\tconst last = result.rounds.at(-1)?.check;\n\tif (last) lines.push(\"## The last check report\", \"\", \"```\", renderReport(last).trimEnd(), \"```\", \"\");\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n\n/** The report appended to the repository's; the run number counts the reports already there. */\nfunction writeReport(root: string, result: AbaifyResult): string {\n\tconst path = join(root, REPORT_FILE);\n\tmkdirSync(join(root, \"abai\"), { recursive: true });\n\tconst previous = existsSync(path) ? readFileSync(path, \"utf8\") : \"\";\n\tconst run = (previous.match(/^# abaify report:/gm) ?? []).length + 1;\n\tresult.report = renderAbaifyReport(result, run);\n\twriteFileSync(path, (previous === \"\" ? \"\" : `${previous.trimEnd()}\\n\\n---\\n\\n`) + result.report);\n\treturn path;\n}\n\nexport async function abaify(options: AbaifyOptions, io: AbaikitIo, bundle: AbaikitApp): Promise<AbaifyResult> {\n\tconst { app, embedding, repo: ctx } = bundle;\n\tconst root = resolve(io.cwd, options.repo);\n\tif (!existsSync(join(root, \"package.json\"))) {\n\t\tthrow new UsageError(\n\t\t\t`${options.repo}: no package.json; abaify retrofits Node repositories (TypeScript or JavaScript) for now`,\n\t\t);\n\t}\n\tif (app.mode !== \"turns\")\n\t\tthrow new UsageError(`abaify runs its agent in-process; unset ABAI_MODE (it is ${app.mode})`);\n\tconst level = options.level ?? 1;\n\tconst rounds = app.knob<number>(\"abaify.max_rounds\");\n\tconst range = app.manifest.cells.find((c) => c.name === \"abaify.max_rounds\")?.range ?? [1, 20];\n\tif (options.rounds !== undefined) {\n\t\tif (options.rounds < range[0] || options.rounds > range[1])\n\t\t\tthrow new UsageError(`--rounds must be ${range[0]} to ${range[1]}`);\n\t\trounds.set(options.rounds);\n\t}\n\tconst say = (text: string) => io.err(text);\n\tsay(consentLine(root, level, options.dryRun));\n\tctx.dryRun = options.dryRun;\n\tctx.cwd = io.cwd;\n\tctx.onChange = (change) => say(`abaify: ${change.how} ${change.path}: ${change.detail}`);\n\tconst changesBefore = ctx.changes.length;\n\tconst result: AbaifyResult = {\n\t\troot,\n\t\trequested: level,\n\t\tlevel: 0,\n\t\tpassed: false,\n\t\tdryRun: options.dryRun,\n\t\trounds: [],\n\t\tchanges: [],\n\t\treport: \"\",\n\t};\n\n\t// the agent: abaikit's own embedded harness, auto consent (the invocation is the person's), a channel that only speaks\n\tconst channel: UserChannel = { say, ask: async () => undefined, confirm: async () => false, close: () => {} };\n\tembedding.options = {\n\t\tmodel: options.model,\n\t\tchannel,\n\t\tharness: { auto: true },\n\t\tconnectTimeoutMs: FIRST_CONTACT_MS,\n\t\taddendum: `You are retrofitting ${root} for a person who asked abaikit to do it; every write is theirs to approve and they approved this run.`,\n\t};\n\tlet form: SessionForm | undefined;\n\ttry {\n\t\tif (!(await app.attach()) || !embedding.current) {\n\t\t\tthrow new Error(\n\t\t\t\t`no agent could be attached: ${app.attachError ?? \"unknown\"} (configure one with \\`abaikit abai config\\`, or follow \\`abaikit learnabai\\` with your own agent)`,\n\t\t\t);\n\t\t}\n\t\tform = embedding.current.form;\n\t\tconst harness = embedding.current.harness;\n\t\tconst inv = inventory(root);\n\t\tlet prompt = brief(root, level, options.mode, inv, options.dryRun);\n\t\t// read once: an agent setting its own knob mid-run changes the next run, not this one\n\t\tconst max = options.dryRun ? 1 : rounds.get();\n\t\tfor (let n = 1; n <= max; n++) {\n\t\t\tsay(`abaify: round ${n} of ${max}`);\n\t\t\tconst answer = await form.prompt(prompt);\n\t\t\tconst round: Round = { number: n, answer, check: undefined };\n\t\t\tresult.rounds.push(round);\n\t\t\t// a run the model could not finish ends the loop: before first contact the form detaches; after it the\n\t\t\t// agent's last message carries the error, and another round would only spend the person's time\n\t\t\tconst last = [...form.agent.state.messages].reverse().find((m) => m.role === \"assistant\");\n\t\t\tconst stop = last && last.role === \"assistant\" ? last.stopReason : undefined;\n\t\t\tif (form.modelFailure !== undefined || !harness.attached) {\n\t\t\t\tresult.failure = `the model could not be reached: ${form.modelFailure ?? \"the harness detached\"}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (stop === \"error\" || stop === \"aborted\") {\n\t\t\t\tconst why =\n\t\t\t\t\tlast && last.role === \"assistant\" && \"errorMessage\" in last ? String(last.errorMessage ?? stop) : stop;\n\t\t\t\tresult.failure = `the model could not be reached: the request ${stop === \"aborted\" ? \"was aborted\" : \"failed\"} (${why}); run abaify again when it is back`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!options.dryRun) {\n\t\t\t\tsay(`abaify: check after round ${n}`);\n\t\t\t\ttry {\n\t\t\t\t\tround.check = await checkRepository({ repo: root, cwd: io.cwd, env: io.env, level, mode: options.mode });\n\t\t\t\t\trecordCheck(app, round.check);\n\t\t\t\t\tresult.level = round.check.level;\n\t\t\t\t\tresult.passed = round.check.passed;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tround.checkError = errorMessage(error);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (result.passed) break;\n\t\t\tprompt = followUp(round, level);\n\t\t}\n\t} catch (error) {\n\t\tresult.failure = result.failure ?? errorMessage(error);\n\t\tthrow error;\n\t} finally {\n\t\tform?.shutdown(\"abaify ended\");\n\t\tctx.dryRun = false;\n\t\tctx.onChange = undefined;\n\t\tresult.changes = ctx.changes.slice(changesBefore);\n\t\t// the report is written whatever happened once the agent was at work, so nothing done goes unrecorded\n\t\tif (options.dryRun) result.report = renderAbaifyReport(result, 1);\n\t\telse if (result.rounds.length > 0 || result.changes.length > 0) result.reportPath = writeReport(root, result);\n\t}\n\tif (options.dryRun) result.passed = true;\n\treturn result;\n}\n\nexport async function runAbaify(\n\tparsed: Extract<ParsedArgs, { verb: \"abaify\" }>,\n\tio: AbaikitIo,\n\tbundle: AbaikitApp,\n\tdeps: { model?: AgentModel } = {},\n): Promise<number> {\n\tconst result = await abaify(\n\t\t{\n\t\t\trepo: parsed.repo,\n\t\t\tlevel: parsed.level,\n\t\t\tmode: parsed.mode,\n\t\t\trounds: parsed.rounds,\n\t\t\tdryRun: parsed.dryRun,\n\t\t\tmodel: deps.model,\n\t\t},\n\t\tio,\n\t\tbundle,\n\t);\n\tio.out(result.report);\n\tif (result.reportPath) io.out(`report: ${result.reportPath}\\n`);\n\tif (result.failure) {\n\t\tio.out(\n\t\t\t`abaify: ended short after ${result.rounds.length} round${result.rounds.length === 1 ? \"\" : \"s\"}: ${result.failure}\\n`,\n\t\t);\n\t\treturn 1;\n\t}\n\tio.out(\n\t\tresult.dryRun\n\t\t\t? `dry run: ${result.changes.length} change${result.changes.length === 1 ? \"\" : \"s\"} proposed, nothing written\\n`\n\t\t\t: result.passed\n\t\t\t\t? `abaify: level ${result.level} reached in ${result.rounds.length} round${result.rounds.length === 1 ? \"\" : \"s\"}\\n`\n\t\t\t\t: `abaify: level ${result.requested} not reached after ${result.rounds.length} round${result.rounds.length === 1 ? \"\" : \"s\"} (reached ${result.level}); the report says what remains\\n`,\n\t);\n\treturn result.passed ? 0 : 1;\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { type Abaigram, type AbaigramExtras, type CapabilityHandler } from "@abaigram/abai-stub";
2
+ export type Handler = CapabilityHandler;
3
+ export interface AbaikitHandlers {
4
+ learnabai?: Handler;
5
+ check?: Handler;
6
+ new?: Handler;
7
+ repoList?: Handler;
8
+ repoRead?: Handler;
9
+ repoWrite?: Handler;
10
+ repoInsert?: Handler;
11
+ repoAddDependency?: Handler;
12
+ repoManifest?: Handler;
13
+ repoInstall?: Handler;
14
+ }
15
+ /** The abaikit package root, where abaigram.yaml and the content live; the same from src/ and dist/. */
16
+ export declare const PACKAGE_ROOT: string;
17
+ export declare function createAbaikit(handlers?: AbaikitHandlers, extras?: AbaigramExtras): Abaigram;
18
+ //# sourceMappingURL=abaigram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abaigram.d.ts","sourceRoot":"","sources":["../src/abaigram.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAE,KAAK,iBAAiB,EAAkB,MAAM,qBAAqB,CAAC;AAEjH,MAAM,MAAM,OAAO,GAAG,iBAAiB,CAAC;AAExC,MAAM,WAAW,eAAe;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wGAAwG;AACxG,eAAO,MAAM,YAAY,QAAqC,CAAC;AAQ/D,wBAAgB,aAAa,CAAC,QAAQ,GAAE,eAAoB,EAAE,MAAM,GAAE,cAAmB,GAAG,QAAQ,CA2InG","sourcesContent":["// abaikit's own manifest: the tool is itself an abaigram. Its agent reads\n// the guide, runs check, creates new abaigrams and changes a repository only\n// through the additive repo.* capabilities. The verbs fill in the handlers;\n// a capability with none supplied says it is not yet implemented. Every\n// capability is dispatched at once: a command-line tool has no hot loop\n// reaching safepoints, and its handlers are I/O-bound.\nimport { resolve } from \"node:path\";\nimport { type Abaigram, type AbaigramExtras, type CapabilityHandler, createAbaigram } from \"@abaigram/abai-stub\";\n\nexport type Handler = CapabilityHandler;\n\nexport interface AbaikitHandlers {\n\tlearnabai?: Handler;\n\tcheck?: Handler;\n\tnew?: Handler;\n\trepoList?: Handler;\n\trepoRead?: Handler;\n\trepoWrite?: Handler;\n\trepoInsert?: Handler;\n\trepoAddDependency?: Handler;\n\trepoManifest?: Handler;\n\trepoInstall?: Handler;\n}\n\n/** The abaikit package root, where abaigram.yaml and the content live; the same from src/ and dist/. */\nexport const PACKAGE_ROOT = resolve(import.meta.dirname, \"..\");\n\nfunction notYet(name: string): Handler {\n\treturn () => {\n\t\tthrow new Error(`${name}: not yet implemented`);\n\t};\n}\n\nexport function createAbaikit(handlers: AbaikitHandlers = {}, extras: AbaigramExtras = {}): Abaigram {\n\treturn createAbaigram(\n\t\t{\n\t\t\tname: \"abaikit\",\n\t\t\tmodes: [\"turns\", \"sidecar\"],\n\t\t\t// no audit path of its own: a tool's audit belongs in the user's abai home, not in its install directory\n\t\t\tcontent: { use: \"abai/use.md\" },\n\t\t\t// run in the package root, where the check example below resolves\n\t\t\tcheck: { run: \"node dist/bin.js check examples/hello\" },\n\t\t\tcells: {\n\t\t\t\t\"check.runs\": { type: \"int\", access: \"read\", doc: \"Conformance checks run by this process.\" },\n\t\t\t\t\"check.last_level\": { type: \"int\", access: \"read\", doc: \"The level the last check reported, 0 to 4.\" },\n\t\t\t\t\"abaify.max_rounds\": {\n\t\t\t\t\ttype: \"int\",\n\t\t\t\t\taccess: \"readwrite\",\n\t\t\t\t\tdefault: 5,\n\t\t\t\t\trange: [1, 20],\n\t\t\t\t\tdoc: \"Agent rounds abaify gives a retrofit before it stops.\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tevents: {\n\t\t\t\t\"check.completed\": {\n\t\t\t\t\tpayload: { repo: { type: \"string\", max: 512 }, level: { type: \"int\" } },\n\t\t\t\t\twakes: \"never\",\n\t\t\t\t\tdoc: \"A conformance check finished.\",\n\t\t\t\t},\n\t\t\t\t\"repo.changed\": {\n\t\t\t\t\tpayload: { path: { type: \"string\", max: 512 }, how: { type: \"string\", max: 32 } },\n\t\t\t\t\twakes: \"never\",\n\t\t\t\t\tdoc: \"abaify changed the repository: wrote a file, inserted lines, added a dependency, regenerated the manifest, or installed.\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tcapabilities: {\n\t\t\t\tlearnabai: {\n\t\t\t\t\tparams: { section: \"string\" },\n\t\t\t\t\tresult: { text: \"string\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"read\",\n\t\t\t\t\texample: {},\n\t\t\t\t\tdoc: \"The guide for an agent: what an abaigram is, how to declare one in TypeScript, how to retrofit a repository, how check judges it; one section or all.\",\n\t\t\t\t\thandler: handlers.learnabai ?? notYet(\"learnabai\"),\n\t\t\t\t},\n\t\t\t\tcheck: {\n\t\t\t\t\tparams: { repo: \"string\", level: \"int\", mode: \"string\", entry: \"string\", runs: \"int\" },\n\t\t\t\t\tresult: { level: \"int\", passed: \"bool\", report: \"string\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"auto\",\n\t\t\t\t\ttimeout: \"1800s\",\n\t\t\t\t\t// relative to the working directory: the package root, where abaikit's own check.run runs\n\t\t\t\t\texample: { repo: \"examples/hello\" },\n\t\t\t\t\tdoc: \"Verify a repository's conformance (section 12): L1 through its entry, L2 to L4 by running the repository's check.run command under the null harness, an exercise run and the measurement runs per mode. Needs no model; may take minutes.\",\n\t\t\t\t\thandler: handlers.check ?? notYet(\"check\"),\n\t\t\t\t},\n\t\t\t\tnew: {\n\t\t\t\t\tparams: { name: \"string\", lang: \"string\", level: \"int\", dir: \"string\" },\n\t\t\t\t\tresult: { path: \"string\", written: \"int\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"confirm\",\n\t\t\t\t\tdoc: \"Create a fresh abaigram in a language, at a level, with one example of each declaration and the content slots in place.\",\n\t\t\t\t\thandler: handlers.new ?? notYet(\"new\"),\n\t\t\t\t},\n\t\t\t\t\"repo.list\": {\n\t\t\t\t\tparams: { repo: \"string\", glob: \"string\" },\n\t\t\t\t\tresult: { count: \"int\", listing: \"string\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"read\",\n\t\t\t\t\texample: { repo: \"examples/hello\" },\n\t\t\t\t\tdoc: \"List a repository's files, skipping dependencies, build output and ignored trees; bounded, and the bound is said first. glob narrows: *.json by name anywhere, src/** or scripts/*.mjs by path.\",\n\t\t\t\t\thandler: handlers.repoList ?? notYet(\"repo.list\"),\n\t\t\t\t},\n\t\t\t\t\"repo.read\": {\n\t\t\t\t\tparams: { repo: \"string\", path: \"string\", start: \"int\", lines: \"int\" },\n\t\t\t\t\tresult: { text: \"string\", total_lines: \"int\", from: \"int\", to: \"int\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"read\",\n\t\t\t\t\texample: { repo: \"examples/hello\", path: \"abaigram.yaml\" },\n\t\t\t\t\tdoc: \"Read part of a file in a repository: a window from line start, 400 lines or 12 KB at most a call; the result says from and to.\",\n\t\t\t\t\thandler: handlers.repoRead ?? notYet(\"repo.read\"),\n\t\t\t\t},\n\t\t\t\t\"repo.write\": {\n\t\t\t\t\tparams: { repo: \"string\", path: \"string\", content: \"string\", why: \"string\" },\n\t\t\t\t\tresult: { written: \"bool\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"confirm\",\n\t\t\t\t\tdoc: \"Write a new file in a repository (any directory this process can reach; under an MCP client each call is the client's permission prompt); an existing file is refused, since abaify adds and never replaces.\",\n\t\t\t\t\thandler: handlers.repoWrite ?? notYet(\"repo.write\"),\n\t\t\t\t},\n\t\t\t\t\"repo.insert\": {\n\t\t\t\t\tparams: {\n\t\t\t\t\t\trepo: \"string\",\n\t\t\t\t\t\tpath: \"string\",\n\t\t\t\t\t\tanchor: \"string\",\n\t\t\t\t\t\twhere: \"string\",\n\t\t\t\t\t\ttext: \"string\",\n\t\t\t\t\t\twhy: \"string\",\n\t\t\t\t\t},\n\t\t\t\t\tresult: { line: \"int\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"confirm\",\n\t\t\t\t\tdoc: \"Insert text before or after a unique anchor line in an existing file of a repository; no line the file had is removed or reordered.\",\n\t\t\t\t\thandler: handlers.repoInsert ?? notYet(\"repo.insert\"),\n\t\t\t\t},\n\t\t\t\t\"repo.add_dependency\": {\n\t\t\t\t\tparams: { repo: \"string\", name: \"string\", spec: \"string\", why: \"string\" },\n\t\t\t\t\tresult: { spec: \"string\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"confirm\",\n\t\t\t\t\tdoc: \"Add a dependency to the repository's package.json in sorted place (the file is re-serialized, keys and indentation kept); the spec defaults to how abaikit reaches @abaigram/abai-stub, @abaigram/abai-embedded-harness and @abaigram/abaikit.\",\n\t\t\t\t\thandler: handlers.repoAddDependency ?? notYet(\"repo.add_dependency\"),\n\t\t\t\t},\n\t\t\t\t\"repo.manifest\": {\n\t\t\t\t\tparams: { repo: \"string\", entry: \"string\", why: \"string\" },\n\t\t\t\t\tresult: { written: \"bool\", lines: \"int\", text: \"string\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"confirm\",\n\t\t\t\t\ttimeout: \"90s\",\n\t\t\t\t\tdoc: \"Run the repository's entry (`<entry> manifest`) and write what it prints to abaigram.yaml, the one file never written by hand.\",\n\t\t\t\t\thandler: handlers.repoManifest ?? notYet(\"repo.manifest\"),\n\t\t\t\t},\n\t\t\t\t\"repo.install\": {\n\t\t\t\t\tparams: { repo: \"string\", why: \"string\" },\n\t\t\t\t\tresult: { ok: \"bool\", output: \"string\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"confirm\",\n\t\t\t\t\ttimeout: \"660s\",\n\t\t\t\t\tdoc: \"Run npm install in the repository (network; the repository's own install scripts run; the lock file and node_modules are rewritten), so the dependencies just added resolve.\",\n\t\t\t\t\thandler: handlers.repoInstall ?? notYet(\"repo.install\"),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{ root: PACKAGE_ROOT, ...extras },\n\t);\n}\n"]}
@@ -0,0 +1,153 @@
1
+ // abaikit's own manifest: the tool is itself an abaigram. Its agent reads
2
+ // the guide, runs check, creates new abaigrams and changes a repository only
3
+ // through the additive repo.* capabilities. The verbs fill in the handlers;
4
+ // a capability with none supplied says it is not yet implemented. Every
5
+ // capability is dispatched at once: a command-line tool has no hot loop
6
+ // reaching safepoints, and its handlers are I/O-bound.
7
+ import { resolve } from "node:path";
8
+ import { createAbaigram } from "@abaigram/abai-stub";
9
+ /** The abaikit package root, where abaigram.yaml and the content live; the same from src/ and dist/. */
10
+ export const PACKAGE_ROOT = resolve(import.meta.dirname, "..");
11
+ function notYet(name) {
12
+ return () => {
13
+ throw new Error(`${name}: not yet implemented`);
14
+ };
15
+ }
16
+ export function createAbaikit(handlers = {}, extras = {}) {
17
+ return createAbaigram({
18
+ name: "abaikit",
19
+ modes: ["turns", "sidecar"],
20
+ // no audit path of its own: a tool's audit belongs in the user's abai home, not in its install directory
21
+ content: { use: "abai/use.md" },
22
+ // run in the package root, where the check example below resolves
23
+ check: { run: "node dist/bin.js check examples/hello" },
24
+ cells: {
25
+ "check.runs": { type: "int", access: "read", doc: "Conformance checks run by this process." },
26
+ "check.last_level": { type: "int", access: "read", doc: "The level the last check reported, 0 to 4." },
27
+ "abaify.max_rounds": {
28
+ type: "int",
29
+ access: "readwrite",
30
+ default: 5,
31
+ range: [1, 20],
32
+ doc: "Agent rounds abaify gives a retrofit before it stops.",
33
+ },
34
+ },
35
+ events: {
36
+ "check.completed": {
37
+ payload: { repo: { type: "string", max: 512 }, level: { type: "int" } },
38
+ wakes: "never",
39
+ doc: "A conformance check finished.",
40
+ },
41
+ "repo.changed": {
42
+ payload: { path: { type: "string", max: 512 }, how: { type: "string", max: 32 } },
43
+ wakes: "never",
44
+ doc: "abaify changed the repository: wrote a file, inserted lines, added a dependency, regenerated the manifest, or installed.",
45
+ },
46
+ },
47
+ capabilities: {
48
+ learnabai: {
49
+ params: { section: "string" },
50
+ result: { text: "string" },
51
+ dispatch: "immediate",
52
+ effect: "read",
53
+ example: {},
54
+ doc: "The guide for an agent: what an abaigram is, how to declare one in TypeScript, how to retrofit a repository, how check judges it; one section or all.",
55
+ handler: handlers.learnabai ?? notYet("learnabai"),
56
+ },
57
+ check: {
58
+ params: { repo: "string", level: "int", mode: "string", entry: "string", runs: "int" },
59
+ result: { level: "int", passed: "bool", report: "string" },
60
+ dispatch: "immediate",
61
+ effect: "mutate",
62
+ policy: "auto",
63
+ timeout: "1800s",
64
+ // relative to the working directory: the package root, where abaikit's own check.run runs
65
+ example: { repo: "examples/hello" },
66
+ doc: "Verify a repository's conformance (section 12): L1 through its entry, L2 to L4 by running the repository's check.run command under the null harness, an exercise run and the measurement runs per mode. Needs no model; may take minutes.",
67
+ handler: handlers.check ?? notYet("check"),
68
+ },
69
+ new: {
70
+ params: { name: "string", lang: "string", level: "int", dir: "string" },
71
+ result: { path: "string", written: "int" },
72
+ dispatch: "immediate",
73
+ effect: "mutate",
74
+ policy: "confirm",
75
+ doc: "Create a fresh abaigram in a language, at a level, with one example of each declaration and the content slots in place.",
76
+ handler: handlers.new ?? notYet("new"),
77
+ },
78
+ "repo.list": {
79
+ params: { repo: "string", glob: "string" },
80
+ result: { count: "int", listing: "string" },
81
+ dispatch: "immediate",
82
+ effect: "read",
83
+ example: { repo: "examples/hello" },
84
+ doc: "List a repository's files, skipping dependencies, build output and ignored trees; bounded, and the bound is said first. glob narrows: *.json by name anywhere, src/** or scripts/*.mjs by path.",
85
+ handler: handlers.repoList ?? notYet("repo.list"),
86
+ },
87
+ "repo.read": {
88
+ params: { repo: "string", path: "string", start: "int", lines: "int" },
89
+ result: { text: "string", total_lines: "int", from: "int", to: "int" },
90
+ dispatch: "immediate",
91
+ effect: "read",
92
+ example: { repo: "examples/hello", path: "abaigram.yaml" },
93
+ doc: "Read part of a file in a repository: a window from line start, 400 lines or 12 KB at most a call; the result says from and to.",
94
+ handler: handlers.repoRead ?? notYet("repo.read"),
95
+ },
96
+ "repo.write": {
97
+ params: { repo: "string", path: "string", content: "string", why: "string" },
98
+ result: { written: "bool" },
99
+ dispatch: "immediate",
100
+ effect: "mutate",
101
+ policy: "confirm",
102
+ doc: "Write a new file in a repository (any directory this process can reach; under an MCP client each call is the client's permission prompt); an existing file is refused, since abaify adds and never replaces.",
103
+ handler: handlers.repoWrite ?? notYet("repo.write"),
104
+ },
105
+ "repo.insert": {
106
+ params: {
107
+ repo: "string",
108
+ path: "string",
109
+ anchor: "string",
110
+ where: "string",
111
+ text: "string",
112
+ why: "string",
113
+ },
114
+ result: { line: "int" },
115
+ dispatch: "immediate",
116
+ effect: "mutate",
117
+ policy: "confirm",
118
+ doc: "Insert text before or after a unique anchor line in an existing file of a repository; no line the file had is removed or reordered.",
119
+ handler: handlers.repoInsert ?? notYet("repo.insert"),
120
+ },
121
+ "repo.add_dependency": {
122
+ params: { repo: "string", name: "string", spec: "string", why: "string" },
123
+ result: { spec: "string" },
124
+ dispatch: "immediate",
125
+ effect: "mutate",
126
+ policy: "confirm",
127
+ doc: "Add a dependency to the repository's package.json in sorted place (the file is re-serialized, keys and indentation kept); the spec defaults to how abaikit reaches @abaigram/abai-stub, @abaigram/abai-embedded-harness and @abaigram/abaikit.",
128
+ handler: handlers.repoAddDependency ?? notYet("repo.add_dependency"),
129
+ },
130
+ "repo.manifest": {
131
+ params: { repo: "string", entry: "string", why: "string" },
132
+ result: { written: "bool", lines: "int", text: "string" },
133
+ dispatch: "immediate",
134
+ effect: "mutate",
135
+ policy: "confirm",
136
+ timeout: "90s",
137
+ doc: "Run the repository's entry (`<entry> manifest`) and write what it prints to abaigram.yaml, the one file never written by hand.",
138
+ handler: handlers.repoManifest ?? notYet("repo.manifest"),
139
+ },
140
+ "repo.install": {
141
+ params: { repo: "string", why: "string" },
142
+ result: { ok: "bool", output: "string" },
143
+ dispatch: "immediate",
144
+ effect: "mutate",
145
+ policy: "confirm",
146
+ timeout: "660s",
147
+ doc: "Run npm install in the repository (network; the repository's own install scripts run; the lock file and node_modules are rewritten), so the dependencies just added resolve.",
148
+ handler: handlers.repoInstall ?? notYet("repo.install"),
149
+ },
150
+ },
151
+ }, { root: PACKAGE_ROOT, ...extras });
152
+ }
153
+ //# sourceMappingURL=abaigram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abaigram.js","sourceRoot":"","sources":["../src/abaigram.ts"],"names":[],"mappings":"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","sourcesContent":["// abaikit's own manifest: the tool is itself an abaigram. Its agent reads\n// the guide, runs check, creates new abaigrams and changes a repository only\n// through the additive repo.* capabilities. The verbs fill in the handlers;\n// a capability with none supplied says it is not yet implemented. Every\n// capability is dispatched at once: a command-line tool has no hot loop\n// reaching safepoints, and its handlers are I/O-bound.\nimport { resolve } from \"node:path\";\nimport { type Abaigram, type AbaigramExtras, type CapabilityHandler, createAbaigram } from \"@abaigram/abai-stub\";\n\nexport type Handler = CapabilityHandler;\n\nexport interface AbaikitHandlers {\n\tlearnabai?: Handler;\n\tcheck?: Handler;\n\tnew?: Handler;\n\trepoList?: Handler;\n\trepoRead?: Handler;\n\trepoWrite?: Handler;\n\trepoInsert?: Handler;\n\trepoAddDependency?: Handler;\n\trepoManifest?: Handler;\n\trepoInstall?: Handler;\n}\n\n/** The abaikit package root, where abaigram.yaml and the content live; the same from src/ and dist/. */\nexport const PACKAGE_ROOT = resolve(import.meta.dirname, \"..\");\n\nfunction notYet(name: string): Handler {\n\treturn () => {\n\t\tthrow new Error(`${name}: not yet implemented`);\n\t};\n}\n\nexport function createAbaikit(handlers: AbaikitHandlers = {}, extras: AbaigramExtras = {}): Abaigram {\n\treturn createAbaigram(\n\t\t{\n\t\t\tname: \"abaikit\",\n\t\t\tmodes: [\"turns\", \"sidecar\"],\n\t\t\t// no audit path of its own: a tool's audit belongs in the user's abai home, not in its install directory\n\t\t\tcontent: { use: \"abai/use.md\" },\n\t\t\t// run in the package root, where the check example below resolves\n\t\t\tcheck: { run: \"node dist/bin.js check examples/hello\" },\n\t\t\tcells: {\n\t\t\t\t\"check.runs\": { type: \"int\", access: \"read\", doc: \"Conformance checks run by this process.\" },\n\t\t\t\t\"check.last_level\": { type: \"int\", access: \"read\", doc: \"The level the last check reported, 0 to 4.\" },\n\t\t\t\t\"abaify.max_rounds\": {\n\t\t\t\t\ttype: \"int\",\n\t\t\t\t\taccess: \"readwrite\",\n\t\t\t\t\tdefault: 5,\n\t\t\t\t\trange: [1, 20],\n\t\t\t\t\tdoc: \"Agent rounds abaify gives a retrofit before it stops.\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tevents: {\n\t\t\t\t\"check.completed\": {\n\t\t\t\t\tpayload: { repo: { type: \"string\", max: 512 }, level: { type: \"int\" } },\n\t\t\t\t\twakes: \"never\",\n\t\t\t\t\tdoc: \"A conformance check finished.\",\n\t\t\t\t},\n\t\t\t\t\"repo.changed\": {\n\t\t\t\t\tpayload: { path: { type: \"string\", max: 512 }, how: { type: \"string\", max: 32 } },\n\t\t\t\t\twakes: \"never\",\n\t\t\t\t\tdoc: \"abaify changed the repository: wrote a file, inserted lines, added a dependency, regenerated the manifest, or installed.\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tcapabilities: {\n\t\t\t\tlearnabai: {\n\t\t\t\t\tparams: { section: \"string\" },\n\t\t\t\t\tresult: { text: \"string\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"read\",\n\t\t\t\t\texample: {},\n\t\t\t\t\tdoc: \"The guide for an agent: what an abaigram is, how to declare one in TypeScript, how to retrofit a repository, how check judges it; one section or all.\",\n\t\t\t\t\thandler: handlers.learnabai ?? notYet(\"learnabai\"),\n\t\t\t\t},\n\t\t\t\tcheck: {\n\t\t\t\t\tparams: { repo: \"string\", level: \"int\", mode: \"string\", entry: \"string\", runs: \"int\" },\n\t\t\t\t\tresult: { level: \"int\", passed: \"bool\", report: \"string\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"auto\",\n\t\t\t\t\ttimeout: \"1800s\",\n\t\t\t\t\t// relative to the working directory: the package root, where abaikit's own check.run runs\n\t\t\t\t\texample: { repo: \"examples/hello\" },\n\t\t\t\t\tdoc: \"Verify a repository's conformance (section 12): L1 through its entry, L2 to L4 by running the repository's check.run command under the null harness, an exercise run and the measurement runs per mode. Needs no model; may take minutes.\",\n\t\t\t\t\thandler: handlers.check ?? notYet(\"check\"),\n\t\t\t\t},\n\t\t\t\tnew: {\n\t\t\t\t\tparams: { name: \"string\", lang: \"string\", level: \"int\", dir: \"string\" },\n\t\t\t\t\tresult: { path: \"string\", written: \"int\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"confirm\",\n\t\t\t\t\tdoc: \"Create a fresh abaigram in a language, at a level, with one example of each declaration and the content slots in place.\",\n\t\t\t\t\thandler: handlers.new ?? notYet(\"new\"),\n\t\t\t\t},\n\t\t\t\t\"repo.list\": {\n\t\t\t\t\tparams: { repo: \"string\", glob: \"string\" },\n\t\t\t\t\tresult: { count: \"int\", listing: \"string\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"read\",\n\t\t\t\t\texample: { repo: \"examples/hello\" },\n\t\t\t\t\tdoc: \"List a repository's files, skipping dependencies, build output and ignored trees; bounded, and the bound is said first. glob narrows: *.json by name anywhere, src/** or scripts/*.mjs by path.\",\n\t\t\t\t\thandler: handlers.repoList ?? notYet(\"repo.list\"),\n\t\t\t\t},\n\t\t\t\t\"repo.read\": {\n\t\t\t\t\tparams: { repo: \"string\", path: \"string\", start: \"int\", lines: \"int\" },\n\t\t\t\t\tresult: { text: \"string\", total_lines: \"int\", from: \"int\", to: \"int\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"read\",\n\t\t\t\t\texample: { repo: \"examples/hello\", path: \"abaigram.yaml\" },\n\t\t\t\t\tdoc: \"Read part of a file in a repository: a window from line start, 400 lines or 12 KB at most a call; the result says from and to.\",\n\t\t\t\t\thandler: handlers.repoRead ?? notYet(\"repo.read\"),\n\t\t\t\t},\n\t\t\t\t\"repo.write\": {\n\t\t\t\t\tparams: { repo: \"string\", path: \"string\", content: \"string\", why: \"string\" },\n\t\t\t\t\tresult: { written: \"bool\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"confirm\",\n\t\t\t\t\tdoc: \"Write a new file in a repository (any directory this process can reach; under an MCP client each call is the client's permission prompt); an existing file is refused, since abaify adds and never replaces.\",\n\t\t\t\t\thandler: handlers.repoWrite ?? notYet(\"repo.write\"),\n\t\t\t\t},\n\t\t\t\t\"repo.insert\": {\n\t\t\t\t\tparams: {\n\t\t\t\t\t\trepo: \"string\",\n\t\t\t\t\t\tpath: \"string\",\n\t\t\t\t\t\tanchor: \"string\",\n\t\t\t\t\t\twhere: \"string\",\n\t\t\t\t\t\ttext: \"string\",\n\t\t\t\t\t\twhy: \"string\",\n\t\t\t\t\t},\n\t\t\t\t\tresult: { line: \"int\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"confirm\",\n\t\t\t\t\tdoc: \"Insert text before or after a unique anchor line in an existing file of a repository; no line the file had is removed or reordered.\",\n\t\t\t\t\thandler: handlers.repoInsert ?? notYet(\"repo.insert\"),\n\t\t\t\t},\n\t\t\t\t\"repo.add_dependency\": {\n\t\t\t\t\tparams: { repo: \"string\", name: \"string\", spec: \"string\", why: \"string\" },\n\t\t\t\t\tresult: { spec: \"string\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"confirm\",\n\t\t\t\t\tdoc: \"Add a dependency to the repository's package.json in sorted place (the file is re-serialized, keys and indentation kept); the spec defaults to how abaikit reaches @abaigram/abai-stub, @abaigram/abai-embedded-harness and @abaigram/abaikit.\",\n\t\t\t\t\thandler: handlers.repoAddDependency ?? notYet(\"repo.add_dependency\"),\n\t\t\t\t},\n\t\t\t\t\"repo.manifest\": {\n\t\t\t\t\tparams: { repo: \"string\", entry: \"string\", why: \"string\" },\n\t\t\t\t\tresult: { written: \"bool\", lines: \"int\", text: \"string\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"confirm\",\n\t\t\t\t\ttimeout: \"90s\",\n\t\t\t\t\tdoc: \"Run the repository's entry (`<entry> manifest`) and write what it prints to abaigram.yaml, the one file never written by hand.\",\n\t\t\t\t\thandler: handlers.repoManifest ?? notYet(\"repo.manifest\"),\n\t\t\t\t},\n\t\t\t\t\"repo.install\": {\n\t\t\t\t\tparams: { repo: \"string\", why: \"string\" },\n\t\t\t\t\tresult: { ok: \"bool\", output: \"string\" },\n\t\t\t\t\tdispatch: \"immediate\",\n\t\t\t\t\teffect: \"mutate\",\n\t\t\t\t\tpolicy: \"confirm\",\n\t\t\t\t\ttimeout: \"660s\",\n\t\t\t\t\tdoc: \"Run npm install in the repository (network; the repository's own install scripts run; the lock file and node_modules are rewritten), so the dependencies just added resolve.\",\n\t\t\t\t\thandler: handlers.repoInstall ?? notYet(\"repo.install\"),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{ root: PACKAGE_ROOT, ...extras },\n\t);\n}\n"]}
package/dist/app.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ import type { Embedded, EmbeddedOptions } from "@abaigram/abai-embedded-harness";
2
+ import type { Abaigram } from "@abaigram/abai-stub";
3
+ import type { AbaikitIo } from "./io.ts";
4
+ import { type Change, type RepoContext } from "./repo.ts";
5
+ export interface Embedding {
6
+ /** What the next attach passes to `attachEmbedded`, beyond the environment. */
7
+ options: EmbeddedOptions;
8
+ /** The harness and form of the current attach, once there is one. */
9
+ current: Embedded | undefined;
10
+ }
11
+ export interface AbaikitApp {
12
+ app: Abaigram;
13
+ embedding: Embedding;
14
+ /** Every change the repo.* capabilities made in this process, for a report. */
15
+ changes: Change[];
16
+ repo: RepoContext;
17
+ }
18
+ export declare function createApp(io: AbaikitIo): AbaikitApp;
19
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGzC,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,WAAW,EAAgB,MAAM,WAAW,CAAC;AAExE,MAAM,WAAW,SAAS;IACzB,+EAA+E;IAC/E,OAAO,EAAE,eAAe,CAAC;IACzB,qEAAqE;IACrE,OAAO,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IAC1B,GAAG,EAAE,QAAQ,CAAC;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,+EAA+E;IAC/E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;CAClB;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,SAAS,GAAG,UAAU,CAkBnD","sourcesContent":["// abaikit's own abaigram, built once for a run of the binary, whichever verb\n// runs (section 13: main hands control to the harness at once), with every\n// capability bound: learnabai, new, check and the repo.* set. Its in-process\n// harness is attached through a factory whose options a verb may set before\n// attaching, which is how abaify gives its agent auto consent and its own\n// channel; the harness package is loaded only when an attach happens.\n\nimport type { Embedded, EmbeddedOptions } from \"@abaigram/abai-embedded-harness\";\nimport type { Abaigram } from \"@abaigram/abai-stub\";\nimport { createAbaikit } from \"./abaigram.ts\";\nimport { checkHandler } from \"./check.ts\";\nimport type { AbaikitIo } from \"./io.ts\";\nimport { learnabaiHandler } from \"./learnabai.ts\";\nimport { newHandler } from \"./new.ts\";\nimport { type Change, type RepoContext, repoHandlers } from \"./repo.ts\";\n\nexport interface Embedding {\n\t/** What the next attach passes to `attachEmbedded`, beyond the environment. */\n\toptions: EmbeddedOptions;\n\t/** The harness and form of the current attach, once there is one. */\n\tcurrent: Embedded | undefined;\n}\n\nexport interface AbaikitApp {\n\tapp: Abaigram;\n\tembedding: Embedding;\n\t/** Every change the repo.* capabilities made in this process, for a report. */\n\tchanges: Change[];\n\trepo: RepoContext;\n}\n\nexport function createApp(io: AbaikitIo): AbaikitApp {\n\tconst embedding: Embedding = { options: {}, current: undefined };\n\tconst changes: Change[] = [];\n\tconst app = createAbaikit(\n\t\t{ learnabai: learnabaiHandler, new: newHandler(io) },\n\t\t{\n\t\t\tenv: io.env,\n\t\t\tharness: async (binding) => {\n\t\t\t\tconst { attachEmbedded } = await import(\"@abaigram/abai-embedded-harness\");\n\t\t\t\tembedding.current = await attachEmbedded(binding, { env: io.env, ...embedding.options });\n\t\t\t},\n\t\t},\n\t);\n\t// check and the repo.* capabilities report into the abaigram itself, so they are bound after it exists\n\tapp.capability(\"check\", checkHandler(app, io));\n\tconst repo: RepoContext = { cwd: io.cwd, env: io.env, app, changes, created: new Set() };\n\tfor (const [name, handler] of Object.entries(repoHandlers(repo))) app.capability(name, handler);\n\treturn { app, embedding, changes, repo };\n}\n"]}
package/dist/app.js ADDED
@@ -0,0 +1,29 @@
1
+ // abaikit's own abaigram, built once for a run of the binary, whichever verb
2
+ // runs (section 13: main hands control to the harness at once), with every
3
+ // capability bound: learnabai, new, check and the repo.* set. Its in-process
4
+ // harness is attached through a factory whose options a verb may set before
5
+ // attaching, which is how abaify gives its agent auto consent and its own
6
+ // channel; the harness package is loaded only when an attach happens.
7
+ import { createAbaikit } from "./abaigram.js";
8
+ import { checkHandler } from "./check.js";
9
+ import { learnabaiHandler } from "./learnabai.js";
10
+ import { newHandler } from "./new.js";
11
+ import { repoHandlers } from "./repo.js";
12
+ export function createApp(io) {
13
+ const embedding = { options: {}, current: undefined };
14
+ const changes = [];
15
+ const app = createAbaikit({ learnabai: learnabaiHandler, new: newHandler(io) }, {
16
+ env: io.env,
17
+ harness: async (binding) => {
18
+ const { attachEmbedded } = await import("@abaigram/abai-embedded-harness");
19
+ embedding.current = await attachEmbedded(binding, { env: io.env, ...embedding.options });
20
+ },
21
+ });
22
+ // check and the repo.* capabilities report into the abaigram itself, so they are bound after it exists
23
+ app.capability("check", checkHandler(app, io));
24
+ const repo = { cwd: io.cwd, env: io.env, app, changes, created: new Set() };
25
+ for (const [name, handler] of Object.entries(repoHandlers(repo)))
26
+ app.capability(name, handler);
27
+ return { app, embedding, changes, repo };
28
+ }
29
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,2EAA2E;AAC3E,6EAA6E;AAC7E,4EAA4E;AAC5E,0EAA0E;AAC1E,sEAAsE;AAItE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAiC,YAAY,EAAE,MAAM,WAAW,CAAC;AAiBxE,MAAM,UAAU,SAAS,CAAC,EAAa,EAAc;IACpD,MAAM,SAAS,GAAc,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IACjE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,aAAa,CACxB,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE,EACpD;QACC,GAAG,EAAE,EAAE,CAAC,GAAG;QACX,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC;YAC3B,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAC;YAC3E,SAAS,CAAC,OAAO,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;QAAA,CACzF;KACD,CACD,CAAC;IACF,uGAAuG;IACvG,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAgB,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;IACzF,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAAE,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChG,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAAA,CACzC","sourcesContent":["// abaikit's own abaigram, built once for a run of the binary, whichever verb\n// runs (section 13: main hands control to the harness at once), with every\n// capability bound: learnabai, new, check and the repo.* set. Its in-process\n// harness is attached through a factory whose options a verb may set before\n// attaching, which is how abaify gives its agent auto consent and its own\n// channel; the harness package is loaded only when an attach happens.\n\nimport type { Embedded, EmbeddedOptions } from \"@abaigram/abai-embedded-harness\";\nimport type { Abaigram } from \"@abaigram/abai-stub\";\nimport { createAbaikit } from \"./abaigram.ts\";\nimport { checkHandler } from \"./check.ts\";\nimport type { AbaikitIo } from \"./io.ts\";\nimport { learnabaiHandler } from \"./learnabai.ts\";\nimport { newHandler } from \"./new.ts\";\nimport { type Change, type RepoContext, repoHandlers } from \"./repo.ts\";\n\nexport interface Embedding {\n\t/** What the next attach passes to `attachEmbedded`, beyond the environment. */\n\toptions: EmbeddedOptions;\n\t/** The harness and form of the current attach, once there is one. */\n\tcurrent: Embedded | undefined;\n}\n\nexport interface AbaikitApp {\n\tapp: Abaigram;\n\tembedding: Embedding;\n\t/** Every change the repo.* capabilities made in this process, for a report. */\n\tchanges: Change[];\n\trepo: RepoContext;\n}\n\nexport function createApp(io: AbaikitIo): AbaikitApp {\n\tconst embedding: Embedding = { options: {}, current: undefined };\n\tconst changes: Change[] = [];\n\tconst app = createAbaikit(\n\t\t{ learnabai: learnabaiHandler, new: newHandler(io) },\n\t\t{\n\t\t\tenv: io.env,\n\t\t\tharness: async (binding) => {\n\t\t\t\tconst { attachEmbedded } = await import(\"@abaigram/abai-embedded-harness\");\n\t\t\t\tembedding.current = await attachEmbedded(binding, { env: io.env, ...embedding.options });\n\t\t\t},\n\t\t},\n\t);\n\t// check and the repo.* capabilities report into the abaigram itself, so they are bound after it exists\n\tapp.capability(\"check\", checkHandler(app, io));\n\tconst repo: RepoContext = { cwd: io.cwd, env: io.env, app, changes, created: new Set() };\n\tfor (const [name, handler] of Object.entries(repoHandlers(repo))) app.capability(name, handler);\n\treturn { app, embedding, changes, repo };\n}\n"]}
package/dist/bin.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ import { type Mode } from "@abaigram/abai-stub";
3
+ import { type AbaikitIo } from "./io.ts";
4
+ export { type AbaikitIo, processIo, UsageError } from "./io.ts";
5
+ export type { Mode };
6
+ export type ParsedArgs = {
7
+ verb: "help";
8
+ } | {
9
+ verb: "learnabai";
10
+ section?: string;
11
+ json: boolean;
12
+ skill: boolean;
13
+ skillDir?: string;
14
+ } | {
15
+ verb: "check";
16
+ repo: string;
17
+ level?: number;
18
+ mode?: Mode;
19
+ entry?: string;
20
+ runs?: number;
21
+ timeoutS?: number;
22
+ json: boolean;
23
+ } | {
24
+ verb: "new";
25
+ name: string;
26
+ lang: "ts";
27
+ level?: number;
28
+ dir?: string;
29
+ abaiImport?: string;
30
+ } | {
31
+ verb: "abaify";
32
+ repo: string;
33
+ level?: number;
34
+ mode?: Mode;
35
+ rounds?: number;
36
+ dryRun: boolean;
37
+ } | {
38
+ verb: "run";
39
+ repo: string;
40
+ args: string[];
41
+ };
42
+ export type Verb = ParsedArgs["verb"];
43
+ export declare function parseArgs(argv: string[]): ParsedArgs;
44
+ /** The binary's entry; resolves to the exit code and never throws. */
45
+ export declare function main(argv: string[], io?: AbaikitIo): Promise<number>;
46
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAQA,OAAO,EAAE,KAAK,IAAI,EAAY,MAAM,qBAAqB,CAAC;AAI1D,OAAO,EAAE,KAAK,SAAS,EAAuC,MAAM,SAAS,CAAC;AAK9E,OAAO,EAAE,KAAK,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEhE,YAAY,EAAE,IAAI,EAAE,CAAC;AAErB,MAAM,MAAM,UAAU,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACzF;IACA,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;CACb,GACD;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5F;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC/F;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEjD,MAAM,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;AAuFtC,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAyFpD;AAED,sEAAsE;AACtE,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,SAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkDrF","sourcesContent":["#!/usr/bin/env node\n// The abaikit binary: learnabai prints the guide, check verifies a\n// repository's conformance, new creates a fresh abaigram, abaify retrofits\n// an existing repository, and run starts a repository's program with an\n// agent attached. `abaikit abai ...` is abaikit's own standard agent entry,\n// served by the stub, since abaikit is itself an abaigram.\nimport { realpathSync } from \"node:fs\";\nimport { pathToFileURL } from \"node:url\";\nimport { type Mode, runEntry } from \"@abaigram/abai-stub\";\nimport { runAbaify } from \"./abaify.ts\";\nimport { type AbaikitApp, createApp } from \"./app.ts\";\nimport { runCheck } from \"./check.ts\";\nimport { type AbaikitIo, errorMessage, processIo, UsageError } from \"./io.ts\";\nimport { runLearnabai } from \"./learnabai.ts\";\nimport { runNew } from \"./new.ts\";\nimport { runRun } from \"./run.ts\";\n\nexport { type AbaikitIo, processIo, UsageError } from \"./io.ts\";\n\nexport type { Mode };\n\nexport type ParsedArgs =\n\t| { verb: \"help\" }\n\t| { verb: \"learnabai\"; section?: string; json: boolean; skill: boolean; skillDir?: string }\n\t| {\n\t\t\tverb: \"check\";\n\t\t\trepo: string;\n\t\t\tlevel?: number;\n\t\t\tmode?: Mode;\n\t\t\tentry?: string;\n\t\t\truns?: number;\n\t\t\ttimeoutS?: number;\n\t\t\tjson: boolean;\n\t }\n\t| { verb: \"new\"; name: string; lang: \"ts\"; level?: number; dir?: string; abaiImport?: string }\n\t| { verb: \"abaify\"; repo: string; level?: number; mode?: Mode; rounds?: number; dryRun: boolean }\n\t| { verb: \"run\"; repo: string; args: string[] };\n\nexport type Verb = ParsedArgs[\"verb\"];\n\nconst USAGE = [\n\t\"usage: abaikit learnabai|check|new|abaify|run ...\",\n\t\" abaikit learnabai [--section <name>] [--json] [--skill] [--skill-dir <dir>]\",\n\t\" abaikit check <repo> [--level <1-4>] [--mode <turns|thread|sidecar>] [--entry <cmd>] [--runs <n>] [--timeout <seconds>] [--json]\",\n\t\" abaikit new <name> --lang <ts> [--level <1-4>] [--dir <dir>]\",\n\t\" abaikit abaify <repo> [--level <1-4>] [--mode <turns|thread|sidecar>] [--rounds <n>] [--dry-run]\",\n\t\" abaikit run <repo> [--] ARGS\",\n\t\" abaikit abai ... the standard agent entry (session, install, manifest, doctor, config, mcp, run)\",\n\t\"\",\n\t\"learnabai prints the guide for an agent; check verifies a repository's conformance and needs no model;\",\n\t\"new creates a fresh abaigram; abaify retrofits an existing repository, adding and never removing;\",\n\t\"run starts the repository's program with everything after -- as its arguments.\",\n];\n\ntype FlagKind = \"bool\" | \"string\" | \"int\" | \"level\" | \"mode\";\n\nfunction positiveInt(value: string, flag: string): number {\n\tconst n = Number(value);\n\tif (!Number.isInteger(n) || n <= 0) throw new UsageError(`${flag} needs a positive integer`);\n\treturn n;\n}\n\n/** The verb's flags and positionals; a flag missing its value, an unknown flag or a stray argument is a usage error. */\nfunction scan(\n\tverb: string,\n\targv: string[],\n\tkinds: Record<string, FlagKind>,\n): { positionals: string[]; values: Record<string, string | number | boolean> } {\n\tconst positionals: string[] = [];\n\tconst values: Record<string, string | number | boolean> = {};\n\tfor (let i = 0; i < argv.length; i++) {\n\t\tconst raw = argv[i];\n\t\tif (raw === \"--\") throw new UsageError(`${verb} takes no program command`);\n\t\tif (!raw.startsWith(\"-\")) {\n\t\t\tpositionals.push(raw);\n\t\t\tcontinue;\n\t\t}\n\t\t// `--flag value` and `--flag=value`, as the stub's entry accepts them\n\t\tconst eq = raw.indexOf(\"=\");\n\t\tconst arg = eq === -1 ? raw : raw.slice(0, eq);\n\t\tconst kind = kinds[arg];\n\t\tif (kind === undefined) throw new UsageError(`unknown argument ${arg}`);\n\t\tif (kind === \"bool\") {\n\t\t\tif (eq !== -1) throw new UsageError(`${arg} takes no value`);\n\t\t\tvalues[arg] = true;\n\t\t\tcontinue;\n\t\t}\n\t\tlet value: string | undefined;\n\t\tif (eq !== -1) value = raw.slice(eq + 1);\n\t\telse {\n\t\t\tvalue = argv[i + 1];\n\t\t\tif (value === undefined || value.startsWith(\"--\")) throw new UsageError(`${arg} needs a value`);\n\t\t\ti += 1;\n\t\t}\n\t\tif (value === \"\") throw new UsageError(`${arg} needs a value`);\n\t\tswitch (kind) {\n\t\t\tcase \"string\":\n\t\t\t\tvalues[arg] = value;\n\t\t\t\tbreak;\n\t\t\tcase \"int\":\n\t\t\t\tvalues[arg] = positiveInt(value, arg);\n\t\t\t\tbreak;\n\t\t\tcase \"level\": {\n\t\t\t\tconst n = Number(value);\n\t\t\t\tif (!Number.isInteger(n) || n < 1 || n > 4) throw new UsageError(`${arg} needs a level from 1 to 4`);\n\t\t\t\tvalues[arg] = n;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"mode\":\n\t\t\t\tif (value !== \"turns\" && value !== \"thread\" && value !== \"sidecar\")\n\t\t\t\t\tthrow new UsageError(`${arg} needs turns, thread or sidecar`);\n\t\t\t\tvalues[arg] = value;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\treturn { positionals, values };\n}\n\n/** Exactly one positional, named `what` in the error. */\nfunction one(verb: string, positionals: string[], what: string): string {\n\tif (positionals.length === 0) throw new UsageError(`${verb} needs ${what}`);\n\tif (positionals.length > 1) throw new UsageError(`unexpected argument ${positionals[1]}`);\n\treturn positionals[0];\n}\n\nexport function parseArgs(argv: string[]): ParsedArgs {\n\tconst verb = argv[0];\n\tif (verb === undefined || verb === \"help\" || verb === \"--help\" || verb === \"-h\") return { verb: \"help\" };\n\tconst rest = argv.slice(1);\n\tswitch (verb) {\n\t\tcase \"learnabai\": {\n\t\t\tconst { positionals, values } = scan(verb, rest, {\n\t\t\t\t\"--section\": \"string\",\n\t\t\t\t\"--json\": \"bool\",\n\t\t\t\t\"--skill\": \"bool\",\n\t\t\t\t\"--skill-dir\": \"string\",\n\t\t\t});\n\t\t\tif (positionals.length > 0) throw new UsageError(`unexpected argument ${positionals[0]}`);\n\t\t\tif (values[\"--skill-dir\"] !== undefined && values[\"--skill\"] !== true)\n\t\t\t\tthrow new UsageError(\"--skill-dir goes with --skill\");\n\t\t\treturn {\n\t\t\t\tverb,\n\t\t\t\tsection: values[\"--section\"] as string | undefined,\n\t\t\t\tjson: values[\"--json\"] === true,\n\t\t\t\tskill: values[\"--skill\"] === true,\n\t\t\t\tskillDir: values[\"--skill-dir\"] as string | undefined,\n\t\t\t};\n\t\t}\n\t\tcase \"check\": {\n\t\t\tconst { positionals, values } = scan(verb, rest, {\n\t\t\t\t\"--level\": \"level\",\n\t\t\t\t\"--mode\": \"mode\",\n\t\t\t\t\"--entry\": \"string\",\n\t\t\t\t\"--runs\": \"int\",\n\t\t\t\t\"--timeout\": \"int\",\n\t\t\t\t\"--json\": \"bool\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tverb,\n\t\t\t\trepo: one(verb, positionals, \"a repository\"),\n\t\t\t\tlevel: values[\"--level\"] as number | undefined,\n\t\t\t\tmode: values[\"--mode\"] as Mode | undefined,\n\t\t\t\tentry: values[\"--entry\"] as string | undefined,\n\t\t\t\truns: values[\"--runs\"] as number | undefined,\n\t\t\t\ttimeoutS: values[\"--timeout\"] as number | undefined,\n\t\t\t\tjson: values[\"--json\"] === true,\n\t\t\t};\n\t\t}\n\t\tcase \"new\": {\n\t\t\tconst { positionals, values } = scan(verb, rest, {\n\t\t\t\t\"--lang\": \"string\",\n\t\t\t\t\"--level\": \"level\",\n\t\t\t\t\"--dir\": \"string\",\n\t\t\t\t\"--abai-import\": \"string\",\n\t\t\t});\n\t\t\tconst name = one(verb, positionals, \"a name\");\n\t\t\tconst lang = values[\"--lang\"];\n\t\t\tif (lang === undefined) throw new UsageError(\"new needs --lang <ts>\");\n\t\t\tif (lang !== \"ts\") throw new UsageError(`unknown language ${lang}; only ts is supported`);\n\t\t\treturn {\n\t\t\t\tverb,\n\t\t\t\tname,\n\t\t\t\tlang,\n\t\t\t\tlevel: values[\"--level\"] as number | undefined,\n\t\t\t\tdir: values[\"--dir\"] as string | undefined,\n\t\t\t\tabaiImport: values[\"--abai-import\"] as string | undefined,\n\t\t\t};\n\t\t}\n\t\tcase \"abaify\": {\n\t\t\tconst { positionals, values } = scan(verb, rest, {\n\t\t\t\t\"--level\": \"level\",\n\t\t\t\t\"--mode\": \"mode\",\n\t\t\t\t\"--rounds\": \"int\",\n\t\t\t\t\"--dry-run\": \"bool\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tverb,\n\t\t\t\trepo: one(verb, positionals, \"a repository\"),\n\t\t\t\tlevel: values[\"--level\"] as number | undefined,\n\t\t\t\tmode: values[\"--mode\"] as Mode | undefined,\n\t\t\t\trounds: values[\"--rounds\"] as number | undefined,\n\t\t\t\tdryRun: values[\"--dry-run\"] === true,\n\t\t\t};\n\t\t}\n\t\tcase \"run\": {\n\t\t\t// the repository, then the program's arguments; `--` before them is allowed, as in the stub's own run\n\t\t\tconst repo = rest[0];\n\t\t\tif (repo === undefined || repo.startsWith(\"-\")) throw new UsageError(\"run needs a repository\");\n\t\t\tconst after = rest.slice(1);\n\t\t\treturn { verb, repo, args: after[0] === \"--\" ? after.slice(1) : after };\n\t\t}\n\t\tdefault:\n\t\t\tthrow new UsageError(`unknown verb ${verb}`);\n\t}\n}\n\n/** The binary's entry; resolves to the exit code and never throws. */\nexport async function main(argv: string[], io: AbaikitIo = processIo): Promise<number> {\n\t// abaikit is an abaigram, built before anything else so its own entry, its null harness under check runs and\n\t// its capabilities are there whichever verb runs (section 13: main hands control to the harness at once)\n\tlet bundle: AbaikitApp;\n\ttry {\n\t\tbundle = createApp(io);\n\t} catch (error) {\n\t\tio.err(`abaikit: ${errorMessage(error)}`);\n\t\treturn 1;\n\t}\n\tconst { app } = bundle;\n\ttry {\n\t\tconst code = await runEntry(app, argv, io);\n\t\tif (code >= 0) return code;\n\t} catch (error) {\n\t\tio.err(`abaikit abai: ${errorMessage(error)}`);\n\t\treturn 1;\n\t}\n\tlet parsed: ParsedArgs;\n\ttry {\n\t\tparsed = parseArgs(argv);\n\t} catch (error) {\n\t\tio.err(`abaikit: ${errorMessage(error)}`);\n\t\tfor (const line of USAGE) io.err(line);\n\t\treturn 2;\n\t}\n\ttry {\n\t\tswitch (parsed.verb) {\n\t\t\tcase \"help\":\n\t\t\t\tfor (const line of USAGE) io.out(`${line}\\n`);\n\t\t\t\treturn 0;\n\t\t\tcase \"learnabai\":\n\t\t\t\treturn await runLearnabai(parsed, io);\n\t\t\tcase \"check\":\n\t\t\t\treturn await runCheck(parsed, io, app);\n\t\t\tcase \"new\":\n\t\t\t\treturn await runNew(parsed, io);\n\t\t\tcase \"abaify\":\n\t\t\t\treturn await runAbaify(parsed, io, bundle);\n\t\t\tcase \"run\":\n\t\t\t\treturn await runRun(parsed, io);\n\t\t}\n\t} catch (error) {\n\t\tif (error instanceof UsageError) {\n\t\t\tio.err(`abaikit: ${error.message}`);\n\t\t\treturn 2;\n\t\t}\n\t\tio.err(`abaikit ${parsed.verb}: ${errorMessage(error)}`);\n\t\treturn 1;\n\t}\n}\n\n/** Whether this module is the process's entry: by its real path, so a relative path or npm's bin symlink both count. */\nfunction isEntry(): boolean {\n\tconst entry = process.argv[1];\n\tif (entry === undefined) return false;\n\ttry {\n\t\treturn import.meta.url === pathToFileURL(realpathSync(entry)).href;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nif (isEntry()) {\n\tmain(process.argv.slice(2)).then((code) => {\n\t\tprocess.exitCode = code;\n\t});\n}\n"]}