@mousedev/harness-core 0.1.1
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 +36 -0
- package/dist/detect.d.ts +45 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +170 -0
- package/dist/detect.js.map +1 -0
- package/dist/engine.d.ts +33 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +2 -0
- package/dist/engine.js.map +1 -0
- package/dist/events.d.ts +13 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +2 -0
- package/dist/events.js.map +1 -0
- package/dist/exec.d.ts +9 -0
- package/dist/exec.d.ts.map +1 -0
- package/dist/exec.js +54 -0
- package/dist/exec.js.map +1 -0
- package/dist/failures.d.ts +10 -0
- package/dist/failures.d.ts.map +1 -0
- package/dist/failures.js +52 -0
- package/dist/failures.js.map +1 -0
- package/dist/git.d.ts +14 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +47 -0
- package/dist/git.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/loop.d.ts +119 -0
- package/dist/loop.d.ts.map +1 -0
- package/dist/loop.js +190 -0
- package/dist/loop.js.map +1 -0
- package/dist/mea.d.ts +80 -0
- package/dist/mea.d.ts.map +1 -0
- package/dist/mea.js +156 -0
- package/dist/mea.js.map +1 -0
- package/dist/paths.d.ts +7 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +27 -0
- package/dist/paths.js.map +1 -0
- package/dist/policy.d.ts +74 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +179 -0
- package/dist/policy.js.map +1 -0
- package/dist/probe.d.ts +21 -0
- package/dist/probe.d.ts.map +1 -0
- package/dist/probe.js +55 -0
- package/dist/probe.js.map +1 -0
- package/dist/prompt.d.ts +33 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +48 -0
- package/dist/prompt.js.map +1 -0
- package/dist/trace.d.ts +57 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +35 -0
- package/dist/trace.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/workspace.d.ts +26 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +8 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pete McGrath and Mouse 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,36 @@
|
|
|
1
|
+
# @mousedev/harness-core
|
|
2
|
+
|
|
3
|
+
The Mouse completion loop and everything it needs, with zero runtime dependencies. After each model turn the loop probes the workspace deterministically (did anything change, do the repository's checks pass, was a test or workflow file deleted), then either stops with evidence or sends a continue prompt to the same session with the failing output and a request for a structured `MOUSE_AUDIT` self-audit. It is engine-agnostic: an `Engine` is anything that can take a prompt and report steps and text, and a `Workspace` is a directory plus a way to run a shell command in it.
|
|
4
|
+
|
|
5
|
+
This package is what a host embeds. The CLI in `@mousedev/harness` wires it to a local checkout and to `opencode run` through `@mousedev/harness-opencode`; a hosted product wires the same functions to its own sandbox. Nothing here touches the network, and the only filesystem writes are the trace file under `~/.mouse/runs/` and the temp marker the CLI creates. Prompt bytes in `prompt.ts` and `loop.ts` are cache-sensitive and pinned by a golden test; see [AGENTS.md](../../AGENTS.md) before editing them.
|
|
6
|
+
|
|
7
|
+
## Main API
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import {
|
|
11
|
+
localWorkspace, loadPolicy, headSha, makeProbe, runCompletionLoop,
|
|
12
|
+
openTrace, traceFile, parseAuditBlock, buildContinuePrompt, buildAgentPrompt,
|
|
13
|
+
DEFAULT_POLICY, parsePolicy, permissionRulesForTool,
|
|
14
|
+
detectEcosystem, checksFromEcosystem, classifyInferenceFailure,
|
|
15
|
+
} from "@mousedev/harness-core";
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
| Module | Exports |
|
|
19
|
+
|---|---|
|
|
20
|
+
| `loop.ts` | `runCompletionLoop(input)`, `buildContinuePrompt(kind, ctx)`, `parseAuditBlock(text)`, `MIN_ROUND_MS`, types `CompletionProbe`, `CompletionBudget`, `CompletionOutcome`, `ContinueKind`, `CompletionRound`, `CompletionResult` |
|
|
21
|
+
| `engine.ts` | `Engine`, `PromptResult`, `PromptOptions`, `TokenTotals` |
|
|
22
|
+
| `workspace.ts`, `exec.ts` | `Workspace`, `localWorkspace({ root })`, `shellPath`, `LOCAL_EXEC_TIMEOUT_CODE` |
|
|
23
|
+
| `probe.ts` | `makeProbe({ workspace, runStartSha, marker, signal, checks?, checkTimeoutMs? })` |
|
|
24
|
+
| `policy.ts` | `DEFAULT_POLICY`, `parsePolicy`, `loadPolicy(ws)`, `parseChecks`, `parsePermissions`, `permissionRulesForTool` |
|
|
25
|
+
| `detect.ts` | `detectEcosystem(ws)`, `checksFromEcosystem`, `checksFromPackageJson`, `pytestCommand`, `detectEcosystemCommand` |
|
|
26
|
+
| `git.ts` | `headSha`, `fingerprint`, `deletedVerificationFiles`, `VERIFICATION_PATH` |
|
|
27
|
+
| `mea.ts` | `initTaskState`, `applyAudit`, `auditFromSandboxProbe`, types `TaskState`, `AuditReport` |
|
|
28
|
+
| `prompt.ts` | `buildAgentPrompt(mode, { profile })`, `AGENT_PROMPT_MAX_CHARS`, types `Mode`, `Profile` |
|
|
29
|
+
| `trace.ts`, `paths.ts` | `openTrace(file)`, `parseTrace(text)`, `TRACE_VERSION`, `mouseHome`, `runsDir`, `traceFile`, `workspaceSlug` |
|
|
30
|
+
| `events.ts` | `LoopEvent` |
|
|
31
|
+
| `version.ts` | `MOUSE_VERSION` |
|
|
32
|
+
| `failures.ts` | `classifyInferenceFailure(message, raw?)` |
|
|
33
|
+
|
|
34
|
+
A complete example that drives the loop from your own code is [`examples/sdk-run`](../../examples/sdk-run/src/run.ts). The loop's behaviour, step by step, is in [docs/loop.md](../../docs/loop.md); the policy file in [docs/config.md](../../docs/config.md).
|
|
35
|
+
|
|
36
|
+
Requires Node 22 or newer. MIT.
|
package/dist/detect.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which checks "done" means for a repo, detected from its manifests.
|
|
3
|
+
*
|
|
4
|
+
* package.json scripts, pytest, go test, cargo test, and make test. One shell
|
|
5
|
+
* round trip prints every signal; parsing is pure so it can be tested without
|
|
6
|
+
* a filesystem.
|
|
7
|
+
*/
|
|
8
|
+
import { type Workspace } from "./workspace.js";
|
|
9
|
+
export type PackageManager = "pnpm" | "yarn" | "npm";
|
|
10
|
+
export interface DetectedCheck {
|
|
11
|
+
name: string;
|
|
12
|
+
command: string;
|
|
13
|
+
}
|
|
14
|
+
export interface EcosystemManifest {
|
|
15
|
+
packageJson: string | null;
|
|
16
|
+
packageManager: PackageManager;
|
|
17
|
+
pyproject: boolean;
|
|
18
|
+
pytestIni: boolean;
|
|
19
|
+
setupCfg: boolean;
|
|
20
|
+
toxIni: boolean;
|
|
21
|
+
testsDir: boolean;
|
|
22
|
+
uvLock: boolean;
|
|
23
|
+
poetryLock: boolean;
|
|
24
|
+
goMod: boolean;
|
|
25
|
+
cargoToml: boolean;
|
|
26
|
+
makefileTest: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare const EMPTY_MANIFEST: EcosystemManifest;
|
|
29
|
+
/** Checks derived from `package.json` scripts, or `[]` when there are none. */
|
|
30
|
+
export declare function checksFromPackageJson(packageJson: string | null, pm?: PackageManager): DetectedCheck[];
|
|
31
|
+
export declare function pytestCommand(m: Pick<EcosystemManifest, "uvLock" | "poetryLock">): string;
|
|
32
|
+
/**
|
|
33
|
+
* Checks for every ecosystem the manifest shows. package.json scripts come
|
|
34
|
+
* first because they are the repo's own declaration; the others are the
|
|
35
|
+
* conventional runner for each toolchain. A monorepo with several gets all
|
|
36
|
+
* of them.
|
|
37
|
+
*/
|
|
38
|
+
export declare function checksFromEcosystem(m: EcosystemManifest): DetectedCheck[];
|
|
39
|
+
/** One shell round trip that prints every manifest signal for `root`. */
|
|
40
|
+
export declare function detectEcosystemCommand(root: string): string;
|
|
41
|
+
/** The probe for the conventional `/workspace` root, as hosted sandboxes lay it out. */
|
|
42
|
+
export declare const DETECT_ECOSYSTEM_COMMAND: string;
|
|
43
|
+
export declare function parseEcosystemOutput(stdout: string): EcosystemManifest;
|
|
44
|
+
export declare function detectEcosystem(ws: Workspace): Promise<EcosystemManifest>;
|
|
45
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3D,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,cAAc,EAAE,iBAa5B,CAAC;AA2BF,+EAA+E;AAC/E,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,EAAE,GAAE,cAAsB,GACzB,aAAa,EAAE,CAUjB;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,GAAG,YAAY,CAAC,GAAG,MAAM,CAIzF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,iBAAiB,GAAG,aAAa,EAAE,CAQzE;AAaD,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW3D;AAED,wFAAwF;AACxF,eAAO,MAAM,wBAAwB,QAAuC,CAAC;AAE7E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAmDtE;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAK/E"}
|
package/dist/detect.js
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which checks "done" means for a repo, detected from its manifests.
|
|
3
|
+
*
|
|
4
|
+
* package.json scripts, pytest, go test, cargo test, and make test. One shell
|
|
5
|
+
* round trip prints every signal; parsing is pure so it can be tested without
|
|
6
|
+
* a filesystem.
|
|
7
|
+
*/
|
|
8
|
+
import { shellPath } from "./workspace.js";
|
|
9
|
+
export const EMPTY_MANIFEST = {
|
|
10
|
+
packageJson: null,
|
|
11
|
+
packageManager: "npm",
|
|
12
|
+
pyproject: false,
|
|
13
|
+
pytestIni: false,
|
|
14
|
+
setupCfg: false,
|
|
15
|
+
toxIni: false,
|
|
16
|
+
testsDir: false,
|
|
17
|
+
uvLock: false,
|
|
18
|
+
poetryLock: false,
|
|
19
|
+
goMod: false,
|
|
20
|
+
cargoToml: false,
|
|
21
|
+
makefileTest: false,
|
|
22
|
+
};
|
|
23
|
+
/** Script-derived defaults, in the order they run. First present script wins per slot. */
|
|
24
|
+
const DEFAULT_SCRIPTS = [
|
|
25
|
+
["build", ["build", "typecheck"]],
|
|
26
|
+
["test", ["test"]],
|
|
27
|
+
["lint", ["lint"]],
|
|
28
|
+
];
|
|
29
|
+
const PYTEST_ARGS = "-q --maxfail=25 -p no:cacheprovider";
|
|
30
|
+
function parseJsonObject(raw) {
|
|
31
|
+
if (!raw?.trim())
|
|
32
|
+
return null;
|
|
33
|
+
try {
|
|
34
|
+
const parsed = JSON.parse(raw);
|
|
35
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
36
|
+
? parsed
|
|
37
|
+
: null;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function runCommand(pm, script) {
|
|
44
|
+
return pm === "npm" ? `npm run ${script} --if-present` : `${pm} run ${script}`;
|
|
45
|
+
}
|
|
46
|
+
/** Checks derived from `package.json` scripts, or `[]` when there are none. */
|
|
47
|
+
export function checksFromPackageJson(packageJson, pm = "npm") {
|
|
48
|
+
const scripts = parseJsonObject(packageJson)?.scripts;
|
|
49
|
+
if (!scripts || typeof scripts !== "object")
|
|
50
|
+
return [];
|
|
51
|
+
const has = (s) => typeof scripts[s] === "string";
|
|
52
|
+
const out = [];
|
|
53
|
+
for (const [name, candidates] of DEFAULT_SCRIPTS) {
|
|
54
|
+
const script = candidates.find(has);
|
|
55
|
+
if (script)
|
|
56
|
+
out.push({ name, command: runCommand(pm, script) });
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
export function pytestCommand(m) {
|
|
61
|
+
if (m.uvLock)
|
|
62
|
+
return `uv run --frozen pytest ${PYTEST_ARGS}`;
|
|
63
|
+
if (m.poetryLock)
|
|
64
|
+
return `poetry run pytest ${PYTEST_ARGS}`;
|
|
65
|
+
return `python3 -m pytest ${PYTEST_ARGS}`;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Checks for every ecosystem the manifest shows. package.json scripts come
|
|
69
|
+
* first because they are the repo's own declaration; the others are the
|
|
70
|
+
* conventional runner for each toolchain. A monorepo with several gets all
|
|
71
|
+
* of them.
|
|
72
|
+
*/
|
|
73
|
+
export function checksFromEcosystem(m) {
|
|
74
|
+
const out = checksFromPackageJson(m.packageJson, m.packageManager);
|
|
75
|
+
const python = m.pyproject || m.pytestIni || m.toxIni || (m.setupCfg && m.testsDir);
|
|
76
|
+
if (python)
|
|
77
|
+
out.push({ name: "pytest", command: pytestCommand(m) });
|
|
78
|
+
if (m.goMod)
|
|
79
|
+
out.push({ name: "go-test", command: "go test ./..." });
|
|
80
|
+
if (m.cargoToml)
|
|
81
|
+
out.push({ name: "cargo-test", command: "cargo test" });
|
|
82
|
+
if (m.makefileTest && out.length === 0)
|
|
83
|
+
out.push({ name: "make-test", command: "make test" });
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
const MANIFEST_FILES = [
|
|
87
|
+
"pyproject.toml",
|
|
88
|
+
"pytest.ini",
|
|
89
|
+
"setup.cfg",
|
|
90
|
+
"tox.ini",
|
|
91
|
+
"uv.lock",
|
|
92
|
+
"poetry.lock",
|
|
93
|
+
"go.mod",
|
|
94
|
+
"Cargo.toml",
|
|
95
|
+
];
|
|
96
|
+
/** One shell round trip that prints every manifest signal for `root`. */
|
|
97
|
+
export function detectEcosystemCommand(root) {
|
|
98
|
+
return [
|
|
99
|
+
`cd ${shellPath(root)} 2>/dev/null || exit 0`,
|
|
100
|
+
`for f in ${MANIFEST_FILES.join(" ")}; do [ -e "$f" ] && echo "F:$f"; done`,
|
|
101
|
+
'{ [ -d tests ] || [ -d test ]; } && echo "D:tests"',
|
|
102
|
+
"grep -qE '^test:' Makefile 2>/dev/null && echo 'M:test'",
|
|
103
|
+
'[ -f pnpm-lock.yaml ] && echo "PM:pnpm"',
|
|
104
|
+
'[ -f yarn.lock ] && echo "PM:yarn"',
|
|
105
|
+
'[ -f package.json ] && { echo "PKG_BEGIN"; cat package.json; echo; echo "PKG_END"; }',
|
|
106
|
+
"true",
|
|
107
|
+
].join("; ");
|
|
108
|
+
}
|
|
109
|
+
/** The probe for the conventional `/workspace` root, as hosted sandboxes lay it out. */
|
|
110
|
+
export const DETECT_ECOSYSTEM_COMMAND = detectEcosystemCommand("/workspace");
|
|
111
|
+
export function parseEcosystemOutput(stdout) {
|
|
112
|
+
const m = { ...EMPTY_MANIFEST };
|
|
113
|
+
const lines = stdout.split("\n");
|
|
114
|
+
const pkgStart = lines.indexOf("PKG_BEGIN");
|
|
115
|
+
const pkgEnd = lines.indexOf("PKG_END");
|
|
116
|
+
if (pkgStart >= 0 && pkgEnd > pkgStart) {
|
|
117
|
+
m.packageJson = lines.slice(pkgStart + 1, pkgEnd).join("\n");
|
|
118
|
+
}
|
|
119
|
+
for (const line of lines) {
|
|
120
|
+
switch (line.trim()) {
|
|
121
|
+
case "F:pyproject.toml":
|
|
122
|
+
m.pyproject = true;
|
|
123
|
+
break;
|
|
124
|
+
case "F:pytest.ini":
|
|
125
|
+
m.pytestIni = true;
|
|
126
|
+
break;
|
|
127
|
+
case "F:setup.cfg":
|
|
128
|
+
m.setupCfg = true;
|
|
129
|
+
break;
|
|
130
|
+
case "F:tox.ini":
|
|
131
|
+
m.toxIni = true;
|
|
132
|
+
break;
|
|
133
|
+
case "F:uv.lock":
|
|
134
|
+
m.uvLock = true;
|
|
135
|
+
break;
|
|
136
|
+
case "F:poetry.lock":
|
|
137
|
+
m.poetryLock = true;
|
|
138
|
+
break;
|
|
139
|
+
case "F:go.mod":
|
|
140
|
+
m.goMod = true;
|
|
141
|
+
break;
|
|
142
|
+
case "F:Cargo.toml":
|
|
143
|
+
m.cargoToml = true;
|
|
144
|
+
break;
|
|
145
|
+
case "D:tests":
|
|
146
|
+
m.testsDir = true;
|
|
147
|
+
break;
|
|
148
|
+
case "M:test":
|
|
149
|
+
m.makefileTest = true;
|
|
150
|
+
break;
|
|
151
|
+
case "PM:pnpm":
|
|
152
|
+
m.packageManager = "pnpm";
|
|
153
|
+
break;
|
|
154
|
+
case "PM:yarn":
|
|
155
|
+
if (m.packageManager === "npm")
|
|
156
|
+
m.packageManager = "yarn";
|
|
157
|
+
break;
|
|
158
|
+
default:
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return m;
|
|
163
|
+
}
|
|
164
|
+
export async function detectEcosystem(ws) {
|
|
165
|
+
const res = await ws
|
|
166
|
+
.exec(detectEcosystemCommand(ws.root), { cwd: ws.root, timeoutMs: 10_000 })
|
|
167
|
+
.catch(() => ({ stdout: "" }));
|
|
168
|
+
return parseEcosystemOutput(res.stdout);
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"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"}
|
package/dist/engine.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the loop needs from a model engine: open a session, send it a prompt,
|
|
3
|
+
* learn how many steps it took and what it said last. `OpencodeRunEngine`
|
|
4
|
+
* in `@mousedev/harness-opencode` is the reference implementation.
|
|
5
|
+
*/
|
|
6
|
+
export interface TokenTotals {
|
|
7
|
+
input: number;
|
|
8
|
+
output: number;
|
|
9
|
+
cacheRead: number;
|
|
10
|
+
cacheWrite: number;
|
|
11
|
+
/** USD as reported by the engine; 0 when the engine does not price the model. */
|
|
12
|
+
cost: number;
|
|
13
|
+
}
|
|
14
|
+
export interface PromptResult {
|
|
15
|
+
steps: number;
|
|
16
|
+
text: string;
|
|
17
|
+
}
|
|
18
|
+
export interface PromptOptions {
|
|
19
|
+
/** Override the session's model for this turn (model escalation). */
|
|
20
|
+
model?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface Engine {
|
|
23
|
+
open(opts?: {
|
|
24
|
+
sessionId?: string;
|
|
25
|
+
title?: string;
|
|
26
|
+
}): Promise<string>;
|
|
27
|
+
prompt(sessionId: string, text: string, signal: AbortSignal, opts?: PromptOptions): Promise<PromptResult>;
|
|
28
|
+
abort(sessionId: string): Promise<void>;
|
|
29
|
+
readonly steps: number;
|
|
30
|
+
readonly tokens: TokenTotals;
|
|
31
|
+
readonly lastText: string;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrE,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EACnB,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAAC,YAAY,CAAC,CAAC;IACzB,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B"}
|
package/dist/engine.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":""}
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Events the loop reports while it runs. A host renders them; the CLI traces them. */
|
|
2
|
+
export type LoopEvent = {
|
|
3
|
+
type: "check_status";
|
|
4
|
+
name: string;
|
|
5
|
+
conclusion: "success" | "failure";
|
|
6
|
+
detail?: string;
|
|
7
|
+
retryable?: boolean;
|
|
8
|
+
} | {
|
|
9
|
+
type: "notice";
|
|
10
|
+
message: string;
|
|
11
|
+
level?: "info" | "warn";
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,MAAM,MAAM,SAAS,GACjB;IACE,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,SAAS,GAAG,SAAS,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GACD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC"}
|
package/dist/events.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":""}
|
package/dist/exec.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Workspace } from "./workspace.js";
|
|
2
|
+
export interface LocalWorkspaceOptions {
|
|
3
|
+
root: string;
|
|
4
|
+
env?: NodeJS.ProcessEnv;
|
|
5
|
+
}
|
|
6
|
+
/** Exit code reported when a command is killed for exceeding its timeout. */
|
|
7
|
+
export declare const LOCAL_EXEC_TIMEOUT_CODE = 124;
|
|
8
|
+
export declare function localWorkspace(opts: LocalWorkspaceOptions): Workspace;
|
|
9
|
+
//# sourceMappingURL=exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAA2B,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEzE,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,6EAA6E;AAC7E,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,qBAAqB,GAAG,SAAS,CA6CrE"}
|
package/dist/exec.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Workspace` over the local machine.
|
|
3
|
+
*/
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
/** Exit code reported when a command is killed for exceeding its timeout. */
|
|
7
|
+
export const LOCAL_EXEC_TIMEOUT_CODE = 124;
|
|
8
|
+
export function localWorkspace(opts) {
|
|
9
|
+
const root = opts.root.replace(/\/+$/, "") || "/";
|
|
10
|
+
const resolveCwd = (cwd) => (cwd && existsSync(cwd) ? cwd : root);
|
|
11
|
+
function run(file, argv, execOpts) {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const child = spawn(file, argv, {
|
|
14
|
+
cwd: resolveCwd(execOpts?.cwd),
|
|
15
|
+
env: opts.env ?? process.env,
|
|
16
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
17
|
+
});
|
|
18
|
+
let stdout = "";
|
|
19
|
+
let stderr = "";
|
|
20
|
+
let timedOut = false;
|
|
21
|
+
child.stdout.on("data", (d) => {
|
|
22
|
+
stdout += String(d);
|
|
23
|
+
});
|
|
24
|
+
child.stderr.on("data", (d) => {
|
|
25
|
+
stderr += String(d);
|
|
26
|
+
});
|
|
27
|
+
const timer = execOpts?.timeoutMs
|
|
28
|
+
? setTimeout(() => {
|
|
29
|
+
timedOut = true;
|
|
30
|
+
child.kill("SIGKILL");
|
|
31
|
+
}, execOpts.timeoutMs)
|
|
32
|
+
: null;
|
|
33
|
+
const onAbort = () => child.kill("SIGKILL");
|
|
34
|
+
execOpts?.signal?.addEventListener("abort", onAbort, { once: true });
|
|
35
|
+
child.on("error", (e) => {
|
|
36
|
+
if (timer)
|
|
37
|
+
clearTimeout(timer);
|
|
38
|
+
execOpts?.signal?.removeEventListener("abort", onAbort);
|
|
39
|
+
reject(e);
|
|
40
|
+
});
|
|
41
|
+
child.on("close", (code) => {
|
|
42
|
+
if (timer)
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
execOpts?.signal?.removeEventListener("abort", onAbort);
|
|
45
|
+
resolve({ stdout, stderr, code: timedOut ? LOCAL_EXEC_TIMEOUT_CODE : (code ?? 1) });
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
root,
|
|
51
|
+
exec: (cmd, execOpts) => run("bash", ["-lc", cmd], execOpts),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=exec.js.map
|
package/dist/exec.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type InferenceFailureKind = "transient" | "model_route" | "other";
|
|
2
|
+
/** Stable string form of provider/SDK errors for classification. */
|
|
3
|
+
export declare function stringifyInferenceUnknown(raw: unknown): string;
|
|
4
|
+
/**
|
|
5
|
+
* Classify provider / engine failures for bounded retry and model fallback.
|
|
6
|
+
* Conservative: prefer "other" when unsure so callers never loop on a
|
|
7
|
+
* non-retryable error.
|
|
8
|
+
*/
|
|
9
|
+
export declare function classifyInferenceFailure(message: string, raw?: unknown): InferenceFailureKind;
|
|
10
|
+
//# sourceMappingURL=failures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failures.d.ts","sourceRoot":"","sources":["../src/failures.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG,aAAa,GAAG,OAAO,CAAC;AAEzE,oEAAoE;AACpE,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAQ9D;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,oBAAoB,CAuC7F"}
|
package/dist/failures.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Stable string form of provider/SDK errors for classification. */
|
|
2
|
+
export function stringifyInferenceUnknown(raw) {
|
|
3
|
+
if (raw == null)
|
|
4
|
+
return "";
|
|
5
|
+
if (typeof raw === "string")
|
|
6
|
+
return raw;
|
|
7
|
+
try {
|
|
8
|
+
return JSON.stringify(raw);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return String(raw);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Classify provider / engine failures for bounded retry and model fallback.
|
|
16
|
+
* Conservative: prefer "other" when unsure so callers never loop on a
|
|
17
|
+
* non-retryable error.
|
|
18
|
+
*/
|
|
19
|
+
export function classifyInferenceFailure(message, raw) {
|
|
20
|
+
const blob = `${message}\n${stringifyInferenceUnknown(raw)}`.toLowerCase();
|
|
21
|
+
if (/\b429\b/.test(blob) ||
|
|
22
|
+
/\b503\b/.test(blob) ||
|
|
23
|
+
/\b502\b/.test(blob) ||
|
|
24
|
+
blob.includes("rate limit") ||
|
|
25
|
+
blob.includes("ratelimit") ||
|
|
26
|
+
blob.includes("too many requests") ||
|
|
27
|
+
blob.includes("overload") ||
|
|
28
|
+
blob.includes("overloaded") ||
|
|
29
|
+
blob.includes("econnreset") ||
|
|
30
|
+
blob.includes("etimedout") ||
|
|
31
|
+
blob.includes("timed out") ||
|
|
32
|
+
blob.includes("timeout") ||
|
|
33
|
+
blob.includes("temporarily unavailable") ||
|
|
34
|
+
blob.includes("service unavailable") ||
|
|
35
|
+
blob.includes("please retry") ||
|
|
36
|
+
blob.includes("retry your request")) {
|
|
37
|
+
return "transient";
|
|
38
|
+
}
|
|
39
|
+
if (blob.includes("model_not_found") ||
|
|
40
|
+
blob.includes("model not found") ||
|
|
41
|
+
blob.includes("invalid model") ||
|
|
42
|
+
blob.includes("no such model") ||
|
|
43
|
+
blob.includes("unknown model") ||
|
|
44
|
+
(blob.includes("does not exist") && blob.includes("model")) ||
|
|
45
|
+
(blob.includes("not available") && (blob.includes("model") || blob.includes("provider"))) ||
|
|
46
|
+
blob.includes("model id") ||
|
|
47
|
+
blob.includes("unsupported model")) {
|
|
48
|
+
return "model_route";
|
|
49
|
+
}
|
|
50
|
+
return "other";
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=failures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failures.js","sourceRoot":"","sources":["../src/failures.ts"],"names":[],"mappings":"AAEA,oEAAoE;AACpE,MAAM,UAAU,yBAAyB,CAAC,GAAY;IACpD,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAC3B,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAe,EAAE,GAAa;IACrE,MAAM,IAAI,GAAG,GAAG,OAAO,KAAK,yBAAyB,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;IAE3E,IACE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QACpB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QACpB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC3B,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAClC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC3B,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC3B,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QACxC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EACnC,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IACE,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAChC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAChC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC9B,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC3D,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;QACzF,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAClC,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/git.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git helpers over a `Workspace`. Every command is `git -C <root>` so the
|
|
3
|
+
* same code serves a local checkout and a hosted sandbox. All best-effort:
|
|
4
|
+
* a non-repo answers with nulls and empty lists, never an exception.
|
|
5
|
+
*/
|
|
6
|
+
import { type Workspace } from "./workspace.js";
|
|
7
|
+
export declare function headSha(ws: Workspace): Promise<string | null>;
|
|
8
|
+
/** Stable digest of the working tree relative to `baseSha`; any edit changes it. */
|
|
9
|
+
export declare function fingerprint(ws: Workspace, baseSha: string | null): Promise<string>;
|
|
10
|
+
/** Paths whose deletion would let a run grade its own homework. */
|
|
11
|
+
export declare const VERIFICATION_PATH: RegExp;
|
|
12
|
+
/** Test, spec, and workflow files deleted since `baseSha`. */
|
|
13
|
+
export declare function deletedVerificationFiles(ws: Workspace, baseSha: string | null): Promise<string[]>;
|
|
14
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAI3D,wBAAsB,OAAO,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOnE;AAED,oFAAoF;AACpF,wBAAsB,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAQxF;AAED,mEAAmE;AACnE,eAAO,MAAM,iBAAiB,QAA8D,CAAC;AAE7F,8DAA8D;AAC9D,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,MAAM,EAAE,CAAC,CAanB"}
|
package/dist/git.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git helpers over a `Workspace`. Every command is `git -C <root>` so the
|
|
3
|
+
* same code serves a local checkout and a hosted sandbox. All best-effort:
|
|
4
|
+
* a non-repo answers with nulls and empty lists, never an exception.
|
|
5
|
+
*/
|
|
6
|
+
import { shellPath } from "./workspace.js";
|
|
7
|
+
const git = (ws) => `git -C ${shellPath(ws.root)}`;
|
|
8
|
+
export async function headSha(ws) {
|
|
9
|
+
const r = await ws
|
|
10
|
+
.exec(`${git(ws)} rev-parse HEAD`, { cwd: ws.root, timeoutMs: 10_000 })
|
|
11
|
+
.catch(() => ({ stdout: "", code: 1 }));
|
|
12
|
+
if (r.code !== 0)
|
|
13
|
+
return null;
|
|
14
|
+
const s = r.stdout.trim();
|
|
15
|
+
return s.length >= 7 ? s : null;
|
|
16
|
+
}
|
|
17
|
+
/** Stable digest of the working tree relative to `baseSha`; any edit changes it. */
|
|
18
|
+
export async function fingerprint(ws, baseSha) {
|
|
19
|
+
const p = await ws.exec(`${git(ws)} status --porcelain`, { cwd: ws.root, timeoutMs: 10_000 });
|
|
20
|
+
if (!baseSha)
|
|
21
|
+
return p.stdout;
|
|
22
|
+
const diff = await ws.exec(`${git(ws)} diff --shortstat ${baseSha} --`, {
|
|
23
|
+
cwd: ws.root,
|
|
24
|
+
timeoutMs: 20_000,
|
|
25
|
+
});
|
|
26
|
+
return `${p.stdout}\n${diff.stdout}`;
|
|
27
|
+
}
|
|
28
|
+
/** Paths whose deletion would let a run grade its own homework. */
|
|
29
|
+
export const VERIFICATION_PATH = /(^|\/)(tests?|spec|__tests__)(\/|$)|\.github\/workflows\//;
|
|
30
|
+
/** Test, spec, and workflow files deleted since `baseSha`. */
|
|
31
|
+
export async function deletedVerificationFiles(ws, baseSha) {
|
|
32
|
+
if (!baseSha)
|
|
33
|
+
return [];
|
|
34
|
+
const r = await ws
|
|
35
|
+
.exec(`${git(ws)} diff --diff-filter=D --name-only ${baseSha} --`, {
|
|
36
|
+
cwd: ws.root,
|
|
37
|
+
timeoutMs: 20_000,
|
|
38
|
+
})
|
|
39
|
+
.catch(() => ({ stdout: "", code: 1 }));
|
|
40
|
+
if (r.code !== 0)
|
|
41
|
+
return [];
|
|
42
|
+
return r.stdout
|
|
43
|
+
.split("\n")
|
|
44
|
+
.map((l) => l.trim())
|
|
45
|
+
.filter((p) => p && VERIFICATION_PATH.test(p));
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=git.js.map
|
package/dist/git.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAkB,MAAM,gBAAgB,CAAC;AAE3D,MAAM,GAAG,GAAG,CAAC,EAAa,EAAE,EAAE,CAAC,UAAU,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;AAE9D,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,EAAa;IACzC,MAAM,CAAC,GAAG,MAAM,EAAE;SACf,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,iBAAiB,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;SACtE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1C,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC1B,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAa,EAAE,OAAsB;IACrE,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,qBAAqB,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9F,IAAI,CAAC,OAAO;QAAE,OAAO,CAAC,CAAC,MAAM,CAAC;IAC9B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,qBAAqB,OAAO,KAAK,EAAE;QACtE,GAAG,EAAE,EAAE,CAAC,IAAI;QACZ,SAAS,EAAE,MAAM;KAClB,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;AACvC,CAAC;AAED,mEAAmE;AACnE,MAAM,CAAC,MAAM,iBAAiB,GAAG,2DAA2D,CAAC;AAE7F,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,EAAa,EACb,OAAsB;IAEtB,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,MAAM,CAAC,GAAG,MAAM,EAAE;SACf,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,qCAAqC,OAAO,KAAK,EAAE;QACjE,GAAG,EAAE,EAAE,CAAC,IAAI;QACZ,SAAS,EAAE,MAAM;KAClB,CAAC;SACD,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1C,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,CAAC,MAAM;SACZ,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export * from "./detect.js";
|
|
2
|
+
export * from "./engine.js";
|
|
3
|
+
export * from "./events.js";
|
|
4
|
+
export * from "./exec.js";
|
|
5
|
+
export * from "./failures.js";
|
|
6
|
+
export * from "./git.js";
|
|
7
|
+
export * from "./loop.js";
|
|
8
|
+
export * from "./mea.js";
|
|
9
|
+
export * from "./paths.js";
|
|
10
|
+
export * from "./policy.js";
|
|
11
|
+
export * from "./probe.js";
|
|
12
|
+
export * from "./prompt.js";
|
|
13
|
+
export * from "./trace.js";
|
|
14
|
+
export * from "./version.js";
|
|
15
|
+
export * from "./workspace.js";
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export * from "./detect.js";
|
|
2
|
+
export * from "./engine.js";
|
|
3
|
+
export * from "./events.js";
|
|
4
|
+
export * from "./exec.js";
|
|
5
|
+
export * from "./failures.js";
|
|
6
|
+
export * from "./git.js";
|
|
7
|
+
export * from "./loop.js";
|
|
8
|
+
export * from "./mea.js";
|
|
9
|
+
export * from "./paths.js";
|
|
10
|
+
export * from "./policy.js";
|
|
11
|
+
export * from "./probe.js";
|
|
12
|
+
export * from "./prompt.js";
|
|
13
|
+
export * from "./trace.js";
|
|
14
|
+
export * from "./version.js";
|
|
15
|
+
export * from "./workspace.js";
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
|