ridgeline 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +137 -0
  3. package/dist/__tests__/cli.test.d.ts +1 -0
  4. package/dist/__tests__/cli.test.js +151 -0
  5. package/dist/__tests__/cli.test.js.map +1 -0
  6. package/dist/__tests__/git.test.d.ts +1 -0
  7. package/dist/__tests__/git.test.js +152 -0
  8. package/dist/__tests__/git.test.js.map +1 -0
  9. package/dist/__tests__/logging.test.d.ts +1 -0
  10. package/dist/__tests__/logging.test.js +119 -0
  11. package/dist/__tests__/logging.test.js.map +1 -0
  12. package/dist/agents/agents/builder.md +99 -0
  13. package/dist/agents/agents/planner.md +87 -0
  14. package/dist/agents/agents/reviewer.md +146 -0
  15. package/dist/agents/builder.md +99 -0
  16. package/dist/agents/planner.md +87 -0
  17. package/dist/agents/reviewer.md +146 -0
  18. package/dist/cli.d.ts +5 -0
  19. package/dist/cli.js +252 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/commands/__tests__/dryRun.test.d.ts +1 -0
  22. package/dist/commands/__tests__/dryRun.test.js +105 -0
  23. package/dist/commands/__tests__/dryRun.test.js.map +1 -0
  24. package/dist/commands/__tests__/init.test.d.ts +1 -0
  25. package/dist/commands/__tests__/init.test.js +99 -0
  26. package/dist/commands/__tests__/init.test.js.map +1 -0
  27. package/dist/commands/__tests__/plan.test.d.ts +1 -0
  28. package/dist/commands/__tests__/plan.test.js +125 -0
  29. package/dist/commands/__tests__/plan.test.js.map +1 -0
  30. package/dist/commands/__tests__/resume.test.d.ts +1 -0
  31. package/dist/commands/__tests__/resume.test.js +141 -0
  32. package/dist/commands/__tests__/resume.test.js.map +1 -0
  33. package/dist/commands/__tests__/run.test.d.ts +1 -0
  34. package/dist/commands/__tests__/run.test.js +157 -0
  35. package/dist/commands/__tests__/run.test.js.map +1 -0
  36. package/dist/commands/dryRun.d.ts +2 -0
  37. package/dist/commands/dryRun.js +81 -0
  38. package/dist/commands/dryRun.js.map +1 -0
  39. package/dist/commands/init.d.ts +1 -0
  40. package/dist/commands/init.js +119 -0
  41. package/dist/commands/init.js.map +1 -0
  42. package/dist/commands/plan.d.ts +2 -0
  43. package/dist/commands/plan.js +78 -0
  44. package/dist/commands/plan.js.map +1 -0
  45. package/dist/commands/resume.d.ts +2 -0
  46. package/dist/commands/resume.js +25 -0
  47. package/dist/commands/resume.js.map +1 -0
  48. package/dist/commands/run.d.ts +2 -0
  49. package/dist/commands/run.js +80 -0
  50. package/dist/commands/run.js.map +1 -0
  51. package/dist/git.d.ts +9 -0
  52. package/dist/git.js +75 -0
  53. package/dist/git.js.map +1 -0
  54. package/dist/logging.d.ts +13 -0
  55. package/dist/logging.js +66 -0
  56. package/dist/logging.js.map +1 -0
  57. package/dist/runner/__tests__/claudeInvoker.test.d.ts +1 -0
  58. package/dist/runner/__tests__/claudeInvoker.test.js +138 -0
  59. package/dist/runner/__tests__/claudeInvoker.test.js.map +1 -0
  60. package/dist/runner/__tests__/phaseRunner.test.d.ts +1 -0
  61. package/dist/runner/__tests__/phaseRunner.test.js +225 -0
  62. package/dist/runner/__tests__/phaseRunner.test.js.map +1 -0
  63. package/dist/runner/__tests__/planInvoker.test.d.ts +1 -0
  64. package/dist/runner/__tests__/planInvoker.test.js +101 -0
  65. package/dist/runner/__tests__/planInvoker.test.js.map +1 -0
  66. package/dist/runner/__tests__/reviewerInvoker.test.d.ts +1 -0
  67. package/dist/runner/__tests__/reviewerInvoker.test.js +90 -0
  68. package/dist/runner/__tests__/reviewerInvoker.test.js.map +1 -0
  69. package/dist/runner/buildInvoker.d.ts +2 -0
  70. package/dist/runner/buildInvoker.js +110 -0
  71. package/dist/runner/buildInvoker.js.map +1 -0
  72. package/dist/runner/claudeInvoker.d.ts +11 -0
  73. package/dist/runner/claudeInvoker.js +135 -0
  74. package/dist/runner/claudeInvoker.js.map +1 -0
  75. package/dist/runner/phaseRunner.d.ts +2 -0
  76. package/dist/runner/phaseRunner.js +145 -0
  77. package/dist/runner/phaseRunner.js.map +1 -0
  78. package/dist/runner/planInvoker.d.ts +6 -0
  79. package/dist/runner/planInvoker.js +117 -0
  80. package/dist/runner/planInvoker.js.map +1 -0
  81. package/dist/runner/reviewerInvoker.d.ts +10 -0
  82. package/dist/runner/reviewerInvoker.js +144 -0
  83. package/dist/runner/reviewerInvoker.js.map +1 -0
  84. package/dist/state/__tests__/budget.test.d.ts +1 -0
  85. package/dist/state/__tests__/budget.test.js +130 -0
  86. package/dist/state/__tests__/budget.test.js.map +1 -0
  87. package/dist/state/__tests__/handoff.test.d.ts +1 -0
  88. package/dist/state/__tests__/handoff.test.js +70 -0
  89. package/dist/state/__tests__/handoff.test.js.map +1 -0
  90. package/dist/state/__tests__/snapshot.test.d.ts +1 -0
  91. package/dist/state/__tests__/snapshot.test.js +105 -0
  92. package/dist/state/__tests__/snapshot.test.js.map +1 -0
  93. package/dist/state/__tests__/stateManager.test.d.ts +1 -0
  94. package/dist/state/__tests__/stateManager.test.js +166 -0
  95. package/dist/state/__tests__/stateManager.test.js.map +1 -0
  96. package/dist/state/budget.d.ts +5 -0
  97. package/dist/state/budget.js +72 -0
  98. package/dist/state/budget.js.map +1 -0
  99. package/dist/state/handoff.d.ts +2 -0
  100. package/dist/state/handoff.js +54 -0
  101. package/dist/state/handoff.js.map +1 -0
  102. package/dist/state/snapshot.d.ts +1 -0
  103. package/dist/state/snapshot.js +154 -0
  104. package/dist/state/snapshot.js.map +1 -0
  105. package/dist/state/stateManager.d.ts +6 -0
  106. package/dist/state/stateManager.js +94 -0
  107. package/dist/state/stateManager.js.map +1 -0
  108. package/dist/types.d.ts +87 -0
  109. package/dist/types.js +3 -0
  110. package/dist/types.js.map +1 -0
  111. package/package.json +34 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rob McLarty
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # Ridgeline
2
+
3
+ Build harness for long-horizon software execution using AI agents.
4
+
5
+ Ridgeline decomposes large software ideas into phased builds using a
6
+ three-agent system (planner, builder, reviewer) driven by the Claude CLI. It
7
+ manages state through git checkpoints, tracks costs, and supports resumable
8
+ execution when things go wrong.
9
+
10
+ ## How it works
11
+
12
+ 1. **Write a spec** -- describe what you want built in a markdown file along
13
+ with technical constraints and optional style preferences.
14
+ 2. **Plan** -- the planner agent reads your spec and produces numbered phase
15
+ files, each with its own scope and acceptance criteria.
16
+ 3. **Build** -- for each phase the builder agent implements the spec inside your
17
+ repo, then creates a git checkpoint.
18
+ 4. **Review** -- the reviewer agent checks the output against the acceptance
19
+ criteria and returns a structured verdict.
20
+ 5. **Retry or advance** -- failed phases are retried up to a configurable limit;
21
+ passing phases hand off context to the next one.
22
+
23
+ ## Install
24
+
25
+ ```sh
26
+ npm install -g ridgeline
27
+ ```
28
+
29
+ Ridgeline requires the [Claude CLI](https://docs.anthropic.com/en/docs/claude-code)
30
+ to be installed and authenticated.
31
+
32
+ ## Quick start
33
+
34
+ ```sh
35
+ # Scaffold a new build (interactive wizard)
36
+ ridgeline init my-feature
37
+
38
+ # Generate the phase plan
39
+ ridgeline plan my-feature
40
+
41
+ # Preview what will run
42
+ ridgeline dry-run my-feature
43
+
44
+ # Execute the full build
45
+ ridgeline run my-feature
46
+
47
+ # Resume after a failure
48
+ ridgeline resume my-feature
49
+ ```
50
+
51
+ ## Commands
52
+
53
+ ### `ridgeline init [build-name]`
54
+
55
+ Interactive wizard that creates the build directory under
56
+ `.ridgeline/builds/<build-name>/` and collects your spec, constraints, and
57
+ optional taste file.
58
+
59
+ ### `ridgeline plan [build-name]`
60
+
61
+ Invokes the planner agent to decompose the spec into numbered phase files
62
+ (`01-slug.md`, `02-slug.md`, ...) stored in the build's `phases/` directory.
63
+
64
+ | Flag | Default | Description |
65
+ |------|---------|-------------|
66
+ | `--model <name>` | `opus` | Model for the planner |
67
+ | `--verbose` | off | Stream planner output to the terminal |
68
+ | `--timeout <minutes>` | `30` | Max planning duration |
69
+ | `--constraints <path>` | auto | Path to constraints file |
70
+ | `--taste <path>` | auto | Path to taste file |
71
+
72
+ ### `ridgeline dry-run [build-name]`
73
+
74
+ Displays the execution plan without invoking builders or reviewers. Accepts
75
+ the same flags as `plan`.
76
+
77
+ ### `ridgeline run [build-name]`
78
+
79
+ Executes the full build pipeline: build each phase, evaluate, retry on failure,
80
+ and advance on success.
81
+
82
+ | Flag | Default | Description |
83
+ |------|---------|-------------|
84
+ | `--model <name>` | `opus` | Model for builder and reviewer |
85
+ | `--verbose` | off | Stream output to the terminal |
86
+ | `--timeout <minutes>` | `30` | Max duration per phase |
87
+ | `--max-retries <n>` | `2` | Max reviewer retry loops per phase |
88
+ | `--check <command>` | from constraints | Baseline check command |
89
+ | `--max-budget-usd <n>` | none | Halt if cumulative cost exceeds this |
90
+ | `--constraints <path>` | auto | Path to constraints file |
91
+ | `--taste <path>` | auto | Path to taste file |
92
+
93
+ ### `ridgeline resume [build-name]`
94
+
95
+ Loads existing state and resumes from the next incomplete phase. Accepts the
96
+ same flags as `run`.
97
+
98
+ ## Build directory structure
99
+
100
+ ```text
101
+ .ridgeline/builds/<build-name>/
102
+ ├── spec.md # What to build
103
+ ├── constraints.md # Technical constraints and check commands
104
+ ├── taste.md # Optional coding style preferences
105
+ ├── phases/
106
+ │ ├── 01-scaffold.md
107
+ │ ├── 02-core.md
108
+ │ └── ...
109
+ ├── state.json # Phase statuses, retries, timestamps, git tags
110
+ ├── budget.json # Per-invocation cost tracking
111
+ ├── trajectory.jsonl # Event log (plan/build/eval start/complete)
112
+ ├── snapshot.md # Summary of latest phase output
113
+ └── handoff.md # Context passed to the next phase
114
+ ```
115
+
116
+ ## Configuration resolution
117
+
118
+ Constraint and taste files are resolved in order:
119
+
120
+ 1. CLI flag (`--constraints <path>`)
121
+ 2. Build-level (`.ridgeline/builds/<build-name>/constraints.md`)
122
+ 3. Project-level (`.ridgeline/constraints.md`)
123
+
124
+ ## Development
125
+
126
+ ```sh
127
+ npm install
128
+ npm run build # Compile TypeScript and copy agent prompts
129
+ npm run dev # Watch mode
130
+ npm test # Run the test suite (vitest)
131
+ npm run test:watch # Watch mode
132
+ npm run lint # Run all linters (oxlint, markdownlint, agnix)
133
+ ```
134
+
135
+ ## License
136
+
137
+ [MIT](LICENSE)
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const vitest_1 = require("vitest");
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const setup_1 = require("../../test/setup");
40
+ // Mock commander to prevent program.parse() from running on import
41
+ vitest_1.vi.mock("commander", () => {
42
+ class MockCommand {
43
+ name() { return this; }
44
+ description() { return this; }
45
+ version() { return this; }
46
+ command() { return this; }
47
+ option() { return this; }
48
+ action() { return this; }
49
+ parse() { }
50
+ }
51
+ return { Command: MockCommand };
52
+ });
53
+ // Mock command modules to avoid side effects
54
+ vitest_1.vi.mock("../commands/init", () => ({ runInit: vitest_1.vi.fn() }));
55
+ vitest_1.vi.mock("../commands/plan", () => ({ runPlan: vitest_1.vi.fn() }));
56
+ vitest_1.vi.mock("../commands/dryRun", () => ({ runDryRun: vitest_1.vi.fn() }));
57
+ vitest_1.vi.mock("../commands/run", () => ({ runBuild: vitest_1.vi.fn() }));
58
+ vitest_1.vi.mock("../commands/resume", () => ({ runResume: vitest_1.vi.fn() }));
59
+ const cli_1 = require("../cli");
60
+ (0, vitest_1.describe)("cli", () => {
61
+ (0, vitest_1.describe)("resolveFile", () => {
62
+ let tmpDir;
63
+ let buildDir;
64
+ let projectDir;
65
+ (0, vitest_1.beforeEach)(() => {
66
+ tmpDir = (0, setup_1.makeTempDir)();
67
+ buildDir = path.join(tmpDir, "build");
68
+ projectDir = path.join(tmpDir, "project");
69
+ fs.mkdirSync(buildDir, { recursive: true });
70
+ fs.mkdirSync(projectDir, { recursive: true });
71
+ });
72
+ (0, vitest_1.afterEach)(() => {
73
+ fs.rmSync(tmpDir, { recursive: true, force: true });
74
+ });
75
+ (0, vitest_1.it)("returns CLI flag path when it exists", () => {
76
+ const flagFile = path.join(tmpDir, "custom.md");
77
+ fs.writeFileSync(flagFile, "custom");
78
+ const result = (0, cli_1.resolveFile)(flagFile, buildDir, "test.md", projectDir);
79
+ (0, vitest_1.expect)(result).toBe(path.resolve(flagFile));
80
+ });
81
+ (0, vitest_1.it)("returns build-level file when no CLI flag", () => {
82
+ fs.writeFileSync(path.join(buildDir, "test.md"), "build");
83
+ const result = (0, cli_1.resolveFile)(undefined, buildDir, "test.md", projectDir);
84
+ (0, vitest_1.expect)(result).toBe(path.join(buildDir, "test.md"));
85
+ });
86
+ (0, vitest_1.it)("returns project-level file as fallback", () => {
87
+ fs.writeFileSync(path.join(projectDir, "test.md"), "project");
88
+ const result = (0, cli_1.resolveFile)(undefined, buildDir, "test.md", projectDir);
89
+ (0, vitest_1.expect)(result).toBe(path.join(projectDir, "test.md"));
90
+ });
91
+ (0, vitest_1.it)("returns null when file not found anywhere", () => {
92
+ const result = (0, cli_1.resolveFile)(undefined, buildDir, "missing.md", projectDir);
93
+ (0, vitest_1.expect)(result).toBeNull();
94
+ });
95
+ (0, vitest_1.it)("prefers CLI flag over build-level", () => {
96
+ const flagFile = path.join(tmpDir, "flag.md");
97
+ fs.writeFileSync(flagFile, "flag");
98
+ fs.writeFileSync(path.join(buildDir, "flag.md"), "build");
99
+ const result = (0, cli_1.resolveFile)(flagFile, buildDir, "flag.md", projectDir);
100
+ (0, vitest_1.expect)(result).toBe(path.resolve(flagFile));
101
+ });
102
+ (0, vitest_1.it)("prefers build-level over project-level", () => {
103
+ fs.writeFileSync(path.join(buildDir, "test.md"), "build");
104
+ fs.writeFileSync(path.join(projectDir, "test.md"), "project");
105
+ const result = (0, cli_1.resolveFile)(undefined, buildDir, "test.md", projectDir);
106
+ (0, vitest_1.expect)(result).toBe(path.join(buildDir, "test.md"));
107
+ });
108
+ });
109
+ (0, vitest_1.describe)("parseCheckCommand", () => {
110
+ let tmpDir;
111
+ (0, vitest_1.beforeEach)(() => {
112
+ tmpDir = (0, setup_1.makeTempDir)();
113
+ });
114
+ (0, vitest_1.afterEach)(() => {
115
+ fs.rmSync(tmpDir, { recursive: true, force: true });
116
+ });
117
+ (0, vitest_1.it)("extracts check command from constraints.md", () => {
118
+ const fp = path.join(tmpDir, "constraints.md");
119
+ fs.writeFileSync(fp, [
120
+ "# Constraints",
121
+ "",
122
+ "## Check Command",
123
+ "",
124
+ "```bash",
125
+ "npm run build && npm test",
126
+ "```",
127
+ ].join("\n"));
128
+ (0, vitest_1.expect)((0, cli_1.parseCheckCommand)(fp)).toBe("npm run build && npm test");
129
+ });
130
+ (0, vitest_1.it)("extracts check command without language tag", () => {
131
+ const fp = path.join(tmpDir, "constraints.md");
132
+ fs.writeFileSync(fp, [
133
+ "## Check Command",
134
+ "",
135
+ "```",
136
+ "make test",
137
+ "```",
138
+ ].join("\n"));
139
+ (0, vitest_1.expect)((0, cli_1.parseCheckCommand)(fp)).toBe("make test");
140
+ });
141
+ (0, vitest_1.it)("returns null when no check command section", () => {
142
+ const fp = path.join(tmpDir, "constraints.md");
143
+ fs.writeFileSync(fp, "# Constraints\n\nNo check command here.");
144
+ (0, vitest_1.expect)((0, cli_1.parseCheckCommand)(fp)).toBeNull();
145
+ });
146
+ (0, vitest_1.it)("returns null when file does not exist", () => {
147
+ (0, vitest_1.expect)((0, cli_1.parseCheckCommand)("/nonexistent/path.md")).toBeNull();
148
+ });
149
+ });
150
+ });
151
+ //# sourceMappingURL=cli.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.test.js","sourceRoot":"","sources":["../../src/__tests__/cli.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mCAAwE;AACxE,4CAA6B;AAC7B,gDAAiC;AACjC,4CAA8C;AAE9C,mEAAmE;AACnE,WAAE,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;IACxB,MAAM,WAAW;QACf,IAAI,KAAK,OAAO,IAAI,CAAA,CAAC,CAAC;QACtB,WAAW,KAAK,OAAO,IAAI,CAAA,CAAC,CAAC;QAC7B,OAAO,KAAK,OAAO,IAAI,CAAA,CAAC,CAAC;QACzB,OAAO,KAAK,OAAO,IAAI,CAAA,CAAC,CAAC;QACzB,MAAM,KAAK,OAAO,IAAI,CAAA,CAAC,CAAC;QACxB,MAAM,KAAK,OAAO,IAAI,CAAA,CAAC,CAAC;QACxB,KAAK,KAAI,CAAC;KACX;IACD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAA;AACjC,CAAC,CAAC,CAAA;AAEF,6CAA6C;AAC7C,WAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,WAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;AACzD,WAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,WAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;AACzD,WAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,WAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;AAC7D,WAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;AACzD,WAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,WAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;AAE7D,gCAAuD;AAEvD,IAAA,iBAAQ,EAAC,KAAK,EAAE,GAAG,EAAE;IACnB,IAAA,iBAAQ,EAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,IAAI,MAAc,CAAA;QAClB,IAAI,QAAgB,CAAA;QACpB,IAAI,UAAkB,CAAA;QAEtB,IAAA,mBAAU,EAAC,GAAG,EAAE;YACd,MAAM,GAAG,IAAA,mBAAW,GAAE,CAAA;YACtB,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;YACrC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;YACzC,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YAC3C,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/C,CAAC,CAAC,CAAA;QAEF,IAAA,kBAAS,EAAC,GAAG,EAAE;YACb,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACrD,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;YAC/C,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;YACpC,MAAM,MAAM,GAAG,IAAA,iBAAW,EAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;YACrE,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC7C,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAA;YACzD,MAAM,MAAM,GAAG,IAAA,iBAAW,EAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;YACtE,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAA;QACrD,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,SAAS,CAAC,CAAA;YAC7D,MAAM,MAAM,GAAG,IAAA,iBAAW,EAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;YACtE,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAA;QACvD,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,MAAM,GAAG,IAAA,iBAAW,EAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC,CAAA;YACzE,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC3B,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;YAC7C,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;YAClC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAA;YACzD,MAAM,MAAM,GAAG,IAAA,iBAAW,EAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;YACrE,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC7C,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAA;YACzD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,SAAS,CAAC,CAAA;YAC7D,MAAM,MAAM,GAAG,IAAA,iBAAW,EAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;YACtE,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAA;QACrD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAA,iBAAQ,EAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,IAAI,MAAc,CAAA;QAElB,IAAA,mBAAU,EAAC,GAAG,EAAE;YACd,MAAM,GAAG,IAAA,mBAAW,GAAE,CAAA;QACxB,CAAC,CAAC,CAAA;QAEF,IAAA,kBAAS,EAAC,GAAG,EAAE;YACb,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACrD,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;YAC9C,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE;gBACnB,eAAe;gBACf,EAAE;gBACF,kBAAkB;gBAClB,EAAE;gBACF,SAAS;gBACT,2BAA2B;gBAC3B,KAAK;aACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YAEb,IAAA,eAAM,EAAC,IAAA,uBAAiB,EAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAA;QACjE,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;YAC9C,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE;gBACnB,kBAAkB;gBAClB,EAAE;gBACF,KAAK;gBACL,WAAW;gBACX,KAAK;aACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YAEb,IAAA,eAAM,EAAC,IAAA,uBAAiB,EAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACjD,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;YAC9C,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE,yCAAyC,CAAC,CAAA;YAE/D,IAAA,eAAM,EAAC,IAAA,uBAAiB,EAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC1C,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,IAAA,eAAM,EAAC,IAAA,uBAAiB,EAAC,sBAAsB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC9D,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const vitest_1 = require("vitest");
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const node_child_process_1 = require("node:child_process");
40
+ const setup_1 = require("../../test/setup");
41
+ const git_1 = require("../git");
42
+ // Helper to create a temp git repo
43
+ const initTempRepo = () => {
44
+ const dir = (0, setup_1.makeTempDir)();
45
+ (0, node_child_process_1.execSync)("git init", { cwd: dir, stdio: "pipe" });
46
+ (0, node_child_process_1.execSync)("git config user.email 'test@test.com'", { cwd: dir, stdio: "pipe" });
47
+ (0, node_child_process_1.execSync)("git config user.name 'Test'", { cwd: dir, stdio: "pipe" });
48
+ // Create initial commit so HEAD exists
49
+ fs.writeFileSync(path.join(dir, "init.txt"), "init");
50
+ (0, node_child_process_1.execSync)("git add -A && git commit -m 'init'", { cwd: dir, stdio: "pipe" });
51
+ return dir;
52
+ };
53
+ (0, vitest_1.describe)("git", () => {
54
+ let repoDir;
55
+ (0, vitest_1.beforeEach)(() => {
56
+ repoDir = initTempRepo();
57
+ });
58
+ (0, vitest_1.afterEach)(() => {
59
+ fs.rmSync(repoDir, { recursive: true, force: true });
60
+ });
61
+ (0, vitest_1.describe)("getCurrentSha", () => {
62
+ (0, vitest_1.it)("returns a 40-character hex string", () => {
63
+ const sha = (0, git_1.getCurrentSha)(repoDir);
64
+ (0, vitest_1.expect)(sha).toMatch(/^[0-9a-f]{40}$/);
65
+ });
66
+ });
67
+ (0, vitest_1.describe)("isWorkingTreeDirty", () => {
68
+ (0, vitest_1.it)("returns false for clean tree", () => {
69
+ (0, vitest_1.expect)((0, git_1.isWorkingTreeDirty)(repoDir)).toBe(false);
70
+ });
71
+ (0, vitest_1.it)("returns true when there are uncommitted changes", () => {
72
+ fs.writeFileSync(path.join(repoDir, "dirty.txt"), "dirty");
73
+ (0, vitest_1.expect)((0, git_1.isWorkingTreeDirty)(repoDir)).toBe(true);
74
+ });
75
+ });
76
+ (0, vitest_1.describe)("commitAll", () => {
77
+ (0, vitest_1.it)("stages and commits all changes", () => {
78
+ fs.writeFileSync(path.join(repoDir, "new.txt"), "new file");
79
+ (0, git_1.commitAll)("test commit", repoDir);
80
+ const log = (0, node_child_process_1.execSync)("git log --oneline", { cwd: repoDir, encoding: "utf-8" });
81
+ (0, vitest_1.expect)(log).toContain("test commit");
82
+ (0, vitest_1.expect)((0, git_1.isWorkingTreeDirty)(repoDir)).toBe(false);
83
+ });
84
+ (0, vitest_1.it)("does not throw when nothing to commit", () => {
85
+ (0, vitest_1.expect)(() => (0, git_1.commitAll)("empty commit", repoDir)).not.toThrow();
86
+ });
87
+ });
88
+ (0, vitest_1.describe)("createTag / tagExists / deleteTag", () => {
89
+ (0, vitest_1.it)("creates a tag that can be detected", () => {
90
+ (0, git_1.createTag)("test-tag", repoDir);
91
+ (0, vitest_1.expect)((0, git_1.tagExists)("test-tag", repoDir)).toBe(true);
92
+ });
93
+ (0, vitest_1.it)("returns false for nonexistent tag", () => {
94
+ (0, vitest_1.expect)((0, git_1.tagExists)("nonexistent", repoDir)).toBe(false);
95
+ });
96
+ (0, vitest_1.it)("deletes an existing tag", () => {
97
+ (0, git_1.createTag)("to-delete", repoDir);
98
+ (0, git_1.deleteTag)("to-delete", repoDir);
99
+ (0, vitest_1.expect)((0, git_1.tagExists)("to-delete", repoDir)).toBe(false);
100
+ });
101
+ (0, vitest_1.it)("does not throw when deleting nonexistent tag", () => {
102
+ (0, vitest_1.expect)(() => (0, git_1.deleteTag)("no-such-tag", repoDir)).not.toThrow();
103
+ });
104
+ });
105
+ (0, vitest_1.describe)("getDiff", () => {
106
+ (0, vitest_1.it)("returns diff between tag and HEAD", () => {
107
+ (0, git_1.createTag)("before-change", repoDir);
108
+ fs.writeFileSync(path.join(repoDir, "changed.txt"), "content");
109
+ (0, git_1.commitAll)("add changed file", repoDir);
110
+ const diff = (0, git_1.getDiff)("before-change", repoDir);
111
+ (0, vitest_1.expect)(diff).toContain("changed.txt");
112
+ (0, vitest_1.expect)(diff).toContain("content");
113
+ });
114
+ (0, vitest_1.it)("returns empty string when tag does not exist", () => {
115
+ (0, vitest_1.expect)((0, git_1.getDiff)("nonexistent-tag", repoDir)).toBe("");
116
+ });
117
+ });
118
+ (0, vitest_1.describe)("getChangedFileNames", () => {
119
+ (0, vitest_1.it)("returns list of changed files", () => {
120
+ (0, git_1.createTag)("baseline", repoDir);
121
+ fs.writeFileSync(path.join(repoDir, "a.txt"), "a");
122
+ fs.writeFileSync(path.join(repoDir, "b.txt"), "b");
123
+ (0, git_1.commitAll)("add files", repoDir);
124
+ const files = (0, git_1.getChangedFileNames)("baseline", repoDir);
125
+ (0, vitest_1.expect)(files).toContain("a.txt");
126
+ (0, vitest_1.expect)(files).toContain("b.txt");
127
+ });
128
+ (0, vitest_1.it)("returns empty array for nonexistent tag", () => {
129
+ (0, vitest_1.expect)((0, git_1.getChangedFileNames)("missing", repoDir)).toEqual([]);
130
+ });
131
+ });
132
+ (0, vitest_1.describe)("getChangedFileContents", () => {
133
+ (0, vitest_1.it)("returns map of filename to contents", () => {
134
+ (0, git_1.createTag)("snap", repoDir);
135
+ fs.writeFileSync(path.join(repoDir, "file.txt"), "hello world");
136
+ (0, git_1.commitAll)("add file", repoDir);
137
+ const contents = (0, git_1.getChangedFileContents)("snap", repoDir);
138
+ (0, vitest_1.expect)(contents.get("file.txt")).toBe("hello world");
139
+ });
140
+ (0, vitest_1.it)("handles deleted files gracefully", () => {
141
+ fs.writeFileSync(path.join(repoDir, "temp.txt"), "temp");
142
+ (0, git_1.commitAll)("add temp", repoDir);
143
+ (0, git_1.createTag)("before-delete", repoDir);
144
+ fs.unlinkSync(path.join(repoDir, "temp.txt"));
145
+ (0, git_1.commitAll)("delete temp", repoDir);
146
+ const contents = (0, git_1.getChangedFileContents)("before-delete", repoDir);
147
+ // temp.txt was deleted so it should not be in the map (readFileSync fails)
148
+ (0, vitest_1.expect)(contents.has("temp.txt")).toBe(false);
149
+ });
150
+ });
151
+ });
152
+ //# sourceMappingURL=git.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.test.js","sourceRoot":"","sources":["../../src/__tests__/git.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const vitest_1 = require("vitest");
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const logging_1 = require("../logging");
40
+ const setup_1 = require("../../test/setup");
41
+ (0, vitest_1.describe)("logging", () => {
42
+ (0, vitest_1.describe)("logInfo", () => {
43
+ (0, vitest_1.it)("logs with [ridgeline] prefix", () => {
44
+ const spy = vitest_1.vi.spyOn(console, "log").mockImplementation(() => { });
45
+ (0, logging_1.logInfo)("hello");
46
+ (0, vitest_1.expect)(spy).toHaveBeenCalledWith("[ridgeline] hello");
47
+ spy.mockRestore();
48
+ });
49
+ });
50
+ (0, vitest_1.describe)("logError", () => {
51
+ (0, vitest_1.it)("logs with [ridgeline] ERROR: prefix to stderr", () => {
52
+ const spy = vitest_1.vi.spyOn(console, "error").mockImplementation(() => { });
53
+ (0, logging_1.logError)("something broke");
54
+ (0, vitest_1.expect)(spy).toHaveBeenCalledWith("[ridgeline] ERROR: something broke");
55
+ spy.mockRestore();
56
+ });
57
+ });
58
+ (0, vitest_1.describe)("logPhase", () => {
59
+ (0, vitest_1.it)("logs with phase id in brackets", () => {
60
+ const spy = vitest_1.vi.spyOn(console, "log").mockImplementation(() => { });
61
+ (0, logging_1.logPhase)("01-scaffold", "Building...");
62
+ (0, vitest_1.expect)(spy).toHaveBeenCalledWith("[ridgeline] [01-scaffold] Building...");
63
+ spy.mockRestore();
64
+ });
65
+ });
66
+ (0, vitest_1.describe)("logTrajectory", () => {
67
+ (0, vitest_1.it)("appends JSON line to trajectory.jsonl", () => {
68
+ const dir = (0, setup_1.makeTempDir)();
69
+ const entry = (0, logging_1.makeTrajectoryEntry)("build_start", "01-scaffold", "Build started");
70
+ (0, logging_1.logTrajectory)(dir, entry);
71
+ const content = fs.readFileSync(path.join(dir, "trajectory.jsonl"), "utf-8");
72
+ const parsed = JSON.parse(content.trim());
73
+ (0, vitest_1.expect)(parsed.type).toBe("build_start");
74
+ (0, vitest_1.expect)(parsed.phaseId).toBe("01-scaffold");
75
+ (0, vitest_1.expect)(parsed.summary).toBe("Build started");
76
+ fs.rmSync(dir, { recursive: true, force: true });
77
+ });
78
+ (0, vitest_1.it)("appends multiple entries on separate lines", () => {
79
+ const dir = (0, setup_1.makeTempDir)();
80
+ (0, logging_1.logTrajectory)(dir, (0, logging_1.makeTrajectoryEntry)("build_start", "01-scaffold", "Start"));
81
+ (0, logging_1.logTrajectory)(dir, (0, logging_1.makeTrajectoryEntry)("build_complete", "01-scaffold", "Done"));
82
+ const lines = fs.readFileSync(path.join(dir, "trajectory.jsonl"), "utf-8")
83
+ .trim()
84
+ .split("\n");
85
+ (0, vitest_1.expect)(lines).toHaveLength(2);
86
+ (0, vitest_1.expect)(JSON.parse(lines[0]).type).toBe("build_start");
87
+ (0, vitest_1.expect)(JSON.parse(lines[1]).type).toBe("build_complete");
88
+ fs.rmSync(dir, { recursive: true, force: true });
89
+ });
90
+ });
91
+ (0, vitest_1.describe)("makeTrajectoryEntry", () => {
92
+ (0, vitest_1.it)("creates entry with required fields", () => {
93
+ const entry = (0, logging_1.makeTrajectoryEntry)("plan_start", null, "Planning started");
94
+ (0, vitest_1.expect)(entry.type).toBe("plan_start");
95
+ (0, vitest_1.expect)(entry.phaseId).toBeNull();
96
+ (0, vitest_1.expect)(entry.summary).toBe("Planning started");
97
+ (0, vitest_1.expect)(entry.duration).toBeNull();
98
+ (0, vitest_1.expect)(entry.tokens).toBeNull();
99
+ (0, vitest_1.expect)(entry.costUsd).toBeNull();
100
+ (0, vitest_1.expect)(entry.timestamp).toBeDefined();
101
+ });
102
+ (0, vitest_1.it)("includes optional metrics when provided", () => {
103
+ const entry = (0, logging_1.makeTrajectoryEntry)("build_complete", "01-scaffold", "Done", {
104
+ duration: 5000,
105
+ tokens: { input: 100, output: 200 },
106
+ costUsd: 0.05,
107
+ });
108
+ (0, vitest_1.expect)(entry.duration).toBe(5000);
109
+ (0, vitest_1.expect)(entry.tokens).toEqual({ input: 100, output: 200 });
110
+ (0, vitest_1.expect)(entry.costUsd).toBe(0.05);
111
+ });
112
+ (0, vitest_1.it)("generates valid ISO timestamp", () => {
113
+ const entry = (0, logging_1.makeTrajectoryEntry)("plan_start", null, "test");
114
+ (0, vitest_1.expect)(() => new Date(entry.timestamp)).not.toThrow();
115
+ (0, vitest_1.expect)(new Date(entry.timestamp).toISOString()).toBe(entry.timestamp);
116
+ });
117
+ });
118
+ });
119
+ //# sourceMappingURL=logging.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.test.js","sourceRoot":"","sources":["../../src/__tests__/logging.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mCAAiD;AACjD,4CAA6B;AAC7B,gDAAiC;AACjC,wCAA4F;AAC5F,4CAA8C;AAE9C,IAAA,iBAAQ,EAAC,SAAS,EAAE,GAAG,EAAE;IACvB,IAAA,iBAAQ,EAAC,SAAS,EAAE,GAAG,EAAE;QACvB,IAAA,WAAE,EAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,GAAG,GAAG,WAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACjE,IAAA,iBAAO,EAAC,OAAO,CAAC,CAAA;YAChB,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,CAAA;YACrD,GAAG,CAAC,WAAW,EAAE,CAAA;QACnB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAA,iBAAQ,EAAC,UAAU,EAAE,GAAG,EAAE;QACxB,IAAA,WAAE,EAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,GAAG,GAAG,WAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACnE,IAAA,kBAAQ,EAAC,iBAAiB,CAAC,CAAA;YAC3B,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,oBAAoB,CAAC,oCAAoC,CAAC,CAAA;YACtE,GAAG,CAAC,WAAW,EAAE,CAAA;QACnB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAA,iBAAQ,EAAC,UAAU,EAAE,GAAG,EAAE;QACxB,IAAA,WAAE,EAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,GAAG,GAAG,WAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACjE,IAAA,kBAAQ,EAAC,aAAa,EAAE,aAAa,CAAC,CAAA;YACtC,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,oBAAoB,CAAC,uCAAuC,CAAC,CAAA;YACzE,GAAG,CAAC,WAAW,EAAE,CAAA;QACnB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAA,iBAAQ,EAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,IAAA,WAAE,EAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,GAAG,GAAG,IAAA,mBAAW,GAAE,CAAA;YACzB,MAAM,KAAK,GAAG,IAAA,6BAAmB,EAAC,aAAa,EAAE,aAAa,EAAE,eAAe,CAAC,CAAA;YAEhF,IAAA,uBAAa,EAAC,GAAG,EAAE,KAAK,CAAC,CAAA;YAEzB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC,CAAA;YAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;YACzC,IAAA,eAAM,EAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YACvC,IAAA,eAAM,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YAC1C,IAAA,eAAM,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;YAE5C,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAClD,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,GAAG,GAAG,IAAA,mBAAW,GAAE,CAAA;YACzB,IAAA,uBAAa,EAAC,GAAG,EAAE,IAAA,6BAAmB,EAAC,aAAa,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC,CAAA;YAC9E,IAAA,uBAAa,EAAC,GAAG,EAAE,IAAA,6BAAmB,EAAC,gBAAgB,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC,CAAA;YAEhF,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC;iBACvE,IAAI,EAAE;iBACN,KAAK,CAAC,IAAI,CAAC,CAAA;YACd,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;YAC7B,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YACrD,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;YAExD,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAClD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAA,iBAAQ,EAAC,qBAAqB,EAAE,GAAG,EAAE;QACnC,IAAA,WAAE,EAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,KAAK,GAAG,IAAA,6BAAmB,EAAC,YAAY,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAA;YACzE,IAAA,eAAM,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YACrC,IAAA,eAAM,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAA;YAChC,IAAA,eAAM,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;YAC9C,IAAA,eAAM,EAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAA;YACjC,IAAA,eAAM,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAA;YAC/B,IAAA,eAAM,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAA;YAChC,IAAA,eAAM,EAAC,KAAK,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAA;QACvC,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,KAAK,GAAG,IAAA,6BAAmB,EAAC,gBAAgB,EAAE,aAAa,EAAE,MAAM,EAAE;gBACzE,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;gBACnC,OAAO,EAAE,IAAI;aACd,CAAC,CAAA;YACF,IAAA,eAAM,EAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACjC,IAAA,eAAM,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;YACzD,IAAA,eAAM,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,IAAA,WAAE,EAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,MAAM,KAAK,GAAG,IAAA,6BAAmB,EAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;YAC7D,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAA;YACrD,IAAA,eAAM,EAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QACvE,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}