@martinloop/mcp 0.2.0 → 0.2.7
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.md +118 -182
- package/dist/discovery-metadata.d.ts +21 -0
- package/dist/discovery-metadata.js +152 -0
- package/dist/discovery-support.d.ts +62 -0
- package/dist/discovery-support.js +224 -0
- package/dist/package-version.d.ts +1 -0
- package/dist/package-version.js +3 -0
- package/dist/prompts.d.ts +13 -3
- package/dist/prompts.js +537 -74
- package/dist/resources.d.ts +35 -5
- package/dist/resources.js +788 -71
- package/dist/server-validation.d.ts +2 -3
- package/dist/server-validation.js +375 -119
- package/dist/server.d.ts +76 -7
- package/dist/server.js +1478 -394
- package/dist/tools/doctor.d.ts +2 -0
- package/dist/tools/doctor.js +18 -6
- package/dist/tools/eval.d.ts +24 -0
- package/dist/tools/eval.js +65 -0
- package/dist/tools/get-attempt.d.ts +13 -6
- package/dist/tools/get-attempt.js +14 -5
- package/dist/tools/get-run.d.ts +19 -12
- package/dist/tools/get-run.js +20 -11
- package/dist/tools/get-status.d.ts +19 -0
- package/dist/tools/get-status.js +30 -2
- package/dist/tools/get-verification-results.d.ts +10 -7
- package/dist/tools/get-verification-results.js +11 -6
- package/dist/tools/inspect-loop.d.ts +9 -0
- package/dist/tools/inspect-loop.js +11 -2
- package/dist/tools/list-runs.d.ts +25 -5
- package/dist/tools/list-runs.js +21 -4
- package/dist/tools/logs.d.ts +25 -0
- package/dist/tools/logs.js +49 -0
- package/dist/tools/plan.d.ts +20 -0
- package/dist/tools/plan.js +10 -0
- package/dist/tools/pr-tools.d.ts +31 -0
- package/dist/tools/pr-tools.js +111 -0
- package/dist/tools/preflight.d.ts +10 -0
- package/dist/tools/preflight.js +18 -4
- package/dist/tools/run-controls.d.ts +36 -0
- package/dist/tools/run-controls.js +88 -0
- package/dist/tools/run-dossier.d.ts +51 -4
- package/dist/tools/run-dossier.js +100 -5
- package/dist/tools/run-loop.d.ts +19 -0
- package/dist/tools/run-loop.js +61 -4
- package/dist/tools/run-store.d.ts +57 -3
- package/dist/tools/run-store.js +404 -53
- package/dist/tools/tool-errors.d.ts +37 -0
- package/dist/tools/tool-errors.js +170 -0
- package/dist/tools/tool-response.d.ts +16 -0
- package/dist/tools/tool-response.js +34 -0
- package/dist/tools/tool-support.d.ts +92 -2
- package/dist/tools/tool-support.js +385 -63
- package/dist/tools/triage-runs.d.ts +33 -0
- package/dist/tools/triage-runs.js +138 -0
- package/dist/tools/workflow-governance.d.ts +133 -0
- package/dist/tools/workflow-governance.js +581 -0
- package/dist/vendor/adapters/claude-cli.js +0 -1
- package/dist/vendor/adapters/cli-bridge.d.ts +5 -0
- package/dist/vendor/adapters/cli-bridge.js +16 -9
- package/dist/vendor/adapters/direct-provider.js +0 -1
- package/dist/vendor/adapters/index.d.ts +2 -1
- package/dist/vendor/adapters/index.js +2 -1
- package/dist/vendor/adapters/openai-compatible.d.ts +47 -0
- package/dist/vendor/adapters/openai-compatible.js +242 -0
- package/dist/vendor/adapters/runtime-support.js +0 -1
- package/dist/vendor/adapters/stub-agent-cli.js +0 -1
- package/dist/vendor/adapters/stub-direct-provider.js +0 -1
- package/dist/vendor/adapters/verifier-only.js +0 -1
- package/dist/vendor/contracts/governance.js +0 -1
- package/dist/vendor/contracts/index.d.ts +2 -0
- package/dist/vendor/contracts/index.js +1 -1
- package/dist/vendor/contracts/operator.d.ts +19 -0
- package/dist/vendor/contracts/operator.js +11 -0
- package/dist/vendor/core/compiler.js +0 -1
- package/dist/vendor/core/context-integrity.js +0 -1
- package/dist/vendor/core/grounding.js +0 -1
- package/dist/vendor/core/index.js +1 -2
- package/dist/vendor/core/leash.js +19 -12
- package/dist/vendor/core/persistence/compiler.js +0 -1
- package/dist/vendor/core/persistence/index.js +0 -1
- package/dist/vendor/core/persistence/ledger.js +0 -1
- package/dist/vendor/core/persistence/runs-reader.js +0 -1
- package/dist/vendor/core/persistence/store.js +0 -1
- package/dist/vendor/core/policy.js +0 -1
- package/dist/vendor/core/red-blue/red-phase.d.ts +64 -0
- package/dist/vendor/core/red-blue/red-phase.js +135 -0
- package/dist/vendor/core/red-blue/risk-tiers.d.ts +22 -0
- package/dist/vendor/core/red-blue/risk-tiers.js +32 -0
- package/dist/vendor/core/rollback.js +2 -3
- package/dist/workflow-state.d.ts +25 -0
- package/dist/workflow-state.js +102 -0
- package/package.json +12 -7
- package/server.json +2 -2
- package/dist/tools/cockpit-support.d.ts +0 -69
- package/dist/tools/cockpit-support.js +0 -108
package/dist/tools/doctor.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type LoopPreview, type MartinEngine } from "./tool-support.js";
|
|
2
|
+
import { type MartinReadinessReport } from "./workflow-governance.js";
|
|
2
3
|
export interface MartinDoctorInput {
|
|
3
4
|
workingDirectory?: string;
|
|
4
5
|
runsDir?: string;
|
|
@@ -30,6 +31,7 @@ export interface MartinDoctorOutput {
|
|
|
30
31
|
loopCount: number;
|
|
31
32
|
latestRun?: LoopPreview;
|
|
32
33
|
};
|
|
34
|
+
readiness: MartinReadinessReport;
|
|
33
35
|
warnings: string[];
|
|
34
36
|
}
|
|
35
37
|
export declare function martinDoctorTool(input: MartinDoctorInput): Promise<MartinDoctorOutput>;
|
package/dist/tools/doctor.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { resolveRunsRoot } from "../vendor/core/index.js";
|
|
2
2
|
import { resolveSafeRepoRoot, resolveSafeRunsRootPath } from "../server-validation.js";
|
|
3
3
|
import { getEngineAvailability, inspectRunsRoot, resolveExecutionMode } from "./tool-support.js";
|
|
4
|
+
import { buildReadinessReport, inspectRepoSignals } from "./workflow-governance.js";
|
|
4
5
|
export async function martinDoctorTool(input) {
|
|
5
6
|
const workingDirectory = resolveSafeRepoRoot(input.workingDirectory);
|
|
6
7
|
const runsRoot = resolveSafeRunsRootPath(input.runsDir, resolveRunsRoot(process.env));
|
|
@@ -8,6 +9,8 @@ export async function martinDoctorTool(input) {
|
|
|
8
9
|
const claude = getEngineAvailability("claude");
|
|
9
10
|
const codex = getEngineAvailability("codex");
|
|
10
11
|
const runStore = await inspectRunsRoot(runsRoot);
|
|
12
|
+
const signals = inspectRepoSignals(workingDirectory);
|
|
13
|
+
const readiness = buildReadinessReport(signals, runStore);
|
|
11
14
|
const warnings = [];
|
|
12
15
|
if (!runStore.exists) {
|
|
13
16
|
warnings.push("Configured Martin runs root does not exist yet.");
|
|
@@ -23,11 +26,12 @@ export async function martinDoctorTool(input) {
|
|
|
23
26
|
}
|
|
24
27
|
warnings.push(...runStore.warnings);
|
|
25
28
|
const status = warnings.length === 0 ? "ok" : "degraded";
|
|
29
|
+
const summary = status === "ok"
|
|
30
|
+
? `Doctor passed: repo readiness ${readiness.score}/100 with ${runStore.loopCount} visible run(s).`
|
|
31
|
+
: `Doctor found ${warnings.length} issue(s); readiness ${readiness.score}/100 before live execution.`;
|
|
26
32
|
return {
|
|
27
33
|
status,
|
|
28
|
-
summary
|
|
29
|
-
? `Doctor passed: ${runStore.loopCount} run(s) visible in ${runsRoot}.`
|
|
30
|
-
: `Doctor found ${warnings.length} issue(s); review warnings before live execution.`,
|
|
34
|
+
summary,
|
|
31
35
|
server: {
|
|
32
36
|
name: "martin-loop",
|
|
33
37
|
nodeVersion: process.version,
|
|
@@ -41,8 +45,16 @@ export async function martinDoctorTool(input) {
|
|
|
41
45
|
liveMode: executionMode.liveMode
|
|
42
46
|
},
|
|
43
47
|
engines: {
|
|
44
|
-
claude
|
|
45
|
-
|
|
48
|
+
claude: {
|
|
49
|
+
available: claude.available,
|
|
50
|
+
detail: claude.detail,
|
|
51
|
+
...(claude.resolvedPath ? { resolvedPath: claude.resolvedPath } : {})
|
|
52
|
+
},
|
|
53
|
+
codex: {
|
|
54
|
+
available: codex.available,
|
|
55
|
+
detail: codex.detail,
|
|
56
|
+
...(codex.resolvedPath ? { resolvedPath: codex.resolvedPath } : {})
|
|
57
|
+
}
|
|
46
58
|
},
|
|
47
59
|
...(input.engine ? { requestedEngine: input.engine } : {}),
|
|
48
60
|
runStore: {
|
|
@@ -50,7 +62,7 @@ export async function martinDoctorTool(input) {
|
|
|
50
62
|
loopCount: runStore.loopCount,
|
|
51
63
|
...(runStore.latestRun ? { latestRun: runStore.latestRun } : {})
|
|
52
64
|
},
|
|
65
|
+
readiness,
|
|
53
66
|
warnings
|
|
54
67
|
};
|
|
55
68
|
}
|
|
56
|
-
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface MartinEvalInput {
|
|
2
|
+
file?: string;
|
|
3
|
+
loopId?: string;
|
|
4
|
+
runsDir?: string;
|
|
5
|
+
latest?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface MartinEvalOutput {
|
|
8
|
+
source: string;
|
|
9
|
+
sourceKind: "file" | "loop_id" | "latest" | "runs_root";
|
|
10
|
+
loopId: string;
|
|
11
|
+
score: number;
|
|
12
|
+
grade: "mergeable" | "mergeable_with_review" | "needs_review" | "blocked" | "insufficient_evidence";
|
|
13
|
+
checks: {
|
|
14
|
+
taskCompletion: "passed" | "warning" | "failed";
|
|
15
|
+
verifier: "passed" | "warning" | "failed";
|
|
16
|
+
diffDiscipline: "passed" | "warning" | "failed";
|
|
17
|
+
regressionRisk: "passed" | "warning" | "failed";
|
|
18
|
+
securityRisk: "passed" | "warning" | "failed";
|
|
19
|
+
reviewability: "passed" | "warning" | "failed";
|
|
20
|
+
};
|
|
21
|
+
warnings: string[];
|
|
22
|
+
summary: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function martinEvalTool(input: MartinEvalInput): Promise<MartinEvalOutput>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { loadDetailedLoopRecord, readLedgerEvents } from "./run-store.js";
|
|
2
|
+
import { buildVerificationSummary } from "./tool-support.js";
|
|
3
|
+
import { assessRunRisk, inspectRepoSignals } from "./workflow-governance.js";
|
|
4
|
+
export async function martinEvalTool(input) {
|
|
5
|
+
const detail = await loadDetailedLoopRecord(input);
|
|
6
|
+
const ledgerEvents = await readLedgerEvents(detail);
|
|
7
|
+
const verification = buildVerificationSummary(detail.loop, ledgerEvents);
|
|
8
|
+
const repoRoot = detail.loop.task?.repoRoot;
|
|
9
|
+
const signals = inspectRepoSignals(repoRoot ?? process.cwd());
|
|
10
|
+
const risk = assessRunRisk({
|
|
11
|
+
objective: detail.loop.task?.objective ?? detail.loop.loopId,
|
|
12
|
+
allowedPaths: detail.loop.task?.allowedPaths ?? [],
|
|
13
|
+
blockedPaths: detail.loop.task?.deniedPaths ?? [],
|
|
14
|
+
verifiers: detail.loop.task?.verificationPlan ?? [],
|
|
15
|
+
signals
|
|
16
|
+
});
|
|
17
|
+
const checks = {
|
|
18
|
+
taskCompletion: detail.loop.status === "completed" ? "passed" : detail.loop.status === "exited" ? "warning" : "failed",
|
|
19
|
+
verifier: verification.status === "passed"
|
|
20
|
+
? "passed"
|
|
21
|
+
: verification.status === "failed"
|
|
22
|
+
? "failed"
|
|
23
|
+
: "warning",
|
|
24
|
+
diffDiscipline: (detail.loop.task?.allowedPaths?.length ?? 0) > 0 ? "passed" : "warning",
|
|
25
|
+
regressionRisk: verification.status === "passed" ? "passed" : "warning",
|
|
26
|
+
securityRisk: risk.level === "high" ? "failed" : risk.level === "medium" ? "warning" : "passed",
|
|
27
|
+
reviewability: detail.loop.attempts.length > 0 && (detail.loop.events?.length ?? 0) > 0 ? "passed" : "warning"
|
|
28
|
+
};
|
|
29
|
+
let score = 100;
|
|
30
|
+
score -= checks.taskCompletion === "failed" ? 25 : checks.taskCompletion === "warning" ? 10 : 0;
|
|
31
|
+
score -= checks.verifier === "failed" ? 25 : checks.verifier === "warning" ? 10 : 0;
|
|
32
|
+
score -= checks.diffDiscipline === "warning" ? 8 : 0;
|
|
33
|
+
score -= checks.regressionRisk === "warning" ? 10 : 0;
|
|
34
|
+
score -= checks.securityRisk === "failed" ? 20 : checks.securityRisk === "warning" ? 10 : 0;
|
|
35
|
+
score -= checks.reviewability === "warning" ? 8 : 0;
|
|
36
|
+
score = Math.max(0, score);
|
|
37
|
+
const grade = verification.status === "unavailable"
|
|
38
|
+
? "insufficient_evidence"
|
|
39
|
+
: score >= 90
|
|
40
|
+
? "mergeable"
|
|
41
|
+
: score >= 75
|
|
42
|
+
? "mergeable_with_review"
|
|
43
|
+
: score >= 55
|
|
44
|
+
? "needs_review"
|
|
45
|
+
: "blocked";
|
|
46
|
+
const warnings = [...detail.warnings, ...verification.warnings, ...risk.reasons];
|
|
47
|
+
return {
|
|
48
|
+
source: detail.source,
|
|
49
|
+
sourceKind: detail.sourceKind,
|
|
50
|
+
loopId: detail.loop.loopId,
|
|
51
|
+
score,
|
|
52
|
+
grade,
|
|
53
|
+
checks: { ...checks },
|
|
54
|
+
warnings,
|
|
55
|
+
summary: grade === "mergeable"
|
|
56
|
+
? `Run ${detail.loop.loopId} looks mergeable with verifier-backed completion.`
|
|
57
|
+
: grade === "mergeable_with_review"
|
|
58
|
+
? `Run ${detail.loop.loopId} looks mergeable with review; inspect dossier and risk notes first.`
|
|
59
|
+
: grade === "needs_review"
|
|
60
|
+
? `Run ${detail.loop.loopId} needs review before promotion.`
|
|
61
|
+
: grade === "insufficient_evidence"
|
|
62
|
+
? `Run ${detail.loop.loopId} does not have enough evidence for a safe promotion decision.`
|
|
63
|
+
: `Run ${detail.loop.loopId} is blocked from promotion by verification or risk gaps.`
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export interface
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { buildAttemptSummary, buildLoopPreview } from "./tool-support.js";
|
|
2
|
+
export interface MartinGetAttemptInput {
|
|
3
|
+
file?: string;
|
|
4
|
+
loopId?: string;
|
|
5
5
|
runsDir?: string;
|
|
6
|
+
attemptIndex?: number;
|
|
6
7
|
}
|
|
7
|
-
export
|
|
8
|
-
|
|
8
|
+
export interface MartinGetAttemptOutput {
|
|
9
|
+
source: string;
|
|
10
|
+
sourceKind: "file" | "loop_id" | "latest" | "runs_root";
|
|
11
|
+
loop: ReturnType<typeof buildLoopPreview>;
|
|
12
|
+
attempt: ReturnType<typeof buildAttemptSummary>;
|
|
13
|
+
warnings: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function martinGetAttemptTool(input: MartinGetAttemptInput): Promise<MartinGetAttemptOutput>;
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { buildAttemptArtifactsReference, buildAttemptSummary, buildLoopPreview } from "./tool-support.js";
|
|
2
|
+
import { loadAttemptFromLoop } from "./run-store.js";
|
|
3
|
+
export async function martinGetAttemptTool(input) {
|
|
4
|
+
const { detail, attempt } = await loadAttemptFromLoop(input);
|
|
5
|
+
const artifacts = detail.canonicalRunDirectory
|
|
6
|
+
? await buildAttemptArtifactsReference(detail.runsRoot, detail.loop.loopId, attempt.index)
|
|
7
|
+
: undefined;
|
|
8
|
+
return {
|
|
9
|
+
source: detail.source,
|
|
10
|
+
sourceKind: detail.sourceKind,
|
|
11
|
+
loop: buildLoopPreview(detail.loop),
|
|
12
|
+
attempt: buildAttemptSummary(attempt, artifacts),
|
|
13
|
+
warnings: detail.warnings
|
|
14
|
+
};
|
|
5
15
|
}
|
|
6
|
-
//# sourceMappingURL=get-attempt.js.map
|
package/dist/tools/get-run.d.ts
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { buildArtifactSummary, buildBudgetSnapshot, buildCostSnapshot, buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
|
|
2
|
+
export interface MartinGetRunInput {
|
|
3
|
+
file?: string;
|
|
4
4
|
loopId?: string;
|
|
5
5
|
runsDir?: string;
|
|
6
6
|
latest?: boolean;
|
|
7
7
|
}
|
|
8
|
-
export interface
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
export interface MartinGetRunOutput {
|
|
9
|
+
source: string;
|
|
10
|
+
sourceKind: "file" | "loop_id" | "latest" | "runs_root";
|
|
11
|
+
loop: ReturnType<typeof buildLoopPreview>;
|
|
12
|
+
budget: ReturnType<typeof buildBudgetSnapshot>;
|
|
13
|
+
cost: ReturnType<typeof buildCostSnapshot>;
|
|
14
|
+
verification: ReturnType<typeof buildVerificationSummary>;
|
|
15
|
+
artifacts: ReturnType<typeof buildArtifactSummary>;
|
|
16
|
+
inspection: {
|
|
17
|
+
runsRoot: string;
|
|
18
|
+
canonicalRunDirectory?: string;
|
|
19
|
+
canonicalLoopRecordPath?: string;
|
|
20
|
+
ledgerPath?: string;
|
|
21
|
+
};
|
|
22
|
+
warnings: string[];
|
|
16
23
|
}
|
|
17
|
-
export declare function
|
|
24
|
+
export declare function martinGetRunTool(input: MartinGetRunInput): Promise<MartinGetRunOutput>;
|
package/dist/tools/get-run.js
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { buildArtifactSummary, buildBudgetSnapshot, buildCostSnapshot, buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
|
|
2
|
+
import { loadDetailedLoopRecord, readLedgerEvents } from "./run-store.js";
|
|
3
|
+
export async function martinGetRunTool(input) {
|
|
4
|
+
const detail = await loadDetailedLoopRecord(input);
|
|
5
|
+
const ledgerEvents = await readLedgerEvents(detail);
|
|
6
|
+
const verification = buildVerificationSummary(detail.loop, ledgerEvents);
|
|
4
7
|
return {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
source: detail.source,
|
|
9
|
+
sourceKind: detail.sourceKind,
|
|
10
|
+
loop: buildLoopPreview(detail.loop),
|
|
11
|
+
budget: buildBudgetSnapshot(detail.loop.budget),
|
|
12
|
+
cost: buildCostSnapshot(detail.loop.cost),
|
|
13
|
+
verification,
|
|
14
|
+
artifacts: buildArtifactSummary(detail.loop),
|
|
15
|
+
inspection: {
|
|
16
|
+
runsRoot: detail.runsRoot,
|
|
17
|
+
...(detail.canonicalRunDirectory ? { canonicalRunDirectory: detail.canonicalRunDirectory } : {}),
|
|
18
|
+
...(detail.canonicalLoopRecordPath ? { canonicalLoopRecordPath: detail.canonicalLoopRecordPath } : {}),
|
|
19
|
+
...(detail.ledgerPath ? { ledgerPath: detail.ledgerPath } : {})
|
|
20
|
+
},
|
|
21
|
+
warnings: [...detail.warnings, ...verification.warnings]
|
|
12
22
|
};
|
|
13
23
|
}
|
|
14
|
-
//# sourceMappingURL=get-run.js.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type LoopPreview } from "./tool-support.js";
|
|
1
2
|
export interface GetStatusInput {
|
|
2
3
|
/** JSON-serialized LoopRecord. */
|
|
3
4
|
loopJson?: string;
|
|
@@ -11,6 +12,7 @@ export interface GetStatusInput {
|
|
|
11
12
|
latest?: boolean;
|
|
12
13
|
}
|
|
13
14
|
export interface GetStatusOutput {
|
|
15
|
+
source: string;
|
|
14
16
|
loopId: string;
|
|
15
17
|
status: string;
|
|
16
18
|
lifecycleState: string;
|
|
@@ -22,5 +24,22 @@ export interface GetStatusOutput {
|
|
|
22
24
|
remainingBudgetUsd: number;
|
|
23
25
|
remainingIterations: number;
|
|
24
26
|
remainingTokens: number;
|
|
27
|
+
budget: {
|
|
28
|
+
maxUsd: number;
|
|
29
|
+
softLimitUsd: number;
|
|
30
|
+
maxIterations: number;
|
|
31
|
+
maxTokens: number;
|
|
32
|
+
};
|
|
33
|
+
inspection: {
|
|
34
|
+
loop: LoopPreview;
|
|
35
|
+
};
|
|
36
|
+
live: {
|
|
37
|
+
phase: string;
|
|
38
|
+
pauseState: "active" | "paused" | "cancellation_requested";
|
|
39
|
+
approvalState: "not_required" | "resume_requested";
|
|
40
|
+
commandsRun: number;
|
|
41
|
+
filesTouched: number;
|
|
42
|
+
verifierStep?: string;
|
|
43
|
+
};
|
|
25
44
|
}
|
|
26
45
|
export declare function getStatusTool(input: GetStatusInput): Promise<GetStatusOutput>;
|
package/dist/tools/get-status.js
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import { evaluateCostGovernor } from "../vendor/core/index.js";
|
|
2
2
|
import { loadLoopRecordForStatus } from "./run-store.js";
|
|
3
|
+
import { buildLoopPreview } from "./tool-support.js";
|
|
4
|
+
import { readRunControlState } from "./run-controls.js";
|
|
3
5
|
export async function getStatusTool(input) {
|
|
4
6
|
const resolved = await loadLoopRecordForStatus(input);
|
|
5
7
|
const loop = resolved.loop;
|
|
8
|
+
const control = input.loopJson !== undefined
|
|
9
|
+
? {
|
|
10
|
+
requestedState: "active",
|
|
11
|
+
approvalState: "not_required",
|
|
12
|
+
receipts: []
|
|
13
|
+
}
|
|
14
|
+
: await readRunControlState(input);
|
|
15
|
+
const latestEvent = loop.events?.at(-1);
|
|
16
|
+
const changedFiles = loop.artifacts?.filter((artifact) => artifact.kind === "diff").length ?? 0;
|
|
6
17
|
const costState = evaluateCostGovernor({
|
|
7
18
|
budget: loop.budget,
|
|
8
19
|
cost: {
|
|
@@ -14,6 +25,7 @@ export async function getStatusTool(input) {
|
|
|
14
25
|
attemptsUsed: loop.attempts.length
|
|
15
26
|
});
|
|
16
27
|
return {
|
|
28
|
+
source: resolved.source,
|
|
17
29
|
loopId: loop.loopId,
|
|
18
30
|
status: loop.status,
|
|
19
31
|
lifecycleState: loop.lifecycleState,
|
|
@@ -24,7 +36,23 @@ export async function getStatusTool(input) {
|
|
|
24
36
|
shouldStop: costState.shouldStop,
|
|
25
37
|
remainingBudgetUsd: costState.remainingBudgetUsd,
|
|
26
38
|
remainingIterations: costState.remainingIterations,
|
|
27
|
-
remainingTokens: costState.remainingTokens
|
|
39
|
+
remainingTokens: costState.remainingTokens,
|
|
40
|
+
budget: {
|
|
41
|
+
maxUsd: loop.budget.maxUsd,
|
|
42
|
+
softLimitUsd: loop.budget.softLimitUsd,
|
|
43
|
+
maxIterations: loop.budget.maxIterations,
|
|
44
|
+
maxTokens: loop.budget.maxTokens
|
|
45
|
+
},
|
|
46
|
+
inspection: {
|
|
47
|
+
loop: buildLoopPreview(loop)
|
|
48
|
+
},
|
|
49
|
+
live: {
|
|
50
|
+
phase: latestEvent?.lifecycleState ?? loop.lifecycleState,
|
|
51
|
+
pauseState: control.requestedState,
|
|
52
|
+
approvalState: control.approvalState,
|
|
53
|
+
commandsRun: loop.attempts.length,
|
|
54
|
+
filesTouched: changedFiles,
|
|
55
|
+
...(loop.task?.verificationPlan?.[0] ? { verifierStep: loop.task.verificationPlan[0] } : {})
|
|
56
|
+
}
|
|
28
57
|
};
|
|
29
58
|
}
|
|
30
|
-
//# sourceMappingURL=get-status.js.map
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export interface
|
|
1
|
+
import { buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
|
|
2
|
+
export interface MartinGetVerificationResultsInput {
|
|
3
|
+
file?: string;
|
|
3
4
|
loopId?: string;
|
|
4
5
|
runsDir?: string;
|
|
5
|
-
latest?: boolean;
|
|
6
6
|
}
|
|
7
|
-
export interface
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export interface MartinGetVerificationResultsOutput {
|
|
8
|
+
source: string;
|
|
9
|
+
sourceKind: "file" | "loop_id" | "latest" | "runs_root";
|
|
10
|
+
loop: ReturnType<typeof buildLoopPreview>;
|
|
11
|
+
verification: ReturnType<typeof buildVerificationSummary>;
|
|
12
|
+
warnings: string[];
|
|
10
13
|
}
|
|
11
|
-
export declare function
|
|
14
|
+
export declare function martinGetVerificationResultsTool(input: MartinGetVerificationResultsInput): Promise<MartinGetVerificationResultsOutput>;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
|
|
2
|
+
import { loadDetailedLoopRecord, readLedgerEvents } from "./run-store.js";
|
|
3
|
+
export async function martinGetVerificationResultsTool(input) {
|
|
4
|
+
const detail = await loadDetailedLoopRecord(input);
|
|
5
|
+
const ledgerEvents = await readLedgerEvents(detail);
|
|
6
|
+
const verification = buildVerificationSummary(detail.loop, ledgerEvents);
|
|
4
7
|
return {
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
source: detail.source,
|
|
9
|
+
sourceKind: detail.sourceKind,
|
|
10
|
+
loop: buildLoopPreview(detail.loop),
|
|
11
|
+
verification,
|
|
12
|
+
warnings: [...detail.warnings, ...verification.warnings]
|
|
7
13
|
};
|
|
8
14
|
}
|
|
9
|
-
//# sourceMappingURL=get-verification-results.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type PortfolioSnapshot } from "../vendor/contracts/index.js";
|
|
2
|
+
import { type LoopPreview } from "./tool-support.js";
|
|
2
3
|
export interface InspectLoopInput {
|
|
3
4
|
/** Optional path to a JSON, JSONL, or run-store directory under the Martin runs root. */
|
|
4
5
|
file?: string;
|
|
@@ -9,5 +10,13 @@ export interface InspectLoopOutput {
|
|
|
9
10
|
source: string;
|
|
10
11
|
loopCount: number;
|
|
11
12
|
portfolio: PortfolioSnapshot;
|
|
13
|
+
latestRun?: LoopPreview;
|
|
14
|
+
recentRuns: LoopPreview[];
|
|
15
|
+
statusBreakdown: Record<string, number>;
|
|
16
|
+
lifecycleBreakdown: Record<string, number>;
|
|
17
|
+
inspection: {
|
|
18
|
+
sourceKind: "file" | "runs_root";
|
|
19
|
+
};
|
|
20
|
+
warnings: string[];
|
|
12
21
|
}
|
|
13
22
|
export declare function inspectLoopTool(input: InspectLoopInput): Promise<InspectLoopOutput>;
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { buildPortfolioSnapshot } from "../vendor/contracts/index.js";
|
|
2
2
|
import { loadLoopRecordsForInspect } from "./run-store.js";
|
|
3
|
+
import { buildLoopCollectionSummary } from "./tool-support.js";
|
|
3
4
|
export async function inspectLoopTool(input) {
|
|
4
5
|
const inspection = await loadLoopRecordsForInspect(input);
|
|
5
6
|
const loops = inspection.loops;
|
|
7
|
+
const summary = buildLoopCollectionSummary(inspection.loops);
|
|
6
8
|
return {
|
|
7
9
|
source: inspection.source,
|
|
8
10
|
loopCount: loops.length,
|
|
9
|
-
portfolio: buildPortfolioSnapshot(loops)
|
|
11
|
+
portfolio: buildPortfolioSnapshot(loops),
|
|
12
|
+
...(summary.latestRun ? { latestRun: summary.latestRun } : {}),
|
|
13
|
+
recentRuns: summary.recentRuns,
|
|
14
|
+
statusBreakdown: summary.statusBreakdown,
|
|
15
|
+
lifecycleBreakdown: summary.lifecycleBreakdown,
|
|
16
|
+
inspection: {
|
|
17
|
+
sourceKind: input.file ? "file" : "runs_root"
|
|
18
|
+
},
|
|
19
|
+
warnings: inspection.warnings
|
|
10
20
|
};
|
|
11
21
|
}
|
|
12
|
-
//# sourceMappingURL=inspect-loop.js.map
|
|
@@ -1,9 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export interface
|
|
1
|
+
import { buildLoopPreview } from "./tool-support.js";
|
|
2
|
+
export interface MartinListRunsInput {
|
|
3
3
|
runsDir?: string;
|
|
4
4
|
limit?: number;
|
|
5
|
+
status?: string;
|
|
6
|
+
lifecycleState?: string;
|
|
7
|
+
adapterId?: string;
|
|
8
|
+
model?: string;
|
|
9
|
+
updatedAfter?: string;
|
|
5
10
|
}
|
|
6
|
-
export interface
|
|
7
|
-
|
|
11
|
+
export interface MartinListRunsOutput {
|
|
12
|
+
source: string;
|
|
13
|
+
runsRoot: string;
|
|
14
|
+
filters: {
|
|
15
|
+
limit: number;
|
|
16
|
+
status?: string;
|
|
17
|
+
lifecycleState?: string;
|
|
18
|
+
adapterId?: string;
|
|
19
|
+
model?: string;
|
|
20
|
+
updatedAfter?: string;
|
|
21
|
+
};
|
|
22
|
+
loopCount: number;
|
|
23
|
+
latestRun?: ReturnType<typeof buildLoopPreview>;
|
|
24
|
+
recentRuns: Array<ReturnType<typeof buildLoopPreview>>;
|
|
25
|
+
statusBreakdown: Record<string, number>;
|
|
26
|
+
lifecycleBreakdown: Record<string, number>;
|
|
27
|
+
warnings: string[];
|
|
8
28
|
}
|
|
9
|
-
export declare function
|
|
29
|
+
export declare function martinListRunsTool(input: MartinListRunsInput): Promise<MartinListRunsOutput>;
|
package/dist/tools/list-runs.js
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { buildLoopCollectionSummary, buildLoopPreview } from "./tool-support.js";
|
|
2
|
+
import { listLoopRecords } from "./run-store.js";
|
|
3
|
+
export async function martinListRunsTool(input) {
|
|
4
|
+
const result = await listLoopRecords(input);
|
|
5
|
+
const summary = buildLoopCollectionSummary(result.loops);
|
|
3
6
|
return {
|
|
4
|
-
|
|
7
|
+
source: result.source,
|
|
8
|
+
runsRoot: result.runsRoot,
|
|
9
|
+
filters: {
|
|
10
|
+
limit: input.limit ?? 20,
|
|
11
|
+
...(input.status ? { status: input.status } : {}),
|
|
12
|
+
...(input.lifecycleState ? { lifecycleState: input.lifecycleState } : {}),
|
|
13
|
+
...(input.adapterId ? { adapterId: input.adapterId } : {}),
|
|
14
|
+
...(input.model ? { model: input.model } : {}),
|
|
15
|
+
...(input.updatedAfter ? { updatedAfter: input.updatedAfter } : {})
|
|
16
|
+
},
|
|
17
|
+
loopCount: result.loops.length,
|
|
18
|
+
...(summary.latestRun ? { latestRun: summary.latestRun } : {}),
|
|
19
|
+
recentRuns: result.loops.map((loop) => buildLoopPreview(loop)),
|
|
20
|
+
statusBreakdown: summary.statusBreakdown,
|
|
21
|
+
lifecycleBreakdown: summary.lifecycleBreakdown,
|
|
22
|
+
warnings: result.warnings
|
|
5
23
|
};
|
|
6
24
|
}
|
|
7
|
-
//# sourceMappingURL=list-runs.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface MartinLogsInput {
|
|
2
|
+
file?: string;
|
|
3
|
+
loopId?: string;
|
|
4
|
+
runsDir?: string;
|
|
5
|
+
latest?: boolean;
|
|
6
|
+
limit?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface MartinLogsOutput {
|
|
9
|
+
source: string;
|
|
10
|
+
sourceKind: "file" | "loop_id" | "latest" | "runs_root";
|
|
11
|
+
loopId: string;
|
|
12
|
+
logCount: number;
|
|
13
|
+
live: {
|
|
14
|
+
lifecycleState: string;
|
|
15
|
+
pauseState: "active" | "paused" | "cancellation_requested";
|
|
16
|
+
approvalState: "not_required" | "resume_requested";
|
|
17
|
+
};
|
|
18
|
+
entries: Array<{
|
|
19
|
+
timestamp?: string;
|
|
20
|
+
source: "event" | "ledger" | "control";
|
|
21
|
+
kind: string;
|
|
22
|
+
payload: Record<string, unknown>;
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
export declare function martinLogsTool(input: MartinLogsInput): Promise<MartinLogsOutput>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { readRunControlState } from "./run-controls.js";
|
|
2
|
+
import { loadDetailedLoopRecord, readLedgerEvents } from "./run-store.js";
|
|
3
|
+
export async function martinLogsTool(input) {
|
|
4
|
+
const detail = await loadDetailedLoopRecord(input);
|
|
5
|
+
const ledgerEvents = await readLedgerEvents(detail);
|
|
6
|
+
const controls = await readRunControlState(detail);
|
|
7
|
+
const limit = input.limit ?? 20;
|
|
8
|
+
const eventEntries = (detail.loop.events ?? []).map((event) => ({
|
|
9
|
+
timestamp: event.timestamp,
|
|
10
|
+
source: "event",
|
|
11
|
+
kind: event.type,
|
|
12
|
+
payload: event.payload ?? {}
|
|
13
|
+
}));
|
|
14
|
+
const ledgerEntries = ledgerEvents.map((event) => ({
|
|
15
|
+
timestamp: event.timestamp,
|
|
16
|
+
source: "ledger",
|
|
17
|
+
kind: event.kind,
|
|
18
|
+
payload: (event.payload ?? {})
|
|
19
|
+
}));
|
|
20
|
+
const controlEntries = controls.receipts.map((receipt) => ({
|
|
21
|
+
timestamp: receipt.requestedAt,
|
|
22
|
+
source: "control",
|
|
23
|
+
kind: `run.${receipt.action}`,
|
|
24
|
+
payload: {
|
|
25
|
+
controlId: receipt.controlId,
|
|
26
|
+
...(receipt.reason ? { reason: receipt.reason } : {}),
|
|
27
|
+
...(receipt.requestedBy ? { requestedBy: receipt.requestedBy } : {})
|
|
28
|
+
}
|
|
29
|
+
}));
|
|
30
|
+
const entries = [...eventEntries, ...ledgerEntries, ...controlEntries]
|
|
31
|
+
.sort((left, right) => {
|
|
32
|
+
const leftTime = left.timestamp ? new Date(left.timestamp).getTime() : 0;
|
|
33
|
+
const rightTime = right.timestamp ? new Date(right.timestamp).getTime() : 0;
|
|
34
|
+
return rightTime - leftTime;
|
|
35
|
+
})
|
|
36
|
+
.slice(0, limit);
|
|
37
|
+
return {
|
|
38
|
+
source: detail.source,
|
|
39
|
+
sourceKind: detail.sourceKind,
|
|
40
|
+
loopId: detail.loop.loopId,
|
|
41
|
+
logCount: entries.length,
|
|
42
|
+
live: {
|
|
43
|
+
lifecycleState: detail.loop.lifecycleState,
|
|
44
|
+
pauseState: controls.requestedState,
|
|
45
|
+
approvalState: controls.approvalState
|
|
46
|
+
},
|
|
47
|
+
entries
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type MartinPlanProposal, type MartinPolicyPack } from "./workflow-governance.js";
|
|
2
|
+
export interface MartinPlanInput {
|
|
3
|
+
objective: string;
|
|
4
|
+
workingDirectory?: string;
|
|
5
|
+
context?: string;
|
|
6
|
+
verificationPlan?: string[];
|
|
7
|
+
allowedPaths?: string[];
|
|
8
|
+
deniedPaths?: string[];
|
|
9
|
+
policyPack?: MartinPolicyPack;
|
|
10
|
+
maxUsd?: number;
|
|
11
|
+
maxIterations?: number;
|
|
12
|
+
maxTokens?: number;
|
|
13
|
+
maxMinutes?: number;
|
|
14
|
+
maxFilesChanged?: number;
|
|
15
|
+
maxCommands?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface MartinPlanOutput extends MartinPlanProposal {
|
|
18
|
+
workingDirectory: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function martinPlanTool(input: MartinPlanInput): Promise<MartinPlanOutput>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { resolveSafeRepoRoot } from "../server-validation.js";
|
|
2
|
+
import { buildPlanProposal } from "./workflow-governance.js";
|
|
3
|
+
export async function martinPlanTool(input) {
|
|
4
|
+
const workingDirectory = resolveSafeRepoRoot(input.workingDirectory);
|
|
5
|
+
const proposal = buildPlanProposal(workingDirectory, input);
|
|
6
|
+
return {
|
|
7
|
+
workingDirectory,
|
|
8
|
+
...proposal
|
|
9
|
+
};
|
|
10
|
+
}
|