Sign In

martin-loop

Package Overview
Dependencies
Maintainers
1
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

martin-loop - npm Package Compare versions

Comparing version
0.4.2
to
0.4.3
+10
-1
dist/vendor/adapters/codex-launcher.js

@@ -360,2 +360,6 @@ import { spawnSync } from "node:child_process";

dirs.push(join(localAppData, "OpenAI", "Codex", "bin"));
// Claude Code native installer places binary at %USERPROFILE%\.local\bin
const userProfile = env.USERPROFILE ?? env.HOMEPATH;
if (userProfile)
dirs.push(join(userProfile, ".local", "bin"));
if (home)

@@ -387,4 +391,9 @@ dirs.push(join(home, "scoop", "shims"));

function suggestInstall(command) {
if (command === "claude") {
const installCmd = process.platform === "win32"
? "irm https://claude.ai/install.ps1 | iex"
: "curl -fsSL https://claude.ai/install.sh | bash";
return `Install with: ${installCmd}`;
}
const installs = {
claude: "Install with: npm install -g @anthropic-ai/claude-code",
codex: "Install with: npm install -g @openai/codex",

@@ -391,0 +400,0 @@ gemini: "Install with: npm install -g @google/gemini-cli"

+1
-1
{
"name": "@martin/cli",
"version": "0.4.2",
"version": "0.4.3",
"type": "module",

@@ -5,0 +5,0 @@ "description": "Martin Loop CLI โ€” budget-aware coding loops with failure classification and verified exits.",

@@ -71,2 +71,3 @@ import { createHash } from "node:crypto";

...(input.receiptScope ? { scopeKey: hashReceiptScope(input.receiptScope) } : {}),
...(input.receiptScope ? { canonicalScopeKey: hashCanonicalReceiptScope(input.receiptScope) } : {}),
pathScopeKey: hashPathScope(input.allowedPaths ?? [], input.deniedPaths ?? []),

@@ -92,7 +93,16 @@ ...(input.budget ? { budgetKey: hashBudget(input.budget) } : {})

});
const canonicalScopeKey = hashCanonicalReceiptScope(input.receiptScope ?? {
invocationRoot: input.workingDirectory,
workingDirectory: input.workingDirectory,
repoRoot: input.workingDirectory,
runsRoot: input.runsRoot
});
const pathScopeKey = hashPathScope(input.allowedPaths ?? [], input.deniedPaths ?? []);
const budgetKey = input.budget ? hashBudget(input.budget) : undefined;
const missingSteps = [];
// Doctor/session-start are repo-scoped readiness checks. They should remain
// valid when INIT_CWD changes inside the same repo, but must still fail
// closed if the canonical repo/runsRoot identity changes.
const doctorReady = isFresh(cliState["doctor"], DOCTOR_TTL_MS, (receipt) => receipt.workingDirectory === workingDirectory &&
receipt.scopeKey === scopeKey);
matchesCanonicalScope(receipt, canonicalScopeKey, scopeKey));
if (!doctorReady) {

@@ -113,16 +123,20 @@ missingSteps.push("doctor");

isFresh(cliState["session-start"], SESSION_TTL_MS, (receipt) => receipt.workingDirectory === workingDirectory &&
receipt.scopeKey === scopeKey) ||
matchesCanonicalScope(receipt, canonicalScopeKey, scopeKey)) ||
isFresh(cliState["start"], SESSION_TTL_MS, (receipt) => receipt.workingDirectory === workingDirectory &&
receipt.scopeKey === scopeKey) ||
matchesCanonicalScope(receipt, canonicalScopeKey, scopeKey)) ||
isFresh(cliState["tour"], SESSION_TTL_MS, (receipt) => receipt.workingDirectory === workingDirectory &&
receipt.scopeKey === scopeKey);
matchesCanonicalScope(receipt, canonicalScopeKey, scopeKey));
if (!sessionReady) {
missingSteps.push("session-start");
}
// Preflight check: match on workingDirectory + engine only (not objective/verifier hash).
// Preflight check: match on workingDirectory + engine + execution bounds.
// The full hash match was too strict โ€” minor objective wording differences would break
// the receipt chain. The key governance signal is that preflight ran for this directory
// and engine recently; the exact objective text can drift between preflight and run.
// Path policy and budget are execution bounds, so changing them requires a fresh preflight.
const preflightReady = isFresh(cliState["preflight"], PREFLIGHT_TTL_MS, (receipt) => receipt.workingDirectory === workingDirectory &&
receipt.engine === engine);
receipt.engine === engine &&
receipt.verificationPlanKey === verificationPlanKey &&
receipt.pathScopeKey === pathScopeKey &&
(!budgetKey || receipt.budgetKey === budgetKey));
if (!preflightReady) {

@@ -162,3 +176,6 @@ missingSteps.push("preflight");

const labels = missingSteps.map((step) => step === "session-start" ? "session start" : step);
return `Governed run blocked until MartinLoop receipts exist for ${labels.join(", ")}. Next command: ${nextCommand}`;
const preflightReason = missingSteps.includes("preflight")
? " Preflight must be rerun when engine, verifier, path scope or budget changed."
: "";
return `Governed run blocked until MartinLoop receipts exist for ${labels.join(", ")}.${preflightReason} Next command: ${nextCommand}`;
}

