martin-loop 0.1.5 → 1.3.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/CODE_OF_CONDUCT.md +32 -0
- package/LICENSE +21 -21
- package/README.md +307 -398
- package/demo/seeded-workspace/README.md +35 -35
- package/demo/seeded-workspace/TASKS.md +29 -29
- package/demo/seeded-workspace/martin.config.yaml +11 -11
- package/demo/seeded-workspace/package.json +8 -8
- package/demo/seeded-workspace/src/invoice-summary.js +11 -11
- package/demo/seeded-workspace/test/invoice-summary.test.js +20 -20
- package/dist/bin/martin-loop.js +0 -0
- package/dist/vendor/adapters/counter.d.ts +1 -0
- package/dist/vendor/adapters/counter.js +4 -0
- package/dist/vendor/adapters/git-baseline.d.ts +50 -0
- package/dist/vendor/adapters/git-baseline.js +233 -0
- package/dist/vendor/adapters/openrouter-adapter.d.ts +15 -0
- package/dist/vendor/adapters/openrouter-adapter.js +302 -0
- package/dist/vendor/adapters/usage.d.ts +48 -0
- package/dist/vendor/adapters/usage.js +66 -0
- package/dist/vendor/cli/bin/exit.d.ts +12 -0
- package/dist/vendor/cli/bin/exit.js +28 -0
- package/dist/vendor/cli/commands/analyze.d.ts +5 -0
- package/dist/vendor/cli/commands/analyze.js +58 -0
- package/dist/vendor/cli/commands/audit-log-verify.d.ts +34 -0
- package/dist/vendor/cli/commands/audit-log-verify.js +99 -0
- package/dist/vendor/cli/commands/audit.d.ts +8 -0
- package/dist/vendor/cli/commands/audit.js +199 -0
- package/dist/vendor/cli/commands/corpus.d.ts +5 -0
- package/dist/vendor/cli/commands/corpus.js +60 -0
- package/dist/vendor/cli/commands/doctor.d.ts +8 -0
- package/dist/vendor/cli/commands/doctor.js +219 -0
- package/dist/vendor/cli/commands/explain.d.ts +17 -0
- package/dist/vendor/cli/commands/explain.js +176 -0
- package/dist/vendor/cli/commands/export.d.ts +5 -0
- package/dist/vendor/cli/commands/export.js +60 -0
- package/dist/vendor/cli/commands/governance.d.ts +8 -0
- package/dist/vendor/cli/commands/governance.js +95 -0
- package/dist/vendor/cli/commands/improve.d.ts +18 -0
- package/dist/vendor/cli/commands/improve.js +396 -0
- package/dist/vendor/cli/commands/init.d.ts +8 -0
- package/dist/vendor/cli/commands/init.js +281 -0
- package/dist/vendor/cli/commands/migration.d.ts +8 -0
- package/dist/vendor/cli/commands/migration.js +67 -0
- package/dist/vendor/cli/commands/prior.d.ts +23 -0
- package/dist/vendor/cli/commands/prior.js +145 -0
- package/dist/vendor/cli/commands/resume.d.ts +21 -0
- package/dist/vendor/cli/commands/resume.js +73 -0
- package/dist/vendor/cli/commands/verify.d.ts +6 -0
- package/dist/vendor/cli/commands/verify.js +43 -0
- package/dist/vendor/cli/research/public-corpus.d.ts +43 -0
- package/dist/vendor/cli/research/public-corpus.js +151 -0
- package/dist/vendor/cli/ui/error-card.d.ts +38 -0
- package/dist/vendor/cli/ui/error-card.js +103 -0
- package/dist/vendor/cli/ui/mission-brief.d.ts +41 -0
- package/dist/vendor/cli/ui/mission-brief.js +173 -0
- package/dist/vendor/cli/ui/summary-card.d.ts +34 -0
- package/dist/vendor/cli/ui/summary-card.js +102 -0
- package/dist/vendor/contracts/audit.d.ts +46 -0
- package/dist/vendor/contracts/audit.js +360 -0
- package/dist/vendor/contracts/post-phase15.d.ts +240 -0
- package/dist/vendor/contracts/post-phase15.js +166 -0
- package/dist/vendor/core/agent/mandates.d.ts +46 -0
- package/dist/vendor/core/agent/mandates.js +178 -0
- package/dist/vendor/core/agent/receipts.d.ts +38 -0
- package/dist/vendor/core/agent/receipts.js +131 -0
- package/dist/vendor/core/agent/signing.d.ts +17 -0
- package/dist/vendor/core/agent/signing.js +91 -0
- package/dist/vendor/core/attestation/sign.d.ts +25 -0
- package/dist/vendor/core/attestation/sign.js +216 -0
- package/dist/vendor/core/autonomy/autonomous-promotion.d.ts +120 -0
- package/dist/vendor/core/autonomy/autonomous-promotion.js +346 -0
- package/dist/vendor/core/autonomy/envelope-v2.d.ts +29 -0
- package/dist/vendor/core/autonomy/envelope-v2.js +60 -0
- package/dist/vendor/core/autonomy/envelope.d.ts +17 -0
- package/dist/vendor/core/autonomy/envelope.js +27 -0
- package/dist/vendor/core/autonomy/escalation-ledger.d.ts +20 -0
- package/dist/vendor/core/autonomy/escalation-ledger.js +18 -0
- package/dist/vendor/core/autonomy/resume.d.ts +15 -0
- package/dist/vendor/core/autonomy/resume.js +23 -0
- package/dist/vendor/core/circuit/circuit-breaker.d.ts +60 -0
- package/dist/vendor/core/circuit/circuit-breaker.js +143 -0
- package/dist/vendor/core/context-distillation.d.ts +3 -0
- package/dist/vendor/core/context-distillation.js +44 -0
- package/dist/vendor/core/context-flow/compile-context.d.ts +8 -0
- package/dist/vendor/core/context-flow/compile-context.js +111 -0
- package/dist/vendor/core/context-flow/entities.d.ts +2 -0
- package/dist/vendor/core/context-flow/entities.js +44 -0
- package/dist/vendor/core/context-flow/evaluate-policy.d.ts +2 -0
- package/dist/vendor/core/context-flow/evaluate-policy.js +42 -0
- package/dist/vendor/core/context-flow/index.d.ts +11 -0
- package/dist/vendor/core/context-flow/index.js +24 -0
- package/dist/vendor/core/context-flow/labels.d.ts +3 -0
- package/dist/vendor/core/context-flow/labels.js +17 -0
- package/dist/vendor/core/context-flow/normalizer.d.ts +9 -0
- package/dist/vendor/core/context-flow/normalizer.js +69 -0
- package/dist/vendor/core/context-flow/profiles.d.ts +33 -0
- package/dist/vendor/core/context-flow/profiles.js +36 -0
- package/dist/vendor/core/context-flow/redaction.d.ts +1 -0
- package/dist/vendor/core/context-flow/redaction.js +6 -0
- package/dist/vendor/core/context-flow/sensitivity.d.ts +2 -0
- package/dist/vendor/core/context-flow/sensitivity.js +27 -0
- package/dist/vendor/core/context-flow/sync-preview.d.ts +2 -0
- package/dist/vendor/core/context-flow/sync-preview.js +22 -0
- package/dist/vendor/core/context-flow/token-estimator.d.ts +3 -0
- package/dist/vendor/core/context-flow/token-estimator.js +13 -0
- package/dist/vendor/core/context-flow/types.d.ts +91 -0
- package/dist/vendor/core/context-flow/types.js +2 -0
- package/dist/vendor/core/context-utility.d.ts +47 -0
- package/dist/vendor/core/context-utility.js +405 -0
- package/dist/vendor/core/cost/pipeline.d.ts +92 -0
- package/dist/vendor/core/cost/pipeline.js +141 -0
- package/dist/vendor/core/cost/tagged-cost.d.ts +27 -0
- package/dist/vendor/core/cost/tagged-cost.js +55 -0
- package/dist/vendor/core/cost-governor.d.ts +2 -0
- package/dist/vendor/core/cost-governor.js +50 -0
- package/dist/vendor/core/cve/cve-check.d.ts +80 -0
- package/dist/vendor/core/cve/cve-check.js +172 -0
- package/dist/vendor/core/digital-twin/index.d.ts +27 -0
- package/dist/vendor/core/digital-twin/index.js +90 -0
- package/dist/vendor/core/drift/drift-graph.d.ts +47 -0
- package/dist/vendor/core/drift/drift-graph.js +100 -0
- package/dist/vendor/core/drift/objective-lock.d.ts +69 -0
- package/dist/vendor/core/drift/objective-lock.js +88 -0
- package/dist/vendor/core/drift/scope.d.ts +46 -0
- package/dist/vendor/core/drift/scope.js +102 -0
- package/dist/vendor/core/drift/signature-lock.d.ts +48 -0
- package/dist/vendor/core/drift/signature-lock.js +202 -0
- package/dist/vendor/core/drift/stale-proof-gate.d.ts +21 -0
- package/dist/vendor/core/drift/stale-proof-gate.js +19 -0
- package/dist/vendor/core/eval/known-bad-world-runner.d.ts +24 -0
- package/dist/vendor/core/eval/known-bad-world-runner.js +256 -0
- package/dist/vendor/core/evidence/claim-audit.d.ts +18 -0
- package/dist/vendor/core/evidence/claim-audit.js +89 -0
- package/dist/vendor/core/exit-intelligence.d.ts +2 -0
- package/dist/vendor/core/exit-intelligence.js +58 -0
- package/dist/vendor/core/explain/formatter.d.ts +42 -0
- package/dist/vendor/core/explain/formatter.js +171 -0
- package/dist/vendor/core/explain/timeline.d.ts +29 -0
- package/dist/vendor/core/explain/timeline.js +213 -0
- package/dist/vendor/core/failure-taxonomy.d.ts +2 -0
- package/dist/vendor/core/failure-taxonomy.js +76 -0
- package/dist/vendor/core/gateway/index.d.ts +10 -0
- package/dist/vendor/core/gateway/index.js +12 -0
- package/dist/vendor/core/gateway/registry.d.ts +40 -0
- package/dist/vendor/core/gateway/registry.js +97 -0
- package/dist/vendor/core/gateway/transport.d.ts +31 -0
- package/dist/vendor/core/gateway/transport.js +82 -0
- package/dist/vendor/core/gateway/vault.d.ts +19 -0
- package/dist/vendor/core/gateway/vault.js +29 -0
- package/dist/vendor/core/graph/adapters.d.ts +43 -0
- package/dist/vendor/core/graph/adapters.js +91 -0
- package/dist/vendor/core/graph/hotspots.d.ts +22 -0
- package/dist/vendor/core/graph/hotspots.js +30 -0
- package/dist/vendor/core/graph/index.d.ts +1 -0
- package/dist/vendor/core/graph/index.js +2 -0
- package/dist/vendor/core/honey/honey-tokens.d.ts +32 -0
- package/dist/vendor/core/honey/honey-tokens.js +44 -0
- package/dist/vendor/core/index.d.ts +2 -2
- package/dist/vendor/core/index.js +38 -12
- package/dist/vendor/core/learning/bayesian-update.d.ts +31 -0
- package/dist/vendor/core/learning/bayesian-update.js +60 -0
- package/dist/vendor/core/learning/prior-sets.d.ts +42 -0
- package/dist/vendor/core/learning/prior-sets.js +111 -0
- package/dist/vendor/core/learning/promotion-gate.d.ts +17 -0
- package/dist/vendor/core/learning/promotion-gate.js +23 -0
- package/dist/vendor/core/leash/blast-radius.d.ts +42 -0
- package/dist/vendor/core/leash/blast-radius.js +156 -0
- package/dist/vendor/core/leash/policy-leash.d.ts +31 -0
- package/dist/vendor/core/leash/policy-leash.js +117 -0
- package/dist/vendor/core/memo/memo.d.ts +63 -0
- package/dist/vendor/core/memo/memo.js +97 -0
- package/dist/vendor/core/memory/learning-pipeline.d.ts +154 -0
- package/dist/vendor/core/memory/learning-pipeline.js +391 -0
- package/dist/vendor/core/memory/palace.d.ts +84 -0
- package/dist/vendor/core/memory/palace.js +379 -0
- package/dist/vendor/core/merge/ast-merge.d.ts +22 -0
- package/dist/vendor/core/merge/ast-merge.js +350 -0
- package/dist/vendor/core/merge/text-merge.d.ts +12 -0
- package/dist/vendor/core/merge/text-merge.js +182 -0
- package/dist/vendor/core/otel/tracer.d.ts +45 -0
- package/dist/vendor/core/otel/tracer.js +116 -0
- package/dist/vendor/core/parallel/parallel-attempts.d.ts +28 -0
- package/dist/vendor/core/parallel/parallel-attempts.js +41 -0
- package/dist/vendor/core/parallel/scorer.d.ts +24 -0
- package/dist/vendor/core/parallel/scorer.js +65 -0
- package/dist/vendor/core/pattern-detection.d.ts +64 -0
- package/dist/vendor/core/pattern-detection.js +108 -0
- package/dist/vendor/core/persistence/checkpoint.d.ts +44 -0
- package/dist/vendor/core/persistence/checkpoint.js +156 -0
- package/dist/vendor/core/persistence/cleanup.d.ts +22 -0
- package/dist/vendor/core/persistence/cleanup.js +131 -0
- package/dist/vendor/core/persistence/index.d.ts +2 -0
- package/dist/vendor/core/persistence/index.js +1 -0
- package/dist/vendor/core/persistence/runs-reader.d.ts +52 -0
- package/dist/vendor/core/persistence/runs-reader.js +84 -0
- package/dist/vendor/core/persistence/store.d.ts +6 -1
- package/dist/vendor/core/persistence/store.js +5 -0
- package/dist/vendor/core/policy/file-touch-quota.d.ts +60 -0
- package/dist/vendor/core/policy/file-touch-quota.js +105 -0
- package/dist/vendor/core/policy/policy-loader.d.ts +30 -0
- package/dist/vendor/core/policy/policy-loader.js +170 -0
- package/dist/vendor/core/policy/policy-schema.d.ts +55 -0
- package/dist/vendor/core/policy/policy-schema.js +78 -0
- package/dist/vendor/core/probe/probe.d.ts +49 -0
- package/dist/vendor/core/probe/probe.js +115 -0
- package/dist/vendor/core/proof/patch-proof.d.ts +58 -0
- package/dist/vendor/core/proof/patch-proof.js +84 -0
- package/dist/vendor/core/proof/semantic-probe.d.ts +25 -0
- package/dist/vendor/core/proof/semantic-probe.js +82 -0
- package/dist/vendor/core/recovery/failure-mode-runner.d.ts +29 -0
- package/dist/vendor/core/recovery/failure-mode-runner.js +39 -0
- package/dist/vendor/core/red-blue/red-phase.d.ts +64 -0
- package/dist/vendor/core/red-blue/red-phase.js +141 -0
- package/dist/vendor/core/red-blue/risk-tiers.d.ts +22 -0
- package/dist/vendor/core/red-blue/risk-tiers.js +33 -0
- package/dist/vendor/core/replay/replay.d.ts +85 -0
- package/dist/vendor/core/replay/replay.js +109 -0
- package/dist/vendor/core/router/engine.d.ts +54 -0
- package/dist/vendor/core/router/engine.js +131 -0
- package/dist/vendor/core/router/index.d.ts +1 -0
- package/dist/vendor/core/router/index.js +2 -0
- package/dist/vendor/core/router/trust-calibration.d.ts +57 -0
- package/dist/vendor/core/router/trust-calibration.js +127 -0
- package/dist/vendor/core/run-martin.d.ts +2 -0
- package/dist/vendor/core/run-martin.js +287 -0
- package/dist/vendor/core/security/cve-scanner.d.ts +62 -0
- package/dist/vendor/core/security/cve-scanner.js +178 -0
- package/dist/vendor/core/sentinel/efficiency-sentinel.d.ts +29 -0
- package/dist/vendor/core/sentinel/efficiency-sentinel.js +30 -0
- package/dist/vendor/core/sentinel/progress-guard.d.ts +35 -0
- package/dist/vendor/core/sentinel/progress-guard.js +46 -0
- package/dist/vendor/core/siem/siem-emitter.d.ts +49 -0
- package/dist/vendor/core/siem/siem-emitter.js +157 -0
- package/dist/vendor/core/strategy/attempt-brief.d.ts +22 -0
- package/dist/vendor/core/strategy/attempt-brief.js +89 -0
- package/dist/vendor/core/summarize/diff-summary.d.ts +35 -0
- package/dist/vendor/core/summarize/diff-summary.js +204 -0
- package/dist/vendor/core/surface-signals.d.ts +21 -0
- package/dist/vendor/core/surface-signals.js +139 -0
- package/dist/vendor/core/truth/truth-wall.d.ts +51 -0
- package/dist/vendor/core/truth/truth-wall.js +69 -0
- package/dist/vendor/core/truth-spine.d.ts +26 -0
- package/dist/vendor/core/truth-spine.js +62 -0
- package/dist/vendor/core/types.d.ts +115 -0
- package/dist/vendor/core/types.js +2 -0
- package/dist/vendor/core/verification/tiered-verify.d.ts +17 -0
- package/dist/vendor/core/verification/tiered-verify.js +29 -0
- package/dist/vendor/core/verifier-pyramid.d.ts +32 -0
- package/dist/vendor/core/verifier-pyramid.js +111 -0
- package/dist/vendor/core/workflow-artifacts.d.ts +99 -0
- package/dist/vendor/core/workflow-artifacts.js +668 -0
- package/dist/vendor/core/wrap/supervised-run.d.ts +96 -0
- package/dist/vendor/core/wrap/supervised-run.js +178 -0
- package/docs/assets/cli-animated.svg +139 -0
- package/docs/assets/cli-static.svg +34 -0
- package/docs/assets/github-hero-v2.svg +23 -0
- package/docs/assets/martin-raplph.png.jpg +0 -0
- package/docs/assets/martinloop-logo.png +0 -0
- package/docs/assets/nvidia-inception-program-light.png +0 -0
- package/docs/assets/nvidia-inception-program.png +0 -0
- package/docs/assets/phase3c-sidesidebyside-demo.html +228 -0
- package/docs/assets/side-by-side.svg +134 -0
- package/docs/oss/CLAUDE-CODE-WALKTHROUGH.md +142 -142
- package/docs/oss/EXAMPLES.md +134 -134
- package/docs/oss/OSS-BOUNDARY-REPORT.json +1 -1
- package/docs/oss/OSS-BOUNDARY-REPORT.md +1 -1
- package/docs/oss/QUICKSTART.md +170 -165
- package/docs/oss/RALPH-LOOP-SAFETY.md +113 -113
- package/docs/oss/README.md +96 -96
- package/docs/oss/RELEASE-SURFACE-REPORT.json +2 -1
- package/docs/oss/RELEASE-SURFACE-REPORT.md +2 -1
- package/package.json +130 -58
- package/docs/distribution/DIRECTORY-SUBMISSIONS.md +0 -89
- package/docs/distribution/INTEGRATION-OUTREACH.md +0 -61
- package/docs/distribution/UNDER-3-CHALLENGE.md +0 -65
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
# MartinLoop Demo Sandbox
|
|
2
|
-
|
|
3
|
-
This workspace is the safe public demo copied by `martin-loop demo`.
|
|
4
|
-
|
|
5
|
-
It is intentionally small:
|
|
6
|
-
|
|
7
|
-
- `npm test` is green out of the box
|
|
8
|
-
- `martin.config.yaml` keeps the budget tiny
|
|
9
|
-
- the first suggested MartinLoop run can stay in stub mode with `MARTIN_LIVE=false`
|
|
10
|
-
|
|
11
|
-
## Files
|
|
12
|
-
|
|
13
|
-
- `src/invoice-summary.js`: tiny module used by the demo task
|
|
14
|
-
- `test/invoice-summary.test.js`: Node test suite
|
|
15
|
-
- `TASKS.md`: suggested objectives for a stub-safe run or a live adapter run
|
|
16
|
-
- `martin.config.yaml`: low-risk governance defaults
|
|
17
|
-
|
|
18
|
-
## Suggested flow
|
|
19
|
-
|
|
20
|
-
```sh
|
|
21
|
-
npm install
|
|
22
|
-
npm test
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Safe first run:
|
|
26
|
-
|
|
27
|
-
```sh
|
|
28
|
-
MARTIN_LIVE=false npx martin-loop run "Summarize the demo workspace and confirm the verifier is green" --verify "npm test"
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Optional live run:
|
|
32
|
-
|
|
33
|
-
```sh
|
|
34
|
-
npx martin-loop run "Add support for a discount percentage to summarizeInvoice and update the tests" --verify "npm test" --engine codex
|
|
35
|
-
```
|
|
1
|
+
# MartinLoop Demo Sandbox
|
|
2
|
+
|
|
3
|
+
This workspace is the safe public demo copied by `martin-loop demo`.
|
|
4
|
+
|
|
5
|
+
It is intentionally small:
|
|
6
|
+
|
|
7
|
+
- `npm test` is green out of the box
|
|
8
|
+
- `martin.config.yaml` keeps the budget tiny
|
|
9
|
+
- the first suggested MartinLoop run can stay in stub mode with `MARTIN_LIVE=false`
|
|
10
|
+
|
|
11
|
+
## Files
|
|
12
|
+
|
|
13
|
+
- `src/invoice-summary.js`: tiny module used by the demo task
|
|
14
|
+
- `test/invoice-summary.test.js`: Node test suite
|
|
15
|
+
- `TASKS.md`: suggested objectives for a stub-safe run or a live adapter run
|
|
16
|
+
- `martin.config.yaml`: low-risk governance defaults
|
|
17
|
+
|
|
18
|
+
## Suggested flow
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
npm install
|
|
22
|
+
npm test
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Safe first run:
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
MARTIN_LIVE=false npx martin-loop run "Summarize the demo workspace and confirm the verifier is green" --verify "npm test"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Optional live run:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
npx martin-loop run "Add support for a discount percentage to summarizeInvoice and update the tests" --verify "npm test" --engine codex
|
|
35
|
+
```
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
# Suggested Demo Tasks
|
|
2
|
-
|
|
3
|
-
## Stub-safe first run
|
|
4
|
-
|
|
5
|
-
Use this when you want to see MartinLoop create a governed run record without spending provider budget:
|
|
6
|
-
|
|
7
|
-
```text
|
|
8
|
-
Summarize the demo workspace, confirm the verifier command is green, and explain the safest next change to make.
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Verifier:
|
|
12
|
-
|
|
13
|
-
```sh
|
|
14
|
-
npm test
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Optional live run
|
|
18
|
-
|
|
19
|
-
Use this when you want a real coding task in the sandbox:
|
|
20
|
-
|
|
21
|
-
```text
|
|
22
|
-
Add support for a discount percentage to summarizeInvoice and update the tests while keeping the existing tax behavior intact.
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Verifier:
|
|
26
|
-
|
|
27
|
-
```sh
|
|
28
|
-
npm test
|
|
29
|
-
```
|
|
1
|
+
# Suggested Demo Tasks
|
|
2
|
+
|
|
3
|
+
## Stub-safe first run
|
|
4
|
+
|
|
5
|
+
Use this when you want to see MartinLoop create a governed run record without spending provider budget:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
Summarize the demo workspace, confirm the verifier command is green, and explain the safest next change to make.
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Verifier:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm test
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Optional live run
|
|
18
|
+
|
|
19
|
+
Use this when you want a real coding task in the sandbox:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
Add support for a discount percentage to summarizeInvoice and update the tests while keeping the existing tax behavior intact.
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Verifier:
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
npm test
|
|
29
|
+
```
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
policyProfile: strict_local
|
|
2
|
-
budget:
|
|
3
|
-
maxUsd: 2
|
|
4
|
-
softLimitUsd: 1
|
|
5
|
-
maxIterations: 2
|
|
6
|
-
maxTokens: 12000
|
|
7
|
-
governance:
|
|
8
|
-
destructiveActionPolicy: approval
|
|
9
|
-
telemetryDestination: local-only
|
|
10
|
-
verifierRules:
|
|
11
|
-
- npm test
|
|
1
|
+
policyProfile: strict_local
|
|
2
|
+
budget:
|
|
3
|
+
maxUsd: 2
|
|
4
|
+
softLimitUsd: 1
|
|
5
|
+
maxIterations: 2
|
|
6
|
+
maxTokens: 12000
|
|
7
|
+
governance:
|
|
8
|
+
destructiveActionPolicy: approval
|
|
9
|
+
telemetryDestination: local-only
|
|
10
|
+
verifierRules:
|
|
11
|
+
- npm test
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "martin-loop-demo-sandbox",
|
|
3
|
-
"private": true,
|
|
4
|
-
"type": "module",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"test": "node --test"
|
|
7
|
-
}
|
|
8
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "martin-loop-demo-sandbox",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "node --test"
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export function summarizeInvoice(items, taxRate = 0) {
|
|
2
|
-
const subtotal = items.reduce((sum, item) => sum + item.quantity * item.unitPrice, 0);
|
|
3
|
-
const tax = Number((subtotal * taxRate).toFixed(2));
|
|
4
|
-
const total = Number((subtotal + tax).toFixed(2));
|
|
5
|
-
|
|
6
|
-
return {
|
|
7
|
-
subtotal: Number(subtotal.toFixed(2)),
|
|
8
|
-
tax,
|
|
9
|
-
total
|
|
10
|
-
};
|
|
11
|
-
}
|
|
1
|
+
export function summarizeInvoice(items, taxRate = 0) {
|
|
2
|
+
const subtotal = items.reduce((sum, item) => sum + item.quantity * item.unitPrice, 0);
|
|
3
|
+
const tax = Number((subtotal * taxRate).toFixed(2));
|
|
4
|
+
const total = Number((subtotal + tax).toFixed(2));
|
|
5
|
+
|
|
6
|
+
return {
|
|
7
|
+
subtotal: Number(subtotal.toFixed(2)),
|
|
8
|
+
tax,
|
|
9
|
+
total
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import test from "node:test";
|
|
2
|
-
import assert from "node:assert/strict";
|
|
3
|
-
|
|
4
|
-
import { summarizeInvoice } from "../src/invoice-summary.js";
|
|
5
|
-
|
|
6
|
-
test("summarizeInvoice returns subtotal, tax, and total", () => {
|
|
7
|
-
const result = summarizeInvoice(
|
|
8
|
-
[
|
|
9
|
-
{ quantity: 2, unitPrice: 19.99 },
|
|
10
|
-
{ quantity: 1, unitPrice: 5.5 }
|
|
11
|
-
],
|
|
12
|
-
0.13
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
assert.deepEqual(result, {
|
|
16
|
-
subtotal: 45.48,
|
|
17
|
-
tax: 5.91,
|
|
18
|
-
total: 51.39
|
|
19
|
-
});
|
|
20
|
-
});
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
|
|
4
|
+
import { summarizeInvoice } from "../src/invoice-summary.js";
|
|
5
|
+
|
|
6
|
+
test("summarizeInvoice returns subtotal, tax, and total", () => {
|
|
7
|
+
const result = summarizeInvoice(
|
|
8
|
+
[
|
|
9
|
+
{ quantity: 2, unitPrice: 19.99 },
|
|
10
|
+
{ quantity: 1, unitPrice: 5.5 }
|
|
11
|
+
],
|
|
12
|
+
0.13
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
assert.deepEqual(result, {
|
|
16
|
+
subtotal: 45.48,
|
|
17
|
+
tax: 5.91,
|
|
18
|
+
total: 51.39
|
|
19
|
+
});
|
|
20
|
+
});
|
package/dist/bin/martin-loop.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function calculateIndex(): number;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { MartinAdapterResult } from "../core/index.js";
|
|
2
|
+
import { type SpawnLike } from "./cli-bridge.js";
|
|
3
|
+
type DiffStats = NonNullable<NonNullable<MartinAdapterResult["execution"]>["diffStats"]>;
|
|
4
|
+
export interface GitBaselineArtifact {
|
|
5
|
+
startHeadSha: string;
|
|
6
|
+
startTrackedStatus: string;
|
|
7
|
+
startTrackedSet: string[];
|
|
8
|
+
startTrackedDiffSha256: Record<string, string>;
|
|
9
|
+
startUntrackedSet: string[];
|
|
10
|
+
startTimestamp: string;
|
|
11
|
+
worktreeClean: boolean;
|
|
12
|
+
pilotRepoClass: string | null;
|
|
13
|
+
}
|
|
14
|
+
export interface GitNormalizationArtifact {
|
|
15
|
+
startHeadSha: string;
|
|
16
|
+
endHeadShaBeforeNormalization: string;
|
|
17
|
+
normalizationApplied: boolean;
|
|
18
|
+
normalizationMode: "reset_mixed_to_start_head" | "none";
|
|
19
|
+
normalizationSucceeded: boolean;
|
|
20
|
+
headAfterNormalization: string;
|
|
21
|
+
}
|
|
22
|
+
export interface ScopeSurfaceArtifact {
|
|
23
|
+
trackedChangedPaths: string[];
|
|
24
|
+
deletedPaths: string[];
|
|
25
|
+
newUntrackedPaths: string[];
|
|
26
|
+
allChangedPaths: string[];
|
|
27
|
+
changedBaselinePaths: string[];
|
|
28
|
+
baselineWasClean: boolean;
|
|
29
|
+
noCodeChange: boolean;
|
|
30
|
+
diffStats?: DiffStats;
|
|
31
|
+
}
|
|
32
|
+
export declare function captureBaseline(options: {
|
|
33
|
+
repoRoot: string;
|
|
34
|
+
timeoutMs: number;
|
|
35
|
+
spawnImpl?: SpawnLike;
|
|
36
|
+
pilotRepoClass?: string | null;
|
|
37
|
+
}): Promise<GitBaselineArtifact>;
|
|
38
|
+
export declare function normalizeAdapterGitState(options: {
|
|
39
|
+
repoRoot: string;
|
|
40
|
+
baseline: GitBaselineArtifact;
|
|
41
|
+
timeoutMs: number;
|
|
42
|
+
spawnImpl?: SpawnLike;
|
|
43
|
+
}): Promise<GitNormalizationArtifact>;
|
|
44
|
+
export declare function collectScopeSurface(options: {
|
|
45
|
+
repoRoot: string;
|
|
46
|
+
baseline: GitBaselineArtifact;
|
|
47
|
+
timeoutMs: number;
|
|
48
|
+
spawnImpl?: SpawnLike;
|
|
49
|
+
}): Promise<ScopeSurfaceArtifact>;
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { runSubprocess } from "./cli-bridge.js";
|
|
3
|
+
import { diffStatsFromNumstat } from "./runtime-support.js";
|
|
4
|
+
export async function captureBaseline(options) {
|
|
5
|
+
const [startHeadSha, startTrackedStatus, startUntrackedSet] = await Promise.all([
|
|
6
|
+
readRequiredScalar(options.repoRoot, ["rev-parse", "HEAD"], options.timeoutMs, options.spawnImpl),
|
|
7
|
+
readOptionalStdout(options.repoRoot, ["status", "--porcelain=v1", "--untracked-files=no"], options.timeoutMs, options.spawnImpl),
|
|
8
|
+
readLines(options.repoRoot, ["ls-files", "--others", "--exclude-standard"], options.timeoutMs, options.spawnImpl)
|
|
9
|
+
]);
|
|
10
|
+
const startTrackedSet = parsePorcelainTrackedPaths(startTrackedStatus);
|
|
11
|
+
const startTrackedDiffSha256 = await collectPathDiffHashes({
|
|
12
|
+
repoRoot: options.repoRoot,
|
|
13
|
+
baseRef: startHeadSha,
|
|
14
|
+
paths: startTrackedSet,
|
|
15
|
+
timeoutMs: options.timeoutMs,
|
|
16
|
+
spawnImpl: options.spawnImpl
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
startHeadSha,
|
|
20
|
+
startTrackedStatus,
|
|
21
|
+
startTrackedSet,
|
|
22
|
+
startTrackedDiffSha256,
|
|
23
|
+
startUntrackedSet,
|
|
24
|
+
startTimestamp: new Date().toISOString(),
|
|
25
|
+
worktreeClean: startTrackedStatus.trim().length === 0 && startUntrackedSet.length === 0,
|
|
26
|
+
pilotRepoClass: options.pilotRepoClass ?? null
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export async function normalizeAdapterGitState(options) {
|
|
30
|
+
const endHeadShaBeforeNormalization = await readRequiredScalar(options.repoRoot, ["rev-parse", "HEAD"], options.timeoutMs, options.spawnImpl);
|
|
31
|
+
const normalizationApplied = endHeadShaBeforeNormalization !== options.baseline.startHeadSha;
|
|
32
|
+
if (!normalizationApplied) {
|
|
33
|
+
return {
|
|
34
|
+
startHeadSha: options.baseline.startHeadSha,
|
|
35
|
+
endHeadShaBeforeNormalization,
|
|
36
|
+
normalizationApplied: false,
|
|
37
|
+
normalizationMode: "none",
|
|
38
|
+
normalizationSucceeded: true,
|
|
39
|
+
headAfterNormalization: endHeadShaBeforeNormalization
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const resetResult = await runSubprocess("git", ["reset", "--mixed", options.baseline.startHeadSha], {
|
|
43
|
+
cwd: options.repoRoot,
|
|
44
|
+
timeoutMs: options.timeoutMs,
|
|
45
|
+
spawnImpl: options.spawnImpl
|
|
46
|
+
});
|
|
47
|
+
const headAfterNormalization = resetResult.exitCode === 0
|
|
48
|
+
? await readRequiredScalar(options.repoRoot, ["rev-parse", "HEAD"], options.timeoutMs, options.spawnImpl)
|
|
49
|
+
: endHeadShaBeforeNormalization;
|
|
50
|
+
return {
|
|
51
|
+
startHeadSha: options.baseline.startHeadSha,
|
|
52
|
+
endHeadShaBeforeNormalization,
|
|
53
|
+
normalizationApplied: true,
|
|
54
|
+
normalizationMode: "reset_mixed_to_start_head",
|
|
55
|
+
normalizationSucceeded: resetResult.exitCode === 0 && headAfterNormalization === options.baseline.startHeadSha,
|
|
56
|
+
headAfterNormalization
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export async function collectScopeSurface(options) {
|
|
60
|
+
const [nameStatusResult, numstatResult, endUntrackedSet] = await Promise.all([
|
|
61
|
+
runSubprocess("git", ["diff", "--name-status", "--no-renames", options.baseline.startHeadSha], {
|
|
62
|
+
cwd: options.repoRoot,
|
|
63
|
+
timeoutMs: options.timeoutMs,
|
|
64
|
+
spawnImpl: options.spawnImpl
|
|
65
|
+
}),
|
|
66
|
+
runSubprocess("git", ["diff", "--numstat", "--no-renames", options.baseline.startHeadSha], {
|
|
67
|
+
cwd: options.repoRoot,
|
|
68
|
+
timeoutMs: options.timeoutMs,
|
|
69
|
+
spawnImpl: options.spawnImpl
|
|
70
|
+
}),
|
|
71
|
+
readLines(options.repoRoot, ["ls-files", "--others", "--exclude-standard"], options.timeoutMs, options.spawnImpl)
|
|
72
|
+
]);
|
|
73
|
+
const trackedChangedPaths = [];
|
|
74
|
+
const deletedPaths = [];
|
|
75
|
+
const changedBaselinePaths = [];
|
|
76
|
+
const seenTracked = new Set();
|
|
77
|
+
const seenDeleted = new Set();
|
|
78
|
+
const baselineTracked = new Set(options.baseline.startTrackedSet.map(normalizeGitPath));
|
|
79
|
+
const candidateTrackedPaths = [];
|
|
80
|
+
if (nameStatusResult.exitCode === 0) {
|
|
81
|
+
for (const rawLine of splitLines(nameStatusResult.stdout)) {
|
|
82
|
+
const parts = rawLine.split(/\t+/u).map((entry) => normalizeGitPath(entry));
|
|
83
|
+
const status = parts[0]?.trim() ?? "";
|
|
84
|
+
const candidatePath = parts.at(-1);
|
|
85
|
+
if (!status || !candidatePath) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (status.startsWith("D")) {
|
|
89
|
+
candidateTrackedPaths.push({ path: candidatePath, deleted: true });
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
candidateTrackedPaths.push({ path: candidatePath, deleted: false });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const endTrackedDiffSha256 = await collectPathDiffHashes({
|
|
96
|
+
repoRoot: options.repoRoot,
|
|
97
|
+
baseRef: options.baseline.startHeadSha,
|
|
98
|
+
paths: candidateTrackedPaths.map((candidate) => candidate.path),
|
|
99
|
+
timeoutMs: options.timeoutMs,
|
|
100
|
+
spawnImpl: options.spawnImpl
|
|
101
|
+
});
|
|
102
|
+
for (const candidate of candidateTrackedPaths) {
|
|
103
|
+
const baselineHash = options.baseline.startTrackedDiffSha256[candidate.path];
|
|
104
|
+
const endHash = endTrackedDiffSha256[candidate.path];
|
|
105
|
+
const changedSinceBaseline = !baselineTracked.has(candidate.path) ||
|
|
106
|
+
baselineHash === undefined ||
|
|
107
|
+
endHash === undefined ||
|
|
108
|
+
baselineHash !== endHash;
|
|
109
|
+
if (!changedSinceBaseline) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (baselineTracked.has(candidate.path)) {
|
|
113
|
+
changedBaselinePaths.push(candidate.path);
|
|
114
|
+
}
|
|
115
|
+
if (candidate.deleted) {
|
|
116
|
+
if (!seenDeleted.has(candidate.path)) {
|
|
117
|
+
seenDeleted.add(candidate.path);
|
|
118
|
+
deletedPaths.push(candidate.path);
|
|
119
|
+
}
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (!seenTracked.has(candidate.path)) {
|
|
123
|
+
seenTracked.add(candidate.path);
|
|
124
|
+
trackedChangedPaths.push(candidate.path);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const startingUntracked = new Set(options.baseline.startUntrackedSet.map(normalizeGitPath));
|
|
128
|
+
const newUntrackedPaths = endUntrackedSet
|
|
129
|
+
.map(normalizeGitPath)
|
|
130
|
+
.filter((entry) => !startingUntracked.has(entry));
|
|
131
|
+
const allChangedPaths = uniquePaths([
|
|
132
|
+
...trackedChangedPaths,
|
|
133
|
+
...deletedPaths,
|
|
134
|
+
...newUntrackedPaths
|
|
135
|
+
]);
|
|
136
|
+
const diffStats = allChangedPaths.length > 0
|
|
137
|
+
? await collectDiffStats({
|
|
138
|
+
repoRoot: options.repoRoot,
|
|
139
|
+
baseRef: options.baseline.startHeadSha,
|
|
140
|
+
paths: allChangedPaths,
|
|
141
|
+
fallbackStdout: numstatResult.stdout,
|
|
142
|
+
fallbackExitCode: numstatResult.exitCode,
|
|
143
|
+
timeoutMs: options.timeoutMs,
|
|
144
|
+
spawnImpl: options.spawnImpl
|
|
145
|
+
})
|
|
146
|
+
: undefined;
|
|
147
|
+
return {
|
|
148
|
+
trackedChangedPaths,
|
|
149
|
+
deletedPaths,
|
|
150
|
+
newUntrackedPaths,
|
|
151
|
+
allChangedPaths,
|
|
152
|
+
changedBaselinePaths: uniquePaths(changedBaselinePaths),
|
|
153
|
+
baselineWasClean: options.baseline.worktreeClean,
|
|
154
|
+
noCodeChange: allChangedPaths.length === 0,
|
|
155
|
+
...(diffStats ? { diffStats } : {})
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function uniquePaths(paths) {
|
|
159
|
+
return [...new Set(paths.map(normalizeGitPath).filter(Boolean))];
|
|
160
|
+
}
|
|
161
|
+
function splitLines(stdout) {
|
|
162
|
+
return stdout
|
|
163
|
+
.split(/\r?\n/u)
|
|
164
|
+
.map((line) => line.trim())
|
|
165
|
+
.filter(Boolean);
|
|
166
|
+
}
|
|
167
|
+
function parsePorcelainTrackedPaths(status) {
|
|
168
|
+
const paths = [];
|
|
169
|
+
for (const line of status.split(/\r?\n/u).filter(Boolean)) {
|
|
170
|
+
const code = line.slice(0, 2);
|
|
171
|
+
if (code === "??" || code === "!!") {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
const rawPath = line.slice(3).trim();
|
|
175
|
+
if (!rawPath) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
for (const path of rawPath.split(" -> ")) {
|
|
179
|
+
paths.push(path);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return uniquePaths(paths);
|
|
183
|
+
}
|
|
184
|
+
async function collectPathDiffHashes(options) {
|
|
185
|
+
const hashes = {};
|
|
186
|
+
for (const path of uniquePaths(options.paths)) {
|
|
187
|
+
const result = await runSubprocess("git", ["diff", "--binary", options.baseRef, "--", path], {
|
|
188
|
+
cwd: options.repoRoot,
|
|
189
|
+
timeoutMs: options.timeoutMs,
|
|
190
|
+
spawnImpl: options.spawnImpl
|
|
191
|
+
});
|
|
192
|
+
hashes[path] = sha256Text(JSON.stringify({
|
|
193
|
+
stdout: result.stdout,
|
|
194
|
+
stderr: result.exitCode === 0 ? "" : result.stderr,
|
|
195
|
+
exitCode: result.exitCode
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
return hashes;
|
|
199
|
+
}
|
|
200
|
+
async function collectDiffStats(options) {
|
|
201
|
+
const result = await runSubprocess("git", ["diff", "--numstat", "--no-renames", options.baseRef, "--", ...uniquePaths(options.paths)], {
|
|
202
|
+
cwd: options.repoRoot,
|
|
203
|
+
timeoutMs: options.timeoutMs,
|
|
204
|
+
spawnImpl: options.spawnImpl
|
|
205
|
+
});
|
|
206
|
+
if (result.exitCode === 0) {
|
|
207
|
+
return diffStatsFromNumstat(result.stdout);
|
|
208
|
+
}
|
|
209
|
+
return options.fallbackExitCode === 0 ? diffStatsFromNumstat(options.fallbackStdout) : undefined;
|
|
210
|
+
}
|
|
211
|
+
function normalizeGitPath(path) {
|
|
212
|
+
return path.replace(/\\/gu, "/").trim();
|
|
213
|
+
}
|
|
214
|
+
function sha256Text(value) {
|
|
215
|
+
return createHash("sha256").update(value).digest("hex");
|
|
216
|
+
}
|
|
217
|
+
async function readRequiredScalar(repoRoot, args, timeoutMs, spawnImpl) {
|
|
218
|
+
const result = await runSubprocess("git", args, { cwd: repoRoot, timeoutMs, spawnImpl });
|
|
219
|
+
if (result.exitCode !== 0) {
|
|
220
|
+
const detail = result.stderr.trim() || result.stdout.trim() || args.join(" ");
|
|
221
|
+
throw new Error(`Git baseline command failed: ${detail}`);
|
|
222
|
+
}
|
|
223
|
+
return result.stdout.trim();
|
|
224
|
+
}
|
|
225
|
+
async function readOptionalStdout(repoRoot, args, timeoutMs, spawnImpl) {
|
|
226
|
+
const result = await runSubprocess("git", args, { cwd: repoRoot, timeoutMs, spawnImpl });
|
|
227
|
+
return result.exitCode === 0 ? result.stdout : "";
|
|
228
|
+
}
|
|
229
|
+
async function readLines(repoRoot, args, timeoutMs, spawnImpl) {
|
|
230
|
+
const result = await runSubprocess("git", args, { cwd: repoRoot, timeoutMs, spawnImpl });
|
|
231
|
+
return result.exitCode === 0 ? splitLines(result.stdout) : [];
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=git-baseline.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRouter Adapter — real LLM-backed coding agent via OpenRouter API.
|
|
3
|
+
*
|
|
4
|
+
* Uses function-calling (tool use) to give the LLM read_file, write_file,
|
|
5
|
+
* and run_command tools. Loops until verification passes or max turns reached.
|
|
6
|
+
*
|
|
7
|
+
* Compatible with any OpenRouter model that supports function calling:
|
|
8
|
+
* openai/gpt-4o, openai/gpt-4o-mini, anthropic/claude-3.5-sonnet, etc.
|
|
9
|
+
*/
|
|
10
|
+
import type { MartinAdapter } from "../core/index.js";
|
|
11
|
+
export declare function createOpenRouterAdapter(options: {
|
|
12
|
+
apiKey: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
maxTurns?: number;
|
|
15
|
+
}): MartinAdapter;
|