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
@@ -0,0 +1,54 @@
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
+ exports.ensureHandoffExists = exports.readHandoff = void 0;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const readHandoff = (buildDir) => {
40
+ const fp = path.join(buildDir, "handoff.md");
41
+ if (fs.existsSync(fp)) {
42
+ return fs.readFileSync(fp, "utf-8");
43
+ }
44
+ return "";
45
+ };
46
+ exports.readHandoff = readHandoff;
47
+ const ensureHandoffExists = (buildDir) => {
48
+ const fp = path.join(buildDir, "handoff.md");
49
+ if (!fs.existsSync(fp)) {
50
+ fs.writeFileSync(fp, "");
51
+ }
52
+ };
53
+ exports.ensureHandoffExists = ensureHandoffExists;
54
+ //# sourceMappingURL=handoff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../src/state/handoff.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA6B;AAC7B,gDAAiC;AAE1B,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAU,EAAE;IACtD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;IAC5C,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IACrC,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC,CAAA;AANY,QAAA,WAAW,eAMvB;AAEM,MAAM,mBAAmB,GAAG,CAAC,QAAgB,EAAQ,EAAE;IAC5D,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;IAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;QACvB,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAC1B,CAAC;AACH,CAAC,CAAA;AALY,QAAA,mBAAmB,uBAK/B"}
@@ -0,0 +1 @@
1
+ export declare const generateSnapshot: (projectDir: string, buildDir: string) => string;
@@ -0,0 +1,154 @@
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
+ exports.generateSnapshot = void 0;
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 EXCLUDED_DIRS = new Set([
41
+ "node_modules", "dist", "build", ".git", ".next", "__pycache__",
42
+ ".venv", "venv", "target", "vendor", ".ridgeline",
43
+ ]);
44
+ const MAX_DEPTH = 3;
45
+ const walkDir = (dir, prefix, depth) => {
46
+ if (depth > MAX_DEPTH)
47
+ return [];
48
+ const lines = [];
49
+ let entries;
50
+ try {
51
+ entries = fs.readdirSync(dir, { withFileTypes: true });
52
+ }
53
+ catch {
54
+ return lines;
55
+ }
56
+ entries.sort((a, b) => a.name.localeCompare(b.name));
57
+ for (const entry of entries) {
58
+ if (entry.name.startsWith(".") && depth === 0 && entry.name !== ".github")
59
+ continue;
60
+ if (EXCLUDED_DIRS.has(entry.name))
61
+ continue;
62
+ if (entry.isDirectory()) {
63
+ lines.push(`${prefix}${entry.name}/`);
64
+ lines.push(...walkDir(path.join(dir, entry.name), prefix + " ", depth + 1));
65
+ }
66
+ else {
67
+ lines.push(`${prefix}${entry.name}`);
68
+ }
69
+ }
70
+ return lines;
71
+ };
72
+ const readFileSafe = (filepath, maxLines) => {
73
+ try {
74
+ const content = fs.readFileSync(filepath, "utf-8");
75
+ const lines = content.split("\n");
76
+ if (lines.length > maxLines) {
77
+ return lines.slice(0, maxLines).join("\n") + `\n... (${lines.length - maxLines} more lines)`;
78
+ }
79
+ return content;
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ };
85
+ const CONFIG_FILES = [
86
+ "package.json", "tsconfig.json", "Cargo.toml", "pyproject.toml", "go.mod",
87
+ ".eslintrc.json", ".eslintrc.js", "eslint.config.js", "eslint.config.mjs",
88
+ "vite.config.ts", "vite.config.js", "next.config.js", "next.config.mjs",
89
+ "webpack.config.js", "tailwind.config.js", "tailwind.config.ts",
90
+ ];
91
+ const countSourceFiles = (dir) => {
92
+ const counts = new Map();
93
+ try {
94
+ const output = (0, node_child_process_1.execSync)("git ls-files --cached --others --exclude-standard", { cwd: dir, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
95
+ for (const file of output.split("\n").filter(Boolean)) {
96
+ const dirName = path.dirname(file);
97
+ counts.set(dirName, (counts.get(dirName) ?? 0) + 1);
98
+ }
99
+ }
100
+ catch {
101
+ // Not a git repo or no files
102
+ }
103
+ return counts;
104
+ };
105
+ const generateSnapshot = (projectDir, buildDir) => {
106
+ const sections = [];
107
+ // Directory tree
108
+ sections.push("## Directory Tree\n");
109
+ sections.push("```");
110
+ sections.push(...walkDir(projectDir, "", 0));
111
+ sections.push("```\n");
112
+ // Config files
113
+ sections.push("## Config Files\n");
114
+ for (const configFile of CONFIG_FILES) {
115
+ const fp = path.join(projectDir, configFile);
116
+ const content = readFileSafe(fp, 50);
117
+ if (content) {
118
+ sections.push(`### ${configFile}\n`);
119
+ sections.push("```");
120
+ sections.push(content);
121
+ sections.push("```\n");
122
+ }
123
+ }
124
+ // Source file counts
125
+ const fileCounts = countSourceFiles(projectDir);
126
+ if (fileCounts.size > 0) {
127
+ sections.push("## Source Files by Directory\n");
128
+ const sorted = [...fileCounts.entries()].sort((a, b) => a[0].localeCompare(b[0]));
129
+ for (const [dir, count] of sorted) {
130
+ sections.push(`- ${dir}: ${count} files`);
131
+ }
132
+ sections.push("");
133
+ }
134
+ // Test structure
135
+ const testDirs = ["test", "tests", "__tests__", "spec", "src/__tests__"];
136
+ const foundTests = [];
137
+ for (const td of testDirs) {
138
+ const fp = path.join(projectDir, td);
139
+ if (fs.existsSync(fp) && fs.statSync(fp).isDirectory()) {
140
+ foundTests.push(td);
141
+ }
142
+ }
143
+ if (foundTests.length > 0) {
144
+ sections.push("## Test Structure\n");
145
+ sections.push(`Test directories: ${foundTests.join(", ")}`);
146
+ sections.push("");
147
+ }
148
+ const snapshot = sections.join("\n");
149
+ const snapshotPath = path.join(buildDir, "snapshot.md");
150
+ fs.writeFileSync(snapshotPath, snapshot);
151
+ return snapshot;
152
+ };
153
+ exports.generateSnapshot = generateSnapshot;
154
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/state/snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { BuildState, PhaseState, PhaseInfo } from "../types";
2
+ export declare const loadState: (buildDir: string) => BuildState | null;
3
+ export declare const saveState: (buildDir: string, state: BuildState) => void;
4
+ export declare const initState: (buildName: string, phases: PhaseInfo[]) => BuildState;
5
+ export declare const updatePhaseStatus: (buildDir: string, state: BuildState, phaseId: string, update: Partial<PhaseState>) => void;
6
+ export declare const getNextIncompletePhase: (state: BuildState, cwd?: string) => PhaseState | null;
@@ -0,0 +1,94 @@
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
+ exports.getNextIncompletePhase = exports.updatePhaseStatus = exports.initState = exports.saveState = exports.loadState = void 0;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const git_1 = require("../git");
40
+ const statePath = (buildDir) => path.join(buildDir, "state.json");
41
+ const loadState = (buildDir) => {
42
+ const fp = statePath(buildDir);
43
+ if (fs.existsSync(fp)) {
44
+ return JSON.parse(fs.readFileSync(fp, "utf-8"));
45
+ }
46
+ return null;
47
+ };
48
+ exports.loadState = loadState;
49
+ const saveState = (buildDir, state) => {
50
+ fs.writeFileSync(statePath(buildDir), JSON.stringify(state, null, 2) + "\n");
51
+ };
52
+ exports.saveState = saveState;
53
+ const initState = (buildName, phases) => ({
54
+ buildName,
55
+ startedAt: new Date().toISOString(),
56
+ phases: phases.map((p) => ({
57
+ id: p.id,
58
+ status: "pending",
59
+ checkpointTag: `ridgeline/checkpoint/${buildName}/${p.id}`,
60
+ completionTag: null,
61
+ retries: 0,
62
+ duration: null,
63
+ completedAt: null,
64
+ failedAt: null,
65
+ })),
66
+ });
67
+ exports.initState = initState;
68
+ const updatePhaseStatus = (buildDir, state, phaseId, update) => {
69
+ const phase = state.phases.find((p) => p.id === phaseId);
70
+ if (phase) {
71
+ Object.assign(phase, update);
72
+ (0, exports.saveState)(buildDir, state);
73
+ }
74
+ };
75
+ exports.updatePhaseStatus = updatePhaseStatus;
76
+ const getNextIncompletePhase = (state, cwd) => {
77
+ for (const phase of state.phases) {
78
+ if (phase.status === "complete") {
79
+ // Verify the completion tag still exists
80
+ const completionTag = `ridgeline/phase/${state.buildName}/${phase.id}`;
81
+ if (!(0, git_1.tagExists)(completionTag, cwd)) {
82
+ // Tag was deleted — treat as incomplete
83
+ phase.status = "pending";
84
+ phase.completionTag = null;
85
+ return phase;
86
+ }
87
+ continue;
88
+ }
89
+ return phase;
90
+ }
91
+ return null;
92
+ };
93
+ exports.getNextIncompletePhase = getNextIncompletePhase;
94
+ //# sourceMappingURL=stateManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stateManager.js","sourceRoot":"","sources":["../../src/state/stateManager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA6B;AAC7B,gDAAiC;AAEjC,gCAAkC;AAElC,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAU,EAAE,CAC7C,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;AAE5B,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAqB,EAAE;IAC/D,MAAM,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;IAC9B,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAA;IACjD,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AANY,QAAA,SAAS,aAMrB;AAEM,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAE,KAAiB,EAAQ,EAAE;IACrE,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;AAC9E,CAAC,CAAA;AAFY,QAAA,SAAS,aAErB;AAEM,MAAM,SAAS,GAAG,CAAC,SAAiB,EAAE,MAAmB,EAAc,EAAE,CAAC,CAAC;IAChF,SAAS;IACT,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;IACnC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,MAAM,EAAE,SAAS;QACjB,aAAa,EAAE,wBAAwB,SAAS,IAAI,CAAC,CAAC,EAAE,EAAE;QAC1D,aAAa,EAAE,IAAI;QACnB,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,IAAI;QACjB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;CACJ,CAAC,CAAA;AAbW,QAAA,SAAS,aAapB;AAEK,MAAM,iBAAiB,GAAG,CAC/B,QAAgB,EAChB,KAAiB,EACjB,OAAe,EACf,MAA2B,EACrB,EAAE;IACR,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAA;IACxD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAC5B,IAAA,iBAAS,EAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAC5B,CAAC;AACH,CAAC,CAAA;AAXY,QAAA,iBAAiB,qBAW7B;AAEM,MAAM,sBAAsB,GAAG,CACpC,KAAiB,EACjB,GAAY,EACO,EAAE;IACrB,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAChC,yCAAyC;YACzC,MAAM,aAAa,GAAG,mBAAmB,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,EAAE,EAAE,CAAA;YACtE,IAAI,CAAC,IAAA,eAAS,EAAC,aAAa,EAAE,GAAG,CAAC,EAAE,CAAC;gBACnC,wCAAwC;gBACxC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAA;gBACxB,KAAK,CAAC,aAAa,GAAG,IAAI,CAAA;gBAC1B,OAAO,KAAK,CAAA;YACd,CAAC;YACD,SAAQ;QACV,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAnBY,QAAA,sBAAsB,0BAmBlC"}
@@ -0,0 +1,87 @@
1
+ export type RidgelineConfig = {
2
+ buildName: string;
3
+ buildDir: string;
4
+ constraintsPath: string;
5
+ tastePath: string | null;
6
+ snapshotPath: string;
7
+ handoffPath: string;
8
+ phasesDir: string;
9
+ model: string;
10
+ maxRetries: number;
11
+ timeoutMinutes: number;
12
+ verbose: boolean;
13
+ checkCommand: string | null;
14
+ maxBudgetUsd: number | null;
15
+ };
16
+ export type PhaseInfo = {
17
+ id: string;
18
+ index: number;
19
+ slug: string;
20
+ filename: string;
21
+ filepath: string;
22
+ };
23
+ export type PhaseState = {
24
+ id: string;
25
+ status: "pending" | "building" | "reviewing" | "complete" | "failed";
26
+ checkpointTag: string;
27
+ completionTag: string | null;
28
+ retries: number;
29
+ duration: number | null;
30
+ completedAt: string | null;
31
+ failedAt: string | null;
32
+ };
33
+ export type BuildState = {
34
+ buildName: string;
35
+ startedAt: string;
36
+ phases: PhaseState[];
37
+ };
38
+ export type ClaudeResult = {
39
+ success: boolean;
40
+ result: string;
41
+ durationMs: number;
42
+ costUsd: number;
43
+ usage: {
44
+ inputTokens: number;
45
+ outputTokens: number;
46
+ cacheReadInputTokens: number;
47
+ cacheCreationInputTokens: number;
48
+ };
49
+ sessionId: string;
50
+ };
51
+ export type ReviewVerdict = {
52
+ passed: boolean;
53
+ summary: string;
54
+ criteriaResults: {
55
+ criterion: number;
56
+ passed: boolean;
57
+ notes: string;
58
+ }[];
59
+ issues: string[];
60
+ suggestions: string[];
61
+ };
62
+ export type BudgetEntry = {
63
+ phase: string;
64
+ role: "planner" | "builder" | "reviewer";
65
+ attempt: number;
66
+ costUsd: number;
67
+ inputTokens: number;
68
+ outputTokens: number;
69
+ durationMs: number;
70
+ timestamp: string;
71
+ };
72
+ export type BudgetState = {
73
+ entries: BudgetEntry[];
74
+ totalCostUsd: number;
75
+ };
76
+ export type TrajectoryEntry = {
77
+ timestamp: string;
78
+ type: "plan_start" | "plan_complete" | "build_start" | "build_complete" | "review_start" | "review_complete" | "phase_advance" | "phase_fail" | "budget_exceeded";
79
+ phaseId: string | null;
80
+ duration: number | null;
81
+ tokens: {
82
+ input: number;
83
+ output: number;
84
+ } | null;
85
+ costUsd: number | null;
86
+ summary: string;
87
+ };
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "ridgeline",
3
+ "version": "0.1.5",
4
+ "description": "Build harness for long-horizon software execution",
5
+ "license": "MIT",
6
+ "bin": {
7
+ "ridgeline": "dist/cli.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc && cp -r src/agents dist/agents",
11
+ "dev": "tsc --watch",
12
+ "lint": "npm run lint:code && npm run lint:markdown && npm run lint:agents",
13
+ "lint:code": "oxlint",
14
+ "lint:markdown": "markdownlint-cli2 '**/*.md'",
15
+ "lint:agents": "agnix",
16
+ "prepublishOnly": "npm run build",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest"
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "dependencies": {
24
+ "commander": "13.0.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "22.0.0",
28
+ "agnix": "0.17.0",
29
+ "markdownlint-cli2": "0.22.0",
30
+ "oxlint": "1.58.0",
31
+ "typescript": "5.9.3",
32
+ "vitest": "4.1.2"
33
+ }
34
+ }