@@ -214,2 +231,16 @@ async function readWorkflowState(runsRoot) {

}
function hashCanonicalReceiptScope(receiptScope) {
const normalized = {
workingDirectory: normalizeWorkingDirectory(receiptScope.workingDirectory ?? receiptScope.repoRoot ?? ""),
repoRoot: normalizeWorkingDirectory(receiptScope.repoRoot ?? receiptScope.workingDirectory ?? ""),
runsRoot: normalizeWorkingDirectory(receiptScope.runsRoot ?? "")
};
return createHash("sha256").update(JSON.stringify(normalized)).digest("hex").slice(0, 12);
}
function matchesCanonicalScope(receipt, canonicalScopeKey, exactScopeKey) {
if (receipt.canonicalScopeKey) {
return receipt.canonicalScopeKey === canonicalScopeKey;
}
return receipt.scopeKey === exactScopeKey;
}
function hashPathScope(allowedPaths, deniedPaths) {

@@ -216,0 +247,0 @@ const normalized = {

{
"name": "martin-loop",
"private": false,
"version": "0.4.2",
"version": "0.4.3",
"type": "module",

@@ -6,0 +6,0 @@ "description": "Open-source command center for governed AI coding agents with built-in onboarding, hard gates, MCP, and shareable run receipts.",

+11
-11

@@ -77,3 +77,3 @@ # MartinLoop

`start` prints the first-run guided path. `run` auto-checks `doctor`, `session-start`, and `preflight`, then executes when the environment is ready. Use `--proof` only when you intentionally want an explicit no-spend lane.
`start` prints the first-run guided path. `run` auto-checks `doctor`, `session-start`, and `preflight`, then executes when the environment is ready.

@@ -90,3 +90,3 @@ Inspect-first flow:

Release notes for the current root package: [MartinLoop 0.4.2](./docs/release/OSS-0.4.2-RELEASE-NOTES.md).
Release notes for the current root package: [MartinLoop 0.4.3](./docs/release/OSS-0.4.3-RELEASE-NOTES.md).

@@ -120,3 +120,3 @@ ## Visual Proof

```sh
npx -y martin-loop@latest run "Summarize the demo workspace and prove tests still pass" --proof --verify "npm test"
npx -y martin-loop@latest run "Summarize the demo workspace and prove tests still pass" --verify "npm test"
npx -y martin-loop@latest runs verify --latest

@@ -133,13 +133,13 @@ npx -y martin-loop@latest share --latest

```sh
npx -y martin-loop@0.4.2 --version
npx -y martin-loop@0.4.2 start
npx -y martin-loop@0.4.2 demo
npx -y martin-loop@0.4.3 --version
npx -y martin-loop@0.4.3 start
npx -y martin-loop@0.4.3 demo
cd martin-loop-demo
npm install
npx -y martin-loop@0.4.1 run "Summarize the demo workspace and prove tests still pass" --verify "npm test" --budget-usd 2 --max-iterations 1 --json
npx -y martin-loop@0.4.1 dossier --latest --json
npx -y martin-loop@0.4.1 share --latest --json
npx -y martin-loop@0.4.3 run "Summarize the demo workspace and prove tests still pass" --verify "npm test" --budget-usd 2 --max-iterations 1 --json
npx -y martin-loop@0.4.3 dossier --latest --json
npx -y martin-loop@0.4.3 share --latest --json
```
For deterministic installs, pin the package line (`martin-loop@0.4.1`) or use `martin-loop@latest`. Plain `npx martin-loop` can resolve a stale local cache on some machines.
For deterministic installs, pin the package line (`martin-loop@0.4.3`) or use `martin-loop@latest`. Plain `npx martin-loop` can resolve a stale local cache on some machines.

@@ -312,3 +312,3 @@ Default share bundle outputs:

The root `martin-loop` package and the standalone `@martinloop/mcp` package move on separate version lines. The current root package line here is `0.4.2`; the current standalone MCP source line is `0.3.7`, and the live npm baseline remains `0.3.6` until that standalone release is cut.
The root `martin-loop` package and the standalone `@martinloop/mcp` package move on separate version lines. The current root package line here is `0.4.3`; the current standalone MCP source line is `0.3.7`, and the live npm baseline is `0.3.7`.

@@ -315,0 +315,0 @@ The public MCP release train labels are:

# Benchmarks
This workspace contains deterministic benchmark suites used to evaluate governed agent execution and reproducibility.
Use `npx martin-loop bench --suite under-3-challenge` for the primary public benchmark lane.
# Demo Workspace
The `seeded-workspace` folder provides a disposable project for first-run guided demos and receipt walkthroughs.

Sorry, the diff of this file is too big to display