ralph-research 0.1.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/LICENSE +21 -0
- package/README.md +98 -0
- package/dist/adapters/extractor/command-extractor.d.ts +9 -0
- package/dist/adapters/extractor/command-extractor.js +93 -0
- package/dist/adapters/extractor/command-extractor.js.map +1 -0
- package/dist/adapters/extractor/llm-judge-extractor.d.ts +9 -0
- package/dist/adapters/extractor/llm-judge-extractor.js +12 -0
- package/dist/adapters/extractor/llm-judge-extractor.js.map +1 -0
- package/dist/adapters/fs/json-file-decision-store.d.ts +10 -0
- package/dist/adapters/fs/json-file-decision-store.js +53 -0
- package/dist/adapters/fs/json-file-decision-store.js.map +1 -0
- package/dist/adapters/fs/json-file-frontier-store.d.ts +8 -0
- package/dist/adapters/fs/json-file-frontier-store.js +29 -0
- package/dist/adapters/fs/json-file-frontier-store.js.map +1 -0
- package/dist/adapters/fs/json-file-run-store.d.ts +10 -0
- package/dist/adapters/fs/json-file-run-store.js +53 -0
- package/dist/adapters/fs/json-file-run-store.js.map +1 -0
- package/dist/adapters/fs/lockfile.d.ts +24 -0
- package/dist/adapters/fs/lockfile.js +110 -0
- package/dist/adapters/fs/lockfile.js.map +1 -0
- package/dist/adapters/fs/manifest-loader.d.ts +10 -0
- package/dist/adapters/fs/manifest-loader.js +43 -0
- package/dist/adapters/fs/manifest-loader.js.map +1 -0
- package/dist/adapters/git/git-client.d.ts +9 -0
- package/dist/adapters/git/git-client.js +23 -0
- package/dist/adapters/git/git-client.js.map +1 -0
- package/dist/adapters/index.d.ts +1 -0
- package/dist/adapters/index.js +3 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/judge/llm-judge-provider.d.ts +33 -0
- package/dist/adapters/judge/llm-judge-provider.js +90 -0
- package/dist/adapters/judge/llm-judge-provider.js.map +1 -0
- package/dist/adapters/proposer/command-proposer.d.ts +15 -0
- package/dist/adapters/proposer/command-proposer.js +29 -0
- package/dist/adapters/proposer/command-proposer.js.map +1 -0
- package/dist/app/context.d.ts +5 -0
- package/dist/app/context.js +7 -0
- package/dist/app/context.js.map +1 -0
- package/dist/app/services/manual-decision-service.d.ts +20 -0
- package/dist/app/services/manual-decision-service.js +143 -0
- package/dist/app/services/manual-decision-service.js.map +1 -0
- package/dist/app/services/project-state-service.d.ts +52 -0
- package/dist/app/services/project-state-service.js +92 -0
- package/dist/app/services/project-state-service.js.map +1 -0
- package/dist/app/services/run-cycle-service.d.ts +25 -0
- package/dist/app/services/run-cycle-service.js +69 -0
- package/dist/app/services/run-cycle-service.js.map +1 -0
- package/dist/cli/commands/accept.d.ts +10 -0
- package/dist/cli/commands/accept.js +54 -0
- package/dist/cli/commands/accept.js.map +1 -0
- package/dist/cli/commands/demo.d.ts +9 -0
- package/dist/cli/commands/demo.js +108 -0
- package/dist/cli/commands/demo.js.map +1 -0
- package/dist/cli/commands/frontier.d.ts +8 -0
- package/dist/cli/commands/frontier.js +48 -0
- package/dist/cli/commands/frontier.js.map +1 -0
- package/dist/cli/commands/init.d.ts +10 -0
- package/dist/cli/commands/init.js +123 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/inspect.d.ts +8 -0
- package/dist/cli/commands/inspect.js +55 -0
- package/dist/cli/commands/inspect.js.map +1 -0
- package/dist/cli/commands/reject.d.ts +10 -0
- package/dist/cli/commands/reject.js +54 -0
- package/dist/cli/commands/reject.js.map +1 -0
- package/dist/cli/commands/run.d.ts +13 -0
- package/dist/cli/commands/run.js +71 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/serve-mcp.d.ts +7 -0
- package/dist/cli/commands/serve-mcp.js +32 -0
- package/dist/cli/commands/serve-mcp.js.map +1 -0
- package/dist/cli/commands/status.d.ts +8 -0
- package/dist/cli/commands/status.js +53 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +11 -0
- package/dist/cli/commands/validate.js +56 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +38 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/core/engine/anchor-checker.d.ts +35 -0
- package/dist/core/engine/anchor-checker.js +84 -0
- package/dist/core/engine/anchor-checker.js.map +1 -0
- package/dist/core/engine/audit-sampler.d.ts +16 -0
- package/dist/core/engine/audit-sampler.js +25 -0
- package/dist/core/engine/audit-sampler.js.map +1 -0
- package/dist/core/engine/change-budget.d.ts +11 -0
- package/dist/core/engine/change-budget.js +10 -0
- package/dist/core/engine/change-budget.js.map +1 -0
- package/dist/core/engine/cycle-runner.d.ts +39 -0
- package/dist/core/engine/cycle-runner.js +652 -0
- package/dist/core/engine/cycle-runner.js.map +1 -0
- package/dist/core/engine/experiment-runner.d.ts +13 -0
- package/dist/core/engine/experiment-runner.js +24 -0
- package/dist/core/engine/experiment-runner.js.map +1 -0
- package/dist/core/engine/history-compactor.d.ts +15 -0
- package/dist/core/engine/history-compactor.js +76 -0
- package/dist/core/engine/history-compactor.js.map +1 -0
- package/dist/core/engine/judge-pack.d.ts +44 -0
- package/dist/core/engine/judge-pack.js +111 -0
- package/dist/core/engine/judge-pack.js.map +1 -0
- package/dist/core/engine/parallel-proposer.d.ts +21 -0
- package/dist/core/engine/parallel-proposer.js +58 -0
- package/dist/core/engine/parallel-proposer.js.map +1 -0
- package/dist/core/engine/scope-checker.d.ts +35 -0
- package/dist/core/engine/scope-checker.js +166 -0
- package/dist/core/engine/scope-checker.js.map +1 -0
- package/dist/core/engine/workspace-manager.d.ts +32 -0
- package/dist/core/engine/workspace-manager.js +145 -0
- package/dist/core/engine/workspace-manager.js.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/manifest/defaults.d.ts +55 -0
- package/dist/core/manifest/defaults.js +56 -0
- package/dist/core/manifest/defaults.js.map +1 -0
- package/dist/core/manifest/schema.d.ts +647 -0
- package/dist/core/manifest/schema.js +254 -0
- package/dist/core/manifest/schema.js.map +1 -0
- package/dist/core/model/decision-record.d.ts +38 -0
- package/dist/core/model/decision-record.js +29 -0
- package/dist/core/model/decision-record.js.map +1 -0
- package/dist/core/model/frontier-entry.d.ts +24 -0
- package/dist/core/model/frontier-entry.js +15 -0
- package/dist/core/model/frontier-entry.js.map +1 -0
- package/dist/core/model/metric.d.ts +13 -0
- package/dist/core/model/metric.js +10 -0
- package/dist/core/model/metric.js.map +1 -0
- package/dist/core/model/run-record.d.ts +110 -0
- package/dist/core/model/run-record.js +104 -0
- package/dist/core/model/run-record.js.map +1 -0
- package/dist/core/ports/decision-store.d.ts +6 -0
- package/dist/core/ports/decision-store.js +2 -0
- package/dist/core/ports/decision-store.js.map +1 -0
- package/dist/core/ports/frontier-store.d.ts +5 -0
- package/dist/core/ports/frontier-store.js +2 -0
- package/dist/core/ports/frontier-store.js.map +1 -0
- package/dist/core/ports/run-store.d.ts +6 -0
- package/dist/core/ports/run-store.js +2 -0
- package/dist/core/ports/run-store.js.map +1 -0
- package/dist/core/state/constraint-engine.d.ts +18 -0
- package/dist/core/state/constraint-engine.js +42 -0
- package/dist/core/state/constraint-engine.js.map +1 -0
- package/dist/core/state/frontier-engine.d.ts +24 -0
- package/dist/core/state/frontier-engine.js +178 -0
- package/dist/core/state/frontier-engine.js.map +1 -0
- package/dist/core/state/ratchet-engine.d.ts +28 -0
- package/dist/core/state/ratchet-engine.js +177 -0
- package/dist/core/state/ratchet-engine.js.map +1 -0
- package/dist/core/state/run-state-machine.d.ts +17 -0
- package/dist/core/state/run-state-machine.js +94 -0
- package/dist/core/state/run-state-machine.js.map +1 -0
- package/dist/mcp/main.d.ts +1 -0
- package/dist/mcp/main.js +8 -0
- package/dist/mcp/main.js.map +1 -0
- package/dist/mcp/server.d.ts +6 -0
- package/dist/mcp/server.js +97 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/shared/fs-errors.d.ts +1 -0
- package/dist/shared/fs-errors.js +4 -0
- package/dist/shared/fs-errors.js.map +1 -0
- package/dist/shared/logger.d.ts +2 -0
- package/dist/shared/logger.js +5 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/template-utils.d.ts +9 -0
- package/dist/shared/template-utils.js +50 -0
- package/dist/shared/template-utils.js.map +1 -0
- package/package.json +44 -0
- package/templates/writing/docs/draft.md +1 -0
- package/templates/writing/prompts/judge.md +15 -0
- package/templates/writing/ralph.yaml +63 -0
- package/templates/writing/scripts/experiment.mjs +6 -0
- package/templates/writing/scripts/metric.mjs +24 -0
- package/templates/writing/scripts/propose.mjs +13 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 research-ratchet contributors
|
|
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,98 @@
|
|
|
1
|
+
# ralph-research
|
|
2
|
+
|
|
3
|
+
Local-first runtime for recursive research improvement.
|
|
4
|
+
|
|
5
|
+
`ralph-research` runs a bounded improvement loop over a real artifact:
|
|
6
|
+
|
|
7
|
+
1. define a metric
|
|
8
|
+
2. generate one candidate change
|
|
9
|
+
3. evaluate it
|
|
10
|
+
4. keep only verified improvements
|
|
11
|
+
|
|
12
|
+
The v0.1 focus is a writing workflow that is runnable in under five minutes on a local machine.
|
|
13
|
+
|
|
14
|
+
## Quickstart
|
|
15
|
+
|
|
16
|
+
### Zero-config demo
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx ralph-research demo writing
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This creates a temporary writing repo, runs one accepted cycle, and prints the path plus the run id. The v0.1 demo supports the bundled `writing` template only.
|
|
23
|
+
|
|
24
|
+
### Template flow
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx ralph-research init --template writing
|
|
28
|
+
npx ralph-research run --json
|
|
29
|
+
npx ralph-research inspect run-0001 --json
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
This path is the v0.1 success bar: `init -> run -> inspect` should work quickly and produce an acceptance reason you can inspect. The bundled template set is currently `writing` only.
|
|
33
|
+
|
|
34
|
+
## Core Concepts
|
|
35
|
+
|
|
36
|
+
- `Manifest`: `ralph.yaml` defines the research program.
|
|
37
|
+
- `Metric`: how candidate quality is measured.
|
|
38
|
+
- `Frontier`: the currently accepted best candidate set.
|
|
39
|
+
- `Ratchet`: the acceptance policy that decides whether the frontier advances.
|
|
40
|
+
- `Proposer`: how a bounded candidate change is generated.
|
|
41
|
+
- `Judge`: how qualitative outputs are compared when numeric metrics are not enough.
|
|
42
|
+
|
|
43
|
+
## Writing Template
|
|
44
|
+
|
|
45
|
+
The bundled writing template is self-contained:
|
|
46
|
+
|
|
47
|
+
- `docs/draft.md`: sample draft
|
|
48
|
+
- `scripts/propose.mjs`: bounded rewrite
|
|
49
|
+
- `scripts/experiment.mjs`: output materialization
|
|
50
|
+
- `scripts/metric.mjs`: local heuristic metric
|
|
51
|
+
- `prompts/judge.md`: pairwise judge prompt you can upgrade to later
|
|
52
|
+
|
|
53
|
+
The default template uses a local command metric so the first run does not require API keys. When you are ready, replace the numeric metric with an `llm_judge` extractor and use the included pairwise prompt as a starting point.
|
|
54
|
+
|
|
55
|
+
## CLI
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
rrx validate
|
|
59
|
+
rrx doctor
|
|
60
|
+
rrx init --template writing
|
|
61
|
+
rrx demo writing
|
|
62
|
+
rrx run
|
|
63
|
+
rrx status
|
|
64
|
+
rrx frontier
|
|
65
|
+
rrx inspect <runId>
|
|
66
|
+
rrx accept <runId>
|
|
67
|
+
rrx reject <runId>
|
|
68
|
+
rrx serve-mcp --stdio
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## MCP
|
|
72
|
+
|
|
73
|
+
The bundled MCP server currently supports stdio transport and exposes three thin tools backed by the same service layer as the CLI:
|
|
74
|
+
|
|
75
|
+
- `run_research_cycle`
|
|
76
|
+
- `get_research_status`
|
|
77
|
+
- `get_frontier`
|
|
78
|
+
|
|
79
|
+
## Design Principles
|
|
80
|
+
|
|
81
|
+
- local-first execution
|
|
82
|
+
- bounded changes
|
|
83
|
+
- recoverable state transitions
|
|
84
|
+
- trusted signal before automation
|
|
85
|
+
- inspectable accept/reject decisions
|
|
86
|
+
|
|
87
|
+
## Development
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npm install
|
|
91
|
+
npm test
|
|
92
|
+
npm run typecheck
|
|
93
|
+
npm run build
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
MIT
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CommandMetricExtractorConfig } from "../../core/manifest/schema.js";
|
|
2
|
+
import type { MetricResult } from "../../core/model/metric.js";
|
|
3
|
+
export interface ExtractCommandMetricInput {
|
|
4
|
+
metricId: string;
|
|
5
|
+
direction: "maximize" | "minimize";
|
|
6
|
+
workspacePath: string;
|
|
7
|
+
env?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
export declare function extractCommandMetric(config: CommandMetricExtractorConfig, input: ExtractCommandMetricInput): Promise<MetricResult>;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { execaCommand } from "execa";
|
|
3
|
+
export async function extractCommandMetric(config, input) {
|
|
4
|
+
const cwd = config.cwd ? resolve(input.workspacePath, config.cwd) : resolve(input.workspacePath);
|
|
5
|
+
const result = await execaCommand(config.command, {
|
|
6
|
+
cwd,
|
|
7
|
+
env: { ...process.env, ...config.env, ...input.env },
|
|
8
|
+
reject: false,
|
|
9
|
+
shell: true,
|
|
10
|
+
timeout: config.timeoutSec * 1_000,
|
|
11
|
+
});
|
|
12
|
+
if (result.exitCode !== 0) {
|
|
13
|
+
throw new Error(`command metric extractor failed with exit code ${result.exitCode}: ${result.stderr || result.stdout}`);
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
metricId: input.metricId,
|
|
17
|
+
direction: input.direction,
|
|
18
|
+
value: parseMetricValue(result.stdout, config),
|
|
19
|
+
details: {
|
|
20
|
+
parser: config.parser,
|
|
21
|
+
command: config.command,
|
|
22
|
+
cwd,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function parseMetricValue(stdout, config) {
|
|
27
|
+
switch (config.parser) {
|
|
28
|
+
case "plain_number":
|
|
29
|
+
return parseNumericValue(stdout.trim(), "plain_number");
|
|
30
|
+
case "regex":
|
|
31
|
+
return parseRegexValue(stdout, config.pattern);
|
|
32
|
+
case "json_path":
|
|
33
|
+
return parseJsonPathValue(stdout, config.valuePath);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function parseRegexValue(stdout, pattern) {
|
|
37
|
+
if (!pattern) {
|
|
38
|
+
throw new Error('command metric extractor with parser="regex" requires a pattern');
|
|
39
|
+
}
|
|
40
|
+
const match = new RegExp(pattern, "m").exec(stdout);
|
|
41
|
+
if (!match) {
|
|
42
|
+
throw new Error(`regex parser did not match pattern ${pattern}`);
|
|
43
|
+
}
|
|
44
|
+
const candidate = match.groups?.value ?? match[1] ?? match[0];
|
|
45
|
+
return parseNumericValue(candidate, "regex");
|
|
46
|
+
}
|
|
47
|
+
function parseJsonPathValue(stdout, valuePath) {
|
|
48
|
+
if (!valuePath) {
|
|
49
|
+
throw new Error('command metric extractor with parser="json_path" requires a valuePath');
|
|
50
|
+
}
|
|
51
|
+
const json = JSON.parse(stdout);
|
|
52
|
+
const value = readJsonPath(json, valuePath);
|
|
53
|
+
return parseNumericValue(value, "json_path");
|
|
54
|
+
}
|
|
55
|
+
function readJsonPath(root, path) {
|
|
56
|
+
if (!path.startsWith("$")) {
|
|
57
|
+
throw new Error(`unsupported JSONPath: ${path}`);
|
|
58
|
+
}
|
|
59
|
+
const tokens = path
|
|
60
|
+
.slice(1)
|
|
61
|
+
.replace(/\[(\d+)\]/g, ".$1")
|
|
62
|
+
.split(".")
|
|
63
|
+
.filter(Boolean);
|
|
64
|
+
let current = root;
|
|
65
|
+
for (const token of tokens) {
|
|
66
|
+
if (current === null || current === undefined) {
|
|
67
|
+
throw new Error(`JSONPath ${path} resolved to undefined at token ${token}`);
|
|
68
|
+
}
|
|
69
|
+
if (Array.isArray(current)) {
|
|
70
|
+
const index = Number.parseInt(token, 10);
|
|
71
|
+
current = current[index];
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (typeof current === "object") {
|
|
75
|
+
current = current[token];
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
throw new Error(`JSONPath ${path} could not descend into non-object value at token ${token}`);
|
|
79
|
+
}
|
|
80
|
+
return current;
|
|
81
|
+
}
|
|
82
|
+
function parseNumericValue(value, parserName) {
|
|
83
|
+
const numericValue = typeof value === "number"
|
|
84
|
+
? value
|
|
85
|
+
: typeof value === "string"
|
|
86
|
+
? Number.parseFloat(value.trim())
|
|
87
|
+
: Number.NaN;
|
|
88
|
+
if (!Number.isFinite(numericValue)) {
|
|
89
|
+
throw new Error(`${parserName} parser did not resolve to a finite number`);
|
|
90
|
+
}
|
|
91
|
+
return numericValue;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=command-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-extractor.js","sourceRoot":"","sources":["../../../src/adapters/extractor/command-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LlmJudgeMetricExtractorConfig, JudgePack } from "../../core/manifest/schema.js";
|
|
2
|
+
import type { MetricResult } from "../../core/model/metric.js";
|
|
3
|
+
import type { JudgeProvider } from "../judge/llm-judge-provider.js";
|
|
4
|
+
export interface ExtractLlmJudgeMetricInput {
|
|
5
|
+
metricId: string;
|
|
6
|
+
direction: "maximize" | "minimize";
|
|
7
|
+
prompt: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function extractLlmJudgeMetric(config: LlmJudgeMetricExtractorConfig, pack: JudgePack, input: ExtractLlmJudgeMetricInput, provider: JudgeProvider): Promise<MetricResult>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { runLlmJudgeMetric } from "../../core/engine/judge-pack.js";
|
|
2
|
+
export async function extractLlmJudgeMetric(config, pack, input, provider) {
|
|
3
|
+
return runLlmJudgeMetric({
|
|
4
|
+
metricId: input.metricId,
|
|
5
|
+
direction: input.direction,
|
|
6
|
+
extractor: config,
|
|
7
|
+
pack,
|
|
8
|
+
prompt: input.prompt,
|
|
9
|
+
provider,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=llm-judge-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-judge-extractor.js","sourceRoot":"","sources":["../../../src/adapters/extractor/llm-judge-extractor.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAQpE,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAqC,EACrC,IAAe,EACf,KAAiC,EACjC,QAAuB;IAEvB,OAAO,iBAAiB,CAAC;QACvB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,SAAS,EAAE,MAAM;QACjB,IAAI;QACJ,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,QAAQ;KACT,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type DecisionRecord } from "../../core/model/decision-record.js";
|
|
2
|
+
import type { DecisionStore } from "../../core/ports/decision-store.js";
|
|
3
|
+
export declare class JsonFileDecisionStore implements DecisionStore {
|
|
4
|
+
private readonly rootDir;
|
|
5
|
+
constructor(rootDir: string);
|
|
6
|
+
put(record: DecisionRecord): Promise<void>;
|
|
7
|
+
get(decisionId: string): Promise<DecisionRecord | null>;
|
|
8
|
+
list(): Promise<DecisionRecord[]>;
|
|
9
|
+
private getPath;
|
|
10
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { decisionRecordSchema } from "../../core/model/decision-record.js";
|
|
4
|
+
import { isMissingFileError } from "../../shared/fs-errors.js";
|
|
5
|
+
export class JsonFileDecisionStore {
|
|
6
|
+
rootDir;
|
|
7
|
+
constructor(rootDir) {
|
|
8
|
+
this.rootDir = resolve(rootDir);
|
|
9
|
+
}
|
|
10
|
+
async put(record) {
|
|
11
|
+
const parsed = decisionRecordSchema.parse(record);
|
|
12
|
+
const path = this.getPath(parsed.decisionId);
|
|
13
|
+
await mkdir(dirname(path), { recursive: true });
|
|
14
|
+
await writeFile(path, `${JSON.stringify(parsed, null, 2)}\n`, "utf8");
|
|
15
|
+
}
|
|
16
|
+
async get(decisionId) {
|
|
17
|
+
const path = this.getPath(decisionId);
|
|
18
|
+
try {
|
|
19
|
+
const raw = await readFile(path, "utf8");
|
|
20
|
+
return decisionRecordSchema.parse(JSON.parse(raw));
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (isMissingFileError(error)) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async list() {
|
|
30
|
+
try {
|
|
31
|
+
const entries = await readdir(this.rootDir, { withFileTypes: true });
|
|
32
|
+
const records = [];
|
|
33
|
+
for (const entry of entries) {
|
|
34
|
+
if (!entry.isFile() || !entry.name.endsWith(".json")) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const raw = await readFile(join(this.rootDir, entry.name), "utf8");
|
|
38
|
+
records.push(decisionRecordSchema.parse(JSON.parse(raw)));
|
|
39
|
+
}
|
|
40
|
+
return records.sort((left, right) => left.decisionId.localeCompare(right.decisionId));
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (isMissingFileError(error)) {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
getPath(decisionId) {
|
|
50
|
+
return join(this.rootDir, `${decisionId}.json`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=json-file-decision-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-file-decision-store.js","sourceRoot":"","sources":["../../../src/adapters/fs/json-file-decision-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,oBAAoB,EAAuB,MAAM,qCAAqC,CAAC;AAEhG,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,OAAO,qBAAqB;IACf,OAAO,CAAS;IAEjC,YAAmB,OAAe;QAChC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,MAAsB;QACrC,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC7C,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,UAAkB;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACzC,OAAO,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YACrE,MAAM,OAAO,GAAqB,EAAE,CAAC;YACrC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBACrD,SAAS;gBACX,CAAC;gBACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;gBACnE,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;QACxF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,OAAO,CAAC,UAAkB;QAChC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,UAAU,OAAO,CAAC,CAAC;IAClD,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type FrontierEntry } from "../../core/model/frontier-entry.js";
|
|
2
|
+
import type { FrontierStore } from "../../core/ports/frontier-store.js";
|
|
3
|
+
export declare class JsonFileFrontierStore implements FrontierStore {
|
|
4
|
+
private readonly path;
|
|
5
|
+
constructor(path: string);
|
|
6
|
+
save(entries: FrontierEntry[]): Promise<void>;
|
|
7
|
+
load(): Promise<FrontierEntry[]>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { frontierEntrySchema } from "../../core/model/frontier-entry.js";
|
|
4
|
+
import { isMissingFileError } from "../../shared/fs-errors.js";
|
|
5
|
+
const frontierSnapshotSchema = frontierEntrySchema.array();
|
|
6
|
+
export class JsonFileFrontierStore {
|
|
7
|
+
path;
|
|
8
|
+
constructor(path) {
|
|
9
|
+
this.path = resolve(path);
|
|
10
|
+
}
|
|
11
|
+
async save(entries) {
|
|
12
|
+
const parsed = frontierSnapshotSchema.parse(entries);
|
|
13
|
+
await mkdir(dirname(this.path), { recursive: true });
|
|
14
|
+
await writeFile(this.path, `${JSON.stringify(parsed, null, 2)}\n`, "utf8");
|
|
15
|
+
}
|
|
16
|
+
async load() {
|
|
17
|
+
try {
|
|
18
|
+
const raw = await readFile(this.path, "utf8");
|
|
19
|
+
return frontierSnapshotSchema.parse(JSON.parse(raw));
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
if (isMissingFileError(error)) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=json-file-frontier-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-file-frontier-store.js","sourceRoot":"","sources":["../../../src/adapters/fs/json-file-frontier-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,mBAAmB,EAAsB,MAAM,oCAAoC,CAAC;AAE7F,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,sBAAsB,GAAG,mBAAmB,CAAC,KAAK,EAAE,CAAC;AAE3D,MAAM,OAAO,qBAAqB;IACf,IAAI,CAAS;IAE9B,YAAmB,IAAY;QAC7B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,OAAwB;QACxC,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrD,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7E,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC9C,OAAO,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type RunRecord } from "../../core/model/run-record.js";
|
|
2
|
+
import type { RunStore } from "../../core/ports/run-store.js";
|
|
3
|
+
export declare class JsonFileRunStore implements RunStore {
|
|
4
|
+
private readonly rootDir;
|
|
5
|
+
constructor(rootDir: string);
|
|
6
|
+
put(record: RunRecord): Promise<void>;
|
|
7
|
+
get(runId: string): Promise<RunRecord | null>;
|
|
8
|
+
list(): Promise<RunRecord[]>;
|
|
9
|
+
private getPath;
|
|
10
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { runRecordSchema } from "../../core/model/run-record.js";
|
|
4
|
+
import { isMissingFileError } from "../../shared/fs-errors.js";
|
|
5
|
+
export class JsonFileRunStore {
|
|
6
|
+
rootDir;
|
|
7
|
+
constructor(rootDir) {
|
|
8
|
+
this.rootDir = resolve(rootDir);
|
|
9
|
+
}
|
|
10
|
+
async put(record) {
|
|
11
|
+
const parsed = runRecordSchema.parse(record);
|
|
12
|
+
const path = this.getPath(parsed.runId);
|
|
13
|
+
await mkdir(dirname(path), { recursive: true });
|
|
14
|
+
await writeFile(path, `${JSON.stringify(parsed, null, 2)}\n`, "utf8");
|
|
15
|
+
}
|
|
16
|
+
async get(runId) {
|
|
17
|
+
const path = this.getPath(runId);
|
|
18
|
+
try {
|
|
19
|
+
const raw = await readFile(path, "utf8");
|
|
20
|
+
return runRecordSchema.parse(JSON.parse(raw));
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (isMissingFileError(error)) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async list() {
|
|
30
|
+
try {
|
|
31
|
+
const entries = await readdir(this.rootDir, { withFileTypes: true });
|
|
32
|
+
const records = [];
|
|
33
|
+
for (const entry of entries) {
|
|
34
|
+
if (!entry.isFile() || !entry.name.endsWith(".json")) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const raw = await readFile(join(this.rootDir, entry.name), "utf8");
|
|
38
|
+
records.push(runRecordSchema.parse(JSON.parse(raw)));
|
|
39
|
+
}
|
|
40
|
+
return records.sort((left, right) => left.runId.localeCompare(right.runId));
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (isMissingFileError(error)) {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
getPath(runId) {
|
|
50
|
+
return join(this.rootDir, `${runId}.json`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=json-file-run-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-file-run-store.js","sourceRoot":"","sources":["../../../src/adapters/fs/json-file-run-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAkB,MAAM,gCAAgC,CAAC;AAEjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,OAAO,gBAAgB;IACV,OAAO,CAAS;IAEjC,YAAmB,OAAe;QAChC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,MAAiB;QAChC,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,KAAa;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACzC,OAAO,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YACrE,MAAM,OAAO,GAAgB,EAAE,CAAC;YAChC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBACrD,SAAS;gBACX,CAAC;gBACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;gBACnE,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACvD,CAAC;YACD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,OAAO,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC;IAC7C,CAAC;CACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
declare const lockfileMetadataSchema: z.ZodObject<{
|
|
3
|
+
pid: z.ZodNumber;
|
|
4
|
+
token: z.ZodString;
|
|
5
|
+
createdAt: z.ZodString;
|
|
6
|
+
updatedAt: z.ZodString;
|
|
7
|
+
ttlMs: z.ZodNumber;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
export type LockfileMetadata = z.infer<typeof lockfileMetadataSchema>;
|
|
10
|
+
export interface AcquireLockOptions {
|
|
11
|
+
ttlMs?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface LockHandle {
|
|
14
|
+
path: string;
|
|
15
|
+
metadata: LockfileMetadata;
|
|
16
|
+
}
|
|
17
|
+
export declare class LockAcquisitionError extends Error {
|
|
18
|
+
constructor(message: string);
|
|
19
|
+
}
|
|
20
|
+
export declare function acquireLock(path: string, options?: AcquireLockOptions): Promise<LockHandle>;
|
|
21
|
+
export declare function releaseLock(path: string, token?: string): Promise<void>;
|
|
22
|
+
export declare function isStaleLock(path: string): Promise<boolean>;
|
|
23
|
+
export declare function readLockMetadata(path: string): Promise<LockfileMetadata | null>;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { isMissingFileError } from "../../shared/fs-errors.js";
|
|
6
|
+
const lockfileMetadataSchema = z.object({
|
|
7
|
+
pid: z.number().int().positive(),
|
|
8
|
+
token: z.string().min(1),
|
|
9
|
+
createdAt: z.string().datetime(),
|
|
10
|
+
updatedAt: z.string().datetime(),
|
|
11
|
+
ttlMs: z.number().int().positive(),
|
|
12
|
+
});
|
|
13
|
+
export class LockAcquisitionError extends Error {
|
|
14
|
+
constructor(message) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "LockAcquisitionError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const DEFAULT_LOCK_TTL_MS = 5 * 60 * 1000;
|
|
20
|
+
export async function acquireLock(path, options = {}) {
|
|
21
|
+
const resolvedPath = resolve(path);
|
|
22
|
+
const ttlMs = options.ttlMs ?? DEFAULT_LOCK_TTL_MS;
|
|
23
|
+
await mkdir(dirname(resolvedPath), { recursive: true });
|
|
24
|
+
const metadata = {
|
|
25
|
+
pid: process.pid,
|
|
26
|
+
token: randomUUID(),
|
|
27
|
+
createdAt: new Date().toISOString(),
|
|
28
|
+
updatedAt: new Date().toISOString(),
|
|
29
|
+
ttlMs,
|
|
30
|
+
};
|
|
31
|
+
try {
|
|
32
|
+
await writeFile(resolvedPath, `${JSON.stringify(metadata, null, 2)}\n`, {
|
|
33
|
+
encoding: "utf8",
|
|
34
|
+
flag: "wx",
|
|
35
|
+
});
|
|
36
|
+
return { path: resolvedPath, metadata };
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (!isAlreadyExistsError(error)) {
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const stale = await isStaleLock(resolvedPath);
|
|
44
|
+
if (!stale) {
|
|
45
|
+
throw new LockAcquisitionError(`Active lock already exists at ${resolvedPath}`);
|
|
46
|
+
}
|
|
47
|
+
await rm(resolvedPath, { force: true });
|
|
48
|
+
await writeFile(resolvedPath, `${JSON.stringify(metadata, null, 2)}\n`, {
|
|
49
|
+
encoding: "utf8",
|
|
50
|
+
flag: "wx",
|
|
51
|
+
});
|
|
52
|
+
return { path: resolvedPath, metadata };
|
|
53
|
+
}
|
|
54
|
+
export async function releaseLock(path, token) {
|
|
55
|
+
const resolvedPath = resolve(path);
|
|
56
|
+
const metadata = await readLockMetadata(resolvedPath);
|
|
57
|
+
if (!metadata) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (token && metadata.token !== token) {
|
|
61
|
+
throw new LockAcquisitionError(`Refusing to release lock at ${resolvedPath}: token mismatch`);
|
|
62
|
+
}
|
|
63
|
+
await rm(resolvedPath, { force: true });
|
|
64
|
+
}
|
|
65
|
+
export async function isStaleLock(path) {
|
|
66
|
+
const metadata = await readLockMetadata(path);
|
|
67
|
+
if (!metadata) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
const ageMs = Date.now() - Date.parse(metadata.updatedAt);
|
|
71
|
+
if (ageMs > metadata.ttlMs) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
return !isProcessAlive(metadata.pid);
|
|
75
|
+
}
|
|
76
|
+
export async function readLockMetadata(path) {
|
|
77
|
+
const resolvedPath = resolve(path);
|
|
78
|
+
try {
|
|
79
|
+
const raw = await readFile(resolvedPath, "utf8");
|
|
80
|
+
return lockfileMetadataSchema.parse(JSON.parse(raw));
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (isMissingFileError(error)) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function isAlreadyExistsError(error) {
|
|
90
|
+
return error instanceof Error && "code" in error && error.code === "EEXIST";
|
|
91
|
+
}
|
|
92
|
+
function isProcessAlive(pid) {
|
|
93
|
+
try {
|
|
94
|
+
process.kill(pid, 0);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (error instanceof Error && "code" in error) {
|
|
99
|
+
const code = error.code;
|
|
100
|
+
if (code === "ESRCH") {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
if (code === "EPERM") {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=lockfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../../../src/adapters/fs/lockfile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type RalphManifest } from "../../core/manifest/schema.js";
|
|
2
|
+
export interface LoadedManifest {
|
|
3
|
+
path: string;
|
|
4
|
+
manifest: RalphManifest;
|
|
5
|
+
}
|
|
6
|
+
export declare class ManifestLoadError extends Error {
|
|
7
|
+
readonly causeValue?: unknown;
|
|
8
|
+
constructor(message: string, causeValue?: unknown);
|
|
9
|
+
}
|
|
10
|
+
export declare function loadManifestFromFile(path?: string): Promise<LoadedManifest>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { parse } from "yaml";
|
|
4
|
+
import { ZodError } from "zod";
|
|
5
|
+
import { DEFAULT_MANIFEST_FILENAME, RalphManifestSchema } from "../../core/manifest/schema.js";
|
|
6
|
+
export class ManifestLoadError extends Error {
|
|
7
|
+
causeValue;
|
|
8
|
+
constructor(message, causeValue) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "ManifestLoadError";
|
|
11
|
+
this.causeValue = causeValue;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function loadManifestFromFile(path = DEFAULT_MANIFEST_FILENAME) {
|
|
15
|
+
const resolvedPath = resolve(path);
|
|
16
|
+
let rawText;
|
|
17
|
+
try {
|
|
18
|
+
rawText = await readFile(resolvedPath, "utf8");
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
throw new ManifestLoadError(`Failed to read manifest at ${resolvedPath}`, error);
|
|
22
|
+
}
|
|
23
|
+
let parsedYaml;
|
|
24
|
+
try {
|
|
25
|
+
parsedYaml = parse(rawText);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
throw new ManifestLoadError(`Failed to parse YAML from ${resolvedPath}`, error);
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
return {
|
|
32
|
+
path: resolvedPath,
|
|
33
|
+
manifest: RalphManifestSchema.parse(parsedYaml),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (error instanceof ZodError) {
|
|
38
|
+
throw new ManifestLoadError(`Manifest validation failed for ${resolvedPath}`, error.flatten());
|
|
39
|
+
}
|
|
40
|
+
throw new ManifestLoadError(`Manifest validation failed for ${resolvedPath}`, error);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=manifest-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-loader.js","sourceRoot":"","sources":["../../../src/adapters/fs/manifest-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAE/B,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAsB,MAAM,+BAA+B,CAAC;AAOnH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1B,UAAU,CAAW;IAErC,YAAmB,OAAe,EAAE,UAAoB;QACtD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAI,GAAG,yBAAyB;IACzE,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,iBAAiB,CAAC,8BAA8B,YAAY,EAAE,EAAE,KAAK,CAAC,CAAC;IACnF,CAAC;IAED,IAAI,UAAmB,CAAC;IACxB,IAAI,CAAC;QACH,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,iBAAiB,CAAC,6BAA6B,YAAY,EAAE,EAAE,KAAK,CAAC,CAAC;IAClF,CAAC;IAED,IAAI,CAAC;QACH,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,QAAQ,EAAE,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC;SAChD,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,iBAAiB,CAAC,kCAAkC,YAAY,EAAE,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACjG,CAAC;QAED,MAAM,IAAI,iBAAiB,CAAC,kCAAkC,YAAY,EAAE,EAAE,KAAK,CAAC,CAAC;IACvF,CAAC;AACH,CAAC"}
|