@martinloop/mcp 0.8.9 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/server-validation.js +2 -3
- package/dist/server.d.ts +1 -0
- package/dist/server.js +181 -24
- package/dist/tools/get-status.d.ts +3 -0
- package/dist/tools/get-status.js +11 -2
- package/dist/tools/logs.d.ts +2 -0
- package/dist/tools/logs.js +25 -3
- package/dist/tools/run-controls.d.ts +51 -6
- package/dist/tools/run-controls.js +905 -35
- package/dist/tools/run-loop.js +7 -0
- package/dist/vendor/adapters/process-supervisor.d.ts +12 -0
- package/dist/vendor/adapters/process-supervisor.js +40 -2
- package/dist/vendor/adapters/verifier-only.js +4 -0
- package/dist/vendor/contracts/index.d.ts +8 -0
- package/dist/vendor/contracts/index.js +1 -0
- package/dist/vendor/contracts/swarm-timing.d.ts +7 -0
- package/dist/vendor/contracts/swarm-timing.js +22 -0
- package/dist/vendor/core/index.d.ts +37 -2
- package/dist/vendor/core/index.js +120 -14
- package/dist/vendor/core/persistence/index.d.ts +1 -1
- package/dist/vendor/core/persistence/index.js +1 -1
- package/dist/vendor/core/persistence/integrity.d.ts +1 -0
- package/dist/vendor/core/persistence/integrity.js +1 -1
- package/dist/vendor/core/policy.js +11 -1
- package/dist/vendor/core/resume.d.ts +25 -1
- package/dist/vendor/core/resume.js +187 -13
- package/dist/vendor/core/rollback.d.ts +14 -0
- package/dist/vendor/core/rollback.js +91 -34
- package/dist/vendor/core/swarm/live-runtime.js +2 -0
- package/dist/vendor/core/verified-handoff.js +62 -2
- package/package.json +3 -7
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -81,6 +81,8 @@ Every attempt runs your verifier. Every dollar is tracked. If the agent drifts o
|
|
|
81
81
|
**Run the loop:**
|
|
82
82
|
`martin_doctor` `martin_plan` `martin_preflight` `martin_run` `martin_pause` `martin_continue` `martin_cancel`
|
|
83
83
|
|
|
84
|
+
The three run-control mutation tools are local-stdio only. They require a live MartinLoop executor lease, and their `local_os_user` authority label describes the same-machine boundary rather than an authenticated person. Remote HTTP sessions are rejected for these tools.
|
|
85
|
+
|
|
84
86
|
**Inspect results:**
|
|
85
87
|
`martin_status` `martin_logs` `martin_dossier` `martin_eval` `martin_inspect` `martin_list_runs` `martin_get_run` `martin_get_attempt` `martin_get_verification_results` `martin_triage_runs`
|
|
86
88
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const MARTIN_MCP_PACKAGE_VERSION = "0.
|
|
1
|
+
export declare const MARTIN_MCP_PACKAGE_VERSION = "0.9.0";
|
package/dist/package-version.js
CHANGED
|
@@ -448,12 +448,11 @@ function validateEvalInput(args) {
|
|
|
448
448
|
}
|
|
449
449
|
function validateRunControlInput(args) {
|
|
450
450
|
const record = requireObject(args);
|
|
451
|
-
assertAllowedKeys(record, ["file", "loopId", "runsDir", "latest", "reason"
|
|
451
|
+
assertAllowedKeys(record, ["file", "loopId", "runsDir", "latest", "reason"]);
|
|
452
452
|
const base = validateGetRunInput(pickKeys(record, RUN_SELECTOR_KEYS));
|
|
453
453
|
return {
|
|
454
454
|
...base,
|
|
455
|
-
...optionalString(record.reason, "reason")
|
|
456
|
-
...optionalString(record.requestedBy, "requestedBy")
|
|
455
|
+
...optionalString(record.reason, "reason")
|
|
457
456
|
};
|
|
458
457
|
}
|
|
459
458
|
function validateCreatePrInput(args) {
|
package/dist/server.d.ts
CHANGED
package/dist/server.js
CHANGED
|
@@ -377,6 +377,44 @@ const statusOutputSchema = {
|
|
|
377
377
|
loop: loopPreviewSchema
|
|
378
378
|
},
|
|
379
379
|
required: ["loop"]
|
|
380
|
+
},
|
|
381
|
+
live: {
|
|
382
|
+
type: "object",
|
|
383
|
+
additionalProperties: false,
|
|
384
|
+
properties: {
|
|
385
|
+
phase: { type: "string" },
|
|
386
|
+
requestedControlState: {
|
|
387
|
+
type: "string",
|
|
388
|
+
enum: ["active", "paused", "cancellation_requested", "terminal"],
|
|
389
|
+
description: "Latest durable operator request; this does not prove executor application."
|
|
390
|
+
},
|
|
391
|
+
appliedControlState: {
|
|
392
|
+
type: "string",
|
|
393
|
+
enum: ["active", "paused", "cancellation_pending", "terminal"],
|
|
394
|
+
description: "Control state reconciled from validated executor application evidence."
|
|
395
|
+
},
|
|
396
|
+
pauseState: {
|
|
397
|
+
type: "string",
|
|
398
|
+
enum: ["active", "paused", "cancellation_requested"],
|
|
399
|
+
description: "Backwards-compatible applied control state; pending pause requests remain active."
|
|
400
|
+
},
|
|
401
|
+
approvalState: {
|
|
402
|
+
type: "string",
|
|
403
|
+
enum: ["not_required", "resume_requested"]
|
|
404
|
+
},
|
|
405
|
+
commandsRun: { type: "integer" },
|
|
406
|
+
filesTouched: { type: "integer" },
|
|
407
|
+
verifierStep: { type: "string" }
|
|
408
|
+
},
|
|
409
|
+
required: [
|
|
410
|
+
"phase",
|
|
411
|
+
"requestedControlState",
|
|
412
|
+
"appliedControlState",
|
|
413
|
+
"pauseState",
|
|
414
|
+
"approvalState",
|
|
415
|
+
"commandsRun",
|
|
416
|
+
"filesTouched"
|
|
417
|
+
]
|
|
380
418
|
}
|
|
381
419
|
},
|
|
382
420
|
required: [
|
|
@@ -392,7 +430,8 @@ const statusOutputSchema = {
|
|
|
392
430
|
"remainingBudgetUsd",
|
|
393
431
|
"remainingIterations",
|
|
394
432
|
"budget",
|
|
395
|
-
"inspection"
|
|
433
|
+
"inspection",
|
|
434
|
+
"live"
|
|
396
435
|
]
|
|
397
436
|
};
|
|
398
437
|
const doctorOutputSchema = {
|
|
@@ -746,10 +785,20 @@ const logsOutputSchema = {
|
|
|
746
785
|
additionalProperties: false,
|
|
747
786
|
properties: {
|
|
748
787
|
lifecycleState: { type: "string", description: "Current run lifecycle state (e.g. running, completed, cancelled)." },
|
|
788
|
+
requestedControlState: {
|
|
789
|
+
type: "string",
|
|
790
|
+
enum: ["active", "paused", "cancellation_requested", "terminal"],
|
|
791
|
+
description: "Latest durable operator request; this does not prove executor application."
|
|
792
|
+
},
|
|
793
|
+
appliedControlState: {
|
|
794
|
+
type: "string",
|
|
795
|
+
enum: ["active", "paused", "cancellation_pending", "terminal"],
|
|
796
|
+
description: "Control state reconciled from validated executor application evidence."
|
|
797
|
+
},
|
|
749
798
|
pauseState: {
|
|
750
799
|
type: "string",
|
|
751
800
|
enum: ["active", "paused", "cancellation_requested"],
|
|
752
|
-
description: "
|
|
801
|
+
description: "Backwards-compatible applied control state; pending pause requests remain active."
|
|
753
802
|
},
|
|
754
803
|
approvalState: {
|
|
755
804
|
type: "string",
|
|
@@ -757,7 +806,7 @@ const logsOutputSchema = {
|
|
|
757
806
|
description: "Whether the run is waiting at a human-approval checkpoint."
|
|
758
807
|
}
|
|
759
808
|
},
|
|
760
|
-
required: ["lifecycleState", "pauseState", "approvalState"]
|
|
809
|
+
required: ["lifecycleState", "requestedControlState", "appliedControlState", "pauseState", "approvalState"]
|
|
761
810
|
},
|
|
762
811
|
entries: {
|
|
763
812
|
type: "array",
|
|
@@ -781,6 +830,84 @@ const logsOutputSchema = {
|
|
|
781
830
|
},
|
|
782
831
|
required: ["source", "sourceKind", "loopId", "logCount", "live", "entries"]
|
|
783
832
|
};
|
|
833
|
+
const controlReceiptSchema = {
|
|
834
|
+
type: "object",
|
|
835
|
+
additionalProperties: false,
|
|
836
|
+
properties: {
|
|
837
|
+
schemaVersion: { const: "martin.run-control.v2" },
|
|
838
|
+
controlId: { type: "string" },
|
|
839
|
+
loopId: { type: "string" },
|
|
840
|
+
action: { type: "string", enum: ["pause", "cancel", "continue"] },
|
|
841
|
+
requestedAt: { type: "string" },
|
|
842
|
+
authorityBoundary: { const: "local_os_user" },
|
|
843
|
+
principal: { const: "local_mcp_client" },
|
|
844
|
+
executorLeaseToken: { type: "string" },
|
|
845
|
+
workspaceId: { type: "string" },
|
|
846
|
+
projectId: { type: "string" },
|
|
847
|
+
expectedPreviousControlId: { type: "string" },
|
|
848
|
+
reason: { type: "string" },
|
|
849
|
+
previousReceiptHash: { type: "string", pattern: "^[a-f0-9]{64}$" },
|
|
850
|
+
receiptHash: { type: "string", pattern: "^[a-f0-9]{64}$" }
|
|
851
|
+
},
|
|
852
|
+
required: [
|
|
853
|
+
"schemaVersion",
|
|
854
|
+
"controlId",
|
|
855
|
+
"loopId",
|
|
856
|
+
"action",
|
|
857
|
+
"requestedAt",
|
|
858
|
+
"authorityBoundary",
|
|
859
|
+
"principal",
|
|
860
|
+
"executorLeaseToken",
|
|
861
|
+
"receiptHash"
|
|
862
|
+
]
|
|
863
|
+
};
|
|
864
|
+
const controlApplicationSchema = {
|
|
865
|
+
type: "object",
|
|
866
|
+
additionalProperties: false,
|
|
867
|
+
properties: {
|
|
868
|
+
schemaVersion: { const: "martin.run-control-application.v2" },
|
|
869
|
+
loopId: { type: "string" },
|
|
870
|
+
controlId: { type: "string" },
|
|
871
|
+
action: { type: "string", enum: ["pause_applied", "continue_applied"] },
|
|
872
|
+
appliedAt: { type: "string" },
|
|
873
|
+
relatedControlId: { type: "string" },
|
|
874
|
+
receiptHash: { type: "string", pattern: "^[a-f0-9]{64}$" },
|
|
875
|
+
previousApplicationHash: { type: "string", pattern: "^[a-f0-9]{64}$" },
|
|
876
|
+
applicationHash: { type: "string", pattern: "^[a-f0-9]{64}$" }
|
|
877
|
+
},
|
|
878
|
+
required: ["schemaVersion", "loopId", "controlId", "action", "appliedAt", "receiptHash", "applicationHash"]
|
|
879
|
+
};
|
|
880
|
+
const controlPublicationSchema = {
|
|
881
|
+
type: "object",
|
|
882
|
+
additionalProperties: false,
|
|
883
|
+
properties: {
|
|
884
|
+
schemaVersion: { const: "martin.run-control-publication.v1" },
|
|
885
|
+
loopId: { type: "string" },
|
|
886
|
+
controlId: { type: "string" },
|
|
887
|
+
receiptHash: { type: "string", pattern: "^[a-f0-9]{64}$" },
|
|
888
|
+
signalState: { type: "string", enum: ["created", "already_exists"] },
|
|
889
|
+
recordedAt: { type: "string" },
|
|
890
|
+
previousPublicationHash: { type: "string", pattern: "^[a-f0-9]{64}$" },
|
|
891
|
+
publicationHash: { type: "string", pattern: "^[a-f0-9]{64}$" }
|
|
892
|
+
},
|
|
893
|
+
required: ["schemaVersion", "loopId", "controlId", "receiptHash", "signalState", "recordedAt", "publicationHash"]
|
|
894
|
+
};
|
|
895
|
+
const controlStateSchema = {
|
|
896
|
+
type: "object",
|
|
897
|
+
additionalProperties: false,
|
|
898
|
+
properties: {
|
|
899
|
+
requestedState: { type: "string", enum: ["active", "paused", "cancellation_requested", "terminal"] },
|
|
900
|
+
latestReceipt: controlReceiptSchema,
|
|
901
|
+
approvalState: { type: "string", enum: ["not_required", "resume_requested"] },
|
|
902
|
+
appliedState: { type: "string", enum: ["active", "paused", "cancellation_pending", "terminal"] },
|
|
903
|
+
receipts: { type: "array", items: controlReceiptSchema },
|
|
904
|
+
applications: { type: "array", items: controlApplicationSchema },
|
|
905
|
+
publications: { type: "array", items: controlPublicationSchema },
|
|
906
|
+
receiptPath: { type: "string" },
|
|
907
|
+
applicationPath: { type: "string" }
|
|
908
|
+
},
|
|
909
|
+
required: ["requestedState", "approvalState", "appliedState", "receipts", "applications", "publications"]
|
|
910
|
+
};
|
|
784
911
|
const controlOutputSchema = {
|
|
785
912
|
type: "object",
|
|
786
913
|
additionalProperties: false,
|
|
@@ -793,7 +920,6 @@ const controlOutputSchema = {
|
|
|
793
920
|
},
|
|
794
921
|
controlId: { type: "string", description: "Unique receipt ID for this control action." },
|
|
795
922
|
requestedAt: { type: "string", description: "ISO 8601 timestamp when the control was recorded." },
|
|
796
|
-
requestedBy: { type: "string", description: "Identity that requested the control, if provided." },
|
|
797
923
|
reason: { type: "string", description: "Human-readable reason for the control, if provided." },
|
|
798
924
|
ok: { type: "boolean", description: "Whether the control receipt was recorded." },
|
|
799
925
|
summary: { type: "string", description: "Human-readable result of the control request." },
|
|
@@ -802,13 +928,36 @@ const controlOutputSchema = {
|
|
|
802
928
|
enum: ["pause", "cancel", "continue"],
|
|
803
929
|
description: "The control action that was requested."
|
|
804
930
|
},
|
|
805
|
-
|
|
806
|
-
type: "
|
|
807
|
-
|
|
808
|
-
description: "
|
|
809
|
-
}
|
|
931
|
+
publicationState: {
|
|
932
|
+
type: "string",
|
|
933
|
+
enum: ["published", "already_requested", "receipt_recorded", "published_audit_pending"],
|
|
934
|
+
description: "Whether an authoritative cancellation signal was published or a cooperative receipt was recorded."
|
|
935
|
+
},
|
|
936
|
+
applicationState: {
|
|
937
|
+
type: "string",
|
|
938
|
+
enum: ["pending_observation", "requested_only", "terminal_reconciled"],
|
|
939
|
+
description: "Whether the active executor has applied the control; publication alone is not application proof."
|
|
940
|
+
},
|
|
941
|
+
authorityBoundary: { const: "local_os_user" },
|
|
942
|
+
principal: { const: "local_mcp_client" },
|
|
943
|
+
receiptHash: { type: "string", pattern: "^[a-f0-9]{64}$" },
|
|
944
|
+
state: controlStateSchema
|
|
810
945
|
},
|
|
811
|
-
required: [
|
|
946
|
+
required: [
|
|
947
|
+
"loopId",
|
|
948
|
+
"action",
|
|
949
|
+
"controlId",
|
|
950
|
+
"requestedAt",
|
|
951
|
+
"ok",
|
|
952
|
+
"summary",
|
|
953
|
+
"requestedAction",
|
|
954
|
+
"publicationState",
|
|
955
|
+
"applicationState",
|
|
956
|
+
"authorityBoundary",
|
|
957
|
+
"principal",
|
|
958
|
+
"receiptHash",
|
|
959
|
+
"state"
|
|
960
|
+
]
|
|
812
961
|
};
|
|
813
962
|
const evalOutputSchema = {
|
|
814
963
|
type: "object",
|
|
@@ -1207,7 +1356,7 @@ export function createMartinMcpServer(serverInfo) {
|
|
|
1207
1356
|
},
|
|
1208
1357
|
{
|
|
1209
1358
|
name: "martin_logs",
|
|
1210
|
-
description: "Read recent MartinLoop events, ledger entries,
|
|
1359
|
+
description: "Read recent MartinLoop events, ledger entries, operator control receipts, and reconciled executor control-application records for a single run. " +
|
|
1211
1360
|
"Use to observe live or completed run activity, diagnose stuck or failed runs, or audit operator actions. " +
|
|
1212
1361
|
"Do not use to check run completion status — use martin_get_status instead. " +
|
|
1213
1362
|
"Do not use to retrieve verification evidence — use martin_get_verification_results instead. " +
|
|
@@ -1233,7 +1382,7 @@ export function createMartinMcpServer(serverInfo) {
|
|
|
1233
1382
|
},
|
|
1234
1383
|
{
|
|
1235
1384
|
name: "martin_pause",
|
|
1236
|
-
description: "
|
|
1385
|
+
description: "Request a durable cooperative pause for one active MartinLoop run. The executor applies it at the next safe attempt boundary; it does not suspend or kill an in-flight provider. Provide exactly one selector: file, loopId, or latest. Use martin_status to distinguish requested from applied state; use martin_cancel to abandon work or martin_continue to release the applied pause.",
|
|
1237
1386
|
annotations: {
|
|
1238
1387
|
destructiveHint: true,
|
|
1239
1388
|
idempotentHint: false
|
|
@@ -1246,18 +1395,17 @@ export function createMartinMcpServer(serverInfo) {
|
|
|
1246
1395
|
loopId: { type: "string", description: "Canonical MartinLoop run identifier. Mutually exclusive with file and latest." },
|
|
1247
1396
|
runsDir: { type: "string", description: "Optional run-store root override used to resolve loopId or latest." },
|
|
1248
1397
|
latest: { const: true, description: "When true, targets the latest canonical run. Mutually exclusive with file and loopId." },
|
|
1249
|
-
reason: { type: "string", description: "Optional non-empty reason recorded in the pause receipt." }
|
|
1250
|
-
requestedBy: { type: "string", description: "Optional human or runtime identity label recorded for audit context." }
|
|
1398
|
+
reason: { type: "string", description: "Optional non-empty reason recorded in the pause receipt." }
|
|
1251
1399
|
}
|
|
1252
1400
|
},
|
|
1253
1401
|
outputSchema: controlOutputSchema
|
|
1254
1402
|
},
|
|
1255
1403
|
{
|
|
1256
1404
|
name: "martin_cancel",
|
|
1257
|
-
description: "
|
|
1405
|
+
description: "Publish the canonical durable cancellation signal for one active MartinLoop run. The active executor polls this signal, aborts its provider, restores governed workspace state, and records terminal evidence. Use the tool when work must stop; publication is not application proof, so use martin_status to observe terminal state or martin_pause for a reversible safe-boundary hold.",
|
|
1258
1406
|
annotations: {
|
|
1259
1407
|
destructiveHint: true,
|
|
1260
|
-
idempotentHint:
|
|
1408
|
+
idempotentHint: true
|
|
1261
1409
|
},
|
|
1262
1410
|
inputSchema: {
|
|
1263
1411
|
type: "object",
|
|
@@ -1267,15 +1415,14 @@ export function createMartinMcpServer(serverInfo) {
|
|
|
1267
1415
|
loopId: { type: "string", description: "Canonical MartinLoop run identifier. Mutually exclusive with file and latest." },
|
|
1268
1416
|
runsDir: { type: "string", description: "Optional run-store root override used to resolve loopId or latest." },
|
|
1269
1417
|
latest: { const: true, description: "When true, targets the latest canonical run. Mutually exclusive with file and loopId." },
|
|
1270
|
-
reason: { type: "string", description: "Optional non-empty reason recorded in the cancellation receipt." }
|
|
1271
|
-
requestedBy: { type: "string", description: "Optional human or runtime identity label recorded for audit context." }
|
|
1418
|
+
reason: { type: "string", description: "Optional non-empty reason recorded in the cancellation receipt." }
|
|
1272
1419
|
}
|
|
1273
1420
|
},
|
|
1274
1421
|
outputSchema: controlOutputSchema
|
|
1275
1422
|
},
|
|
1276
1423
|
{
|
|
1277
1424
|
name: "martin_continue",
|
|
1278
|
-
description: "
|
|
1425
|
+
description: "Release the exact pending cooperative pause for one active MartinLoop run. Continue is bound to that pause and does not grant approval, widen safety policy, or resume a terminal approval escalation.",
|
|
1279
1426
|
annotations: {
|
|
1280
1427
|
destructiveHint: true,
|
|
1281
1428
|
idempotentHint: false
|
|
@@ -1288,8 +1435,7 @@ export function createMartinMcpServer(serverInfo) {
|
|
|
1288
1435
|
loopId: { type: "string" },
|
|
1289
1436
|
runsDir: { type: "string" },
|
|
1290
1437
|
latest: { const: true },
|
|
1291
|
-
reason: { type: "string" }
|
|
1292
|
-
requestedBy: { type: "string" }
|
|
1438
|
+
reason: { type: "string" }
|
|
1293
1439
|
}
|
|
1294
1440
|
},
|
|
1295
1441
|
outputSchema: controlOutputSchema
|
|
@@ -1832,17 +1978,26 @@ export function createMartinMcpServer(serverInfo) {
|
|
|
1832
1978
|
}
|
|
1833
1979
|
if (name === "martin_pause") {
|
|
1834
1980
|
const input = validateToolInput("martin_pause", args);
|
|
1835
|
-
const output = await createRunControlReceipt("pause",
|
|
1981
|
+
const output = await createRunControlReceipt("pause", {
|
|
1982
|
+
...input,
|
|
1983
|
+
authority: { transport: serverInfo?.controlTransport ?? "untrusted_remote" }
|
|
1984
|
+
});
|
|
1836
1985
|
return createToolSuccessResult(output, output.summary);
|
|
1837
1986
|
}
|
|
1838
1987
|
if (name === "martin_cancel") {
|
|
1839
1988
|
const input = validateToolInput("martin_cancel", args);
|
|
1840
|
-
const output = await createRunControlReceipt("cancel",
|
|
1989
|
+
const output = await createRunControlReceipt("cancel", {
|
|
1990
|
+
...input,
|
|
1991
|
+
authority: { transport: serverInfo?.controlTransport ?? "untrusted_remote" }
|
|
1992
|
+
});
|
|
1841
1993
|
return createToolSuccessResult(output, output.summary);
|
|
1842
1994
|
}
|
|
1843
1995
|
if (name === "martin_continue") {
|
|
1844
1996
|
const input = validateToolInput("martin_continue", args);
|
|
1845
|
-
const output = await createRunControlReceipt("continue",
|
|
1997
|
+
const output = await createRunControlReceipt("continue", {
|
|
1998
|
+
...input,
|
|
1999
|
+
authority: { transport: serverInfo?.controlTransport ?? "untrusted_remote" }
|
|
2000
|
+
});
|
|
1846
2001
|
return createToolSuccessResult(output, output.summary);
|
|
1847
2002
|
}
|
|
1848
2003
|
if (name === "martin_list_runs") {
|
|
@@ -1967,6 +2122,7 @@ function normalizeRunBudget(input) {
|
|
|
1967
2122
|
}
|
|
1968
2123
|
export async function connectMartinMcpStdioServer(options = {}) {
|
|
1969
2124
|
const server = createMartinMcpServer({
|
|
2125
|
+
controlTransport: "local_stdio",
|
|
1970
2126
|
...(options.toolProfile ? { toolProfile: options.toolProfile } : {})
|
|
1971
2127
|
});
|
|
1972
2128
|
const transport = new StdioServerTransport();
|
|
@@ -2031,6 +2187,7 @@ export async function connectMartinMcpHttpServer(options = {}) {
|
|
|
2031
2187
|
const port = options.port ?? 3033;
|
|
2032
2188
|
const path = options.path ?? "/mcp";
|
|
2033
2189
|
const mcpServer = createMartinMcpServer({
|
|
2190
|
+
controlTransport: "untrusted_remote",
|
|
2034
2191
|
...(options.toolProfile ? { toolProfile: options.toolProfile } : {})
|
|
2035
2192
|
});
|
|
2036
2193
|
const transport = new StreamableHTTPServerTransport({
|
|
@@ -35,6 +35,9 @@ export interface GetStatusOutput {
|
|
|
35
35
|
};
|
|
36
36
|
live: {
|
|
37
37
|
phase: string;
|
|
38
|
+
requestedControlState: "active" | "paused" | "cancellation_requested" | "terminal";
|
|
39
|
+
appliedControlState: "active" | "paused" | "cancellation_pending" | "terminal";
|
|
40
|
+
/** Backwards-compatible applied pause state. Never reflects an unapplied request. */
|
|
38
41
|
pauseState: "active" | "paused" | "cancellation_requested";
|
|
39
42
|
approvalState: "not_required" | "resume_requested";
|
|
40
43
|
commandsRun: number;
|
package/dist/tools/get-status.js
CHANGED
|
@@ -8,8 +8,11 @@ export async function getStatusTool(input) {
|
|
|
8
8
|
const control = input.loopJson !== undefined
|
|
9
9
|
? {
|
|
10
10
|
requestedState: "active",
|
|
11
|
+
appliedState: "active",
|
|
11
12
|
approvalState: "not_required",
|
|
12
|
-
receipts: []
|
|
13
|
+
receipts: [],
|
|
14
|
+
applications: [],
|
|
15
|
+
publications: []
|
|
13
16
|
}
|
|
14
17
|
: await readRunControlState(input);
|
|
15
18
|
const latestEvent = loop.events?.at(-1);
|
|
@@ -52,7 +55,13 @@ export async function getStatusTool(input) {
|
|
|
52
55
|
},
|
|
53
56
|
live: {
|
|
54
57
|
phase: latestEvent?.lifecycleState ?? loop.lifecycleState,
|
|
55
|
-
|
|
58
|
+
requestedControlState: control.requestedState,
|
|
59
|
+
appliedControlState: control.appliedState,
|
|
60
|
+
pauseState: control.appliedState === "paused"
|
|
61
|
+
? "paused"
|
|
62
|
+
: control.appliedState === "cancellation_pending"
|
|
63
|
+
? "cancellation_requested"
|
|
64
|
+
: "active",
|
|
56
65
|
approvalState: control.approvalState,
|
|
57
66
|
commandsRun: loop.attempts.length,
|
|
58
67
|
filesTouched: changedFiles,
|
package/dist/tools/logs.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface MartinLogsOutput {
|
|
|
12
12
|
logCount: number;
|
|
13
13
|
live: {
|
|
14
14
|
lifecycleState: string;
|
|
15
|
+
requestedControlState: "active" | "paused" | "cancellation_requested" | "terminal";
|
|
16
|
+
appliedControlState: "active" | "paused" | "cancellation_pending" | "terminal";
|
|
15
17
|
pauseState: "active" | "paused" | "cancellation_requested";
|
|
16
18
|
approvalState: "not_required" | "resume_requested";
|
|
17
19
|
};
|
package/dist/tools/logs.js
CHANGED
|
@@ -23,11 +23,27 @@ export async function martinLogsTool(input) {
|
|
|
23
23
|
kind: `run.${receipt.action}`,
|
|
24
24
|
payload: {
|
|
25
25
|
controlId: receipt.controlId,
|
|
26
|
+
...(receipt.expectedPreviousControlId
|
|
27
|
+
? { expectedPreviousControlId: receipt.expectedPreviousControlId }
|
|
28
|
+
: {}),
|
|
26
29
|
...(receipt.reason ? { reason: receipt.reason } : {}),
|
|
27
|
-
|
|
30
|
+
principal: receipt.principal,
|
|
31
|
+
authorityBoundary: receipt.authorityBoundary,
|
|
32
|
+
receiptHash: receipt.receiptHash
|
|
28
33
|
}
|
|
29
34
|
}));
|
|
30
|
-
const
|
|
35
|
+
const applicationEntries = controls.applications.map((application) => ({
|
|
36
|
+
timestamp: application.appliedAt,
|
|
37
|
+
source: "control",
|
|
38
|
+
kind: `run.${application.action}`,
|
|
39
|
+
payload: {
|
|
40
|
+
controlId: application.controlId,
|
|
41
|
+
...(application.relatedControlId
|
|
42
|
+
? { relatedControlId: application.relatedControlId }
|
|
43
|
+
: {})
|
|
44
|
+
}
|
|
45
|
+
}));
|
|
46
|
+
const entries = [...eventEntries, ...ledgerEntries, ...controlEntries, ...applicationEntries]
|
|
31
47
|
.sort((left, right) => {
|
|
32
48
|
const leftTime = left.timestamp ? new Date(left.timestamp).getTime() : 0;
|
|
33
49
|
const rightTime = right.timestamp ? new Date(right.timestamp).getTime() : 0;
|
|
@@ -41,7 +57,13 @@ export async function martinLogsTool(input) {
|
|
|
41
57
|
logCount: entries.length,
|
|
42
58
|
live: {
|
|
43
59
|
lifecycleState: detail.loop.lifecycleState,
|
|
44
|
-
|
|
60
|
+
requestedControlState: controls.requestedState,
|
|
61
|
+
appliedControlState: controls.appliedState,
|
|
62
|
+
pauseState: controls.appliedState === "paused"
|
|
63
|
+
? "paused"
|
|
64
|
+
: controls.appliedState === "cancellation_pending"
|
|
65
|
+
? "cancellation_requested"
|
|
66
|
+
: "active",
|
|
45
67
|
approvalState: controls.approvalState
|
|
46
68
|
},
|
|
47
69
|
entries
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type RunControlApplication, type RunControlSnapshot, type RunControlSource } from "../vendor/core/index.js";
|
|
1
2
|
import { type DetailedLoopSource } from "./run-store.js";
|
|
2
3
|
export type MartinControlAction = "pause" | "cancel" | "continue";
|
|
3
4
|
export interface MartinRunControlRequestInput {
|
|
@@ -6,22 +7,52 @@ export interface MartinRunControlRequestInput {
|
|
|
6
7
|
runsDir?: string;
|
|
7
8
|
latest?: boolean;
|
|
8
9
|
reason?: string;
|
|
9
|
-
|
|
10
|
+
/** Injected by the server; never accepted from MCP tool arguments. */
|
|
11
|
+
authority?: {
|
|
12
|
+
transport: "local_stdio" | "untrusted_remote";
|
|
13
|
+
};
|
|
10
14
|
}
|
|
11
15
|
export interface MartinRunControlReceipt {
|
|
16
|
+
schemaVersion: "martin.run-control.v2";
|
|
12
17
|
controlId: string;
|
|
13
18
|
loopId: string;
|
|
14
19
|
action: MartinControlAction;
|
|
15
20
|
requestedAt: string;
|
|
21
|
+
authorityBoundary: "local_os_user";
|
|
22
|
+
principal: "local_mcp_client";
|
|
23
|
+
executorLeaseToken: string;
|
|
24
|
+
workspaceId?: string;
|
|
25
|
+
projectId?: string;
|
|
26
|
+
expectedPreviousControlId?: string;
|
|
16
27
|
reason?: string;
|
|
17
|
-
|
|
28
|
+
previousReceiptHash?: string;
|
|
29
|
+
receiptHash: string;
|
|
30
|
+
}
|
|
31
|
+
interface RunControlPublication {
|
|
32
|
+
schemaVersion: "martin.run-control-publication.v1";
|
|
33
|
+
loopId: string;
|
|
34
|
+
controlId: string;
|
|
35
|
+
receiptHash: string;
|
|
36
|
+
signalState: "created" | "already_exists";
|
|
37
|
+
recordedAt: string;
|
|
38
|
+
previousPublicationHash?: string;
|
|
39
|
+
publicationHash: string;
|
|
40
|
+
}
|
|
41
|
+
interface StoredRunControlApplication extends RunControlApplication {
|
|
42
|
+
schemaVersion: "martin.run-control-application.v2";
|
|
43
|
+
previousApplicationHash?: string;
|
|
44
|
+
applicationHash: string;
|
|
18
45
|
}
|
|
19
46
|
export interface MartinRunControlState {
|
|
20
|
-
requestedState: "active" | "paused" | "cancellation_requested";
|
|
47
|
+
requestedState: "active" | "paused" | "cancellation_requested" | "terminal";
|
|
21
48
|
latestReceipt?: MartinRunControlReceipt;
|
|
22
49
|
approvalState: "not_required" | "resume_requested";
|
|
50
|
+
appliedState: "active" | "paused" | "cancellation_pending" | "terminal";
|
|
23
51
|
receipts: MartinRunControlReceipt[];
|
|
52
|
+
applications: StoredRunControlApplication[];
|
|
53
|
+
publications: RunControlPublication[];
|
|
24
54
|
receiptPath?: string;
|
|
55
|
+
applicationPath?: string;
|
|
25
56
|
}
|
|
26
57
|
export interface MartinRunControlOutput {
|
|
27
58
|
ok: boolean;
|
|
@@ -32,10 +63,24 @@ export interface MartinRunControlOutput {
|
|
|
32
63
|
action: MartinControlAction;
|
|
33
64
|
controlId: string;
|
|
34
65
|
requestedAt: string;
|
|
66
|
+
publicationState: "published" | "already_requested" | "receipt_recorded" | "published_audit_pending";
|
|
67
|
+
applicationState: "pending_observation" | "requested_only" | "terminal_reconciled";
|
|
35
68
|
reason?: string;
|
|
36
|
-
|
|
69
|
+
authorityBoundary: "local_os_user";
|
|
70
|
+
principal: "local_mcp_client";
|
|
71
|
+
receiptHash: string;
|
|
37
72
|
}
|
|
38
|
-
export declare function createRunControlReceipt(action: MartinControlAction, input: MartinRunControlRequestInput
|
|
73
|
+
export declare function createRunControlReceipt(action: MartinControlAction, input: MartinRunControlRequestInput, testHooks?: {
|
|
74
|
+
beforeLockedReload?: () => Promise<void>;
|
|
75
|
+
afterJournalOpen?: (journalPath: string) => Promise<void>;
|
|
76
|
+
lockMaxRetries?: number;
|
|
77
|
+
}): Promise<MartinRunControlOutput>;
|
|
39
78
|
export declare function readRunControlState(detailOrInput: DetailedLoopSource | MartinRunControlRequestInput): Promise<MartinRunControlState>;
|
|
40
|
-
export declare function
|
|
79
|
+
export declare function createFileRunControlSource(runsRoot: string): RunControlSource;
|
|
80
|
+
export declare function reconcileRunControlApplications(receipts: readonly MartinRunControlReceipt[], applications: readonly StoredRunControlApplication[]): "active" | "paused";
|
|
81
|
+
export declare function resolveRunControlSnapshot(receipts: readonly MartinRunControlReceipt[]): RunControlSnapshot;
|
|
82
|
+
export declare function readRunControlApplications(applicationPath: string, expectedLoopId?: string): Promise<StoredRunControlApplication[]>;
|
|
83
|
+
export declare function readControlReceipts(receiptPath: string, expectedLoopId?: string): Promise<MartinRunControlReceipt[]>;
|
|
84
|
+
export declare function hashCanonical(value: unknown): string;
|
|
41
85
|
export declare function validateControlReason(value?: string): string | undefined;
|
|
86
|
+
export {};
|