ralphy-spec 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +74 -130
- package/README.ko.md +74 -130
- package/README.md +75 -133
- package/README.zh.md +74 -130
- package/bin/ralphy-spec.js +0 -0
- package/dist/cli/checkpoint.d.ts +3 -0
- package/dist/cli/checkpoint.d.ts.map +1 -0
- package/dist/cli/checkpoint.js +23 -0
- package/dist/cli/checkpoint.js.map +1 -0
- package/dist/cli/init.d.ts +3 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +66 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/report.d.ts +3 -0
- package/dist/cli/report.d.ts.map +1 -0
- package/dist/cli/report.js +53 -0
- package/dist/cli/report.js.map +1 -0
- package/dist/cli/run.d.ts +3 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +79 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/status.d.ts +3 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +45 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/tail.d.ts +3 -0
- package/dist/cli/tail.d.ts.map +1 -0
- package/dist/cli/tail.js +46 -0
- package/dist/cli/tail.js.map +1 -0
- package/dist/cli/update.d.ts +3 -0
- package/dist/cli/update.d.ts.map +1 -0
- package/dist/cli/update.js +62 -0
- package/dist/cli/update.js.map +1 -0
- package/dist/cli/validate.d.ts +3 -0
- package/dist/cli/validate.d.ts.map +1 -0
- package/dist/cli/validate.js +83 -0
- package/dist/cli/validate.js.map +1 -0
- package/dist/core/backends/claude-code.d.ts +17 -0
- package/dist/core/backends/claude-code.d.ts.map +1 -0
- package/dist/core/backends/claude-code.js +75 -0
- package/dist/core/backends/claude-code.js.map +1 -0
- package/dist/core/backends/cursor.d.ts +17 -0
- package/dist/core/backends/cursor.d.ts.map +1 -0
- package/dist/core/backends/cursor.js +75 -0
- package/dist/core/backends/cursor.js.map +1 -0
- package/dist/core/backends/noop.d.ts +10 -0
- package/dist/core/backends/noop.d.ts.map +1 -0
- package/dist/core/backends/noop.js +17 -0
- package/dist/core/backends/noop.js.map +1 -0
- package/dist/core/backends/opencode.d.ts +16 -0
- package/dist/core/backends/opencode.d.ts.map +1 -0
- package/dist/core/backends/opencode.js +73 -0
- package/dist/core/backends/opencode.js.map +1 -0
- package/dist/core/backends/types.d.ts +21 -0
- package/dist/core/backends/types.d.ts.map +1 -0
- package/dist/core/backends/types.js +3 -0
- package/dist/core/backends/types.js.map +1 -0
- package/dist/core/budgets/manager.d.ts +21 -0
- package/dist/core/budgets/manager.d.ts.map +1 -0
- package/dist/core/budgets/manager.js +48 -0
- package/dist/core/budgets/manager.js.map +1 -0
- package/dist/core/budgets/state.d.ts +25 -0
- package/dist/core/budgets/state.d.ts.map +1 -0
- package/dist/core/budgets/state.js +33 -0
- package/dist/core/budgets/state.js.map +1 -0
- package/dist/core/budgets/tiers.d.ts +32 -0
- package/dist/core/budgets/tiers.d.ts.map +1 -0
- package/dist/core/budgets/tiers.js +67 -0
- package/dist/core/budgets/tiers.js.map +1 -0
- package/dist/core/engine/context-pack.d.ts +12 -0
- package/dist/core/engine/context-pack.d.ts.map +1 -0
- package/dist/core/engine/context-pack.js +45 -0
- package/dist/core/engine/context-pack.js.map +1 -0
- package/dist/core/engine/loop.d.ts +28 -0
- package/dist/core/engine/loop.d.ts.map +1 -0
- package/dist/core/engine/loop.js +366 -0
- package/dist/core/engine/loop.js.map +1 -0
- package/dist/core/engine/phases.d.ts +2 -0
- package/dist/core/engine/phases.d.ts.map +1 -0
- package/dist/core/engine/phases.js +3 -0
- package/dist/core/engine/phases.js.map +1 -0
- package/dist/core/engine/repair.d.ts +6 -0
- package/dist/core/engine/repair.d.ts.map +1 -0
- package/dist/core/engine/repair.js +23 -0
- package/dist/core/engine/repair.js.map +1 -0
- package/dist/core/folders.d.ts +26 -0
- package/dist/core/folders.d.ts.map +1 -0
- package/dist/core/folders.js +58 -0
- package/dist/core/folders.js.map +1 -0
- package/dist/core/memory/ledger.d.ts +13 -0
- package/dist/core/memory/ledger.d.ts.map +1 -0
- package/dist/core/memory/ledger.js +24 -0
- package/dist/core/memory/ledger.js.map +1 -0
- package/dist/core/memory/persistence.d.ts +45 -0
- package/dist/core/memory/persistence.d.ts.map +1 -0
- package/dist/core/memory/persistence.js +162 -0
- package/dist/core/memory/persistence.js.map +1 -0
- package/dist/core/reporting/spend.d.ts +40 -0
- package/dist/core/reporting/spend.d.ts.map +1 -0
- package/dist/core/reporting/spend.js +157 -0
- package/dist/core/reporting/spend.js.map +1 -0
- package/dist/core/spec/dag.d.ts +7 -0
- package/dist/core/spec/dag.d.ts.map +1 -0
- package/dist/core/spec/dag.js +65 -0
- package/dist/core/spec/dag.js.map +1 -0
- package/dist/core/spec/file-contract.d.ts +13 -0
- package/dist/core/spec/file-contract.d.ts.map +1 -0
- package/dist/core/spec/file-contract.js +29 -0
- package/dist/core/spec/file-contract.js.map +1 -0
- package/dist/core/spec/loader.d.ts +8 -0
- package/dist/core/spec/loader.d.ts.map +1 -0
- package/dist/core/spec/loader.js +51 -0
- package/dist/core/spec/loader.js.map +1 -0
- package/dist/core/spec/schemas.d.ts +278 -0
- package/dist/core/spec/schemas.d.ts.map +1 -0
- package/dist/core/spec/schemas.js +207 -0
- package/dist/core/spec/schemas.js.map +1 -0
- package/dist/core/spec/types.d.ts +71 -0
- package/dist/core/spec/types.d.ts.map +1 -0
- package/dist/core/spec/types.js +3 -0
- package/dist/core/spec/types.js.map +1 -0
- package/dist/core/validators/parsers/eslint.d.ts +3 -0
- package/dist/core/validators/parsers/eslint.d.ts.map +1 -0
- package/dist/core/validators/parsers/eslint.js +35 -0
- package/dist/core/validators/parsers/eslint.js.map +1 -0
- package/dist/core/validators/parsers/jest.d.ts +3 -0
- package/dist/core/validators/parsers/jest.d.ts.map +1 -0
- package/dist/core/validators/parsers/jest.js +16 -0
- package/dist/core/validators/parsers/jest.js.map +1 -0
- package/dist/core/validators/parsers/tsc.d.ts +3 -0
- package/dist/core/validators/parsers/tsc.d.ts.map +1 -0
- package/dist/core/validators/parsers/tsc.js +32 -0
- package/dist/core/validators/parsers/tsc.js.map +1 -0
- package/dist/core/validators/runner.d.ts +8 -0
- package/dist/core/validators/runner.d.ts.map +1 -0
- package/dist/core/validators/runner.js +85 -0
- package/dist/core/validators/runner.js.map +1 -0
- package/dist/core/validators/signatures.d.ts +3 -0
- package/dist/core/validators/signatures.d.ts.map +1 -0
- package/dist/core/validators/signatures.js +10 -0
- package/dist/core/validators/signatures.js.map +1 -0
- package/dist/core/validators/types.d.ts +27 -0
- package/dist/core/validators/types.d.ts.map +1 -0
- package/dist/core/validators/types.js +3 -0
- package/dist/core/validators/types.js.map +1 -0
- package/dist/core/workspace/contract-enforcer.d.ts +54 -0
- package/dist/core/workspace/contract-enforcer.d.ts.map +1 -0
- package/dist/core/workspace/contract-enforcer.js +128 -0
- package/dist/core/workspace/contract-enforcer.js.map +1 -0
- package/dist/core/workspace/manager.d.ts +28 -0
- package/dist/core/workspace/manager.d.ts.map +1 -0
- package/dist/core/workspace/manager.js +3 -0
- package/dist/core/workspace/manager.js.map +1 -0
- package/dist/core/workspace/merge.d.ts +38 -0
- package/dist/core/workspace/merge.d.ts.map +1 -0
- package/dist/core/workspace/merge.js +92 -0
- package/dist/core/workspace/merge.js.map +1 -0
- package/dist/core/workspace/patch-mode.d.ts +22 -0
- package/dist/core/workspace/patch-mode.d.ts.map +1 -0
- package/dist/core/workspace/patch-mode.js +91 -0
- package/dist/core/workspace/patch-mode.js.map +1 -0
- package/dist/core/workspace/worktree-mode.d.ts +28 -0
- package/dist/core/workspace/worktree-mode.d.ts.map +1 -0
- package/dist/core/workspace/worktree-mode.js +156 -0
- package/dist/core/workspace/worktree-mode.js.map +1 -0
- package/dist/index.js +14 -4
- package/dist/index.js.map +1 -1
- package/dist/templates/shared/openspec-tasks-template.md +23 -3
- package/dist/templates/shared/project-template.yml +232 -0
- package/dist/utils/installer.d.ts.map +1 -1
- package/dist/utils/installer.js +31 -1
- package/dist/utils/installer.js.map +1 -1
- package/dist/utils/validator.d.ts.map +1 -1
- package/dist/utils/validator.js +10 -0
- package/dist/utils/validator.js.map +1 -1
- package/package.json +11 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tsc.d.ts","sourceRoot":"","sources":["../../../../src/core/validators/parsers/tsc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAOtC,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,CAyBtD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTscOutput = parseTscOutput;
|
|
4
|
+
// Example:
|
|
5
|
+
// src/foo.ts(12,3): error TS2322: Type 'x' is not assignable...
|
|
6
|
+
const tscLineRe = /^(?<file>[^:(]+)\((?<line>\d+),(?<col>\d+)\):\s+(?<level>error|warning)\s+TS\d+:\s+(?<msg>.*)$/;
|
|
7
|
+
function parseTscOutput(output) {
|
|
8
|
+
const issues = [];
|
|
9
|
+
for (const line of output.split("\n")) {
|
|
10
|
+
const m = line.match(tscLineRe);
|
|
11
|
+
if (!m?.groups)
|
|
12
|
+
continue;
|
|
13
|
+
issues.push({
|
|
14
|
+
kind: "tsc",
|
|
15
|
+
level: m.groups.level === "warning" ? "warning" : "error",
|
|
16
|
+
message: m.groups.msg.trim(),
|
|
17
|
+
file: m.groups.file.trim(),
|
|
18
|
+
line: Number(m.groups.line),
|
|
19
|
+
raw: { line },
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
// If there is output but no matches, surface a generic issue.
|
|
23
|
+
if (!issues.length && output.trim()) {
|
|
24
|
+
issues.push({
|
|
25
|
+
kind: "tsc",
|
|
26
|
+
level: "error",
|
|
27
|
+
message: output.trim().slice(0, 4000),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return issues;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=tsc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tsc.js","sourceRoot":"","sources":["../../../../src/core/validators/parsers/tsc.ts"],"names":[],"mappings":";;AAOA,wCAyBC;AA9BD,WAAW;AACX,gEAAgE;AAChE,MAAM,SAAS,GACb,gGAAgG,CAAC;AAEnG,SAAgB,cAAc,CAAC,MAAc;IAC3C,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,CAAC,CAAC,EAAE,MAAM;YAAE,SAAS;QACzB,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;YACzD,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE;YAC5B,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE;YAC1B,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;YAC3B,GAAG,EAAE,EAAE,IAAI,EAAE;SACd,CAAC,CAAC;IACL,CAAC;IAED,8DAA8D;IAC9D,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;SACtC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ValidateContext, ValidateResult, Validator } from "./types";
|
|
2
|
+
export declare class ValidatorRunner {
|
|
3
|
+
private readonly ctx;
|
|
4
|
+
constructor(ctx: ValidateContext);
|
|
5
|
+
runAll(validators: Validator[]): Promise<Record<string, ValidateResult>>;
|
|
6
|
+
runOne(validator: Validator): Promise<ValidateResult>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/core/validators/runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AA0B1E,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,eAAe;IAE3C,MAAM,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAQxE,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC;CA6C5D"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValidatorRunner = void 0;
|
|
4
|
+
const execa_1 = require("execa");
|
|
5
|
+
const tsc_1 = require("./parsers/tsc");
|
|
6
|
+
const eslint_1 = require("./parsers/eslint");
|
|
7
|
+
const jest_1 = require("./parsers/jest");
|
|
8
|
+
function parseIssues(parser, combinedOutput) {
|
|
9
|
+
switch (parser) {
|
|
10
|
+
case "tsc":
|
|
11
|
+
return (0, tsc_1.parseTscOutput)(combinedOutput);
|
|
12
|
+
case "eslint":
|
|
13
|
+
return (0, eslint_1.parseEslintOutput)(combinedOutput);
|
|
14
|
+
case "jest":
|
|
15
|
+
return (0, jest_1.parseJestOutput)(combinedOutput);
|
|
16
|
+
default:
|
|
17
|
+
return combinedOutput.trim()
|
|
18
|
+
? [
|
|
19
|
+
{
|
|
20
|
+
kind: "unknown",
|
|
21
|
+
level: "error",
|
|
22
|
+
message: combinedOutput.trim().slice(0, 4000),
|
|
23
|
+
},
|
|
24
|
+
]
|
|
25
|
+
: [];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
class ValidatorRunner {
|
|
29
|
+
ctx;
|
|
30
|
+
constructor(ctx) {
|
|
31
|
+
this.ctx = ctx;
|
|
32
|
+
}
|
|
33
|
+
async runAll(validators) {
|
|
34
|
+
const results = {};
|
|
35
|
+
for (const v of validators) {
|
|
36
|
+
results[v.id] = await this.runOne(v);
|
|
37
|
+
}
|
|
38
|
+
return results;
|
|
39
|
+
}
|
|
40
|
+
async runOne(validator) {
|
|
41
|
+
const started = Date.now();
|
|
42
|
+
const timeoutMs = validator.timeoutMs ?? this.ctx.commandTimeoutMs;
|
|
43
|
+
try {
|
|
44
|
+
const res = await (0, execa_1.execa)(validator.run, {
|
|
45
|
+
cwd: this.ctx.cwd,
|
|
46
|
+
shell: true,
|
|
47
|
+
timeout: timeoutMs,
|
|
48
|
+
reject: false,
|
|
49
|
+
stdio: "pipe",
|
|
50
|
+
});
|
|
51
|
+
const stdout = res.stdout ?? "";
|
|
52
|
+
const stderr = res.stderr ?? "";
|
|
53
|
+
const combined = [stdout, stderr].filter(Boolean).join("\n");
|
|
54
|
+
const issues = parseIssues(validator.parser, combined);
|
|
55
|
+
return {
|
|
56
|
+
ok: res.exitCode === 0,
|
|
57
|
+
exitCode: res.exitCode ?? null,
|
|
58
|
+
durationMs: Date.now() - started,
|
|
59
|
+
issues,
|
|
60
|
+
stdout,
|
|
61
|
+
stderr,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
const msg = err?.message ? String(err.message) : String(err);
|
|
66
|
+
return {
|
|
67
|
+
ok: false,
|
|
68
|
+
exitCode: null,
|
|
69
|
+
durationMs: Date.now() - started,
|
|
70
|
+
issues: [
|
|
71
|
+
{
|
|
72
|
+
kind: "unknown",
|
|
73
|
+
level: "error",
|
|
74
|
+
message: msg,
|
|
75
|
+
raw: err,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
stdout: "",
|
|
79
|
+
stderr: "",
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.ValidatorRunner = ValidatorRunner;
|
|
85
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/core/validators/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signatures.d.ts","sourceRoot":"","sources":["../../../src/core/validators/signatures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAK/C"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.issueSignature = issueSignature;
|
|
4
|
+
function issueSignature(i) {
|
|
5
|
+
const file = i.file ?? "";
|
|
6
|
+
const line = i.line ?? 0;
|
|
7
|
+
const msg = i.message.replace(/\s+/g, " ").trim();
|
|
8
|
+
return `${i.kind}|${file}|${line}|${msg}`;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=signatures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signatures.js","sourceRoot":"","sources":["../../../src/core/validators/signatures.ts"],"names":[],"mappings":";;AAEA,wCAKC;AALD,SAAgB,cAAc,CAAC,CAAQ;IACrC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;IACzB,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,OAAO,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type Issue = {
|
|
2
|
+
kind: "tsc" | "eslint" | "jest" | "contract_violation" | "unknown";
|
|
3
|
+
level: "error" | "warning";
|
|
4
|
+
message: string;
|
|
5
|
+
file?: string;
|
|
6
|
+
line?: number;
|
|
7
|
+
raw?: unknown;
|
|
8
|
+
};
|
|
9
|
+
export type ValidateContext = {
|
|
10
|
+
cwd: string;
|
|
11
|
+
commandTimeoutMs: number;
|
|
12
|
+
};
|
|
13
|
+
export type ValidateResult = {
|
|
14
|
+
ok: boolean;
|
|
15
|
+
exitCode: number | null;
|
|
16
|
+
durationMs: number;
|
|
17
|
+
issues: Issue[];
|
|
18
|
+
stdout: string;
|
|
19
|
+
stderr: string;
|
|
20
|
+
};
|
|
21
|
+
export type Validator = {
|
|
22
|
+
id: string;
|
|
23
|
+
run: string;
|
|
24
|
+
timeoutMs?: number;
|
|
25
|
+
parser?: "tsc" | "eslint" | "jest" | string;
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/validators/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAAC;IACnE,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;CAC7C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/validators/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { FileContract } from "../spec/types";
|
|
2
|
+
import { type ContractViolation } from "../spec/file-contract";
|
|
3
|
+
import type { Issue } from "../validators/types";
|
|
4
|
+
export type EnforcementResult = {
|
|
5
|
+
violations: ContractViolation[];
|
|
6
|
+
revertedFiles: string[];
|
|
7
|
+
issues: Issue[];
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* ContractEnforcer handles automatic reversion of files that violate contracts.
|
|
11
|
+
*
|
|
12
|
+
* Unlike WorkspaceManager.enforceContract which reverts ALL changes on violation,
|
|
13
|
+
* this enforcer can selectively revert only the violating files.
|
|
14
|
+
*/
|
|
15
|
+
export declare class ContractEnforcer {
|
|
16
|
+
private readonly repoRoot;
|
|
17
|
+
constructor(repoRoot: string);
|
|
18
|
+
/**
|
|
19
|
+
* Check changed files against a contract and auto-revert violations.
|
|
20
|
+
*
|
|
21
|
+
* @param changedFiles - List of changed files with isNew flag
|
|
22
|
+
* @param contract - The file contract to enforce
|
|
23
|
+
* @param autoRevert - If true, automatically revert violating files
|
|
24
|
+
* @returns Enforcement result with violations, reverted files, and issues
|
|
25
|
+
*/
|
|
26
|
+
enforce(args: {
|
|
27
|
+
changedFiles: Array<{
|
|
28
|
+
file: string;
|
|
29
|
+
isNew: boolean;
|
|
30
|
+
}>;
|
|
31
|
+
contract: FileContract;
|
|
32
|
+
autoRevert?: boolean;
|
|
33
|
+
}): Promise<EnforcementResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Revert a single file to its last committed state.
|
|
36
|
+
*/
|
|
37
|
+
private revertFile;
|
|
38
|
+
/**
|
|
39
|
+
* Get list of changed files in the working directory.
|
|
40
|
+
*/
|
|
41
|
+
getChangedFiles(): Promise<Array<{
|
|
42
|
+
file: string;
|
|
43
|
+
isNew: boolean;
|
|
44
|
+
}>>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Quick helper to enforce contract on current changes.
|
|
48
|
+
*/
|
|
49
|
+
export declare function enforceFileContract(args: {
|
|
50
|
+
repoRoot: string;
|
|
51
|
+
contract: FileContract;
|
|
52
|
+
autoRevert?: boolean;
|
|
53
|
+
}): Promise<EnforcementResult>;
|
|
54
|
+
//# sourceMappingURL=contract-enforcer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-enforcer.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/contract-enforcer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAwB,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAE7C;;;;;;;OAOG;IACG,OAAO,CAAC,IAAI,EAAE;QAClB,YAAY,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QACtD,QAAQ,EAAE,YAAY,CAAC;QACvB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA+C9B;;OAEG;YACW,UAAU;IAiBxB;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CA6B1E;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAQ7B"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContractEnforcer = void 0;
|
|
4
|
+
exports.enforceFileContract = enforceFileContract;
|
|
5
|
+
const execa_1 = require("execa");
|
|
6
|
+
const file_contract_1 = require("../spec/file-contract");
|
|
7
|
+
/**
|
|
8
|
+
* ContractEnforcer handles automatic reversion of files that violate contracts.
|
|
9
|
+
*
|
|
10
|
+
* Unlike WorkspaceManager.enforceContract which reverts ALL changes on violation,
|
|
11
|
+
* this enforcer can selectively revert only the violating files.
|
|
12
|
+
*/
|
|
13
|
+
class ContractEnforcer {
|
|
14
|
+
repoRoot;
|
|
15
|
+
constructor(repoRoot) {
|
|
16
|
+
this.repoRoot = repoRoot;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Check changed files against a contract and auto-revert violations.
|
|
20
|
+
*
|
|
21
|
+
* @param changedFiles - List of changed files with isNew flag
|
|
22
|
+
* @param contract - The file contract to enforce
|
|
23
|
+
* @param autoRevert - If true, automatically revert violating files
|
|
24
|
+
* @returns Enforcement result with violations, reverted files, and issues
|
|
25
|
+
*/
|
|
26
|
+
async enforce(args) {
|
|
27
|
+
const { changedFiles, contract, autoRevert = true } = args;
|
|
28
|
+
const violations = (0, file_contract_1.evaluateFileContract)({ changedFiles, contract });
|
|
29
|
+
if (violations.length === 0) {
|
|
30
|
+
return { violations: [], revertedFiles: [], issues: [] };
|
|
31
|
+
}
|
|
32
|
+
const revertedFiles = [];
|
|
33
|
+
const issues = [];
|
|
34
|
+
if (autoRevert) {
|
|
35
|
+
for (const v of violations) {
|
|
36
|
+
try {
|
|
37
|
+
await this.revertFile(v.file, changedFiles.find((f) => f.file === v.file)?.isNew ?? false);
|
|
38
|
+
revertedFiles.push(v.file);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
// If revert fails, create an issue instead
|
|
42
|
+
issues.push({
|
|
43
|
+
kind: "contract_violation",
|
|
44
|
+
level: "error",
|
|
45
|
+
message: `Failed to auto-revert ${v.file}: ${err?.message ?? String(err)}`,
|
|
46
|
+
file: v.file,
|
|
47
|
+
raw: { violation: v, error: err?.message },
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Create issues for all violations
|
|
53
|
+
for (const v of violations) {
|
|
54
|
+
const wasReverted = revertedFiles.includes(v.file);
|
|
55
|
+
issues.push({
|
|
56
|
+
kind: "contract_violation",
|
|
57
|
+
level: wasReverted ? "warning" : "error",
|
|
58
|
+
message: wasReverted
|
|
59
|
+
? `File contract violation (auto-reverted): ${v.reason} - ${v.file}`
|
|
60
|
+
: `File contract violation: ${v.reason} - ${v.file}`,
|
|
61
|
+
file: v.file,
|
|
62
|
+
raw: { violation: v, reverted: wasReverted },
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return { violations, revertedFiles, issues };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Revert a single file to its last committed state.
|
|
69
|
+
*/
|
|
70
|
+
async revertFile(file, isNew) {
|
|
71
|
+
if (isNew) {
|
|
72
|
+
// For new files, remove them
|
|
73
|
+
await (0, execa_1.execa)("git", ["rm", "-f", file], {
|
|
74
|
+
cwd: this.repoRoot,
|
|
75
|
+
stdio: "pipe",
|
|
76
|
+
reject: false,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// For modified files, checkout from HEAD
|
|
81
|
+
await (0, execa_1.execa)("git", ["checkout", "HEAD", "--", file], {
|
|
82
|
+
cwd: this.repoRoot,
|
|
83
|
+
stdio: "pipe",
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get list of changed files in the working directory.
|
|
89
|
+
*/
|
|
90
|
+
async getChangedFiles() {
|
|
91
|
+
// Get staged + unstaged changes
|
|
92
|
+
const res = await (0, execa_1.execa)("git", ["status", "--porcelain"], {
|
|
93
|
+
cwd: this.repoRoot,
|
|
94
|
+
stdio: "pipe",
|
|
95
|
+
});
|
|
96
|
+
const lines = res.stdout
|
|
97
|
+
.split("\n")
|
|
98
|
+
.map((l) => l.trim())
|
|
99
|
+
.filter(Boolean);
|
|
100
|
+
const changed = [];
|
|
101
|
+
for (const line of lines) {
|
|
102
|
+
// Format: XY filename or XY -> filename (for renames)
|
|
103
|
+
const status = line.substring(0, 2);
|
|
104
|
+
let file = line.substring(3);
|
|
105
|
+
// Handle renames: "R old -> new"
|
|
106
|
+
if (file.includes(" -> ")) {
|
|
107
|
+
file = file.split(" -> ")[1] ?? file;
|
|
108
|
+
}
|
|
109
|
+
const isNew = status.includes("A") || status.includes("?");
|
|
110
|
+
changed.push({ file, isNew });
|
|
111
|
+
}
|
|
112
|
+
return changed;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.ContractEnforcer = ContractEnforcer;
|
|
116
|
+
/**
|
|
117
|
+
* Quick helper to enforce contract on current changes.
|
|
118
|
+
*/
|
|
119
|
+
async function enforceFileContract(args) {
|
|
120
|
+
const enforcer = new ContractEnforcer(args.repoRoot);
|
|
121
|
+
const changedFiles = await enforcer.getChangedFiles();
|
|
122
|
+
return enforcer.enforce({
|
|
123
|
+
changedFiles,
|
|
124
|
+
contract: args.contract,
|
|
125
|
+
autoRevert: args.autoRevert,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=contract-enforcer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-enforcer.js","sourceRoot":"","sources":["../../../src/core/workspace/contract-enforcer.ts"],"names":[],"mappings":";;;AAwIA,kDAYC;AApJD,iCAA8B;AAE9B,yDAAqF;AASrF;;;;;GAKG;AACH,MAAa,gBAAgB;IACE;IAA7B,YAA6B,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;IAAG,CAAC;IAEjD;;;;;;;OAOG;IACH,KAAK,CAAC,OAAO,CAAC,IAIb;QACC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;QAE3D,MAAM,UAAU,GAAG,IAAA,oCAAoB,EAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEpE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAC3D,CAAC;QAED,MAAM,aAAa,GAAa,EAAE,CAAC;QACnC,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,IAAI,UAAU,EAAE,CAAC;YACf,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,KAAK,CAAC,CAAC;oBAC3F,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAC7B,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAClB,2CAA2C;oBAC3C,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,oBAAoB;wBAC1B,KAAK,EAAE,OAAO;wBACd,OAAO,EAAE,yBAAyB,CAAC,CAAC,IAAI,KAAK,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE;wBAC1E,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE;qBAC3C,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,mCAAmC;QACnC,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACnD,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,oBAAoB;gBAC1B,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;gBACxC,OAAO,EAAE,WAAW;oBAClB,CAAC,CAAC,4CAA4C,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,IAAI,EAAE;oBACpE,CAAC,CAAC,4BAA4B,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,IAAI,EAAE;gBACtD,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE;aAC7C,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;IAC/C,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,KAAc;QACnD,IAAI,KAAK,EAAE,CAAC;YACV,6BAA6B;YAC7B,MAAM,IAAA,aAAK,EAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;gBACrC,GAAG,EAAE,IAAI,CAAC,QAAQ;gBAClB,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,KAAK;aACd,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,yCAAyC;YACzC,MAAM,IAAA,aAAK,EAAC,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;gBACnD,GAAG,EAAE,IAAI,CAAC,QAAQ;gBAClB,KAAK,EAAE,MAAM;aACd,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,gCAAgC;QAChC,MAAM,GAAG,GAAG,MAAM,IAAA,aAAK,EAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE;YACxD,GAAG,EAAE,IAAI,CAAC,QAAQ;YAClB,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM;aACrB,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;QAEnB,MAAM,OAAO,GAA4C,EAAE,CAAC;QAC5D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,sDAAsD;YACtD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACpC,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAE7B,kCAAkC;YAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YACvC,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAChC,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAlHD,4CAkHC;AAED;;GAEG;AACI,KAAK,UAAU,mBAAmB,CAAC,IAIzC;IACC,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;IACtD,OAAO,QAAQ,CAAC,OAAO,CAAC;QACtB,YAAY;QACZ,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU;KAC5B,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { FileContract } from "../spec/types";
|
|
2
|
+
export type WorkspaceMode = "worktree" | "patch";
|
|
3
|
+
export type WorkspaceContext = {
|
|
4
|
+
taskId: string;
|
|
5
|
+
workingDir: string;
|
|
6
|
+
};
|
|
7
|
+
export type CheckpointRef = {
|
|
8
|
+
ref: string;
|
|
9
|
+
};
|
|
10
|
+
export type ContractViolation = {
|
|
11
|
+
file: string;
|
|
12
|
+
reason: "forbidden" | "not_allowed" | "new_file_disallowed";
|
|
13
|
+
};
|
|
14
|
+
export interface WorkspaceManager {
|
|
15
|
+
mode: WorkspaceMode;
|
|
16
|
+
prepare(taskId: string): Promise<WorkspaceContext>;
|
|
17
|
+
getWorkingDir(taskId: string): string;
|
|
18
|
+
getChangedFiles(taskId: string): Promise<Array<{
|
|
19
|
+
file: string;
|
|
20
|
+
isNew: boolean;
|
|
21
|
+
}>>;
|
|
22
|
+
enforceContract(taskId: string, contract: FileContract): Promise<ContractViolation[]>;
|
|
23
|
+
checkpoint(taskId: string, message: string): Promise<CheckpointRef>;
|
|
24
|
+
merge(taskId: string): Promise<void>;
|
|
25
|
+
revert(taskId: string): Promise<void>;
|
|
26
|
+
cleanup(taskId: string): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,OAAO,CAAC;AAEjD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,aAAa,GAAG,qBAAqB,CAAC;CAC7D,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,aAAa,CAAC;IAEpB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAEnD,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;IAElF,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAEtF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAEpE,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/core/workspace/manager.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type MergeStrategy = "squash" | "merge" | "rebase";
|
|
2
|
+
export type MergeOptions = {
|
|
3
|
+
repoRoot: string;
|
|
4
|
+
sourceBranch: string;
|
|
5
|
+
targetBranch?: string;
|
|
6
|
+
strategy: MergeStrategy;
|
|
7
|
+
message?: string;
|
|
8
|
+
};
|
|
9
|
+
export type MergeResult = {
|
|
10
|
+
ok: boolean;
|
|
11
|
+
commitRef?: string;
|
|
12
|
+
error?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Merge a source branch into the current (or target) branch.
|
|
16
|
+
*
|
|
17
|
+
* Strategies:
|
|
18
|
+
* - squash: Combines all commits into one (cleanest history)
|
|
19
|
+
* - merge: Standard merge commit
|
|
20
|
+
* - rebase: Rebase source onto target
|
|
21
|
+
*/
|
|
22
|
+
export declare function mergeBranch(opts: MergeOptions): Promise<MergeResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Apply a patch file to the current working directory.
|
|
25
|
+
*/
|
|
26
|
+
export declare function applyPatch(opts: {
|
|
27
|
+
repoRoot: string;
|
|
28
|
+
patchContent: string;
|
|
29
|
+
}): Promise<MergeResult>;
|
|
30
|
+
/**
|
|
31
|
+
* Generate a patch from changes between two refs.
|
|
32
|
+
*/
|
|
33
|
+
export declare function generatePatch(opts: {
|
|
34
|
+
repoRoot: string;
|
|
35
|
+
fromRef: string;
|
|
36
|
+
toRef?: string;
|
|
37
|
+
}): Promise<string>;
|
|
38
|
+
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/merge.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE1D,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAuC1E;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,WAAW,CAAC,CAiBvB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAWlB"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergeBranch = mergeBranch;
|
|
4
|
+
exports.applyPatch = applyPatch;
|
|
5
|
+
exports.generatePatch = generatePatch;
|
|
6
|
+
const execa_1 = require("execa");
|
|
7
|
+
/**
|
|
8
|
+
* Merge a source branch into the current (or target) branch.
|
|
9
|
+
*
|
|
10
|
+
* Strategies:
|
|
11
|
+
* - squash: Combines all commits into one (cleanest history)
|
|
12
|
+
* - merge: Standard merge commit
|
|
13
|
+
* - rebase: Rebase source onto target
|
|
14
|
+
*/
|
|
15
|
+
async function mergeBranch(opts) {
|
|
16
|
+
const { repoRoot, sourceBranch, targetBranch, strategy, message } = opts;
|
|
17
|
+
try {
|
|
18
|
+
// If target branch specified, checkout to it first
|
|
19
|
+
if (targetBranch) {
|
|
20
|
+
await git(["checkout", targetBranch], repoRoot);
|
|
21
|
+
}
|
|
22
|
+
switch (strategy) {
|
|
23
|
+
case "squash": {
|
|
24
|
+
await git(["merge", "--squash", sourceBranch], repoRoot);
|
|
25
|
+
const commitMsg = message ?? `Squash merge ${sourceBranch}`;
|
|
26
|
+
await git(["commit", "-m", commitMsg], repoRoot);
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
case "merge": {
|
|
30
|
+
const commitMsg = message ?? `Merge branch '${sourceBranch}'`;
|
|
31
|
+
await git(["merge", sourceBranch, "-m", commitMsg], repoRoot);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case "rebase": {
|
|
35
|
+
await git(["rebase", sourceBranch], repoRoot);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const commitRef = await git(["rev-parse", "HEAD"], repoRoot);
|
|
40
|
+
return { ok: true, commitRef };
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
return {
|
|
44
|
+
ok: false,
|
|
45
|
+
error: err?.message ?? String(err),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Apply a patch file to the current working directory.
|
|
51
|
+
*/
|
|
52
|
+
async function applyPatch(opts) {
|
|
53
|
+
try {
|
|
54
|
+
const res = await (0, execa_1.execa)("git", ["apply", "--3way", "-"], {
|
|
55
|
+
cwd: opts.repoRoot,
|
|
56
|
+
input: opts.patchContent,
|
|
57
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
58
|
+
reject: false,
|
|
59
|
+
});
|
|
60
|
+
if (res.exitCode !== 0) {
|
|
61
|
+
return { ok: false, error: res.stderr || "Patch apply failed" };
|
|
62
|
+
}
|
|
63
|
+
return { ok: true };
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
return { ok: false, error: err?.message ?? String(err) };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Generate a patch from changes between two refs.
|
|
71
|
+
*/
|
|
72
|
+
async function generatePatch(opts) {
|
|
73
|
+
const { repoRoot, fromRef, toRef } = opts;
|
|
74
|
+
const args = toRef ? ["diff", fromRef, toRef] : ["diff", fromRef];
|
|
75
|
+
const res = await (0, execa_1.execa)("git", args, {
|
|
76
|
+
cwd: repoRoot,
|
|
77
|
+
stdio: "pipe",
|
|
78
|
+
});
|
|
79
|
+
return res.stdout;
|
|
80
|
+
}
|
|
81
|
+
async function git(args, cwd) {
|
|
82
|
+
const res = await (0, execa_1.execa)("git", args, {
|
|
83
|
+
cwd,
|
|
84
|
+
stdio: "pipe",
|
|
85
|
+
reject: false,
|
|
86
|
+
});
|
|
87
|
+
if (res.exitCode !== 0) {
|
|
88
|
+
throw new Error(`git ${args.join(" ")} failed: ${res.stderr || res.stdout}`);
|
|
89
|
+
}
|
|
90
|
+
return res.stdout.trim();
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../../src/core/workspace/merge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FileContract } from "../spec/types";
|
|
2
|
+
import type { CheckpointRef, ContractViolation, WorkspaceContext, WorkspaceManager } from "./manager";
|
|
3
|
+
export declare class PatchModeWorkspace implements WorkspaceManager {
|
|
4
|
+
private readonly repoRoot;
|
|
5
|
+
mode: "patch";
|
|
6
|
+
private readonly stateByTask;
|
|
7
|
+
constructor(repoRoot: string);
|
|
8
|
+
prepare(taskId: string): Promise<WorkspaceContext>;
|
|
9
|
+
getWorkingDir(_taskId: string): string;
|
|
10
|
+
getChangedFiles(_taskId: string): Promise<Array<{
|
|
11
|
+
file: string;
|
|
12
|
+
isNew: boolean;
|
|
13
|
+
}>>;
|
|
14
|
+
enforceContract(taskId: string, contract: FileContract): Promise<ContractViolation[]>;
|
|
15
|
+
checkpoint(taskId: string, message: string): Promise<CheckpointRef>;
|
|
16
|
+
merge(_taskId: string): Promise<void>;
|
|
17
|
+
revert(taskId: string): Promise<void>;
|
|
18
|
+
cleanup(_taskId: string): Promise<void>;
|
|
19
|
+
private git;
|
|
20
|
+
}
|
|
21
|
+
export declare function getPatchWorkspaceRoot(repoRoot: string): string;
|
|
22
|
+
//# sourceMappingURL=patch-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch-mode.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/patch-mode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,WAAW,CAAC;AAMnB,qBAAa,kBAAmB,YAAW,gBAAgB;IAI7C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAHrC,IAAI,EAAE,OAAO,CAAW;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;gBAEpC,QAAQ,EAAE,MAAM;IAEvC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAMxD,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAIhC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAmBlF,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IASrF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAanE,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASrC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAI/B,GAAG;CAOlB;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE9D"}
|