@vaka.world/cli 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.
- package/README.md +10 -3
- package/dist/index.js +197 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,13 +21,20 @@ npx @vaka.world/cli init
|
|
|
21
21
|
## Commands
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
vaka init # detect your AI coding tool(s)
|
|
25
|
-
vaka start # walk through the Build → Design → Implementation checkpoints
|
|
26
|
-
vaka status # check where you are without answering anything
|
|
24
|
+
vaka init # detect your AI coding tool(s), add Vaka's guidance + rules, and install the Claude Code/Codex skill
|
|
25
|
+
vaka start # terminal wizard: walk through the Build → Design → Implementation checkpoints yourself
|
|
26
|
+
vaka status # check where you are without answering anything (add --json for machine-readable output)
|
|
27
|
+
vaka log ... # headless event recording an AI assistant uses to record a checkpoint it conducted itself
|
|
27
28
|
```
|
|
28
29
|
|
|
29
30
|
Sessions are local and labeled `unverified` - nothing leaves your machine.
|
|
30
31
|
|
|
32
|
+
## The default experience: checkpoints inline in Claude Code / Codex
|
|
33
|
+
|
|
34
|
+
`vaka init` installs a skill (`.claude/skills/vaka/` and `.agents/skills/vaka/`) that Claude Code and Codex pick up automatically — no extra install step. Once it's there, just describe the feature you want built, the same way you always would. The assistant itself asks the Build/Design/Implementation checkpoint questions inline, specific to what you're actually building, instead of a fixed script — and still records every question, answer, and confirmation into the same local, tamper-evident chain that `vaka start` uses, via the `vaka log` command running quietly in the background.
|
|
35
|
+
|
|
36
|
+
`vaka start`'s terminal wizard (fixed question bank, `@clack/prompts`) still exists as a fallback for contexts with no AI assistant present — a plain terminal, CI, or a tool without Skill support.
|
|
37
|
+
|
|
31
38
|
## Supported coding agents & IDEs
|
|
32
39
|
|
|
33
40
|
Cursor, Claude Code, GitHub Copilot, OpenAI Codex, Windsurf, Cline.
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Command } from "commander";
|
|
|
5
5
|
import { cancel, confirm, intro, isCancel, log, outro, text } from "@clack/prompts";
|
|
6
6
|
|
|
7
7
|
// src/commands/init.ts
|
|
8
|
-
import { lstat, mkdir, readFile, rename, unlink, writeFile } from "fs/promises";
|
|
8
|
+
import { lstat, mkdir, readdir, readFile, rename, unlink, writeFile } from "fs/promises";
|
|
9
9
|
import { basename, dirname, isAbsolute, join, relative, resolve } from "path";
|
|
10
10
|
var rules = `version: 1
|
|
11
11
|
checkpoints:
|
|
@@ -23,6 +23,66 @@ var managedEnd = "<!-- END VAKA MANAGED INSTRUCTIONS -->";
|
|
|
23
23
|
var sharedGuidance = `Before implementing a feature, help the developer reason through its behavior, data, and failure cases. Keep understanding, design confirmation, and implementation authorization distinct. Do not write code until the developer explicitly authorizes the scoped implementation; design confirmation alone is not implementation approval. Explain unfamiliar code and why each change is needed.
|
|
24
24
|
|
|
25
25
|
Vaka instructions are guidance, not a technical enforcement boundary. Local session files are unverified; only a server-accepted seal can be described as server-verified.`;
|
|
26
|
+
var vakaSkillBody = `This project uses Vaka to make sure a developer reasons through a feature before code gets written, and to keep a local, tamper-evident record that they did. You generate the actual checkpoint questions yourself, specific to what's being built \u2014 there is no fixed script to recite.
|
|
27
|
+
|
|
28
|
+
## Check where things stand
|
|
29
|
+
|
|
30
|
+
Before doing anything else for a build request, run \`vaka status --json\` from the project root. It tells you whether a session already exists, how many cycles have completed, and which checkpoint (\`build\`, \`design\`, or \`implementation\`) comes next \u2014 including whether a checkpoint was turned off in \`.vaka/rules.yml\` and should be skipped entirely. Only engage a checkpoint \`vaka status --json\` says is actually next; if a checkpoint is off, don't ask for it.
|
|
31
|
+
|
|
32
|
+
## Build checkpoint \u2014 make them reason, don't accept a shrug
|
|
33
|
+
|
|
34
|
+
Ask a question specific to what they just described: the actual data involved, who/what talks to what, a concrete failure case that could bite this exact feature \u2014 not a generic template. One well-aimed question can be enough; something more involved may need several. This has to stay free-text: never offer multiple-choice options here, and never let a non-answer pass.
|
|
35
|
+
|
|
36
|
+
- Before asking, record the question: \`vaka log question --checkpoint build --prompt "<exact question>"\` \u2014 it prints a question id; keep it.
|
|
37
|
+
- Ask the question in chat and wait for a real answer.
|
|
38
|
+
- If they answer "not sure," "whatever you think," or anything else that isn't actual reasoning, say so plainly and ask again, pointing at the specific thing you need them to think through. Don't supply the answer yourself, and don't move on until they've reasoned about it, even briefly \u2014 accepting a non-answer defeats the point of this checkpoint.
|
|
39
|
+
- Once they've given a real answer, record it: \`vaka log answer --checkpoint build --question-id <id> --answer "<their answer, verbatim>"\`.
|
|
40
|
+
- Repeat for as many Build questions as the feature actually needs, then move to Design.
|
|
41
|
+
|
|
42
|
+
## Design checkpoint \u2014 confirm, don't just build
|
|
43
|
+
|
|
44
|
+
Summarize the design you now share (components, data shape, the key tradeoff) in 1-3 sentences, then offer two choices: **Confirm and continue** (this design is right, move on; no code yet) or **Discuss** (something needs clarifying first). Wait for an actual confirmation; don't treat silence or an unrelated reply as one.
|
|
45
|
+
|
|
46
|
+
On confirmation: \`vaka log design-confirmed\`.
|
|
47
|
+
|
|
48
|
+
## Implementation checkpoint \u2014 get explicit authorization before writing code
|
|
49
|
+
|
|
50
|
+
Describe exactly what you're about to change (files, the specific behavior, nothing broader than what was just designed). Offer **Implement this step** or **Discuss**. Do not write or edit any code for this feature before this step is confirmed.
|
|
51
|
+
|
|
52
|
+
On authorization: \`vaka log implementation-approved\`. Only then write the code.
|
|
53
|
+
|
|
54
|
+
## After implementing
|
|
55
|
+
|
|
56
|
+
Briefly explain what changed and why it matches what was agreed, including any tests added or run. Keep it proportional to the size of the change.
|
|
57
|
+
|
|
58
|
+
## Honesty
|
|
59
|
+
|
|
60
|
+
Never call a local Vaka record "verified" \u2014 say "recorded locally, unverified," matching what \`vaka status\` itself says. Don't soften or drop that distinction.`;
|
|
61
|
+
var vakaSkillDescription = "Use when the developer in this project describes a feature, change, or bug fix they want built. Walk them through Vaka's Build, Design, and Implementation reasoning checkpoints before writing code, with questions and confirmations generated from what they're actually building (not a fixed script), and record each step into the local Vaka audit trail with the `vaka log`/`vaka status` commands.";
|
|
62
|
+
var vakaSkills = {
|
|
63
|
+
claude: `---
|
|
64
|
+
name: vaka
|
|
65
|
+
description: ${vakaSkillDescription}
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
# Vaka reasoning checkpoints
|
|
69
|
+
|
|
70
|
+
${vakaSkillBody}
|
|
71
|
+
|
|
72
|
+
Use the \`AskUserQuestion\` tool for the Design and Implementation confirm/discuss choices \u2014 never for the Build checkpoint's reasoning question, which must stay free-text.
|
|
73
|
+
`,
|
|
74
|
+
codex: `---
|
|
75
|
+
name: vaka
|
|
76
|
+
description: ${vakaSkillDescription}
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
# Vaka reasoning checkpoints
|
|
80
|
+
|
|
81
|
+
${vakaSkillBody}
|
|
82
|
+
|
|
83
|
+
This is Codex, not Claude Code: there is no \`AskUserQuestion\` tool. For the Design and Implementation confirm/discuss choices, ask one plain-text question listing the options, then end your turn and wait for the reply. Everything else above applies as written.
|
|
84
|
+
`
|
|
85
|
+
};
|
|
26
86
|
var instructions = {
|
|
27
87
|
claude: `# Vaka
|
|
28
88
|
|
|
@@ -74,11 +134,17 @@ async function inspectPath(path) {
|
|
|
74
134
|
throw error;
|
|
75
135
|
}
|
|
76
136
|
}
|
|
137
|
+
async function hasPreExistingClaudeDirectoryMarker(projectRoot) {
|
|
138
|
+
const claudeDirectoryPath = join(projectRoot, ".claude");
|
|
139
|
+
if (await inspectPath(claudeDirectoryPath) !== "directory") return false;
|
|
140
|
+
const entries = await readdir(claudeDirectoryPath);
|
|
141
|
+
return entries.length === 0 || entries.some((entry) => entry !== "skills");
|
|
142
|
+
}
|
|
77
143
|
async function detectIntegrations(projectRoot) {
|
|
78
144
|
const [
|
|
79
145
|
cursor,
|
|
80
146
|
claudeManifest,
|
|
81
|
-
|
|
147
|
+
hasClaudeDirectoryMarker,
|
|
82
148
|
copilotManifest,
|
|
83
149
|
instructionsDirectory,
|
|
84
150
|
codexManifest,
|
|
@@ -89,7 +155,7 @@ async function detectIntegrations(projectRoot) {
|
|
|
89
155
|
] = await Promise.all([
|
|
90
156
|
inspectPath(join(projectRoot, ".cursor")),
|
|
91
157
|
inspectPath(join(projectRoot, "CLAUDE.md")),
|
|
92
|
-
|
|
158
|
+
hasPreExistingClaudeDirectoryMarker(projectRoot),
|
|
93
159
|
inspectPath(join(projectRoot, ".github", "copilot-instructions.md")),
|
|
94
160
|
inspectPath(join(projectRoot, ".github", "instructions")),
|
|
95
161
|
inspectPath(join(projectRoot, "AGENTS.md")),
|
|
@@ -100,7 +166,7 @@ async function detectIntegrations(projectRoot) {
|
|
|
100
166
|
]);
|
|
101
167
|
const integrations = [];
|
|
102
168
|
if (cursor === "directory") integrations.push("cursor");
|
|
103
|
-
if (claudeManifest === "file" ||
|
|
169
|
+
if (claudeManifest === "file" || hasClaudeDirectoryMarker) {
|
|
104
170
|
integrations.push("claude");
|
|
105
171
|
}
|
|
106
172
|
let copilotDetected = copilotManifest === "file" || instructionsDirectory === "directory";
|
|
@@ -258,7 +324,9 @@ async function initializeProject(projectPath) {
|
|
|
258
324
|
const integrations = await detectIntegrations(projectRoot);
|
|
259
325
|
const result = { integrations, created: [], updated: [], skipped: [] };
|
|
260
326
|
const ownFiles = [
|
|
261
|
-
{ relativePath: ".vaka/rules.yml", contents: rules }
|
|
327
|
+
{ relativePath: ".vaka/rules.yml", contents: rules },
|
|
328
|
+
{ relativePath: ".claude/skills/vaka/SKILL.md", contents: vakaSkills.claude },
|
|
329
|
+
{ relativePath: ".agents/skills/vaka/SKILL.md", contents: vakaSkills.codex }
|
|
262
330
|
];
|
|
263
331
|
if (integrations.includes("claude")) {
|
|
264
332
|
ownFiles.push({ relativePath: "CLAUDE.md", contents: instructions.claude });
|
|
@@ -621,6 +689,7 @@ function lastIndexOfType(events, type) {
|
|
|
621
689
|
}
|
|
622
690
|
return -1;
|
|
623
691
|
}
|
|
692
|
+
var FIXED_BANK_QUESTION_IDS = new Set(CHECKPOINT_QUESTIONS.map((question) => question.id));
|
|
624
693
|
function answeredQuestionIds(cycle, checkpoint) {
|
|
625
694
|
const answered = /* @__PURE__ */ new Set();
|
|
626
695
|
for (const event of cycle) {
|
|
@@ -635,6 +704,17 @@ function answeredQuestionIds(cycle, checkpoint) {
|
|
|
635
704
|
}
|
|
636
705
|
return answered;
|
|
637
706
|
}
|
|
707
|
+
function hasFreeformAnswer(cycle, checkpoint) {
|
|
708
|
+
return cycle.some((event) => {
|
|
709
|
+
if (event.checkpoint !== checkpoint || event.type !== "checkpoint-answer")
|
|
710
|
+
return false;
|
|
711
|
+
const payload = event.payload;
|
|
712
|
+
if (typeof payload !== "object" || payload === null || Array.isArray(payload))
|
|
713
|
+
return false;
|
|
714
|
+
const questionId = payload.questionId;
|
|
715
|
+
return typeof questionId === "string" && !FIXED_BANK_QUESTION_IDS.has(questionId);
|
|
716
|
+
});
|
|
717
|
+
}
|
|
638
718
|
function currentCycleEvents(events) {
|
|
639
719
|
const lastApprovalIndex = lastIndexOfType(events, "implementation-approved");
|
|
640
720
|
return events.slice(lastApprovalIndex + 1);
|
|
@@ -646,7 +726,7 @@ function resolveResumeState(events, rules2) {
|
|
|
646
726
|
continue;
|
|
647
727
|
const answered = answeredQuestionIds(cycle, checkpoint);
|
|
648
728
|
const nextQuestion = questionsFor(checkpoint).find((question) => !answered.has(question.id));
|
|
649
|
-
if (nextQuestion) {
|
|
729
|
+
if (nextQuestion && !hasFreeformAnswer(cycle, checkpoint)) {
|
|
650
730
|
return { kind: "ask-question", question: nextQuestion };
|
|
651
731
|
}
|
|
652
732
|
if (checkpoint === "design" && lastIndexOfType(cycle, "design-confirmed") === -1) {
|
|
@@ -807,6 +887,59 @@ function createLineReaderPrompter(input = process.stdin, output = process.stdout
|
|
|
807
887
|
};
|
|
808
888
|
}
|
|
809
889
|
|
|
890
|
+
// src/commands/log.ts
|
|
891
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
892
|
+
var CHECKPOINT_NAMES2 = ["build", "design", "implementation"];
|
|
893
|
+
function isCheckpointName2(value) {
|
|
894
|
+
return CHECKPOINT_NAMES2.includes(value);
|
|
895
|
+
}
|
|
896
|
+
async function runLog(projectRoot, input) {
|
|
897
|
+
const session = await loadOrCreateLocalSession(projectRoot);
|
|
898
|
+
switch (input.kind) {
|
|
899
|
+
case "question": {
|
|
900
|
+
const questionId = input.questionId ?? `freeform-${randomUUID2()}`;
|
|
901
|
+
const next = appendSessionEvent(session, {
|
|
902
|
+
checkpoint: input.checkpoint,
|
|
903
|
+
actor: "assistant",
|
|
904
|
+
type: "checkpoint-question",
|
|
905
|
+
payload: { questionId, prompt: input.prompt }
|
|
906
|
+
});
|
|
907
|
+
await saveLocalSession(projectRoot, next);
|
|
908
|
+
return { questionId };
|
|
909
|
+
}
|
|
910
|
+
case "answer": {
|
|
911
|
+
const next = appendSessionEvent(session, {
|
|
912
|
+
checkpoint: input.checkpoint,
|
|
913
|
+
actor: "developer",
|
|
914
|
+
type: "checkpoint-answer",
|
|
915
|
+
payload: { questionId: input.questionId, answer: input.answer }
|
|
916
|
+
});
|
|
917
|
+
await saveLocalSession(projectRoot, next);
|
|
918
|
+
return {};
|
|
919
|
+
}
|
|
920
|
+
case "design-confirmed": {
|
|
921
|
+
const next = appendSessionEvent(session, {
|
|
922
|
+
checkpoint: "design",
|
|
923
|
+
actor: "developer",
|
|
924
|
+
type: "design-confirmed",
|
|
925
|
+
payload: {}
|
|
926
|
+
});
|
|
927
|
+
await saveLocalSession(projectRoot, next);
|
|
928
|
+
return {};
|
|
929
|
+
}
|
|
930
|
+
case "implementation-approved": {
|
|
931
|
+
const next = appendSessionEvent(session, {
|
|
932
|
+
checkpoint: "implementation",
|
|
933
|
+
actor: "developer",
|
|
934
|
+
type: "implementation-approved",
|
|
935
|
+
payload: {}
|
|
936
|
+
});
|
|
937
|
+
await saveLocalSession(projectRoot, next);
|
|
938
|
+
return {};
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
|
|
810
943
|
// src/commands/status.ts
|
|
811
944
|
async function runStatus(projectRoot) {
|
|
812
945
|
const rules2 = await loadRulesConfig(projectRoot);
|
|
@@ -1126,7 +1259,7 @@ function formatUpdateNotice(notice, packageName) {
|
|
|
1126
1259
|
}
|
|
1127
1260
|
|
|
1128
1261
|
// src/index.ts
|
|
1129
|
-
var VERSION = "0.
|
|
1262
|
+
var VERSION = "0.2.0";
|
|
1130
1263
|
var PACKAGE_NAME = "@vaka.world/cli";
|
|
1131
1264
|
var clackPrompter = {
|
|
1132
1265
|
async askQuestion(question) {
|
|
@@ -1216,9 +1349,13 @@ program.command("start").description(
|
|
|
1216
1349
|
nonInteractivePrompter?.close();
|
|
1217
1350
|
}
|
|
1218
1351
|
});
|
|
1219
|
-
program.command("status").description("Show the current local/unverified checkpoint status.").action(async () => {
|
|
1352
|
+
program.command("status").description("Show the current local/unverified checkpoint status.").option("--json", "Print the status as machine-readable JSON instead of log lines.").action(async (options) => {
|
|
1220
1353
|
try {
|
|
1221
1354
|
const report = await runStatus(process.cwd());
|
|
1355
|
+
if (options.json) {
|
|
1356
|
+
console.log(JSON.stringify(report));
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1222
1359
|
log.info(report.sessionExists ? "Local session: unverified" : "No local session yet.");
|
|
1223
1360
|
log.info(`Recorded events: ${report.totalEvents}`);
|
|
1224
1361
|
log.info(`Completed cycles: ${report.completedCycles}`);
|
|
@@ -1228,6 +1365,58 @@ program.command("status").description("Show the current local/unverified checkpo
|
|
|
1228
1365
|
process.exitCode = 1;
|
|
1229
1366
|
}
|
|
1230
1367
|
});
|
|
1368
|
+
var logCommand = program.command("log").description(
|
|
1369
|
+
"Headless, non-interactive event recording for an AI assistant (e.g. the Vaka Claude Code/Codex skill) to append a checkpoint event directly to the local hash chain, without the vaka start wizard."
|
|
1370
|
+
);
|
|
1371
|
+
function requireCheckpoint(raw) {
|
|
1372
|
+
if (!isCheckpointName2(raw)) {
|
|
1373
|
+
throw new Error(`--checkpoint must be one of build, design, implementation (got "${raw}").`);
|
|
1374
|
+
}
|
|
1375
|
+
return raw;
|
|
1376
|
+
}
|
|
1377
|
+
logCommand.command("question").description("Record a question an assistant is about to ask, and print its question id.").requiredOption("--checkpoint <name>", "build, design, or implementation").requiredOption("--prompt <text>", "The question being asked, verbatim").option("--question-id <id>", "Stable id to reuse later with `log answer` (auto-generated if omitted)").action(async (options) => {
|
|
1378
|
+
try {
|
|
1379
|
+
const result = await runLog(process.cwd(), {
|
|
1380
|
+
kind: "question",
|
|
1381
|
+
checkpoint: requireCheckpoint(options.checkpoint),
|
|
1382
|
+
prompt: options.prompt,
|
|
1383
|
+
questionId: options.questionId
|
|
1384
|
+
});
|
|
1385
|
+
console.log(result.questionId);
|
|
1386
|
+
} catch (error) {
|
|
1387
|
+
log.error(error instanceof Error ? error.message : String(error));
|
|
1388
|
+
process.exitCode = 1;
|
|
1389
|
+
}
|
|
1390
|
+
});
|
|
1391
|
+
logCommand.command("answer").description("Record the developer's answer to a previously logged question.").requiredOption("--checkpoint <name>", "build, design, or implementation").requiredOption("--question-id <id>", "The id printed by `log question`").requiredOption("--answer <text>", "The developer's answer, verbatim").action(async (options) => {
|
|
1392
|
+
try {
|
|
1393
|
+
await runLog(process.cwd(), {
|
|
1394
|
+
kind: "answer",
|
|
1395
|
+
checkpoint: requireCheckpoint(options.checkpoint),
|
|
1396
|
+
questionId: options.questionId,
|
|
1397
|
+
answer: options.answer
|
|
1398
|
+
});
|
|
1399
|
+
} catch (error) {
|
|
1400
|
+
log.error(error instanceof Error ? error.message : String(error));
|
|
1401
|
+
process.exitCode = 1;
|
|
1402
|
+
}
|
|
1403
|
+
});
|
|
1404
|
+
logCommand.command("design-confirmed").description("Record that the developer confirmed the design (does not authorize code changes).").action(async () => {
|
|
1405
|
+
try {
|
|
1406
|
+
await runLog(process.cwd(), { kind: "design-confirmed" });
|
|
1407
|
+
} catch (error) {
|
|
1408
|
+
log.error(error instanceof Error ? error.message : String(error));
|
|
1409
|
+
process.exitCode = 1;
|
|
1410
|
+
}
|
|
1411
|
+
});
|
|
1412
|
+
logCommand.command("implementation-approved").description("Record that the developer authorized this scoped implementation.").action(async () => {
|
|
1413
|
+
try {
|
|
1414
|
+
await runLog(process.cwd(), { kind: "implementation-approved" });
|
|
1415
|
+
} catch (error) {
|
|
1416
|
+
log.error(error instanceof Error ? error.message : String(error));
|
|
1417
|
+
process.exitCode = 1;
|
|
1418
|
+
}
|
|
1419
|
+
});
|
|
1231
1420
|
await program.parseAsync(process.argv);
|
|
1232
1421
|
var updateNotice = checkForUpdates(VERSION, PACKAGE_NAME);
|
|
1233
1422
|
if (updateNotice) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/commands/line-prompter.ts","../../../packages/core/src/session.ts","../../../packages/core/src/checkpoints.ts","../../../packages/core/src/rules.ts","../src/commands/start.ts","../src/commands/status.ts","../src/ui/banner.ts","../src/ui/terminal-theme.ts","../src/update-check.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { cancel, confirm, intro, isCancel, log, outro, text } from \"@clack/prompts\";\nimport { initializeProject } from \"./commands/init.js\";\nimport { createLineReaderPrompter } from \"./commands/line-prompter.js\";\nimport { CANCELLED, runStart, type StartPrompter } from \"./commands/start.js\";\nimport { runStatus } from \"./commands/status.js\";\nimport { animateVakaEntrance } from \"./ui/banner.js\";\nimport { checkForUpdates, formatUpdateNotice } from \"./update-check.js\";\n\nconst VERSION = \"0.1.0\";\nconst PACKAGE_NAME = \"@vaka.world/cli\";\n\nconst clackPrompter: StartPrompter = {\n async askQuestion(question) {\n const answer = await text({\n message: question.prompt,\n validate: (value) => (value.trim().length === 0 ? \"An answer is required.\" : undefined),\n });\n return isCancel(answer) ? CANCELLED : answer;\n },\n async askConfirm(message) {\n const answer = await confirm({ message });\n return isCancel(answer) ? CANCELLED : answer;\n },\n};\n\nfunction describeResumeState(state: { kind: string; question?: { prompt: string } }): string {\n switch (state.kind) {\n case \"ask-question\":\n return `Next: ${state.question?.prompt}`;\n case \"confirm-design\":\n return \"Next: confirm the design.\";\n case \"authorize-implementation\":\n return \"Next: authorize implementation.\";\n case \"cycle-complete\":\n return \"Nothing required by .vaka/rules.yml for this cycle.\";\n default:\n return \"Unknown state.\";\n }\n}\n\nconst program = new Command()\n .name(\"vaka\")\n .description(\"Make the reasoning behind engineering decisions visible.\")\n .version(VERSION);\n\nprogram\n .command(\"init\")\n .description(\"Add Vaka rules and instructions to the current project.\")\n .action(async () => {\n await animateVakaEntrance({ version: VERSION });\n intro(\"vaka init\");\n\n try {\n const result = await initializeProject(process.cwd());\n\n for (const file of result.created) {\n log.success(`Created ${file}`);\n }\n\n for (const file of result.skipped) {\n log.warn(`Preserved existing file: ${file}`);\n }\n\n if (result.integrations.length === 0) {\n log.info(\n \"No supported AI integration was detected. Created the Vaka project rules; add a Cursor, Claude Code, Codex, Copilot, Windsurf, or Cline marker to install its instructions.\",\n );\n } else {\n log.info(`Detected: ${result.integrations.join(\", \")}`);\n }\n\n outro(\"Local setup is ready. Local records are not server-verified.\");\n } catch (error) {\n log.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nprogram\n .command(\"start\")\n .description(\n \"Work through the Build, Design, and Implementation checkpoints for the current cycle.\",\n )\n .action(async () => {\n intro(\"Vaka | Your mind is the architect.\");\n\n const nonInteractivePrompter =\n process.stdin.isTTY === true ? undefined : createLineReaderPrompter();\n const prompter: StartPrompter = nonInteractivePrompter ?? clackPrompter;\n\n try {\n const outcome = await runStart(process.cwd(), prompter);\n switch (outcome.kind) {\n case \"implementation-approved\":\n outro(\n \"Implementation authorized. Local session is unverified — this records what Vaka accepted locally, not independent proof of understanding or a server verification.\",\n );\n break;\n case \"design-declined\":\n log.warn(\"Design not confirmed. Revisit the edge cases above, then run `vaka start` again.\");\n outro(\"Stopped before design was confirmed.\");\n break;\n case \"implementation-declined\":\n log.warn(\"Implementation not authorized. Nothing was unlocked.\");\n outro(\"Stopped before implementation was authorized.\");\n break;\n case \"cancelled\":\n cancel(\"Stopped (input ended or was interrupted). Resume anytime with `vaka start`.\");\n break;\n case \"nothing-required\":\n outro(\"Nothing is required by .vaka/rules.yml for this cycle.\");\n break;\n }\n } catch (error) {\n log.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n } finally {\n nonInteractivePrompter?.close();\n }\n });\n\nprogram\n .command(\"status\")\n .description(\"Show the current local/unverified checkpoint status.\")\n .action(async () => {\n try {\n const report = await runStatus(process.cwd());\n log.info(report.sessionExists ? \"Local session: unverified\" : \"No local session yet.\");\n log.info(`Recorded events: ${report.totalEvents}`);\n log.info(`Completed cycles: ${report.completedCycles}`);\n log.info(describeResumeState(report.resumeState));\n } catch (error) {\n log.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nawait program.parseAsync(process.argv);\n\nconst updateNotice = checkForUpdates(VERSION, PACKAGE_NAME);\nif (updateNotice) {\n console.log(formatUpdateNotice(updateNotice, PACKAGE_NAME));\n}\n","import { lstat, mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, relative, resolve } from \"node:path\";\n\nexport type Integration = \"claude\" | \"cursor\" | \"copilot\" | \"codex\" | \"windsurf\" | \"cline\";\n\nexport interface InitResult {\n integrations: Integration[];\n created: string[];\n updated: string[];\n skipped: string[];\n}\n\nconst rules = `version: 1\ncheckpoints:\n build:\n required: true\n design:\n required: true\n implementation:\n required: true\nverification:\n local_status: unverified\n`;\n\nconst managedStart = \"<!-- BEGIN VAKA MANAGED INSTRUCTIONS -->\";\nconst managedEnd = \"<!-- END VAKA MANAGED INSTRUCTIONS -->\";\n\nconst sharedGuidance = `Before implementing a feature, help the developer reason through its behavior, data, and failure cases. Keep understanding, design confirmation, and implementation authorization distinct. Do not write code until the developer explicitly authorizes the scoped implementation; design confirmation alone is not implementation approval. Explain unfamiliar code and why each change is needed.\n\nVaka instructions are guidance, not a technical enforcement boundary. Local session files are unverified; only a server-accepted seal can be described as server-verified.`;\n\nconst instructions = {\n claude: `# Vaka\\n\\n${sharedGuidance}\\n`,\n cursor: `---\\ndescription: Vaka architecture and reasoning guidance\\nalwaysApply: true\\n---\\n\\n${sharedGuidance}\\n`,\n copilot: `# Vaka\\n\\n${sharedGuidance}\\n`,\n codex: sharedGuidance,\n windsurfOwnFile: `---\\ntrigger: always_on\\ndescription: Vaka architecture and reasoning guidance\\n---\\n\\n${sharedGuidance}\\n`,\n windsurfMerge: sharedGuidance,\n clineOwnFile: `# Vaka\\n\\n${sharedGuidance}\\n`,\n clineMerge: sharedGuidance,\n} as const;\n\nfunction isMissing(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n );\n}\n\nfunction isAlreadyExists(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"EEXIST\"\n );\n}\n\nasync function inspectPath(path: string): Promise<\"file\" | \"directory\" | undefined> {\n try {\n const stat = await lstat(path);\n if (stat.isSymbolicLink()) {\n throw new Error(`Refusing to follow symbolic link: ${path}`);\n }\n if (stat.isDirectory()) return \"directory\";\n if (stat.isFile()) return \"file\";\n return undefined;\n } catch (error) {\n if (isMissing(error)) return undefined;\n throw error;\n }\n}\n\nasync function detectIntegrations(projectRoot: string): Promise<Integration[]> {\n const [\n cursor,\n claudeManifest,\n claudeDirectory,\n copilotManifest,\n instructionsDirectory,\n codexManifest,\n codexDirectory,\n windsurfDirectory,\n windsurfLegacyFile,\n clinerules,\n ] = await Promise.all([\n inspectPath(join(projectRoot, \".cursor\")),\n inspectPath(join(projectRoot, \"CLAUDE.md\")),\n inspectPath(join(projectRoot, \".claude\")),\n inspectPath(join(projectRoot, \".github\", \"copilot-instructions.md\")),\n inspectPath(join(projectRoot, \".github\", \"instructions\")),\n inspectPath(join(projectRoot, \"AGENTS.md\")),\n inspectPath(join(projectRoot, \".codex\")),\n inspectPath(join(projectRoot, \".windsurf\")),\n inspectPath(join(projectRoot, \".windsurfrules\")),\n inspectPath(join(projectRoot, \".clinerules\")),\n ]);\n\n const integrations: Integration[] = [];\n if (cursor === \"directory\") integrations.push(\"cursor\");\n if (claudeManifest === \"file\" || claudeDirectory === \"directory\") {\n integrations.push(\"claude\");\n }\n\n let copilotDetected =\n copilotManifest === \"file\" || instructionsDirectory === \"directory\";\n const vscodeSettings = join(projectRoot, \".vscode\", \"settings.json\");\n if (!copilotDetected && (await inspectPath(vscodeSettings)) === \"file\") {\n const settings = await readFile(vscodeSettings, \"utf8\");\n copilotDetected = /\"github\\.copilot\\.[^\"]+\"\\s*:/.test(settings);\n }\n if (copilotDetected) integrations.push(\"copilot\");\n\n if (codexManifest === \"file\" || codexDirectory === \"directory\") {\n integrations.push(\"codex\");\n }\n if (windsurfDirectory === \"directory\" || windsurfLegacyFile === \"file\") {\n integrations.push(\"windsurf\");\n }\n if (clinerules === \"file\" || clinerules === \"directory\") {\n integrations.push(\"cline\");\n }\n\n return integrations;\n}\n\nasync function ensureDirectory(projectRoot: string, relativePath: string): Promise<void> {\n const absolutePath = resolve(projectRoot, relativePath);\n const fromRoot = relative(projectRoot, absolutePath);\n if (fromRoot.startsWith(\"..\") || isAbsolute(fromRoot)) {\n throw new Error(`Refusing to create a directory outside the project: ${relativePath}`);\n }\n\n const segments = fromRoot.split(/[/\\\\]/).filter(Boolean);\n let current = projectRoot;\n\n for (const segment of segments) {\n current = join(current, segment);\n const existing = await inspectPath(current);\n if (existing === \"file\") {\n throw new Error(`Expected a directory, found a file: ${current}`);\n }\n if (existing === undefined) {\n try {\n await mkdir(current, { mode: segment === \".vaka\" ? 0o700 : 0o755 });\n } catch (error) {\n if (!isAlreadyExists(error)) throw error;\n }\n if ((await inspectPath(current)) !== \"directory\") {\n throw new Error(`Could not safely create directory: ${current}`);\n }\n }\n }\n}\n\nasync function createIfMissing(\n projectRoot: string,\n relativePath: string,\n contents: string,\n): Promise<\"created\" | \"skipped\"> {\n const absolutePath = resolve(projectRoot, relativePath);\n const parent = relative(projectRoot, absolutePath).split(/[/\\\\]/).slice(0, -1).join(\"/\");\n if (parent) await ensureDirectory(projectRoot, parent);\n\n try {\n await writeFile(absolutePath, contents, {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: 0o644,\n });\n return \"created\";\n } catch (error) {\n if (isAlreadyExists(error)) return \"skipped\";\n throw error;\n }\n}\n\nfunction wrapManagedSection(body: string): string {\n return `${managedStart}\\n${body}\\n${managedEnd}`;\n}\n\nfunction mergeManagedSection(existing: string, body: string): string {\n const section = wrapManagedSection(body);\n const start = existing.indexOf(managedStart);\n const end = existing.indexOf(managedEnd);\n if (start === -1 && end === -1) {\n const separator = existing.length === 0 ? \"\" : existing.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n return `${existing}${separator}${section}\\n`;\n }\n\n if (\n start === -1 ||\n end === -1 ||\n end < start ||\n existing.indexOf(managedStart, start + managedStart.length) !== -1 ||\n existing.indexOf(managedEnd, end + managedEnd.length) !== -1\n ) {\n throw new Error(\"File has malformed Vaka instruction markers; refusing to modify it.\");\n }\n\n const managedEndIndex = end + managedEnd.length;\n return `${existing.slice(0, start)}${section}${existing.slice(managedEndIndex)}`;\n}\n\nasync function mergeIntoFile(\n projectRoot: string,\n relativePath: string,\n sectionBody: string,\n): Promise<\"created\" | \"updated\" | \"skipped\"> {\n const absolutePath = resolve(projectRoot, relativePath);\n const parent = relative(projectRoot, absolutePath).split(/[/\\\\]/).slice(0, -1).join(\"/\");\n if (parent) await ensureDirectory(projectRoot, parent);\n\n const pathType = await inspectPath(absolutePath);\n if (pathType === undefined) {\n try {\n await writeFile(absolutePath, `${wrapManagedSection(sectionBody)}\\n`, {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: 0o644,\n });\n return \"created\";\n } catch (error) {\n if (!isAlreadyExists(error)) throw error;\n }\n } else if (pathType !== \"file\") {\n throw new Error(`Expected a regular file, found a directory: ${absolutePath}`);\n }\n\n const stat = await lstat(absolutePath);\n if (!stat.isFile() || stat.isSymbolicLink()) {\n throw new Error(`Expected a regular file: ${absolutePath}`);\n }\n\n const existing = await readFile(absolutePath, \"utf8\");\n const updated = mergeManagedSection(existing, sectionBody);\n if (updated === existing) return \"skipped\";\n\n const temporaryPath = join(\n dirname(absolutePath),\n `.${basename(absolutePath)}.${crypto.randomUUID()}.tmp`,\n );\n try {\n await writeFile(temporaryPath, updated, {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: stat.mode & 0o777,\n });\n await rename(temporaryPath, absolutePath);\n } catch (error) {\n try {\n await unlink(temporaryPath);\n } catch (cleanupError) {\n if (!isMissing(cleanupError)) {\n throw new AggregateError(\n [error, cleanupError],\n `Could not update ${absolutePath} or clean up ${temporaryPath}.`,\n );\n }\n }\n throw error;\n }\n return \"updated\";\n}\n\nasync function resolveWindsurfTarget(\n projectRoot: string,\n): Promise<{ mode: \"own-file\" | \"merge\"; relativePath: string }> {\n const directory = await inspectPath(join(projectRoot, \".windsurf\"));\n if (directory === \"directory\") {\n return { mode: \"own-file\", relativePath: \".windsurf/rules/vaka.md\" };\n }\n return { mode: \"merge\", relativePath: \".windsurfrules\" };\n}\n\nasync function resolveClineTarget(\n projectRoot: string,\n): Promise<{ mode: \"own-file\" | \"merge\"; relativePath: string }> {\n const existing = await inspectPath(join(projectRoot, \".clinerules\"));\n if (existing === \"directory\") {\n return { mode: \"own-file\", relativePath: \".clinerules/vaka.md\" };\n }\n return { mode: \"merge\", relativePath: \".clinerules\" };\n}\n\nexport async function initializeProject(projectPath: string): Promise<InitResult> {\n const projectRoot = resolve(projectPath);\n if ((await inspectPath(projectRoot)) !== \"directory\") {\n throw new Error(`Project path is not a directory: ${projectRoot}`);\n }\n\n const integrations = await detectIntegrations(projectRoot);\n const result: InitResult = { integrations, created: [], updated: [], skipped: [] };\n\n const ownFiles: Array<{ relativePath: string; contents: string }> = [\n { relativePath: \".vaka/rules.yml\", contents: rules },\n ];\n if (integrations.includes(\"claude\")) {\n ownFiles.push({ relativePath: \"CLAUDE.md\", contents: instructions.claude });\n }\n if (integrations.includes(\"cursor\")) {\n ownFiles.push({ relativePath: \".cursor/rules/vaka.mdc\", contents: instructions.cursor });\n }\n if (integrations.includes(\"copilot\")) {\n ownFiles.push({\n relativePath: \".github/copilot-instructions.md\",\n contents: instructions.copilot,\n });\n }\n\n for (const file of ownFiles) {\n const status = await createIfMissing(projectRoot, file.relativePath, file.contents);\n result[status].push(file.relativePath);\n }\n\n if (integrations.includes(\"codex\")) {\n const status = await mergeIntoFile(projectRoot, \"AGENTS.md\", instructions.codex);\n result[status].push(\"AGENTS.md\");\n }\n\n if (integrations.includes(\"windsurf\")) {\n const target = await resolveWindsurfTarget(projectRoot);\n const status =\n target.mode === \"own-file\"\n ? await createIfMissing(projectRoot, target.relativePath, instructions.windsurfOwnFile)\n : await mergeIntoFile(projectRoot, target.relativePath, instructions.windsurfMerge);\n result[status].push(target.relativePath);\n }\n\n if (integrations.includes(\"cline\")) {\n const target = await resolveClineTarget(projectRoot);\n const status =\n target.mode === \"own-file\"\n ? await createIfMissing(projectRoot, target.relativePath, instructions.clineOwnFile)\n : await mergeIntoFile(projectRoot, target.relativePath, instructions.clineMerge);\n result[status].push(target.relativePath);\n }\n\n return result;\n}\n","import { createInterface } from \"node:readline\";\nimport type { Readable, Writable } from \"node:stream\";\nimport { CANCELLED, type StartPrompter } from \"./start.js\";\n\nexport interface LineReaderPrompter extends StartPrompter {\n close(): void;\n}\n\nexport function createLineReaderPrompter(\n input: Readable = process.stdin,\n output: Writable = process.stdout,\n): LineReaderPrompter {\n const rl = createInterface({ input, terminal: false });\n const lines = rl[Symbol.asyncIterator]();\n\n async function nextLine(): Promise<string | undefined> {\n const { value, done } = await lines.next();\n return done ? undefined : value;\n }\n\n return {\n async askQuestion(question) {\n output.write(`${question.prompt}\\n> `);\n const line = await nextLine();\n if (line === undefined) return CANCELLED;\n const answer = line.trim();\n if (answer.length === 0) {\n throw new Error(`Expected a non-empty answer for: ${question.prompt}`);\n }\n return answer;\n },\n async askConfirm(message) {\n output.write(`${message} (y/n)\\n> `);\n const line = await nextLine();\n if (line === undefined) return CANCELLED;\n const normalized = line.trim().toLowerCase();\n if (normalized === \"y\" || normalized === \"yes\") return true;\n if (normalized === \"n\" || normalized === \"no\") return false;\n throw new Error(`Expected \"y\" or \"n\" for: ${message} (got ${JSON.stringify(line)})`);\n },\n close() {\n rl.close();\n },\n };\n}\n","import { createHash, randomUUID } from \"node:crypto\";\nimport { lstat, mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\n\nexport type JsonValue =\n | null\n | boolean\n | number\n | string\n | JsonValue[]\n | { [key: string]: JsonValue };\n\nexport type CheckpointName = \"build\" | \"design\" | \"implementation\";\nexport type EventActor = \"developer\" | \"assistant\";\nexport type EventType =\n | \"checkpoint-question\"\n | \"checkpoint-answer\"\n | \"design-confirmed\"\n | \"implementation-approved\";\n\nexport interface SessionEventInput {\n checkpoint: CheckpointName;\n actor: EventActor;\n type: EventType;\n payload: JsonValue;\n}\n\nexport interface SessionEvent extends SessionEventInput {\n sequence: number;\n recordedAt: string;\n previousHash: string | null;\n hash: string;\n}\n\nexport interface LocalSession {\n schemaVersion: 1;\n id: string;\n provenance: \"local\";\n status: \"unverified\";\n createdAt: string;\n events: SessionEvent[];\n}\n\nexport type SessionIntegrityResult =\n | { valid: true }\n | { valid: false; eventIndex?: number; reason: string };\n\nexport const LOCAL_SESSION_RELATIVE_PATH = \".vaka/session.json\";\n\nfunction canonicalize(value: unknown, ancestors: WeakSet<object>): string {\n if (value === null || typeof value === \"boolean\" || typeof value === \"string\") {\n return JSON.stringify(value);\n }\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) throw new TypeError(\"Session payload numbers must be finite.\");\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) {\n if (ancestors.has(value)) throw new TypeError(\"Session payload cannot contain cycles.\");\n ancestors.add(value);\n const serialized = `[${value.map((item) => canonicalize(item, ancestors)).join(\",\")}]`;\n ancestors.delete(value);\n return serialized;\n }\n if (typeof value === \"object\") {\n const object = value as Record<string, unknown>;\n const prototype = Object.getPrototypeOf(object);\n if (prototype !== Object.prototype && prototype !== null) {\n throw new TypeError(\"Session payload must contain only plain JSON objects.\");\n }\n if (ancestors.has(object)) throw new TypeError(\"Session payload cannot contain cycles.\");\n ancestors.add(object);\n const serialized = `{${Object.keys(object)\n .sort()\n .map((key) => {\n const item = object[key];\n if (item === undefined) {\n throw new TypeError(\"Session payload cannot contain undefined values.\");\n }\n return `${JSON.stringify(key)}:${canonicalize(item, ancestors)}`;\n })\n .join(\",\")}}`;\n ancestors.delete(object);\n return serialized;\n }\n throw new TypeError(\"Session payload must be valid JSON.\");\n}\n\nfunction canonicalJson(value: unknown): string {\n return canonicalize(value, new WeakSet());\n}\n\nfunction isCheckpointName(value: unknown): value is CheckpointName {\n return value === \"build\" || value === \"design\" || value === \"implementation\";\n}\n\nfunction isEventActor(value: unknown): value is EventActor {\n return value === \"developer\" || value === \"assistant\";\n}\n\nfunction isEventType(value: unknown): value is EventType {\n return (\n value === \"checkpoint-question\" ||\n value === \"checkpoint-answer\" ||\n value === \"design-confirmed\" ||\n value === \"implementation-approved\"\n );\n}\n\nfunction hasExactKeys(value: object, keys: string[]): boolean {\n const actual = Object.keys(value).sort();\n const expected = [...keys].sort();\n return actual.length === expected.length && actual.every((key, index) => key === expected[index]);\n}\n\nfunction hashEvent(\n sessionId: string,\n event: Omit<SessionEvent, \"hash\">,\n): string {\n const content = canonicalJson({\n sessionId,\n sequence: event.sequence,\n checkpoint: event.checkpoint,\n actor: event.actor,\n type: event.type,\n payload: event.payload,\n recordedAt: event.recordedAt,\n previousHash: event.previousHash,\n });\n return createHash(\"sha256\").update(content, \"utf8\").digest(\"hex\");\n}\n\nexport function createLocalSession(options: {\n id?: string;\n createdAt?: string;\n} = {}): LocalSession {\n return {\n schemaVersion: 1,\n id: options.id ?? randomUUID(),\n provenance: \"local\",\n status: \"unverified\",\n createdAt: options.createdAt ?? new Date().toISOString(),\n events: [],\n };\n}\n\nexport function verifySessionIntegrity(session: unknown): SessionIntegrityResult {\n if (typeof session !== \"object\" || session === null) {\n return { valid: false, reason: \"Session must be an object.\" };\n }\n\n const candidate = session as Partial<LocalSession>;\n if (\n !hasExactKeys(candidate, [\n \"schemaVersion\",\n \"id\",\n \"provenance\",\n \"status\",\n \"createdAt\",\n \"events\",\n ]) ||\n candidate.schemaVersion !== 1 ||\n typeof candidate.id !== \"string\" ||\n candidate.id.length === 0 ||\n candidate.provenance !== \"local\" ||\n candidate.status !== \"unverified\" ||\n typeof candidate.createdAt !== \"string\" ||\n Number.isNaN(Date.parse(candidate.createdAt)) ||\n !Array.isArray(candidate.events)\n ) {\n return { valid: false, reason: \"Session metadata is invalid or has an unsupported version.\" };\n }\n\n let previousHash: string | null = null;\n let previousRecordedAt = candidate.createdAt;\n for (let index = 0; index < candidate.events.length; index += 1) {\n const event = candidate.events[index];\n if (\n typeof event !== \"object\" ||\n event === null ||\n !hasExactKeys(event, [\n \"sequence\",\n \"checkpoint\",\n \"actor\",\n \"type\",\n \"payload\",\n \"recordedAt\",\n \"previousHash\",\n \"hash\",\n ]) ||\n event.sequence !== index ||\n !isCheckpointName(event.checkpoint) ||\n !isEventActor(event.actor) ||\n !isEventType(event.type) ||\n typeof event.recordedAt !== \"string\" ||\n Number.isNaN(Date.parse(event.recordedAt)) ||\n event.previousHash !== previousHash ||\n typeof event.hash !== \"string\" ||\n !/^[a-f0-9]{64}$/.test(event.hash)\n ) {\n return { valid: false, eventIndex: index, reason: \"Event shape or sequence is invalid.\" };\n }\n\n if (Date.parse(event.recordedAt) < Date.parse(previousRecordedAt)) {\n return {\n valid: false,\n eventIndex: index,\n reason:\n \"Event timestamp is earlier than a prior event or the session's creation time.\",\n };\n }\n\n try {\n const { hash, ...eventWithoutHash } = event;\n if (hashEvent(candidate.id, eventWithoutHash) !== hash) {\n return { valid: false, eventIndex: index, reason: \"Event hash does not match its contents.\" };\n }\n } catch (error) {\n return {\n valid: false,\n eventIndex: index,\n reason: error instanceof Error ? error.message : String(error),\n };\n }\n\n previousRecordedAt = event.recordedAt;\n previousHash = event.hash;\n }\n\n return { valid: true };\n}\n\nexport function appendSessionEvent(\n session: LocalSession,\n input: SessionEventInput,\n recordedAt = new Date().toISOString(),\n): LocalSession {\n const integrity = verifySessionIntegrity(session);\n if (!integrity.valid) {\n throw new Error(\n `Cannot append to an invalid local session${integrity.eventIndex === undefined ? \"\" : ` at event ${integrity.eventIndex}`}: ${integrity.reason}`,\n );\n }\n if (!isCheckpointName(input.checkpoint) || !isEventActor(input.actor) || !isEventType(input.type)) {\n throw new TypeError(\"Session event has an unsupported checkpoint, actor, or type.\");\n }\n if (Number.isNaN(Date.parse(recordedAt))) {\n throw new TypeError(\"Session event timestamp must be a valid date.\");\n }\n const previousRecordedAt = session.events.at(-1)?.recordedAt ?? session.createdAt;\n if (Date.parse(recordedAt) < Date.parse(previousRecordedAt)) {\n throw new RangeError(\n \"Session event timestamp cannot be earlier than the previous event or the session's creation time.\",\n );\n }\n\n const previousHash = session.events.at(-1)?.hash ?? null;\n const eventWithoutHash: Omit<SessionEvent, \"hash\"> = {\n sequence: session.events.length,\n checkpoint: input.checkpoint,\n actor: input.actor,\n type: input.type,\n payload: input.payload,\n recordedAt,\n previousHash,\n };\n const event: SessionEvent = {\n ...eventWithoutHash,\n hash: hashEvent(session.id, eventWithoutHash),\n };\n return { ...session, events: [...session.events, event] };\n}\n\nfunction isMissing(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n );\n}\n\nasync function ensureStateDirectory(projectRoot: string): Promise<string> {\n const root = resolve(projectRoot);\n const rootStat = await lstat(root);\n if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) {\n throw new Error(`Project path is not a safe directory: ${root}`);\n }\n\n const stateDirectory = join(root, \".vaka\");\n try {\n const stateStat = await lstat(stateDirectory);\n if (!stateStat.isDirectory() || stateStat.isSymbolicLink()) {\n throw new Error(`Vaka state path must be a real directory: ${stateDirectory}`);\n }\n } catch (error) {\n if (!isMissing(error)) throw error;\n try {\n await mkdir(stateDirectory, { mode: 0o700 });\n } catch (createError) {\n if (\n !(\n typeof createError === \"object\" &&\n createError !== null &&\n \"code\" in createError &&\n createError.code === \"EEXIST\"\n )\n ) {\n throw createError;\n }\n }\n const stateStat = await lstat(stateDirectory);\n if (!stateStat.isDirectory() || stateStat.isSymbolicLink()) {\n throw new Error(`Vaka state path must be a real directory: ${stateDirectory}`);\n }\n }\n return stateDirectory;\n}\n\nasync function inspectStateDirectory(projectRoot: string): Promise<string> {\n const root = resolve(projectRoot);\n const rootStat = await lstat(root);\n if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) {\n throw new Error(`Project path is not a safe directory: ${root}`);\n }\n\n const stateDirectory = join(root, \".vaka\");\n const stateStat = await lstat(stateDirectory);\n if (!stateStat.isDirectory() || stateStat.isSymbolicLink()) {\n throw new Error(`Vaka state path must be a real directory: ${stateDirectory}`);\n }\n return stateDirectory;\n}\n\nexport async function saveLocalSession(\n projectRoot: string,\n session: LocalSession,\n): Promise<void> {\n const integrity = verifySessionIntegrity(session);\n if (!integrity.valid) {\n throw new Error(`Refusing to save an invalid local session: ${integrity.reason}`);\n }\n\n const stateDirectory = await ensureStateDirectory(projectRoot);\n const sessionPath = join(stateDirectory, \"session.json\");\n try {\n const existing = await lstat(sessionPath);\n if (existing.isSymbolicLink() || !existing.isFile()) {\n throw new Error(`Session path must be a regular file: ${sessionPath}`);\n }\n } catch (error) {\n if (!isMissing(error)) throw error;\n }\n\n const temporaryPath = join(stateDirectory, `session.${randomUUID()}.tmp`);\n try {\n await writeFile(temporaryPath, `${JSON.stringify(session, null, 2)}\\n`, {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: 0o600,\n });\n await rename(temporaryPath, sessionPath);\n } catch (error) {\n try {\n await unlink(temporaryPath);\n } catch (cleanupError) {\n if (!isMissing(cleanupError)) {\n throw new AggregateError(\n [error, cleanupError],\n `Could not save the session or clean up ${temporaryPath}.`,\n );\n }\n }\n throw error;\n }\n}\n\nexport async function loadLocalSession(projectRoot: string): Promise<LocalSession> {\n const stateDirectory = await inspectStateDirectory(projectRoot);\n const sessionPath = join(stateDirectory, \"session.json\");\n const stat = await lstat(sessionPath);\n if (!stat.isFile() || stat.isSymbolicLink()) {\n throw new Error(`Session path must be a regular file: ${sessionPath}`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(await readFile(sessionPath, \"utf8\"));\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(`Session JSON is invalid: ${sessionPath}`, { cause: error });\n }\n throw error;\n }\n\n const integrity = verifySessionIntegrity(parsed);\n if (!integrity.valid) {\n throw new Error(`Local session integrity check failed: ${integrity.reason}`);\n }\n return parsed as LocalSession;\n}\n\nexport async function tryLoadLocalSession(\n projectRoot: string,\n): Promise<LocalSession | undefined> {\n try {\n return await loadLocalSession(projectRoot);\n } catch (error) {\n if (isMissing(error)) return undefined;\n throw error;\n }\n}\n\nexport async function loadOrCreateLocalSession(projectRoot: string): Promise<LocalSession> {\n return (await tryLoadLocalSession(projectRoot)) ?? createLocalSession();\n}\n","import type { CheckpointName, SessionEvent } from \"./session.js\";\n\nexport interface CheckpointQuestion {\n id: string;\n checkpoint: CheckpointName;\n prompt: string;\n}\n\nexport const CHECKPOINT_QUESTIONS: readonly CheckpointQuestion[] = [\n {\n id: \"build-goal\",\n checkpoint: \"build\",\n prompt: \"What is the goal of this feature, in one or two sentences?\",\n },\n {\n id: \"build-flow\",\n checkpoint: \"build\",\n prompt:\n \"What are the system boundaries and state transitions — what talks to what, and where does this sit in the flow?\",\n },\n {\n id: \"build-data\",\n checkpoint: \"build\",\n prompt: \"What data does this touch, and why these structures, relations, and indexes?\",\n },\n {\n id: \"design-edge-cases\",\n checkpoint: \"design\",\n prompt:\n \"What edge cases could break this — concurrency, idempotency, timeouts, or network failure — and how are they handled?\",\n },\n];\n\nexport interface CheckpointRequirement {\n required: boolean;\n}\n\nexport interface RulesConfig {\n checkpoints: Record<CheckpointName, CheckpointRequirement>;\n}\n\nexport const DEFAULT_RULES: RulesConfig = {\n checkpoints: {\n build: { required: true },\n design: { required: true },\n implementation: { required: true },\n },\n};\n\nexport type ResumeState =\n | { kind: \"ask-question\"; question: CheckpointQuestion }\n | { kind: \"confirm-design\" }\n | { kind: \"authorize-implementation\" }\n | { kind: \"cycle-complete\" };\n\nconst CHECKPOINT_ORDER: readonly CheckpointName[] = [\"build\", \"design\", \"implementation\"];\n\nfunction questionsFor(checkpoint: CheckpointName): readonly CheckpointQuestion[] {\n return CHECKPOINT_QUESTIONS.filter((question) => question.checkpoint === checkpoint);\n}\n\nfunction lastIndexOfType(\n events: readonly SessionEvent[],\n type: SessionEvent[\"type\"],\n): number {\n for (let index = events.length - 1; index >= 0; index -= 1) {\n if (events[index]?.type === type) return index;\n }\n return -1;\n}\n\nfunction answeredQuestionIds(\n cycle: readonly SessionEvent[],\n checkpoint: CheckpointName,\n): Set<string> {\n const answered = new Set<string>();\n for (const event of cycle) {\n if (event.checkpoint !== checkpoint || event.type !== \"checkpoint-answer\") continue;\n const payload = event.payload;\n if (typeof payload === \"object\" && payload !== null && !Array.isArray(payload)) {\n const questionId = payload.questionId;\n if (typeof questionId === \"string\") answered.add(questionId);\n }\n }\n return answered;\n}\n\n/**\n * A session is one continuous, append-only chain for the whole project's\n * life. Each completed Build -> Design -> Implementation pass is a \"cycle\";\n * the current cycle is everything recorded after the most recent\n * implementation-approved event (or the whole history, if none has happened\n * yet).\n */\nexport function currentCycleEvents(events: readonly SessionEvent[]): readonly SessionEvent[] {\n const lastApprovalIndex = lastIndexOfType(events, \"implementation-approved\");\n return events.slice(lastApprovalIndex + 1);\n}\n\nexport function resolveResumeState(\n events: readonly SessionEvent[],\n rules: RulesConfig,\n): ResumeState {\n const cycle = currentCycleEvents(events);\n\n for (const checkpoint of CHECKPOINT_ORDER) {\n if (!rules.checkpoints[checkpoint].required) continue;\n\n const answered = answeredQuestionIds(cycle, checkpoint);\n const nextQuestion = questionsFor(checkpoint).find((question) => !answered.has(question.id));\n if (nextQuestion) {\n return { kind: \"ask-question\", question: nextQuestion };\n }\n\n if (checkpoint === \"design\" && lastIndexOfType(cycle, \"design-confirmed\") === -1) {\n return { kind: \"confirm-design\" };\n }\n if (\n checkpoint === \"implementation\" &&\n lastIndexOfType(cycle, \"implementation-approved\") === -1\n ) {\n return { kind: \"authorize-implementation\" };\n }\n }\n\n return { kind: \"cycle-complete\" };\n}\n","import { lstat, readFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { DEFAULT_RULES, type RulesConfig } from \"./checkpoints.js\";\nimport type { CheckpointName } from \"./session.js\";\n\nconst CHECKPOINT_NAMES: readonly CheckpointName[] = [\"build\", \"design\", \"implementation\"];\n\nfunction isMissing(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n );\n}\n\nfunction parseRulesDocument(path: string, text: string): RulesConfig {\n let parsed: unknown;\n try {\n parsed = parseYaml(text);\n } catch (error) {\n throw new Error(`Could not parse ${path} as YAML.`, { cause: error });\n }\n\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(`${path} must contain a YAML mapping at the top level.`);\n }\n\n const document = parsed as Record<string, unknown>;\n const checkpointsField = document.checkpoints;\n if (\n typeof checkpointsField !== \"object\" ||\n checkpointsField === null ||\n Array.isArray(checkpointsField)\n ) {\n throw new Error(`${path} is missing a valid top-level \"checkpoints\" mapping.`);\n }\n const checkpointsDocument = checkpointsField as Record<string, unknown>;\n\n const checkpoints = {} as Record<CheckpointName, { required: boolean }>;\n for (const name of CHECKPOINT_NAMES) {\n const entry = checkpointsDocument[name];\n if (\n typeof entry !== \"object\" ||\n entry === null ||\n Array.isArray(entry) ||\n typeof (entry as Record<string, unknown>).required !== \"boolean\"\n ) {\n throw new Error(\n `${path} is missing a boolean \"checkpoints.${name}.required\" value.`,\n );\n }\n checkpoints[name] = { required: (entry as Record<string, unknown>).required as boolean };\n }\n\n return { checkpoints };\n}\n\nexport async function loadRulesConfig(projectRoot: string): Promise<RulesConfig> {\n const root = resolve(projectRoot);\n const rulesPath = join(root, \".vaka\", \"rules.yml\");\n\n let stat;\n try {\n stat = await lstat(rulesPath);\n } catch (error) {\n if (isMissing(error)) return DEFAULT_RULES;\n throw error;\n }\n if (!stat.isFile() || stat.isSymbolicLink()) {\n throw new Error(`Vaka rules path must be a regular file: ${rulesPath}`);\n }\n\n const text = await readFile(rulesPath, \"utf8\");\n return parseRulesDocument(rulesPath, text);\n}\n","import {\n appendSessionEvent,\n loadOrCreateLocalSession,\n loadRulesConfig,\n resolveResumeState,\n saveLocalSession,\n type CheckpointQuestion,\n} from \"@vaka/core\";\n\nexport const CANCELLED = Symbol(\"cancelled\");\n\nexport interface StartPrompter {\n askQuestion(question: CheckpointQuestion): Promise<string | typeof CANCELLED>;\n askConfirm(message: string): Promise<boolean | typeof CANCELLED>;\n}\n\nexport type StartOutcome =\n | { kind: \"implementation-approved\" }\n | { kind: \"design-declined\" }\n | { kind: \"implementation-declined\" }\n | { kind: \"cancelled\" }\n | { kind: \"nothing-required\" };\n\nexport async function runStart(\n projectRoot: string,\n prompter: StartPrompter,\n): Promise<StartOutcome> {\n const rules = await loadRulesConfig(projectRoot);\n let session = await loadOrCreateLocalSession(projectRoot);\n\n for (;;) {\n const state = resolveResumeState(session.events, rules);\n\n if (state.kind === \"cycle-complete\") {\n return { kind: \"nothing-required\" };\n }\n\n if (state.kind === \"ask-question\") {\n session = appendSessionEvent(session, {\n checkpoint: state.question.checkpoint,\n actor: \"assistant\",\n type: \"checkpoint-question\",\n payload: { questionId: state.question.id, prompt: state.question.prompt },\n });\n await saveLocalSession(projectRoot, session);\n\n const answer = await prompter.askQuestion(state.question);\n if (answer === CANCELLED) return { kind: \"cancelled\" };\n\n session = appendSessionEvent(session, {\n checkpoint: state.question.checkpoint,\n actor: \"developer\",\n type: \"checkpoint-answer\",\n payload: { questionId: state.question.id, answer },\n });\n await saveLocalSession(projectRoot, session);\n continue;\n }\n\n if (state.kind === \"confirm-design\") {\n const confirmed = await prompter.askConfirm(\n \"Does this design look right to proceed with?\",\n );\n if (confirmed === CANCELLED) return { kind: \"cancelled\" };\n if (!confirmed) return { kind: \"design-declined\" };\n\n session = appendSessionEvent(session, {\n checkpoint: \"design\",\n actor: \"developer\",\n type: \"design-confirmed\",\n payload: {},\n });\n await saveLocalSession(projectRoot, session);\n continue;\n }\n\n const approved = await prompter.askConfirm(\n \"Authorize implementation of exactly this scoped change?\",\n );\n if (approved === CANCELLED) return { kind: \"cancelled\" };\n if (!approved) return { kind: \"implementation-declined\" };\n\n session = appendSessionEvent(session, {\n checkpoint: \"implementation\",\n actor: \"developer\",\n type: \"implementation-approved\",\n payload: {},\n });\n await saveLocalSession(projectRoot, session);\n return { kind: \"implementation-approved\" };\n }\n}\n","import {\n loadRulesConfig,\n resolveResumeState,\n tryLoadLocalSession,\n type ResumeState,\n} from \"@vaka/core\";\n\nexport interface StatusReport {\n sessionExists: boolean;\n totalEvents: number;\n completedCycles: number;\n resumeState: ResumeState;\n}\n\nexport async function runStatus(projectRoot: string): Promise<StatusReport> {\n const rules = await loadRulesConfig(projectRoot);\n const session = await tryLoadLocalSession(projectRoot);\n const events = session?.events ?? [];\n\n return {\n sessionExists: session !== undefined,\n totalEvents: events.length,\n completedCycles: events.filter((event) => event.type === \"implementation-approved\").length,\n resumeState: resolveResumeState(events, rules),\n };\n}\n","import readline from \"node:readline\";\nimport { detectTerminalTheme, supportsColor, type TerminalTheme } from \"./terminal-theme.js\";\n\nconst BOLD = \"\\x1b[1m\";\nconst RESET = \"\\x1b[0m\";\nconst HIDE_CURSOR = \"\\x1b[?25l\";\nconst SHOW_CURSOR = \"\\x1b[?25h\";\n\nfunction rgb(hex: string): string {\n const r = Number.parseInt(hex.slice(1, 3), 16);\n const g = Number.parseInt(hex.slice(3, 5), 16);\n const b = Number.parseInt(hex.slice(5, 7), 16);\n return `\\x1b[38;2;${r};${g};${b}m`;\n}\n\nfunction stripAnsi(input: string): string {\n return input.replace(/\\x1b\\[[0-9;?]*[a-zA-Z]/g, \"\");\n}\n\n/**\n * Two complete palettes, each a real pairing from docs/design/vaka-theme.css\n * (the dark \"ink\" tokens, or the default light tokens) — never cross-mixed.\n * A banner forced onto the wrong half (e.g. near-white ink-text on a light\n * terminal, or near-black ink-border on a dark one) is the \"invisible\n * banner\" failure this exists to avoid.\n */\nconst PALETTES: Record<\n TerminalTheme,\n { border: string; text: string; muted: string; ring: string; core: string }\n> = {\n dark: {\n border: rgb(\"#2C303D\"), // --ink-border\n text: rgb(\"#F3F4F7\"), // --ink-text\n muted: rgb(\"#9AA1B2\"), // --ink-muted (the dark-canvas muted token, not --muted-foreground)\n ring: rgb(\"#9DB0E8\"), // --accent-light (\"numerals on dark\")\n core: rgb(\"#2E478C\"), // --primary\n },\n light: {\n border: rgb(\"#E5E6EB\"), // --border\n text: rgb(\"#1B1D26\"), // --foreground\n muted: rgb(\"#70747F\"), // --muted-foreground\n ring: rgb(\"#8E9AC2\"), // --secondary-indigo (the light-canvas pair for --accent-light)\n core: rgb(\"#2E478C\"), // --primary\n },\n};\n\nconst SEED_FRAMES: string[][] = [\n // Frame 0: The Origin (Point of Intention)\n [\n ` · `,\n ` `,\n ` ● `,\n ` `,\n ` · `,\n ],\n // Frame 1: The Central Sphere (First Circle of Reasoning)\n [\n ` . ─── . `,\n ` / \\\\ `,\n ` | ◈ | `,\n ` \\\\ / `,\n ` ' ─── ' `,\n ],\n // Frame 2: The Vertical Polar Axis\n [\n ` . ─── . `,\n ` ╭─/───┬───\\\\─╮ `,\n ` ││ │ ││ `,\n ` ╰─\\\\───┴───/─╯ `,\n ` ' ─── ' `,\n ],\n // Frame 3: Triad Intersection (State, Schema, Edge Checkpoints)\n [\n ` . ─── . `,\n ` ╭─/───┬───\\\\─╮ `,\n ` ( ( ◸ ┼ ◹ ) ) `,\n ` ╰─\\\\───┴───/─╯ `,\n ` ' ─── ' `,\n ],\n // Frame 4: Hexagonal Petals Emerge\n [\n ` .──. .──. `,\n ` / ╭──\\\\ /──╮ \\\\ `,\n ` | ( ◸ ✕ ◹ ) | `,\n ` \\\\ ╰──/ \\\\──╯ / `,\n ` '──' '──' `,\n ],\n // Frame 5: Fully Assembled Seed of Life\n [\n ` .──. ▲ .──. `,\n ` ╭─( ◸ ╲ │ / ◹ )─╮ `,\n ` │ ╲─── ◈ ───╱ │ `,\n ` ╰─( ◺ ╱ │ \\\\ ◿ )─╯ `,\n ` '──' ▼ '──' `,\n ],\n // Frame 6: Harmonic Pulse Lock\n [\n ` .──. ✦ .──. `,\n ` ╭─( ◸ ╲ │ / ◹ )─╮ `,\n ` │ ╲─── ◈ ───╱ │ `,\n ` ╰─( ◺ ╱ │ \\\\ ◿ )─╯ `,\n ` '──' ✦ '──' `,\n ],\n];\nconst FINAL_FRAME = SEED_FRAMES.length - 1;\n\nfunction center(text: string, width: number): string {\n const totalPad = Math.max(width - text.length, 0);\n const left = Math.floor(totalPad / 2);\n return \" \".repeat(left) + text + \" \".repeat(totalPad - left);\n}\n\nfunction padEndSafe(text: string, width: number): string {\n return text.length >= width ? text : text + \" \".repeat(width - text.length);\n}\n\nexport function buildVakaCard(\n frameIndex: number,\n isPulsing: boolean,\n theme: TerminalTheme,\n colorEnabled: boolean,\n version: string,\n): string {\n const palette = PALETTES[theme];\n const glyph = SEED_FRAMES[frameIndex] ?? SEED_FRAMES[FINAL_FRAME]!;\n const ringColor = isPulsing ? palette.text : palette.ring;\n const coreColor = isPulsing ? palette.ring : palette.core;\n\n const title = \"YOUR MIND IS THE ARCHITECT\";\n const subtitle = \"Architecture checkpoints for engineers.\";\n // Honest status only: no feature this line implies may exist that isn't shipped.\n const footer = `v${version} · Local checkpoints: unverified`;\n\n const innerWidth = Math.max(\n ...glyph.map((line) => line.length),\n title.length,\n subtitle.length,\n footer.length,\n );\n\n const colorWrap = (code: string, text: string, bold = false) =>\n colorEnabled ? `${bold ? BOLD : \"\"}${code}${text}${RESET}` : text;\n const border = (char: string) => colorWrap(palette.border, char);\n const contentRow = (text: string) => `${border(\"│\")} ${text} ${border(\"│\")}`;\n\n const glyphRow = (line: string, color: string) =>\n contentRow(colorWrap(color, padEndSafe(line, innerWidth)));\n\n const lines = [\n `${border(\"┌\")}${border(\"─\".repeat(innerWidth + 2))}${border(\"┐\")}`,\n contentRow(\" \".repeat(innerWidth)),\n glyphRow(glyph[0]!, ringColor),\n glyphRow(glyph[1]!, ringColor),\n glyphRow(glyph[2]!, coreColor),\n glyphRow(glyph[3]!, ringColor),\n glyphRow(glyph[4]!, ringColor),\n contentRow(\" \".repeat(innerWidth)),\n contentRow(colorWrap(palette.text, center(title, innerWidth), true)),\n contentRow(colorWrap(palette.muted, center(subtitle, innerWidth))),\n contentRow(\" \".repeat(innerWidth)),\n contentRow(colorWrap(palette.muted, center(footer, innerWidth))),\n `${border(\"└\")}${border(\"─\".repeat(innerWidth + 2))}${border(\"┘\")}`,\n ];\n\n return lines.join(\"\\n\");\n}\n\nfunction buildMinimalBanner(version: string): string {\n return `Vaka v${version} — Your mind is the architect.`;\n}\n\nexport interface AnimateOptions {\n stdout?: NodeJS.WriteStream;\n env?: NodeJS.ProcessEnv;\n version?: string;\n}\n\nexport async function animateVakaEntrance(options: AnimateOptions = {}): Promise<void> {\n const stdout = options.stdout ?? process.stdout;\n const env = options.env ?? process.env;\n const version = options.version ?? \"0.1.0\";\n\n const theme = detectTerminalTheme(env);\n const colorEnabled = supportsColor(stdout, env);\n const interactive = stdout.isTTY === true;\n\n const finalCard = buildVakaCard(FINAL_FRAME, false, theme, colorEnabled, version);\n const cardWidth = Math.max(...finalCard.split(\"\\n\").map((line) => stripAnsi(line).length));\n const columns = stdout.columns ?? cardWidth;\n\n // Piped/CI/non-interactive: print once, no cursor tricks, no animation delay.\n if (!interactive) {\n stdout.write(`${finalCard}\\n`);\n return;\n }\n\n // The card can't fit without wrapping into garbage; a plain line always fits.\n if (columns < cardWidth) {\n stdout.write(`${buildMinimalBanner(version)}\\n`);\n return;\n }\n\n stdout.write(HIDE_CURSOR);\n readline.cursorTo(stdout, 0, 0);\n readline.clearScreenDown(stdout);\n\n for (let i = 0; i < SEED_FRAMES.length; i++) {\n readline.cursorTo(stdout, 0, 0);\n stdout.write(`${buildVakaCard(i, false, theme, colorEnabled, version)}\\n`);\n await new Promise((resolve) => setTimeout(resolve, 85));\n }\n\n const pulseRhythm = [true, false, true, false];\n for (const pulse of pulseRhythm) {\n readline.cursorTo(stdout, 0, 0);\n stdout.write(`${buildVakaCard(FINAL_FRAME, pulse, theme, colorEnabled, version)}\\n`);\n await new Promise((resolve) => setTimeout(resolve, pulse ? 130 : 90));\n }\n\n stdout.write(SHOW_CURSOR);\n}\n","export type TerminalTheme = \"dark\" | \"light\";\n\ninterface ThemeEnv {\n VAKA_THEME?: string;\n COLORFGBG?: string;\n}\n\n/**\n * Most terminal emulators (iTerm2, Terminal.app, VS Code, Windows Terminal)\n * never expose their actual background color to a running process — querying\n * one directly (OSC 11) needs raw-mode stdin and a response timeout, which is\n * too fragile to gate a CLI's startup banner on. So this is a best-effort\n * heuristic (the COLORFGBG convention some terminals like rxvt/mintty set),\n * with an explicit override for everyone else, including for a reliable demo.\n */\nexport function detectTerminalTheme(env: ThemeEnv = process.env): TerminalTheme {\n const override = env.VAKA_THEME?.toLowerCase();\n if (override === \"light\" || override === \"dark\") {\n return override;\n }\n\n const colorFgBg = env.COLORFGBG;\n if (colorFgBg) {\n const bg = Number.parseInt(colorFgBg.split(\";\").pop() ?? \"\", 10);\n if (!Number.isNaN(bg)) {\n // ANSI 16-color palette: 0-6 and 8 are the dark half, 7 and 9-15 are light.\n return bg === 7 || bg >= 9 ? \"light\" : \"dark\";\n }\n }\n\n // No signal either way: most developer terminals default to a dark theme.\n return \"dark\";\n}\n\ninterface ColorEnv {\n NO_COLOR?: string;\n FORCE_COLOR?: string;\n TERM?: string;\n}\n\nexport function supportsColor(\n stream: { isTTY?: boolean } = process.stdout,\n env: ColorEnv = process.env,\n): boolean {\n if (env.NO_COLOR !== undefined) {\n return false;\n }\n if (env.FORCE_COLOR !== undefined && env.FORCE_COLOR !== \"0\") {\n return true;\n }\n if (!stream.isTTY) {\n return false;\n }\n return env.TERM !== \"dumb\";\n}\n","import { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nconst REGISTRY_DIST_TAGS_URL = \"https://registry.npmjs.org/-/package/\";\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000;\nconst FETCH_TIMEOUT_MS = 1500;\n\ninterface UpdateCache {\n lastChecked: number;\n latestVersion: string;\n}\n\nexport type FetchLike = (\n url: string,\n init?: { signal?: AbortSignal },\n) => Promise<{ ok: boolean; json: () => Promise<unknown> }>;\n\nexport interface UpdateNotice {\n currentVersion: string;\n latestVersion: string;\n}\n\ninterface CheckForUpdatesOptions {\n cachePath?: string;\n now?: () => number;\n fetchImpl?: FetchLike;\n}\n\nfunction defaultCachePath(): string {\n return join(homedir(), \".vaka\", \"update-check.json\");\n}\n\nfunction readCache(cachePath: string): UpdateCache | undefined {\n try {\n const parsed = JSON.parse(readFileSync(cachePath, \"utf8\")) as Partial<UpdateCache>;\n if (typeof parsed.lastChecked === \"number\" && typeof parsed.latestVersion === \"string\") {\n return { lastChecked: parsed.lastChecked, latestVersion: parsed.latestVersion };\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction writeCache(cachePath: string, cache: UpdateCache): void {\n try {\n mkdirSync(dirname(cachePath), { recursive: true });\n writeFileSync(cachePath, JSON.stringify(cache), \"utf8\");\n } catch {\n // Best-effort: a write failure just means we check again next run.\n }\n}\n\n/** Compares dotted numeric versions, ignoring any -prerelease/+build suffix. Returns >0 if a is newer. */\nexport function compareVersions(a: string, b: string): number {\n const toParts = (version: string) =>\n (version.split(/[-+]/)[0] ?? \"\").split(\".\").map((part) => Number.parseInt(part, 10) || 0);\n const partsA = toParts(a);\n const partsB = toParts(b);\n const length = Math.max(partsA.length, partsB.length);\n for (let i = 0; i < length; i++) {\n const diff = (partsA[i] ?? 0) - (partsB[i] ?? 0);\n if (diff !== 0) {\n return diff > 0 ? 1 : -1;\n }\n }\n return 0;\n}\n\nasync function fetchLatestVersion(\n packageName: string,\n fetchImpl: FetchLike,\n): Promise<string | undefined> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n try {\n const response = await fetchImpl(`${REGISTRY_DIST_TAGS_URL}${encodeURIComponent(packageName)}/dist-tags`, {\n signal: controller.signal,\n });\n if (!response.ok) {\n return undefined;\n }\n const tags = (await response.json()) as Record<string, unknown>;\n return typeof tags.latest === \"string\" ? tags.latest : undefined;\n } catch {\n // Offline, timed out, or registry unreachable: silently skip this check.\n return undefined;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Returns a notice built from the last cached registry check (instant, no network wait).\n * When the cache is missing or older than CACHE_TTL_MS, also kicks off a background refetch\n * (not awaited) so the cache is fresh for the *next* run. Never blocks and never throws.\n */\nexport function checkForUpdates(\n currentVersion: string,\n packageName: string,\n options: CheckForUpdatesOptions = {},\n): UpdateNotice | undefined {\n const cachePath = options.cachePath ?? defaultCachePath();\n const now = options.now ?? Date.now;\n const fetchImpl = options.fetchImpl ?? (fetch as FetchLike);\n\n const cache = readCache(cachePath);\n const isStale = !cache || now() - cache.lastChecked > CACHE_TTL_MS;\n\n if (isStale) {\n void fetchLatestVersion(packageName, fetchImpl).then((latestVersion) => {\n if (latestVersion) {\n writeCache(cachePath, { lastChecked: now(), latestVersion });\n }\n });\n }\n\n if (cache && compareVersions(cache.latestVersion, currentVersion) > 0) {\n return { currentVersion, latestVersion: cache.latestVersion };\n }\n return undefined;\n}\n\nexport function formatUpdateNotice(notice: UpdateNotice, packageName: string): string {\n const line1 = `Update available: ${notice.currentVersion} → ${notice.latestVersion}`;\n const line2 = `Run: npm install -g ${packageName}`;\n const width = Math.max(line1.length, line2.length) + 2;\n const pad = (line: string) => `│ ${line.padEnd(width - 1)}│`;\n return [\n `┌${\"─\".repeat(width)}┐`,\n pad(line1),\n pad(line2),\n `└${\"─\".repeat(width)}┘`,\n ].join(\"\\n\");\n}\n"],"mappings":"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","names":["lstat","mkdir","readFile","rename","unlink","writeFile","join","resolve","isMissing","resolve","lstat","join","mkdir","writeFile","rename","unlink","readFile","rules","lstat","readFile","join","resolve","isMissing","text","resolve","join","lstat","readFile","rules","rules","text","resolve","dirname","join"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/commands/line-prompter.ts","../../../packages/core/src/session.ts","../../../packages/core/src/checkpoints.ts","../../../packages/core/src/rules.ts","../src/commands/start.ts","../src/commands/log.ts","../src/commands/status.ts","../src/ui/banner.ts","../src/ui/terminal-theme.ts","../src/update-check.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { cancel, confirm, intro, isCancel, log, outro, text } from \"@clack/prompts\";\nimport { initializeProject } from \"./commands/init.js\";\nimport { createLineReaderPrompter } from \"./commands/line-prompter.js\";\nimport { isCheckpointName, runLog } from \"./commands/log.js\";\nimport { CANCELLED, runStart, type StartPrompter } from \"./commands/start.js\";\nimport { runStatus } from \"./commands/status.js\";\nimport { animateVakaEntrance } from \"./ui/banner.js\";\nimport { checkForUpdates, formatUpdateNotice } from \"./update-check.js\";\n\nconst VERSION = \"0.2.0\";\nconst PACKAGE_NAME = \"@vaka.world/cli\";\n\nconst clackPrompter: StartPrompter = {\n async askQuestion(question) {\n const answer = await text({\n message: question.prompt,\n validate: (value) => (value.trim().length === 0 ? \"An answer is required.\" : undefined),\n });\n return isCancel(answer) ? CANCELLED : answer;\n },\n async askConfirm(message) {\n const answer = await confirm({ message });\n return isCancel(answer) ? CANCELLED : answer;\n },\n};\n\nfunction describeResumeState(state: { kind: string; question?: { prompt: string } }): string {\n switch (state.kind) {\n case \"ask-question\":\n return `Next: ${state.question?.prompt}`;\n case \"confirm-design\":\n return \"Next: confirm the design.\";\n case \"authorize-implementation\":\n return \"Next: authorize implementation.\";\n case \"cycle-complete\":\n return \"Nothing required by .vaka/rules.yml for this cycle.\";\n default:\n return \"Unknown state.\";\n }\n}\n\nconst program = new Command()\n .name(\"vaka\")\n .description(\"Make the reasoning behind engineering decisions visible.\")\n .version(VERSION);\n\nprogram\n .command(\"init\")\n .description(\"Add Vaka rules and instructions to the current project.\")\n .action(async () => {\n await animateVakaEntrance({ version: VERSION });\n intro(\"vaka init\");\n\n try {\n const result = await initializeProject(process.cwd());\n\n for (const file of result.created) {\n log.success(`Created ${file}`);\n }\n\n for (const file of result.skipped) {\n log.warn(`Preserved existing file: ${file}`);\n }\n\n if (result.integrations.length === 0) {\n log.info(\n \"No supported AI integration was detected. Created the Vaka project rules; add a Cursor, Claude Code, Codex, Copilot, Windsurf, or Cline marker to install its instructions.\",\n );\n } else {\n log.info(`Detected: ${result.integrations.join(\", \")}`);\n }\n\n outro(\"Local setup is ready. Local records are not server-verified.\");\n } catch (error) {\n log.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nprogram\n .command(\"start\")\n .description(\n \"Work through the Build, Design, and Implementation checkpoints for the current cycle.\",\n )\n .action(async () => {\n intro(\"Vaka | Your mind is the architect.\");\n\n const nonInteractivePrompter =\n process.stdin.isTTY === true ? undefined : createLineReaderPrompter();\n const prompter: StartPrompter = nonInteractivePrompter ?? clackPrompter;\n\n try {\n const outcome = await runStart(process.cwd(), prompter);\n switch (outcome.kind) {\n case \"implementation-approved\":\n outro(\n \"Implementation authorized. Local session is unverified — this records what Vaka accepted locally, not independent proof of understanding or a server verification.\",\n );\n break;\n case \"design-declined\":\n log.warn(\"Design not confirmed. Revisit the edge cases above, then run `vaka start` again.\");\n outro(\"Stopped before design was confirmed.\");\n break;\n case \"implementation-declined\":\n log.warn(\"Implementation not authorized. Nothing was unlocked.\");\n outro(\"Stopped before implementation was authorized.\");\n break;\n case \"cancelled\":\n cancel(\"Stopped (input ended or was interrupted). Resume anytime with `vaka start`.\");\n break;\n case \"nothing-required\":\n outro(\"Nothing is required by .vaka/rules.yml for this cycle.\");\n break;\n }\n } catch (error) {\n log.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n } finally {\n nonInteractivePrompter?.close();\n }\n });\n\nprogram\n .command(\"status\")\n .description(\"Show the current local/unverified checkpoint status.\")\n .option(\"--json\", \"Print the status as machine-readable JSON instead of log lines.\")\n .action(async (options: { json?: boolean }) => {\n try {\n const report = await runStatus(process.cwd());\n if (options.json) {\n console.log(JSON.stringify(report));\n return;\n }\n log.info(report.sessionExists ? \"Local session: unverified\" : \"No local session yet.\");\n log.info(`Recorded events: ${report.totalEvents}`);\n log.info(`Completed cycles: ${report.completedCycles}`);\n log.info(describeResumeState(report.resumeState));\n } catch (error) {\n log.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nconst logCommand = program\n .command(\"log\")\n .description(\n \"Headless, non-interactive event recording for an AI assistant (e.g. the Vaka Claude Code/Codex skill) to append a checkpoint event directly to the local hash chain, without the vaka start wizard.\",\n );\n\nfunction requireCheckpoint(raw: string): \"build\" | \"design\" | \"implementation\" {\n if (!isCheckpointName(raw)) {\n throw new Error(`--checkpoint must be one of build, design, implementation (got \"${raw}\").`);\n }\n return raw;\n}\n\nlogCommand\n .command(\"question\")\n .description(\"Record a question an assistant is about to ask, and print its question id.\")\n .requiredOption(\"--checkpoint <name>\", \"build, design, or implementation\")\n .requiredOption(\"--prompt <text>\", \"The question being asked, verbatim\")\n .option(\"--question-id <id>\", \"Stable id to reuse later with `log answer` (auto-generated if omitted)\")\n .action(async (options: { checkpoint: string; prompt: string; questionId?: string }) => {\n try {\n const result = await runLog(process.cwd(), {\n kind: \"question\",\n checkpoint: requireCheckpoint(options.checkpoint),\n prompt: options.prompt,\n questionId: options.questionId,\n });\n console.log(result.questionId);\n } catch (error) {\n log.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nlogCommand\n .command(\"answer\")\n .description(\"Record the developer's answer to a previously logged question.\")\n .requiredOption(\"--checkpoint <name>\", \"build, design, or implementation\")\n .requiredOption(\"--question-id <id>\", \"The id printed by `log question`\")\n .requiredOption(\"--answer <text>\", \"The developer's answer, verbatim\")\n .action(async (options: { checkpoint: string; questionId: string; answer: string }) => {\n try {\n await runLog(process.cwd(), {\n kind: \"answer\",\n checkpoint: requireCheckpoint(options.checkpoint),\n questionId: options.questionId,\n answer: options.answer,\n });\n } catch (error) {\n log.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nlogCommand\n .command(\"design-confirmed\")\n .description(\"Record that the developer confirmed the design (does not authorize code changes).\")\n .action(async () => {\n try {\n await runLog(process.cwd(), { kind: \"design-confirmed\" });\n } catch (error) {\n log.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nlogCommand\n .command(\"implementation-approved\")\n .description(\"Record that the developer authorized this scoped implementation.\")\n .action(async () => {\n try {\n await runLog(process.cwd(), { kind: \"implementation-approved\" });\n } catch (error) {\n log.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nawait program.parseAsync(process.argv);\n\nconst updateNotice = checkForUpdates(VERSION, PACKAGE_NAME);\nif (updateNotice) {\n console.log(formatUpdateNotice(updateNotice, PACKAGE_NAME));\n}\n","import { lstat, mkdir, readdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, relative, resolve } from \"node:path\";\n\nexport type Integration = \"claude\" | \"cursor\" | \"copilot\" | \"codex\" | \"windsurf\" | \"cline\";\n\nexport interface InitResult {\n integrations: Integration[];\n created: string[];\n updated: string[];\n skipped: string[];\n}\n\nconst rules = `version: 1\ncheckpoints:\n build:\n required: true\n design:\n required: true\n implementation:\n required: true\nverification:\n local_status: unverified\n`;\n\nconst managedStart = \"<!-- BEGIN VAKA MANAGED INSTRUCTIONS -->\";\nconst managedEnd = \"<!-- END VAKA MANAGED INSTRUCTIONS -->\";\n\nconst sharedGuidance = `Before implementing a feature, help the developer reason through its behavior, data, and failure cases. Keep understanding, design confirmation, and implementation authorization distinct. Do not write code until the developer explicitly authorizes the scoped implementation; design confirmation alone is not implementation approval. Explain unfamiliar code and why each change is needed.\n\nVaka instructions are guidance, not a technical enforcement boundary. Local session files are unverified; only a server-accepted seal can be described as server-verified.`;\n\nconst vakaSkillBody = `This project uses Vaka to make sure a developer reasons through a feature before code gets written, and to keep a local, tamper-evident record that they did. You generate the actual checkpoint questions yourself, specific to what's being built — there is no fixed script to recite.\n\n## Check where things stand\n\nBefore doing anything else for a build request, run \\`vaka status --json\\` from the project root. It tells you whether a session already exists, how many cycles have completed, and which checkpoint (\\`build\\`, \\`design\\`, or \\`implementation\\`) comes next — including whether a checkpoint was turned off in \\`.vaka/rules.yml\\` and should be skipped entirely. Only engage a checkpoint \\`vaka status --json\\` says is actually next; if a checkpoint is off, don't ask for it.\n\n## Build checkpoint — make them reason, don't accept a shrug\n\nAsk a question specific to what they just described: the actual data involved, who/what talks to what, a concrete failure case that could bite this exact feature — not a generic template. One well-aimed question can be enough; something more involved may need several. This has to stay free-text: never offer multiple-choice options here, and never let a non-answer pass.\n\n- Before asking, record the question: \\`vaka log question --checkpoint build --prompt \"<exact question>\"\\` — it prints a question id; keep it.\n- Ask the question in chat and wait for a real answer.\n- If they answer \"not sure,\" \"whatever you think,\" or anything else that isn't actual reasoning, say so plainly and ask again, pointing at the specific thing you need them to think through. Don't supply the answer yourself, and don't move on until they've reasoned about it, even briefly — accepting a non-answer defeats the point of this checkpoint.\n- Once they've given a real answer, record it: \\`vaka log answer --checkpoint build --question-id <id> --answer \"<their answer, verbatim>\"\\`.\n- Repeat for as many Build questions as the feature actually needs, then move to Design.\n\n## Design checkpoint — confirm, don't just build\n\nSummarize the design you now share (components, data shape, the key tradeoff) in 1-3 sentences, then offer two choices: **Confirm and continue** (this design is right, move on; no code yet) or **Discuss** (something needs clarifying first). Wait for an actual confirmation; don't treat silence or an unrelated reply as one.\n\nOn confirmation: \\`vaka log design-confirmed\\`.\n\n## Implementation checkpoint — get explicit authorization before writing code\n\nDescribe exactly what you're about to change (files, the specific behavior, nothing broader than what was just designed). Offer **Implement this step** or **Discuss**. Do not write or edit any code for this feature before this step is confirmed.\n\nOn authorization: \\`vaka log implementation-approved\\`. Only then write the code.\n\n## After implementing\n\nBriefly explain what changed and why it matches what was agreed, including any tests added or run. Keep it proportional to the size of the change.\n\n## Honesty\n\nNever call a local Vaka record \"verified\" — say \"recorded locally, unverified,\" matching what \\`vaka status\\` itself says. Don't soften or drop that distinction.`;\n\nconst vakaSkillDescription =\n \"Use when the developer in this project describes a feature, change, or bug fix they want built. Walk them through Vaka's Build, Design, and Implementation reasoning checkpoints before writing code, with questions and confirmations generated from what they're actually building (not a fixed script), and record each step into the local Vaka audit trail with the `vaka log`/`vaka status` commands.\";\n\nconst vakaSkills = {\n claude: `---\nname: vaka\ndescription: ${vakaSkillDescription}\n---\n\n# Vaka reasoning checkpoints\n\n${vakaSkillBody}\n\nUse the \\`AskUserQuestion\\` tool for the Design and Implementation confirm/discuss choices — never for the Build checkpoint's reasoning question, which must stay free-text.\n`,\n codex: `---\nname: vaka\ndescription: ${vakaSkillDescription}\n---\n\n# Vaka reasoning checkpoints\n\n${vakaSkillBody}\n\nThis is Codex, not Claude Code: there is no \\`AskUserQuestion\\` tool. For the Design and Implementation confirm/discuss choices, ask one plain-text question listing the options, then end your turn and wait for the reply. Everything else above applies as written.\n`,\n} as const;\n\nconst instructions = {\n claude: `# Vaka\\n\\n${sharedGuidance}\\n`,\n cursor: `---\\ndescription: Vaka architecture and reasoning guidance\\nalwaysApply: true\\n---\\n\\n${sharedGuidance}\\n`,\n copilot: `# Vaka\\n\\n${sharedGuidance}\\n`,\n codex: sharedGuidance,\n windsurfOwnFile: `---\\ntrigger: always_on\\ndescription: Vaka architecture and reasoning guidance\\n---\\n\\n${sharedGuidance}\\n`,\n windsurfMerge: sharedGuidance,\n clineOwnFile: `# Vaka\\n\\n${sharedGuidance}\\n`,\n clineMerge: sharedGuidance,\n} as const;\n\nfunction isMissing(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n );\n}\n\nfunction isAlreadyExists(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"EEXIST\"\n );\n}\n\nasync function inspectPath(path: string): Promise<\"file\" | \"directory\" | undefined> {\n try {\n const stat = await lstat(path);\n if (stat.isSymbolicLink()) {\n throw new Error(`Refusing to follow symbolic link: ${path}`);\n }\n if (stat.isDirectory()) return \"directory\";\n if (stat.isFile()) return \"file\";\n return undefined;\n } catch (error) {\n if (isMissing(error)) return undefined;\n throw error;\n }\n}\n\n/**\n * `vaka init` always creates `.claude/skills/vaka/`, regardless of whether\n * this project otherwise uses Claude Code — so a bare `.claude` directory\n * whose only content is Vaka's own skill must not itself be read back as\n * \"this project already uses Claude Code\" on a later run (that would start\n * writing CLAUDE.md into projects that never asked for it).\n */\nasync function hasPreExistingClaudeDirectoryMarker(projectRoot: string): Promise<boolean> {\n const claudeDirectoryPath = join(projectRoot, \".claude\");\n if ((await inspectPath(claudeDirectoryPath)) !== \"directory\") return false;\n const entries = await readdir(claudeDirectoryPath);\n return entries.length === 0 || entries.some((entry) => entry !== \"skills\");\n}\n\nasync function detectIntegrations(projectRoot: string): Promise<Integration[]> {\n const [\n cursor,\n claudeManifest,\n hasClaudeDirectoryMarker,\n copilotManifest,\n instructionsDirectory,\n codexManifest,\n codexDirectory,\n windsurfDirectory,\n windsurfLegacyFile,\n clinerules,\n ] = await Promise.all([\n inspectPath(join(projectRoot, \".cursor\")),\n inspectPath(join(projectRoot, \"CLAUDE.md\")),\n hasPreExistingClaudeDirectoryMarker(projectRoot),\n inspectPath(join(projectRoot, \".github\", \"copilot-instructions.md\")),\n inspectPath(join(projectRoot, \".github\", \"instructions\")),\n inspectPath(join(projectRoot, \"AGENTS.md\")),\n inspectPath(join(projectRoot, \".codex\")),\n inspectPath(join(projectRoot, \".windsurf\")),\n inspectPath(join(projectRoot, \".windsurfrules\")),\n inspectPath(join(projectRoot, \".clinerules\")),\n ]);\n\n const integrations: Integration[] = [];\n if (cursor === \"directory\") integrations.push(\"cursor\");\n if (claudeManifest === \"file\" || hasClaudeDirectoryMarker) {\n integrations.push(\"claude\");\n }\n\n let copilotDetected =\n copilotManifest === \"file\" || instructionsDirectory === \"directory\";\n const vscodeSettings = join(projectRoot, \".vscode\", \"settings.json\");\n if (!copilotDetected && (await inspectPath(vscodeSettings)) === \"file\") {\n const settings = await readFile(vscodeSettings, \"utf8\");\n copilotDetected = /\"github\\.copilot\\.[^\"]+\"\\s*:/.test(settings);\n }\n if (copilotDetected) integrations.push(\"copilot\");\n\n if (codexManifest === \"file\" || codexDirectory === \"directory\") {\n integrations.push(\"codex\");\n }\n if (windsurfDirectory === \"directory\" || windsurfLegacyFile === \"file\") {\n integrations.push(\"windsurf\");\n }\n if (clinerules === \"file\" || clinerules === \"directory\") {\n integrations.push(\"cline\");\n }\n\n return integrations;\n}\n\nasync function ensureDirectory(projectRoot: string, relativePath: string): Promise<void> {\n const absolutePath = resolve(projectRoot, relativePath);\n const fromRoot = relative(projectRoot, absolutePath);\n if (fromRoot.startsWith(\"..\") || isAbsolute(fromRoot)) {\n throw new Error(`Refusing to create a directory outside the project: ${relativePath}`);\n }\n\n const segments = fromRoot.split(/[/\\\\]/).filter(Boolean);\n let current = projectRoot;\n\n for (const segment of segments) {\n current = join(current, segment);\n const existing = await inspectPath(current);\n if (existing === \"file\") {\n throw new Error(`Expected a directory, found a file: ${current}`);\n }\n if (existing === undefined) {\n try {\n await mkdir(current, { mode: segment === \".vaka\" ? 0o700 : 0o755 });\n } catch (error) {\n if (!isAlreadyExists(error)) throw error;\n }\n if ((await inspectPath(current)) !== \"directory\") {\n throw new Error(`Could not safely create directory: ${current}`);\n }\n }\n }\n}\n\nasync function createIfMissing(\n projectRoot: string,\n relativePath: string,\n contents: string,\n): Promise<\"created\" | \"skipped\"> {\n const absolutePath = resolve(projectRoot, relativePath);\n const parent = relative(projectRoot, absolutePath).split(/[/\\\\]/).slice(0, -1).join(\"/\");\n if (parent) await ensureDirectory(projectRoot, parent);\n\n try {\n await writeFile(absolutePath, contents, {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: 0o644,\n });\n return \"created\";\n } catch (error) {\n if (isAlreadyExists(error)) return \"skipped\";\n throw error;\n }\n}\n\nfunction wrapManagedSection(body: string): string {\n return `${managedStart}\\n${body}\\n${managedEnd}`;\n}\n\nfunction mergeManagedSection(existing: string, body: string): string {\n const section = wrapManagedSection(body);\n const start = existing.indexOf(managedStart);\n const end = existing.indexOf(managedEnd);\n if (start === -1 && end === -1) {\n const separator = existing.length === 0 ? \"\" : existing.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n return `${existing}${separator}${section}\\n`;\n }\n\n if (\n start === -1 ||\n end === -1 ||\n end < start ||\n existing.indexOf(managedStart, start + managedStart.length) !== -1 ||\n existing.indexOf(managedEnd, end + managedEnd.length) !== -1\n ) {\n throw new Error(\"File has malformed Vaka instruction markers; refusing to modify it.\");\n }\n\n const managedEndIndex = end + managedEnd.length;\n return `${existing.slice(0, start)}${section}${existing.slice(managedEndIndex)}`;\n}\n\nasync function mergeIntoFile(\n projectRoot: string,\n relativePath: string,\n sectionBody: string,\n): Promise<\"created\" | \"updated\" | \"skipped\"> {\n const absolutePath = resolve(projectRoot, relativePath);\n const parent = relative(projectRoot, absolutePath).split(/[/\\\\]/).slice(0, -1).join(\"/\");\n if (parent) await ensureDirectory(projectRoot, parent);\n\n const pathType = await inspectPath(absolutePath);\n if (pathType === undefined) {\n try {\n await writeFile(absolutePath, `${wrapManagedSection(sectionBody)}\\n`, {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: 0o644,\n });\n return \"created\";\n } catch (error) {\n if (!isAlreadyExists(error)) throw error;\n }\n } else if (pathType !== \"file\") {\n throw new Error(`Expected a regular file, found a directory: ${absolutePath}`);\n }\n\n const stat = await lstat(absolutePath);\n if (!stat.isFile() || stat.isSymbolicLink()) {\n throw new Error(`Expected a regular file: ${absolutePath}`);\n }\n\n const existing = await readFile(absolutePath, \"utf8\");\n const updated = mergeManagedSection(existing, sectionBody);\n if (updated === existing) return \"skipped\";\n\n const temporaryPath = join(\n dirname(absolutePath),\n `.${basename(absolutePath)}.${crypto.randomUUID()}.tmp`,\n );\n try {\n await writeFile(temporaryPath, updated, {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: stat.mode & 0o777,\n });\n await rename(temporaryPath, absolutePath);\n } catch (error) {\n try {\n await unlink(temporaryPath);\n } catch (cleanupError) {\n if (!isMissing(cleanupError)) {\n throw new AggregateError(\n [error, cleanupError],\n `Could not update ${absolutePath} or clean up ${temporaryPath}.`,\n );\n }\n }\n throw error;\n }\n return \"updated\";\n}\n\nasync function resolveWindsurfTarget(\n projectRoot: string,\n): Promise<{ mode: \"own-file\" | \"merge\"; relativePath: string }> {\n const directory = await inspectPath(join(projectRoot, \".windsurf\"));\n if (directory === \"directory\") {\n return { mode: \"own-file\", relativePath: \".windsurf/rules/vaka.md\" };\n }\n return { mode: \"merge\", relativePath: \".windsurfrules\" };\n}\n\nasync function resolveClineTarget(\n projectRoot: string,\n): Promise<{ mode: \"own-file\" | \"merge\"; relativePath: string }> {\n const existing = await inspectPath(join(projectRoot, \".clinerules\"));\n if (existing === \"directory\") {\n return { mode: \"own-file\", relativePath: \".clinerules/vaka.md\" };\n }\n return { mode: \"merge\", relativePath: \".clinerules\" };\n}\n\nexport async function initializeProject(projectPath: string): Promise<InitResult> {\n const projectRoot = resolve(projectPath);\n if ((await inspectPath(projectRoot)) !== \"directory\") {\n throw new Error(`Project path is not a directory: ${projectRoot}`);\n }\n\n const integrations = await detectIntegrations(projectRoot);\n const result: InitResult = { integrations, created: [], updated: [], skipped: [] };\n\n const ownFiles: Array<{ relativePath: string; contents: string }> = [\n { relativePath: \".vaka/rules.yml\", contents: rules },\n { relativePath: \".claude/skills/vaka/SKILL.md\", contents: vakaSkills.claude },\n { relativePath: \".agents/skills/vaka/SKILL.md\", contents: vakaSkills.codex },\n ];\n if (integrations.includes(\"claude\")) {\n ownFiles.push({ relativePath: \"CLAUDE.md\", contents: instructions.claude });\n }\n if (integrations.includes(\"cursor\")) {\n ownFiles.push({ relativePath: \".cursor/rules/vaka.mdc\", contents: instructions.cursor });\n }\n if (integrations.includes(\"copilot\")) {\n ownFiles.push({\n relativePath: \".github/copilot-instructions.md\",\n contents: instructions.copilot,\n });\n }\n\n for (const file of ownFiles) {\n const status = await createIfMissing(projectRoot, file.relativePath, file.contents);\n result[status].push(file.relativePath);\n }\n\n if (integrations.includes(\"codex\")) {\n const status = await mergeIntoFile(projectRoot, \"AGENTS.md\", instructions.codex);\n result[status].push(\"AGENTS.md\");\n }\n\n if (integrations.includes(\"windsurf\")) {\n const target = await resolveWindsurfTarget(projectRoot);\n const status =\n target.mode === \"own-file\"\n ? await createIfMissing(projectRoot, target.relativePath, instructions.windsurfOwnFile)\n : await mergeIntoFile(projectRoot, target.relativePath, instructions.windsurfMerge);\n result[status].push(target.relativePath);\n }\n\n if (integrations.includes(\"cline\")) {\n const target = await resolveClineTarget(projectRoot);\n const status =\n target.mode === \"own-file\"\n ? await createIfMissing(projectRoot, target.relativePath, instructions.clineOwnFile)\n : await mergeIntoFile(projectRoot, target.relativePath, instructions.clineMerge);\n result[status].push(target.relativePath);\n }\n\n return result;\n}\n","import { createInterface } from \"node:readline\";\nimport type { Readable, Writable } from \"node:stream\";\nimport { CANCELLED, type StartPrompter } from \"./start.js\";\n\nexport interface LineReaderPrompter extends StartPrompter {\n close(): void;\n}\n\nexport function createLineReaderPrompter(\n input: Readable = process.stdin,\n output: Writable = process.stdout,\n): LineReaderPrompter {\n const rl = createInterface({ input, terminal: false });\n const lines = rl[Symbol.asyncIterator]();\n\n async function nextLine(): Promise<string | undefined> {\n const { value, done } = await lines.next();\n return done ? undefined : value;\n }\n\n return {\n async askQuestion(question) {\n output.write(`${question.prompt}\\n> `);\n const line = await nextLine();\n if (line === undefined) return CANCELLED;\n const answer = line.trim();\n if (answer.length === 0) {\n throw new Error(`Expected a non-empty answer for: ${question.prompt}`);\n }\n return answer;\n },\n async askConfirm(message) {\n output.write(`${message} (y/n)\\n> `);\n const line = await nextLine();\n if (line === undefined) return CANCELLED;\n const normalized = line.trim().toLowerCase();\n if (normalized === \"y\" || normalized === \"yes\") return true;\n if (normalized === \"n\" || normalized === \"no\") return false;\n throw new Error(`Expected \"y\" or \"n\" for: ${message} (got ${JSON.stringify(line)})`);\n },\n close() {\n rl.close();\n },\n };\n}\n","import { createHash, randomUUID } from \"node:crypto\";\nimport { lstat, mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\n\nexport type JsonValue =\n | null\n | boolean\n | number\n | string\n | JsonValue[]\n | { [key: string]: JsonValue };\n\nexport type CheckpointName = \"build\" | \"design\" | \"implementation\";\nexport type EventActor = \"developer\" | \"assistant\";\nexport type EventType =\n | \"checkpoint-question\"\n | \"checkpoint-answer\"\n | \"design-confirmed\"\n | \"implementation-approved\";\n\nexport interface SessionEventInput {\n checkpoint: CheckpointName;\n actor: EventActor;\n type: EventType;\n payload: JsonValue;\n}\n\nexport interface SessionEvent extends SessionEventInput {\n sequence: number;\n recordedAt: string;\n previousHash: string | null;\n hash: string;\n}\n\nexport interface LocalSession {\n schemaVersion: 1;\n id: string;\n provenance: \"local\";\n status: \"unverified\";\n createdAt: string;\n events: SessionEvent[];\n}\n\nexport type SessionIntegrityResult =\n | { valid: true }\n | { valid: false; eventIndex?: number; reason: string };\n\nexport const LOCAL_SESSION_RELATIVE_PATH = \".vaka/session.json\";\n\nfunction canonicalize(value: unknown, ancestors: WeakSet<object>): string {\n if (value === null || typeof value === \"boolean\" || typeof value === \"string\") {\n return JSON.stringify(value);\n }\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) throw new TypeError(\"Session payload numbers must be finite.\");\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) {\n if (ancestors.has(value)) throw new TypeError(\"Session payload cannot contain cycles.\");\n ancestors.add(value);\n const serialized = `[${value.map((item) => canonicalize(item, ancestors)).join(\",\")}]`;\n ancestors.delete(value);\n return serialized;\n }\n if (typeof value === \"object\") {\n const object = value as Record<string, unknown>;\n const prototype = Object.getPrototypeOf(object);\n if (prototype !== Object.prototype && prototype !== null) {\n throw new TypeError(\"Session payload must contain only plain JSON objects.\");\n }\n if (ancestors.has(object)) throw new TypeError(\"Session payload cannot contain cycles.\");\n ancestors.add(object);\n const serialized = `{${Object.keys(object)\n .sort()\n .map((key) => {\n const item = object[key];\n if (item === undefined) {\n throw new TypeError(\"Session payload cannot contain undefined values.\");\n }\n return `${JSON.stringify(key)}:${canonicalize(item, ancestors)}`;\n })\n .join(\",\")}}`;\n ancestors.delete(object);\n return serialized;\n }\n throw new TypeError(\"Session payload must be valid JSON.\");\n}\n\nfunction canonicalJson(value: unknown): string {\n return canonicalize(value, new WeakSet());\n}\n\nfunction isCheckpointName(value: unknown): value is CheckpointName {\n return value === \"build\" || value === \"design\" || value === \"implementation\";\n}\n\nfunction isEventActor(value: unknown): value is EventActor {\n return value === \"developer\" || value === \"assistant\";\n}\n\nfunction isEventType(value: unknown): value is EventType {\n return (\n value === \"checkpoint-question\" ||\n value === \"checkpoint-answer\" ||\n value === \"design-confirmed\" ||\n value === \"implementation-approved\"\n );\n}\n\nfunction hasExactKeys(value: object, keys: string[]): boolean {\n const actual = Object.keys(value).sort();\n const expected = [...keys].sort();\n return actual.length === expected.length && actual.every((key, index) => key === expected[index]);\n}\n\nfunction hashEvent(\n sessionId: string,\n event: Omit<SessionEvent, \"hash\">,\n): string {\n const content = canonicalJson({\n sessionId,\n sequence: event.sequence,\n checkpoint: event.checkpoint,\n actor: event.actor,\n type: event.type,\n payload: event.payload,\n recordedAt: event.recordedAt,\n previousHash: event.previousHash,\n });\n return createHash(\"sha256\").update(content, \"utf8\").digest(\"hex\");\n}\n\nexport function createLocalSession(options: {\n id?: string;\n createdAt?: string;\n} = {}): LocalSession {\n return {\n schemaVersion: 1,\n id: options.id ?? randomUUID(),\n provenance: \"local\",\n status: \"unverified\",\n createdAt: options.createdAt ?? new Date().toISOString(),\n events: [],\n };\n}\n\nexport function verifySessionIntegrity(session: unknown): SessionIntegrityResult {\n if (typeof session !== \"object\" || session === null) {\n return { valid: false, reason: \"Session must be an object.\" };\n }\n\n const candidate = session as Partial<LocalSession>;\n if (\n !hasExactKeys(candidate, [\n \"schemaVersion\",\n \"id\",\n \"provenance\",\n \"status\",\n \"createdAt\",\n \"events\",\n ]) ||\n candidate.schemaVersion !== 1 ||\n typeof candidate.id !== \"string\" ||\n candidate.id.length === 0 ||\n candidate.provenance !== \"local\" ||\n candidate.status !== \"unverified\" ||\n typeof candidate.createdAt !== \"string\" ||\n Number.isNaN(Date.parse(candidate.createdAt)) ||\n !Array.isArray(candidate.events)\n ) {\n return { valid: false, reason: \"Session metadata is invalid or has an unsupported version.\" };\n }\n\n let previousHash: string | null = null;\n let previousRecordedAt = candidate.createdAt;\n for (let index = 0; index < candidate.events.length; index += 1) {\n const event = candidate.events[index];\n if (\n typeof event !== \"object\" ||\n event === null ||\n !hasExactKeys(event, [\n \"sequence\",\n \"checkpoint\",\n \"actor\",\n \"type\",\n \"payload\",\n \"recordedAt\",\n \"previousHash\",\n \"hash\",\n ]) ||\n event.sequence !== index ||\n !isCheckpointName(event.checkpoint) ||\n !isEventActor(event.actor) ||\n !isEventType(event.type) ||\n typeof event.recordedAt !== \"string\" ||\n Number.isNaN(Date.parse(event.recordedAt)) ||\n event.previousHash !== previousHash ||\n typeof event.hash !== \"string\" ||\n !/^[a-f0-9]{64}$/.test(event.hash)\n ) {\n return { valid: false, eventIndex: index, reason: \"Event shape or sequence is invalid.\" };\n }\n\n if (Date.parse(event.recordedAt) < Date.parse(previousRecordedAt)) {\n return {\n valid: false,\n eventIndex: index,\n reason:\n \"Event timestamp is earlier than a prior event or the session's creation time.\",\n };\n }\n\n try {\n const { hash, ...eventWithoutHash } = event;\n if (hashEvent(candidate.id, eventWithoutHash) !== hash) {\n return { valid: false, eventIndex: index, reason: \"Event hash does not match its contents.\" };\n }\n } catch (error) {\n return {\n valid: false,\n eventIndex: index,\n reason: error instanceof Error ? error.message : String(error),\n };\n }\n\n previousRecordedAt = event.recordedAt;\n previousHash = event.hash;\n }\n\n return { valid: true };\n}\n\nexport function appendSessionEvent(\n session: LocalSession,\n input: SessionEventInput,\n recordedAt = new Date().toISOString(),\n): LocalSession {\n const integrity = verifySessionIntegrity(session);\n if (!integrity.valid) {\n throw new Error(\n `Cannot append to an invalid local session${integrity.eventIndex === undefined ? \"\" : ` at event ${integrity.eventIndex}`}: ${integrity.reason}`,\n );\n }\n if (!isCheckpointName(input.checkpoint) || !isEventActor(input.actor) || !isEventType(input.type)) {\n throw new TypeError(\"Session event has an unsupported checkpoint, actor, or type.\");\n }\n if (Number.isNaN(Date.parse(recordedAt))) {\n throw new TypeError(\"Session event timestamp must be a valid date.\");\n }\n const previousRecordedAt = session.events.at(-1)?.recordedAt ?? session.createdAt;\n if (Date.parse(recordedAt) < Date.parse(previousRecordedAt)) {\n throw new RangeError(\n \"Session event timestamp cannot be earlier than the previous event or the session's creation time.\",\n );\n }\n\n const previousHash = session.events.at(-1)?.hash ?? null;\n const eventWithoutHash: Omit<SessionEvent, \"hash\"> = {\n sequence: session.events.length,\n checkpoint: input.checkpoint,\n actor: input.actor,\n type: input.type,\n payload: input.payload,\n recordedAt,\n previousHash,\n };\n const event: SessionEvent = {\n ...eventWithoutHash,\n hash: hashEvent(session.id, eventWithoutHash),\n };\n return { ...session, events: [...session.events, event] };\n}\n\nfunction isMissing(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n );\n}\n\nasync function ensureStateDirectory(projectRoot: string): Promise<string> {\n const root = resolve(projectRoot);\n const rootStat = await lstat(root);\n if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) {\n throw new Error(`Project path is not a safe directory: ${root}`);\n }\n\n const stateDirectory = join(root, \".vaka\");\n try {\n const stateStat = await lstat(stateDirectory);\n if (!stateStat.isDirectory() || stateStat.isSymbolicLink()) {\n throw new Error(`Vaka state path must be a real directory: ${stateDirectory}`);\n }\n } catch (error) {\n if (!isMissing(error)) throw error;\n try {\n await mkdir(stateDirectory, { mode: 0o700 });\n } catch (createError) {\n if (\n !(\n typeof createError === \"object\" &&\n createError !== null &&\n \"code\" in createError &&\n createError.code === \"EEXIST\"\n )\n ) {\n throw createError;\n }\n }\n const stateStat = await lstat(stateDirectory);\n if (!stateStat.isDirectory() || stateStat.isSymbolicLink()) {\n throw new Error(`Vaka state path must be a real directory: ${stateDirectory}`);\n }\n }\n return stateDirectory;\n}\n\nasync function inspectStateDirectory(projectRoot: string): Promise<string> {\n const root = resolve(projectRoot);\n const rootStat = await lstat(root);\n if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) {\n throw new Error(`Project path is not a safe directory: ${root}`);\n }\n\n const stateDirectory = join(root, \".vaka\");\n const stateStat = await lstat(stateDirectory);\n if (!stateStat.isDirectory() || stateStat.isSymbolicLink()) {\n throw new Error(`Vaka state path must be a real directory: ${stateDirectory}`);\n }\n return stateDirectory;\n}\n\nexport async function saveLocalSession(\n projectRoot: string,\n session: LocalSession,\n): Promise<void> {\n const integrity = verifySessionIntegrity(session);\n if (!integrity.valid) {\n throw new Error(`Refusing to save an invalid local session: ${integrity.reason}`);\n }\n\n const stateDirectory = await ensureStateDirectory(projectRoot);\n const sessionPath = join(stateDirectory, \"session.json\");\n try {\n const existing = await lstat(sessionPath);\n if (existing.isSymbolicLink() || !existing.isFile()) {\n throw new Error(`Session path must be a regular file: ${sessionPath}`);\n }\n } catch (error) {\n if (!isMissing(error)) throw error;\n }\n\n const temporaryPath = join(stateDirectory, `session.${randomUUID()}.tmp`);\n try {\n await writeFile(temporaryPath, `${JSON.stringify(session, null, 2)}\\n`, {\n encoding: \"utf8\",\n flag: \"wx\",\n mode: 0o600,\n });\n await rename(temporaryPath, sessionPath);\n } catch (error) {\n try {\n await unlink(temporaryPath);\n } catch (cleanupError) {\n if (!isMissing(cleanupError)) {\n throw new AggregateError(\n [error, cleanupError],\n `Could not save the session or clean up ${temporaryPath}.`,\n );\n }\n }\n throw error;\n }\n}\n\nexport async function loadLocalSession(projectRoot: string): Promise<LocalSession> {\n const stateDirectory = await inspectStateDirectory(projectRoot);\n const sessionPath = join(stateDirectory, \"session.json\");\n const stat = await lstat(sessionPath);\n if (!stat.isFile() || stat.isSymbolicLink()) {\n throw new Error(`Session path must be a regular file: ${sessionPath}`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(await readFile(sessionPath, \"utf8\"));\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(`Session JSON is invalid: ${sessionPath}`, { cause: error });\n }\n throw error;\n }\n\n const integrity = verifySessionIntegrity(parsed);\n if (!integrity.valid) {\n throw new Error(`Local session integrity check failed: ${integrity.reason}`);\n }\n return parsed as LocalSession;\n}\n\nexport async function tryLoadLocalSession(\n projectRoot: string,\n): Promise<LocalSession | undefined> {\n try {\n return await loadLocalSession(projectRoot);\n } catch (error) {\n if (isMissing(error)) return undefined;\n throw error;\n }\n}\n\nexport async function loadOrCreateLocalSession(projectRoot: string): Promise<LocalSession> {\n return (await tryLoadLocalSession(projectRoot)) ?? createLocalSession();\n}\n","import type { CheckpointName, SessionEvent } from \"./session.js\";\n\nexport interface CheckpointQuestion {\n id: string;\n checkpoint: CheckpointName;\n prompt: string;\n}\n\nexport const CHECKPOINT_QUESTIONS: readonly CheckpointQuestion[] = [\n {\n id: \"build-goal\",\n checkpoint: \"build\",\n prompt: \"What is the goal of this feature, in one or two sentences?\",\n },\n {\n id: \"build-flow\",\n checkpoint: \"build\",\n prompt:\n \"What are the system boundaries and state transitions — what talks to what, and where does this sit in the flow?\",\n },\n {\n id: \"build-data\",\n checkpoint: \"build\",\n prompt: \"What data does this touch, and why these structures, relations, and indexes?\",\n },\n {\n id: \"design-edge-cases\",\n checkpoint: \"design\",\n prompt:\n \"What edge cases could break this — concurrency, idempotency, timeouts, or network failure — and how are they handled?\",\n },\n];\n\nexport interface CheckpointRequirement {\n required: boolean;\n}\n\nexport interface RulesConfig {\n checkpoints: Record<CheckpointName, CheckpointRequirement>;\n}\n\nexport const DEFAULT_RULES: RulesConfig = {\n checkpoints: {\n build: { required: true },\n design: { required: true },\n implementation: { required: true },\n },\n};\n\nexport type ResumeState =\n | { kind: \"ask-question\"; question: CheckpointQuestion }\n | { kind: \"confirm-design\" }\n | { kind: \"authorize-implementation\" }\n | { kind: \"cycle-complete\" };\n\nconst CHECKPOINT_ORDER: readonly CheckpointName[] = [\"build\", \"design\", \"implementation\"];\n\nfunction questionsFor(checkpoint: CheckpointName): readonly CheckpointQuestion[] {\n return CHECKPOINT_QUESTIONS.filter((question) => question.checkpoint === checkpoint);\n}\n\nfunction lastIndexOfType(\n events: readonly SessionEvent[],\n type: SessionEvent[\"type\"],\n): number {\n for (let index = events.length - 1; index >= 0; index -= 1) {\n if (events[index]?.type === type) return index;\n }\n return -1;\n}\n\nconst FIXED_BANK_QUESTION_IDS = new Set(CHECKPOINT_QUESTIONS.map((question) => question.id));\n\nfunction answeredQuestionIds(\n cycle: readonly SessionEvent[],\n checkpoint: CheckpointName,\n): Set<string> {\n const answered = new Set<string>();\n for (const event of cycle) {\n if (event.checkpoint !== checkpoint || event.type !== \"checkpoint-answer\") continue;\n const payload = event.payload;\n if (typeof payload === \"object\" && payload !== null && !Array.isArray(payload)) {\n const questionId = payload.questionId;\n if (typeof questionId === \"string\") answered.add(questionId);\n }\n }\n return answered;\n}\n\n/**\n * A question/answer pair recorded with an ID outside the fixed bank — e.g. a\n * context-specific question an AI assistant asked inline (via `vaka log`)\n * instead of the `vaka start` wizard's scripted bank. One freeform answer at\n * a checkpoint satisfies that checkpoint's question phase on its own: unlike\n * the fixed bank (which always asks all of its questions), the right number\n * of dynamic questions is a judgment call for whoever's asking them, not a\n * fixed count this function can know in advance.\n */\nfunction hasFreeformAnswer(cycle: readonly SessionEvent[], checkpoint: CheckpointName): boolean {\n return cycle.some((event) => {\n if (event.checkpoint !== checkpoint || event.type !== \"checkpoint-answer\") return false;\n const payload = event.payload;\n if (typeof payload !== \"object\" || payload === null || Array.isArray(payload)) return false;\n const questionId = payload.questionId;\n return typeof questionId === \"string\" && !FIXED_BANK_QUESTION_IDS.has(questionId);\n });\n}\n\n/**\n * A session is one continuous, append-only chain for the whole project's\n * life. Each completed Build -> Design -> Implementation pass is a \"cycle\";\n * the current cycle is everything recorded after the most recent\n * implementation-approved event (or the whole history, if none has happened\n * yet).\n */\nexport function currentCycleEvents(events: readonly SessionEvent[]): readonly SessionEvent[] {\n const lastApprovalIndex = lastIndexOfType(events, \"implementation-approved\");\n return events.slice(lastApprovalIndex + 1);\n}\n\nexport function resolveResumeState(\n events: readonly SessionEvent[],\n rules: RulesConfig,\n): ResumeState {\n const cycle = currentCycleEvents(events);\n\n for (const checkpoint of CHECKPOINT_ORDER) {\n if (!rules.checkpoints[checkpoint].required) continue;\n\n const answered = answeredQuestionIds(cycle, checkpoint);\n const nextQuestion = questionsFor(checkpoint).find((question) => !answered.has(question.id));\n if (nextQuestion && !hasFreeformAnswer(cycle, checkpoint)) {\n return { kind: \"ask-question\", question: nextQuestion };\n }\n\n if (checkpoint === \"design\" && lastIndexOfType(cycle, \"design-confirmed\") === -1) {\n return { kind: \"confirm-design\" };\n }\n if (\n checkpoint === \"implementation\" &&\n lastIndexOfType(cycle, \"implementation-approved\") === -1\n ) {\n return { kind: \"authorize-implementation\" };\n }\n }\n\n return { kind: \"cycle-complete\" };\n}\n","import { lstat, readFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { DEFAULT_RULES, type RulesConfig } from \"./checkpoints.js\";\nimport type { CheckpointName } from \"./session.js\";\n\nconst CHECKPOINT_NAMES: readonly CheckpointName[] = [\"build\", \"design\", \"implementation\"];\n\nfunction isMissing(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n );\n}\n\nfunction parseRulesDocument(path: string, text: string): RulesConfig {\n let parsed: unknown;\n try {\n parsed = parseYaml(text);\n } catch (error) {\n throw new Error(`Could not parse ${path} as YAML.`, { cause: error });\n }\n\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(`${path} must contain a YAML mapping at the top level.`);\n }\n\n const document = parsed as Record<string, unknown>;\n const checkpointsField = document.checkpoints;\n if (\n typeof checkpointsField !== \"object\" ||\n checkpointsField === null ||\n Array.isArray(checkpointsField)\n ) {\n throw new Error(`${path} is missing a valid top-level \"checkpoints\" mapping.`);\n }\n const checkpointsDocument = checkpointsField as Record<string, unknown>;\n\n const checkpoints = {} as Record<CheckpointName, { required: boolean }>;\n for (const name of CHECKPOINT_NAMES) {\n const entry = checkpointsDocument[name];\n if (\n typeof entry !== \"object\" ||\n entry === null ||\n Array.isArray(entry) ||\n typeof (entry as Record<string, unknown>).required !== \"boolean\"\n ) {\n throw new Error(\n `${path} is missing a boolean \"checkpoints.${name}.required\" value.`,\n );\n }\n checkpoints[name] = { required: (entry as Record<string, unknown>).required as boolean };\n }\n\n return { checkpoints };\n}\n\nexport async function loadRulesConfig(projectRoot: string): Promise<RulesConfig> {\n const root = resolve(projectRoot);\n const rulesPath = join(root, \".vaka\", \"rules.yml\");\n\n let stat;\n try {\n stat = await lstat(rulesPath);\n } catch (error) {\n if (isMissing(error)) return DEFAULT_RULES;\n throw error;\n }\n if (!stat.isFile() || stat.isSymbolicLink()) {\n throw new Error(`Vaka rules path must be a regular file: ${rulesPath}`);\n }\n\n const text = await readFile(rulesPath, \"utf8\");\n return parseRulesDocument(rulesPath, text);\n}\n","import {\n appendSessionEvent,\n loadOrCreateLocalSession,\n loadRulesConfig,\n resolveResumeState,\n saveLocalSession,\n type CheckpointQuestion,\n} from \"@vaka/core\";\n\nexport const CANCELLED = Symbol(\"cancelled\");\n\nexport interface StartPrompter {\n askQuestion(question: CheckpointQuestion): Promise<string | typeof CANCELLED>;\n askConfirm(message: string): Promise<boolean | typeof CANCELLED>;\n}\n\nexport type StartOutcome =\n | { kind: \"implementation-approved\" }\n | { kind: \"design-declined\" }\n | { kind: \"implementation-declined\" }\n | { kind: \"cancelled\" }\n | { kind: \"nothing-required\" };\n\nexport async function runStart(\n projectRoot: string,\n prompter: StartPrompter,\n): Promise<StartOutcome> {\n const rules = await loadRulesConfig(projectRoot);\n let session = await loadOrCreateLocalSession(projectRoot);\n\n for (;;) {\n const state = resolveResumeState(session.events, rules);\n\n if (state.kind === \"cycle-complete\") {\n return { kind: \"nothing-required\" };\n }\n\n if (state.kind === \"ask-question\") {\n session = appendSessionEvent(session, {\n checkpoint: state.question.checkpoint,\n actor: \"assistant\",\n type: \"checkpoint-question\",\n payload: { questionId: state.question.id, prompt: state.question.prompt },\n });\n await saveLocalSession(projectRoot, session);\n\n const answer = await prompter.askQuestion(state.question);\n if (answer === CANCELLED) return { kind: \"cancelled\" };\n\n session = appendSessionEvent(session, {\n checkpoint: state.question.checkpoint,\n actor: \"developer\",\n type: \"checkpoint-answer\",\n payload: { questionId: state.question.id, answer },\n });\n await saveLocalSession(projectRoot, session);\n continue;\n }\n\n if (state.kind === \"confirm-design\") {\n const confirmed = await prompter.askConfirm(\n \"Does this design look right to proceed with?\",\n );\n if (confirmed === CANCELLED) return { kind: \"cancelled\" };\n if (!confirmed) return { kind: \"design-declined\" };\n\n session = appendSessionEvent(session, {\n checkpoint: \"design\",\n actor: \"developer\",\n type: \"design-confirmed\",\n payload: {},\n });\n await saveLocalSession(projectRoot, session);\n continue;\n }\n\n const approved = await prompter.askConfirm(\n \"Authorize implementation of exactly this scoped change?\",\n );\n if (approved === CANCELLED) return { kind: \"cancelled\" };\n if (!approved) return { kind: \"implementation-declined\" };\n\n session = appendSessionEvent(session, {\n checkpoint: \"implementation\",\n actor: \"developer\",\n type: \"implementation-approved\",\n payload: {},\n });\n await saveLocalSession(projectRoot, session);\n return { kind: \"implementation-approved\" };\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n appendSessionEvent,\n loadOrCreateLocalSession,\n saveLocalSession,\n type CheckpointName,\n} from \"@vaka/core\";\n\nconst CHECKPOINT_NAMES: readonly CheckpointName[] = [\"build\", \"design\", \"implementation\"];\n\nexport function isCheckpointName(value: string): value is CheckpointName {\n return (CHECKPOINT_NAMES as readonly string[]).includes(value);\n}\n\nexport type LogInput =\n | { kind: \"question\"; checkpoint: CheckpointName; prompt: string; questionId?: string }\n | { kind: \"answer\"; checkpoint: CheckpointName; questionId: string; answer: string }\n | { kind: \"design-confirmed\" }\n | { kind: \"implementation-approved\" };\n\nexport interface LogResult {\n questionId?: string;\n}\n\n/**\n * Headless counterpart to `runStart`'s interactive wizard: appends exactly\n * one event to the same local hash chain, but driven by an AI assistant\n * (e.g. the Vaka Claude Code/Codex skill) asking a dynamic, context-specific\n * question instead of the fixed `CHECKPOINT_QUESTIONS` bank. Event shapes and\n * actors intentionally match `runStart` so both paths produce an\n * indistinguishable chain.\n */\nexport async function runLog(projectRoot: string, input: LogInput): Promise<LogResult> {\n const session = await loadOrCreateLocalSession(projectRoot);\n\n switch (input.kind) {\n case \"question\": {\n const questionId = input.questionId ?? `freeform-${randomUUID()}`;\n const next = appendSessionEvent(session, {\n checkpoint: input.checkpoint,\n actor: \"assistant\",\n type: \"checkpoint-question\",\n payload: { questionId, prompt: input.prompt },\n });\n await saveLocalSession(projectRoot, next);\n return { questionId };\n }\n case \"answer\": {\n const next = appendSessionEvent(session, {\n checkpoint: input.checkpoint,\n actor: \"developer\",\n type: \"checkpoint-answer\",\n payload: { questionId: input.questionId, answer: input.answer },\n });\n await saveLocalSession(projectRoot, next);\n return {};\n }\n case \"design-confirmed\": {\n const next = appendSessionEvent(session, {\n checkpoint: \"design\",\n actor: \"developer\",\n type: \"design-confirmed\",\n payload: {},\n });\n await saveLocalSession(projectRoot, next);\n return {};\n }\n case \"implementation-approved\": {\n const next = appendSessionEvent(session, {\n checkpoint: \"implementation\",\n actor: \"developer\",\n type: \"implementation-approved\",\n payload: {},\n });\n await saveLocalSession(projectRoot, next);\n return {};\n }\n }\n}\n","import {\n loadRulesConfig,\n resolveResumeState,\n tryLoadLocalSession,\n type ResumeState,\n} from \"@vaka/core\";\n\nexport interface StatusReport {\n sessionExists: boolean;\n totalEvents: number;\n completedCycles: number;\n resumeState: ResumeState;\n}\n\nexport async function runStatus(projectRoot: string): Promise<StatusReport> {\n const rules = await loadRulesConfig(projectRoot);\n const session = await tryLoadLocalSession(projectRoot);\n const events = session?.events ?? [];\n\n return {\n sessionExists: session !== undefined,\n totalEvents: events.length,\n completedCycles: events.filter((event) => event.type === \"implementation-approved\").length,\n resumeState: resolveResumeState(events, rules),\n };\n}\n","import readline from \"node:readline\";\nimport { detectTerminalTheme, supportsColor, type TerminalTheme } from \"./terminal-theme.js\";\n\nconst BOLD = \"\\x1b[1m\";\nconst RESET = \"\\x1b[0m\";\nconst HIDE_CURSOR = \"\\x1b[?25l\";\nconst SHOW_CURSOR = \"\\x1b[?25h\";\n\nfunction rgb(hex: string): string {\n const r = Number.parseInt(hex.slice(1, 3), 16);\n const g = Number.parseInt(hex.slice(3, 5), 16);\n const b = Number.parseInt(hex.slice(5, 7), 16);\n return `\\x1b[38;2;${r};${g};${b}m`;\n}\n\nfunction stripAnsi(input: string): string {\n return input.replace(/\\x1b\\[[0-9;?]*[a-zA-Z]/g, \"\");\n}\n\n/**\n * Two complete palettes, each a real pairing from docs/design/vaka-theme.css\n * (the dark \"ink\" tokens, or the default light tokens) — never cross-mixed.\n * A banner forced onto the wrong half (e.g. near-white ink-text on a light\n * terminal, or near-black ink-border on a dark one) is the \"invisible\n * banner\" failure this exists to avoid.\n */\nconst PALETTES: Record<\n TerminalTheme,\n { border: string; text: string; muted: string; ring: string; core: string }\n> = {\n dark: {\n border: rgb(\"#2C303D\"), // --ink-border\n text: rgb(\"#F3F4F7\"), // --ink-text\n muted: rgb(\"#9AA1B2\"), // --ink-muted (the dark-canvas muted token, not --muted-foreground)\n ring: rgb(\"#9DB0E8\"), // --accent-light (\"numerals on dark\")\n core: rgb(\"#2E478C\"), // --primary\n },\n light: {\n border: rgb(\"#E5E6EB\"), // --border\n text: rgb(\"#1B1D26\"), // --foreground\n muted: rgb(\"#70747F\"), // --muted-foreground\n ring: rgb(\"#8E9AC2\"), // --secondary-indigo (the light-canvas pair for --accent-light)\n core: rgb(\"#2E478C\"), // --primary\n },\n};\n\nconst SEED_FRAMES: string[][] = [\n // Frame 0: The Origin (Point of Intention)\n [\n ` · `,\n ` `,\n ` ● `,\n ` `,\n ` · `,\n ],\n // Frame 1: The Central Sphere (First Circle of Reasoning)\n [\n ` . ─── . `,\n ` / \\\\ `,\n ` | ◈ | `,\n ` \\\\ / `,\n ` ' ─── ' `,\n ],\n // Frame 2: The Vertical Polar Axis\n [\n ` . ─── . `,\n ` ╭─/───┬───\\\\─╮ `,\n ` ││ │ ││ `,\n ` ╰─\\\\───┴───/─╯ `,\n ` ' ─── ' `,\n ],\n // Frame 3: Triad Intersection (State, Schema, Edge Checkpoints)\n [\n ` . ─── . `,\n ` ╭─/───┬───\\\\─╮ `,\n ` ( ( ◸ ┼ ◹ ) ) `,\n ` ╰─\\\\───┴───/─╯ `,\n ` ' ─── ' `,\n ],\n // Frame 4: Hexagonal Petals Emerge\n [\n ` .──. .──. `,\n ` / ╭──\\\\ /──╮ \\\\ `,\n ` | ( ◸ ✕ ◹ ) | `,\n ` \\\\ ╰──/ \\\\──╯ / `,\n ` '──' '──' `,\n ],\n // Frame 5: Fully Assembled Seed of Life\n [\n ` .──. ▲ .──. `,\n ` ╭─( ◸ ╲ │ / ◹ )─╮ `,\n ` │ ╲─── ◈ ───╱ │ `,\n ` ╰─( ◺ ╱ │ \\\\ ◿ )─╯ `,\n ` '──' ▼ '──' `,\n ],\n // Frame 6: Harmonic Pulse Lock\n [\n ` .──. ✦ .──. `,\n ` ╭─( ◸ ╲ │ / ◹ )─╮ `,\n ` │ ╲─── ◈ ───╱ │ `,\n ` ╰─( ◺ ╱ │ \\\\ ◿ )─╯ `,\n ` '──' ✦ '──' `,\n ],\n];\nconst FINAL_FRAME = SEED_FRAMES.length - 1;\n\nfunction center(text: string, width: number): string {\n const totalPad = Math.max(width - text.length, 0);\n const left = Math.floor(totalPad / 2);\n return \" \".repeat(left) + text + \" \".repeat(totalPad - left);\n}\n\nfunction padEndSafe(text: string, width: number): string {\n return text.length >= width ? text : text + \" \".repeat(width - text.length);\n}\n\nexport function buildVakaCard(\n frameIndex: number,\n isPulsing: boolean,\n theme: TerminalTheme,\n colorEnabled: boolean,\n version: string,\n): string {\n const palette = PALETTES[theme];\n const glyph = SEED_FRAMES[frameIndex] ?? SEED_FRAMES[FINAL_FRAME]!;\n const ringColor = isPulsing ? palette.text : palette.ring;\n const coreColor = isPulsing ? palette.ring : palette.core;\n\n const title = \"YOUR MIND IS THE ARCHITECT\";\n const subtitle = \"Architecture checkpoints for engineers.\";\n // Honest status only: no feature this line implies may exist that isn't shipped.\n const footer = `v${version} · Local checkpoints: unverified`;\n\n const innerWidth = Math.max(\n ...glyph.map((line) => line.length),\n title.length,\n subtitle.length,\n footer.length,\n );\n\n const colorWrap = (code: string, text: string, bold = false) =>\n colorEnabled ? `${bold ? BOLD : \"\"}${code}${text}${RESET}` : text;\n const border = (char: string) => colorWrap(palette.border, char);\n const contentRow = (text: string) => `${border(\"│\")} ${text} ${border(\"│\")}`;\n\n const glyphRow = (line: string, color: string) =>\n contentRow(colorWrap(color, padEndSafe(line, innerWidth)));\n\n const lines = [\n `${border(\"┌\")}${border(\"─\".repeat(innerWidth + 2))}${border(\"┐\")}`,\n contentRow(\" \".repeat(innerWidth)),\n glyphRow(glyph[0]!, ringColor),\n glyphRow(glyph[1]!, ringColor),\n glyphRow(glyph[2]!, coreColor),\n glyphRow(glyph[3]!, ringColor),\n glyphRow(glyph[4]!, ringColor),\n contentRow(\" \".repeat(innerWidth)),\n contentRow(colorWrap(palette.text, center(title, innerWidth), true)),\n contentRow(colorWrap(palette.muted, center(subtitle, innerWidth))),\n contentRow(\" \".repeat(innerWidth)),\n contentRow(colorWrap(palette.muted, center(footer, innerWidth))),\n `${border(\"└\")}${border(\"─\".repeat(innerWidth + 2))}${border(\"┘\")}`,\n ];\n\n return lines.join(\"\\n\");\n}\n\nfunction buildMinimalBanner(version: string): string {\n return `Vaka v${version} — Your mind is the architect.`;\n}\n\nexport interface AnimateOptions {\n stdout?: NodeJS.WriteStream;\n env?: NodeJS.ProcessEnv;\n version?: string;\n}\n\nexport async function animateVakaEntrance(options: AnimateOptions = {}): Promise<void> {\n const stdout = options.stdout ?? process.stdout;\n const env = options.env ?? process.env;\n const version = options.version ?? \"0.1.0\";\n\n const theme = detectTerminalTheme(env);\n const colorEnabled = supportsColor(stdout, env);\n const interactive = stdout.isTTY === true;\n\n const finalCard = buildVakaCard(FINAL_FRAME, false, theme, colorEnabled, version);\n const cardWidth = Math.max(...finalCard.split(\"\\n\").map((line) => stripAnsi(line).length));\n const columns = stdout.columns ?? cardWidth;\n\n // Piped/CI/non-interactive: print once, no cursor tricks, no animation delay.\n if (!interactive) {\n stdout.write(`${finalCard}\\n`);\n return;\n }\n\n // The card can't fit without wrapping into garbage; a plain line always fits.\n if (columns < cardWidth) {\n stdout.write(`${buildMinimalBanner(version)}\\n`);\n return;\n }\n\n stdout.write(HIDE_CURSOR);\n readline.cursorTo(stdout, 0, 0);\n readline.clearScreenDown(stdout);\n\n for (let i = 0; i < SEED_FRAMES.length; i++) {\n readline.cursorTo(stdout, 0, 0);\n stdout.write(`${buildVakaCard(i, false, theme, colorEnabled, version)}\\n`);\n await new Promise((resolve) => setTimeout(resolve, 85));\n }\n\n const pulseRhythm = [true, false, true, false];\n for (const pulse of pulseRhythm) {\n readline.cursorTo(stdout, 0, 0);\n stdout.write(`${buildVakaCard(FINAL_FRAME, pulse, theme, colorEnabled, version)}\\n`);\n await new Promise((resolve) => setTimeout(resolve, pulse ? 130 : 90));\n }\n\n stdout.write(SHOW_CURSOR);\n}\n","export type TerminalTheme = \"dark\" | \"light\";\n\ninterface ThemeEnv {\n VAKA_THEME?: string;\n COLORFGBG?: string;\n}\n\n/**\n * Most terminal emulators (iTerm2, Terminal.app, VS Code, Windows Terminal)\n * never expose their actual background color to a running process — querying\n * one directly (OSC 11) needs raw-mode stdin and a response timeout, which is\n * too fragile to gate a CLI's startup banner on. So this is a best-effort\n * heuristic (the COLORFGBG convention some terminals like rxvt/mintty set),\n * with an explicit override for everyone else, including for a reliable demo.\n */\nexport function detectTerminalTheme(env: ThemeEnv = process.env): TerminalTheme {\n const override = env.VAKA_THEME?.toLowerCase();\n if (override === \"light\" || override === \"dark\") {\n return override;\n }\n\n const colorFgBg = env.COLORFGBG;\n if (colorFgBg) {\n const bg = Number.parseInt(colorFgBg.split(\";\").pop() ?? \"\", 10);\n if (!Number.isNaN(bg)) {\n // ANSI 16-color palette: 0-6 and 8 are the dark half, 7 and 9-15 are light.\n return bg === 7 || bg >= 9 ? \"light\" : \"dark\";\n }\n }\n\n // No signal either way: most developer terminals default to a dark theme.\n return \"dark\";\n}\n\ninterface ColorEnv {\n NO_COLOR?: string;\n FORCE_COLOR?: string;\n TERM?: string;\n}\n\nexport function supportsColor(\n stream: { isTTY?: boolean } = process.stdout,\n env: ColorEnv = process.env,\n): boolean {\n if (env.NO_COLOR !== undefined) {\n return false;\n }\n if (env.FORCE_COLOR !== undefined && env.FORCE_COLOR !== \"0\") {\n return true;\n }\n if (!stream.isTTY) {\n return false;\n }\n return env.TERM !== \"dumb\";\n}\n","import { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nconst REGISTRY_DIST_TAGS_URL = \"https://registry.npmjs.org/-/package/\";\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000;\nconst FETCH_TIMEOUT_MS = 1500;\n\ninterface UpdateCache {\n lastChecked: number;\n latestVersion: string;\n}\n\nexport type FetchLike = (\n url: string,\n init?: { signal?: AbortSignal },\n) => Promise<{ ok: boolean; json: () => Promise<unknown> }>;\n\nexport interface UpdateNotice {\n currentVersion: string;\n latestVersion: string;\n}\n\ninterface CheckForUpdatesOptions {\n cachePath?: string;\n now?: () => number;\n fetchImpl?: FetchLike;\n}\n\nfunction defaultCachePath(): string {\n return join(homedir(), \".vaka\", \"update-check.json\");\n}\n\nfunction readCache(cachePath: string): UpdateCache | undefined {\n try {\n const parsed = JSON.parse(readFileSync(cachePath, \"utf8\")) as Partial<UpdateCache>;\n if (typeof parsed.lastChecked === \"number\" && typeof parsed.latestVersion === \"string\") {\n return { lastChecked: parsed.lastChecked, latestVersion: parsed.latestVersion };\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction writeCache(cachePath: string, cache: UpdateCache): void {\n try {\n mkdirSync(dirname(cachePath), { recursive: true });\n writeFileSync(cachePath, JSON.stringify(cache), \"utf8\");\n } catch {\n // Best-effort: a write failure just means we check again next run.\n }\n}\n\n/** Compares dotted numeric versions, ignoring any -prerelease/+build suffix. Returns >0 if a is newer. */\nexport function compareVersions(a: string, b: string): number {\n const toParts = (version: string) =>\n (version.split(/[-+]/)[0] ?? \"\").split(\".\").map((part) => Number.parseInt(part, 10) || 0);\n const partsA = toParts(a);\n const partsB = toParts(b);\n const length = Math.max(partsA.length, partsB.length);\n for (let i = 0; i < length; i++) {\n const diff = (partsA[i] ?? 0) - (partsB[i] ?? 0);\n if (diff !== 0) {\n return diff > 0 ? 1 : -1;\n }\n }\n return 0;\n}\n\nasync function fetchLatestVersion(\n packageName: string,\n fetchImpl: FetchLike,\n): Promise<string | undefined> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n try {\n const response = await fetchImpl(`${REGISTRY_DIST_TAGS_URL}${encodeURIComponent(packageName)}/dist-tags`, {\n signal: controller.signal,\n });\n if (!response.ok) {\n return undefined;\n }\n const tags = (await response.json()) as Record<string, unknown>;\n return typeof tags.latest === \"string\" ? tags.latest : undefined;\n } catch {\n // Offline, timed out, or registry unreachable: silently skip this check.\n return undefined;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Returns a notice built from the last cached registry check (instant, no network wait).\n * When the cache is missing or older than CACHE_TTL_MS, also kicks off a background refetch\n * (not awaited) so the cache is fresh for the *next* run. Never blocks and never throws.\n */\nexport function checkForUpdates(\n currentVersion: string,\n packageName: string,\n options: CheckForUpdatesOptions = {},\n): UpdateNotice | undefined {\n const cachePath = options.cachePath ?? defaultCachePath();\n const now = options.now ?? Date.now;\n const fetchImpl = options.fetchImpl ?? (fetch as FetchLike);\n\n const cache = readCache(cachePath);\n const isStale = !cache || now() - cache.lastChecked > CACHE_TTL_MS;\n\n if (isStale) {\n void fetchLatestVersion(packageName, fetchImpl).then((latestVersion) => {\n if (latestVersion) {\n writeCache(cachePath, { lastChecked: now(), latestVersion });\n }\n });\n }\n\n if (cache && compareVersions(cache.latestVersion, currentVersion) > 0) {\n return { currentVersion, latestVersion: cache.latestVersion };\n }\n return undefined;\n}\n\nexport function formatUpdateNotice(notice: UpdateNotice, packageName: string): string {\n const line1 = `Update available: ${notice.currentVersion} → ${notice.latestVersion}`;\n const line2 = `Run: npm install -g ${packageName}`;\n const width = Math.max(line1.length, line2.length) + 2;\n const pad = (line: string) => `│ ${line.padEnd(width - 1)}│`;\n return [\n `┌${\"─\".repeat(width)}┐`,\n pad(line1),\n pad(line2),\n `└${\"─\".repeat(width)}┘`,\n ].join(\"\\n\");\n}\n"],"mappings":"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","names":["lstat","mkdir","readFile","rename","unlink","writeFile","join","resolve","isMissing","resolve","lstat","join","mkdir","writeFile","rename","unlink","readFile","rules","lstat","readFile","join","resolve","isMissing","text","resolve","join","lstat","readFile","rules","randomUUID","CHECKPOINT_NAMES","isCheckpointName","randomUUID","rules","text","resolve","dirname","join","isCheckpointName"]}
|