@loomfsm/mcp-server 0.1.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.
Files changed (60) hide show
  1. package/LICENSE +201 -0
  2. package/cc-adapter/commands/done.md +30 -0
  3. package/cc-adapter/commands/task.md +29 -0
  4. package/cc-adapter/pipeline-guard.sh +58 -0
  5. package/cc-adapter/pipeline-stop.sh +65 -0
  6. package/dist/src/bin/stdio.d.ts +2 -0
  7. package/dist/src/bin/stdio.js +43 -0
  8. package/dist/src/bin/stdio.js.map +1 -0
  9. package/dist/src/bootstrap.d.ts +4 -0
  10. package/dist/src/bootstrap.js +130 -0
  11. package/dist/src/bootstrap.js.map +1 -0
  12. package/dist/src/index.d.ts +21 -0
  13. package/dist/src/index.js +16 -0
  14. package/dist/src/index.js.map +1 -0
  15. package/dist/src/lib/parse-task-args.d.ts +4 -0
  16. package/dist/src/lib/parse-task-args.js +38 -0
  17. package/dist/src/lib/parse-task-args.js.map +1 -0
  18. package/dist/src/lib/persist-progress.d.ts +2 -0
  19. package/dist/src/lib/persist-progress.js +20 -0
  20. package/dist/src/lib/persist-progress.js.map +1 -0
  21. package/dist/src/server.d.ts +25 -0
  22. package/dist/src/server.js +257 -0
  23. package/dist/src/server.js.map +1 -0
  24. package/dist/src/tools/backup.d.ts +5 -0
  25. package/dist/src/tools/backup.js +69 -0
  26. package/dist/src/tools/backup.js.map +1 -0
  27. package/dist/src/tools/continue-task.d.ts +7 -0
  28. package/dist/src/tools/continue-task.js +156 -0
  29. package/dist/src/tools/continue-task.js.map +1 -0
  30. package/dist/src/tools/extensions-list.d.ts +2 -0
  31. package/dist/src/tools/extensions-list.js +49 -0
  32. package/dist/src/tools/extensions-list.js.map +1 -0
  33. package/dist/src/tools/issue-marker.d.ts +5 -0
  34. package/dist/src/tools/issue-marker.js +57 -0
  35. package/dist/src/tools/issue-marker.js.map +1 -0
  36. package/dist/src/tools/meta.d.ts +6 -0
  37. package/dist/src/tools/meta.js +52 -0
  38. package/dist/src/tools/meta.js.map +1 -0
  39. package/dist/src/tools/recover.d.ts +7 -0
  40. package/dist/src/tools/recover.js +243 -0
  41. package/dist/src/tools/recover.js.map +1 -0
  42. package/dist/src/tools/restore.d.ts +5 -0
  43. package/dist/src/tools/restore.js +82 -0
  44. package/dist/src/tools/restore.js.map +1 -0
  45. package/dist/src/tools/run-task.d.ts +7 -0
  46. package/dist/src/tools/run-task.js +172 -0
  47. package/dist/src/tools/run-task.js.map +1 -0
  48. package/dist/src/tools/state-get.d.ts +2 -0
  49. package/dist/src/tools/state-get.js +176 -0
  50. package/dist/src/tools/state-get.js.map +1 -0
  51. package/dist/src/transport-adapter.d.ts +6 -0
  52. package/dist/src/transport-adapter.js +94 -0
  53. package/dist/src/transport-adapter.js.map +1 -0
  54. package/dist/src/types.d.ts +171 -0
  55. package/dist/src/types.js +9 -0
  56. package/dist/src/types.js.map +1 -0
  57. package/dist/src/version.d.ts +3 -0
  58. package/dist/src/version.js +8 -0
  59. package/dist/src/version.js.map +1 -0
  60. package/package.json +45 -0
@@ -0,0 +1,172 @@
1
+ // pipeline_run_task — task-create handler.
2
+ //
3
+ // Composition order:
4
+ // 1. assertProjectDirAllowed — refusal lands as an error-shaped wire
5
+ // envelope, NOT a thrown exception.
6
+ // 2. Validate client_idempotency_uuid — empty → error envelope.
7
+ // 3. Ledger cache lookup — a `task-create:<uuid>` row carrying a
8
+ // materialized response_blob replays the cached creation envelope
9
+ // verbatim (same task_id / driver_state_id, read off the canonical
10
+ // pipeline_state row).
11
+ // 4. Parse the raw task string when no policy_preset was supplied.
12
+ // 5. Open one withStateTransaction → initializeTask (atomic multi-table
13
+ // insert + co-committed task-create ledger row) + a co-committed
14
+ // audit row → commit.
15
+ // 6. Load state, run the FSM to its first directive, shape it.
16
+ // 7. Update the ledger row's response_blob with the shaped envelope so
17
+ // a later replay returns it verbatim.
18
+ //
19
+ // Operational failures (allowlist refusal, missing UUID, kernel-coded
20
+ // refusals) become structured error envelopes; the MCP client sees the
21
+ // same wire shape for a refusal as for the happy path. Only programmer
22
+ // errors throw.
23
+ import { assertProjectDirAllowed, captureNow, initializeTask, KernelError, loadState, openDb, readLedgerRow, runFSM, TransactionImpl, withStateTransaction, writeLedgerRow, } from "@loomfsm/kernel";
24
+ import { parseTaskArgs } from "../lib/parse-task-args.js";
25
+ import { persistDriverStepIndex } from "../lib/persist-progress.js";
26
+ import { createTransportAdapter } from "../transport-adapter.js";
27
+ const UNKNOWN_DRIVER = "d-unknown";
28
+ export function createRunTaskTool(deps = {}) {
29
+ const adapter = createTransportAdapter();
30
+ return async (input) => {
31
+ // 1. Project-dir allowlist.
32
+ try {
33
+ await assertProjectDirAllowed(input.project_dir, deps.allowlistPath !== undefined ? { allowlistPath: deps.allowlistPath } : undefined);
34
+ }
35
+ catch (err) {
36
+ return refusal(err);
37
+ }
38
+ // 2. client_idempotency_uuid is REQUIRED.
39
+ if (typeof input.client_idempotency_uuid !== "string" ||
40
+ input.client_idempotency_uuid.length === 0) {
41
+ return {
42
+ response: errorResponse(UNKNOWN_DRIVER, "TASK_IDEMPOTENCY_REQUIRED", "client_idempotency_uuid is required on every pipeline_run_task call"),
43
+ };
44
+ }
45
+ // 3. Replay — return the cached creation envelope verbatim.
46
+ const cached = await readCachedCreation(input.project_dir, input.client_idempotency_uuid);
47
+ if (cached !== null)
48
+ return cached;
49
+ if (deps.resolveRegistry === undefined) {
50
+ return {
51
+ response: errorResponse(UNKNOWN_DRIVER, "REGISTRY_UNAVAILABLE", "no registry resolver is wired for the active-task path"),
52
+ };
53
+ }
54
+ const registry = await deps.resolveRegistry(input.project_dir);
55
+ // 4. Parse the raw task only when the host did not name a preset.
56
+ let task = input.task;
57
+ let policyPreset = input.policy_preset;
58
+ let warnings = [];
59
+ if (policyPreset === undefined) {
60
+ const parsed = parseTaskArgs(input.task);
61
+ task = parsed.task;
62
+ policyPreset = parsed.policy_preset;
63
+ warnings = parsed.warnings;
64
+ }
65
+ // 5. Atomic create + co-committed audit row.
66
+ const identifier = typeof input.client_identifier_unverified === "string" &&
67
+ input.client_identifier_unverified.length > 0
68
+ ? input.client_identifier_unverified
69
+ : "unknown";
70
+ let ids;
71
+ try {
72
+ ids = await withStateTransaction(input.project_dir, captureNow(), async (tx) => {
73
+ const created = await initializeTask(tx, {
74
+ project_dir: input.project_dir,
75
+ task,
76
+ task_short: null,
77
+ owner_id: input.owner_id ?? "anonymous",
78
+ ...(policyPreset !== undefined ? { policy_preset: policyPreset } : {}),
79
+ ...(input.gate_policies !== undefined
80
+ ? { gate_policies: input.gate_policies }
81
+ : {}),
82
+ ...(input.complexity_hint !== undefined
83
+ ? { complexity_hint: input.complexity_hint }
84
+ : {}),
85
+ ...(input.tests_mode_hint !== undefined
86
+ ? { tests_mode_hint: input.tests_mode_hint }
87
+ : {}),
88
+ stack: input.stack ?? null,
89
+ client_idempotency_uuid: input.client_idempotency_uuid,
90
+ phases: registry.bundle.phases,
91
+ // Drive the bundle's declared default flow. The kernel stores
92
+ // this on the driver row at create; runFSM resolves it against
93
+ // the registry's flow map every tick.
94
+ flow_name: registry.bundle.default_flow,
95
+ });
96
+ await writeAuditRow(tx, "pipeline_run_task", created.task_id, created.driver_state_id, {
97
+ client_identifier_unverified: identifier,
98
+ });
99
+ return created;
100
+ });
101
+ }
102
+ catch (err) {
103
+ return refusal(err);
104
+ }
105
+ // 6. Load state, run the FSM to its first directive, shape it.
106
+ const loaded = await readState(input.project_dir);
107
+ const { state: ticked, directive } = await runFSM(loaded, registry);
108
+ const response = adapter.shape(directive, { driver_state_id: ids.driver_state_id });
109
+ // 7. Persist the tick's paused step index + materialize the cached
110
+ // creation response on the ledger row, co-committed.
111
+ await withStateTransaction(input.project_dir, captureNow(), async (tx) => {
112
+ await persistDriverStepIndex(tx, ticked.driver.step_index);
113
+ await writeLedgerRow(tx, `task-create:${input.client_idempotency_uuid}`, {
114
+ driver_state_id: ids.driver_state_id,
115
+ task_id: ids.task_id,
116
+ response_blob: JSON.stringify(response),
117
+ });
118
+ });
119
+ return {
120
+ response,
121
+ task_id: ids.task_id,
122
+ driver_state_id: ids.driver_state_id,
123
+ ...(warnings.length > 0 ? { warnings } : {}),
124
+ };
125
+ };
126
+ }
127
+ // Read the canonical state through a read-only TransactionImpl — the
128
+ // handler never commits this scope, so the now token threaded here is
129
+ // local and not observable on disk.
130
+ async function readState(projectDir) {
131
+ const db = openDb(projectDir);
132
+ const tx = new TransactionImpl(db, captureNow());
133
+ return await loadState(tx);
134
+ }
135
+ async function readCachedCreation(projectDir, uuid) {
136
+ const db = openDb(projectDir);
137
+ const tx = new TransactionImpl(db, captureNow());
138
+ const row = await readLedgerRow(tx, `task-create:${uuid}`);
139
+ if (row === null || row.response_blob === null)
140
+ return null;
141
+ const response = JSON.parse(row.response_blob);
142
+ const ps = await tx.queryRow("SELECT task_id, driver_state_id FROM pipeline_state WHERE id = 1");
143
+ const out = { response };
144
+ if (ps !== null) {
145
+ if (ps.task_id !== null)
146
+ out.task_id = String(ps.task_id);
147
+ out.driver_state_id = String(ps.driver_state_id);
148
+ }
149
+ return out;
150
+ }
151
+ async function writeAuditRow(tx, type, taskId, driverStateId, payload) {
152
+ await tx.exec("INSERT INTO audit (ts, type, task_id, driver_state_id, payload, verdict, error_class) " +
153
+ "VALUES (?, ?, ?, ?, ?, 'ok', NULL)", [tx.now, type, taskId, driverStateId, JSON.stringify(payload)]);
154
+ }
155
+ // Map a thrown KernelError into an error-shaped wire envelope; rethrow
156
+ // anything that is not a kernel-coded refusal (programmer error).
157
+ function refusal(err) {
158
+ if (err instanceof KernelError) {
159
+ return { response: errorResponse(UNKNOWN_DRIVER, err.code, err.message) };
160
+ }
161
+ throw err;
162
+ }
163
+ function errorResponse(driverStateId, code, message) {
164
+ return {
165
+ status: "error",
166
+ driver_state_id: driverStateId,
167
+ code,
168
+ message,
169
+ recovery_options: [],
170
+ };
171
+ }
172
+ //# sourceMappingURL=run-task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-task.js","sourceRoot":"","sources":["../../../src/tools/run-task.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,qBAAqB;AACrB,uEAAuE;AACvE,yCAAyC;AACzC,kEAAkE;AAClE,mEAAmE;AACnE,uEAAuE;AACvE,wEAAwE;AACxE,4BAA4B;AAC5B,qEAAqE;AACrE,0EAA0E;AAC1E,sEAAsE;AACtE,2BAA2B;AAC3B,iEAAiE;AACjE,yEAAyE;AACzE,2CAA2C;AAC3C,EAAE;AACF,sEAAsE;AACtE,uEAAuE;AACvE,uEAAuE;AACvE,gBAAgB;AAEhB,OAAO,EACL,uBAAuB,EACvB,UAAU,EACV,cAAc,EACd,WAAW,EACX,SAAS,EACT,MAAM,EACN,aAAa,EACb,MAAM,EACN,eAAe,EACf,oBAAoB,EACpB,cAAc,GAKf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAcjE,MAAM,cAAc,GAAG,WAAW,CAAC;AAEnC,MAAM,UAAU,iBAAiB,CAC/B,OAAoB,EAAE;IAEtB,MAAM,OAAO,GAAG,sBAAsB,EAAE,CAAC;IAEzC,OAAO,KAAK,EAAE,KAAK,EAAE,EAAE;QACrB,4BAA4B;QAC5B,IAAI,CAAC;YACH,MAAM,uBAAuB,CAC3B,KAAK,CAAC,WAAW,EACjB,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,SAAS,CACrF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC;QAED,0CAA0C;QAC1C,IACE,OAAO,KAAK,CAAC,uBAAuB,KAAK,QAAQ;YACjD,KAAK,CAAC,uBAAuB,CAAC,MAAM,KAAK,CAAC,EAC1C,CAAC;YACD,OAAO;gBACL,QAAQ,EAAE,aAAa,CACrB,cAAc,EACd,2BAA2B,EAC3B,qEAAqE,CACtE;aACF,CAAC;QACJ,CAAC;QAED,4DAA4D;QAC5D,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC1F,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;QAEnC,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACvC,OAAO;gBACL,QAAQ,EAAE,aAAa,CACrB,cAAc,EACd,sBAAsB,EACtB,wDAAwD,CACzD;aACF,CAAC;QACJ,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAE/D,kEAAkE;QAClE,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACtB,IAAI,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;QACvC,IAAI,QAAQ,GAAa,EAAE,CAAC;QAC5B,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACnB,YAAY,GAAG,MAAM,CAAC,aAAa,CAAC;YACpC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC7B,CAAC;QAED,6CAA6C;QAC7C,MAAM,UAAU,GACd,OAAO,KAAK,CAAC,4BAA4B,KAAK,QAAQ;YACtD,KAAK,CAAC,4BAA4B,CAAC,MAAM,GAAG,CAAC;YAC3C,CAAC,CAAC,KAAK,CAAC,4BAA4B;YACpC,CAAC,CAAC,SAAS,CAAC;QAChB,IAAI,GAAiD,CAAC;QACtD,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;gBAC7E,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,EAAE,EAAE;oBACvC,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,IAAI;oBACJ,UAAU,EAAE,IAAI;oBAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,WAAW;oBACvC,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACtE,GAAG,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS;wBACnC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAA6C,EAAE;wBACxE,CAAC,CAAC,EAAE,CAAC;oBACP,GAAG,CAAC,KAAK,CAAC,eAAe,KAAK,SAAS;wBACrC,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE;wBAC5C,CAAC,CAAC,EAAE,CAAC;oBACP,GAAG,CAAC,KAAK,CAAC,eAAe,KAAK,SAAS;wBACrC,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE;wBAC5C,CAAC,CAAC,EAAE,CAAC;oBACP,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI;oBAC1B,uBAAuB,EAAE,KAAK,CAAC,uBAAuB;oBACtD,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;oBAC9B,8DAA8D;oBAC9D,+DAA+D;oBAC/D,sCAAsC;oBACtC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY;iBACxC,CAAC,CAAC;gBACH,MAAM,aAAa,CAAC,EAAE,EAAE,mBAAmB,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,EAAE;oBACrF,4BAA4B,EAAE,UAAU;iBACzC,CAAC,CAAC;gBACH,OAAO,OAAO,CAAC;YACjB,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC;QAED,+DAA+D;QAC/D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;QAEpF,mEAAmE;QACnE,wDAAwD;QACxD,MAAM,oBAAoB,CAAC,KAAK,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YACvE,MAAM,sBAAsB,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC3D,MAAM,cAAc,CAAC,EAAE,EAAE,eAAe,KAAK,CAAC,uBAAuB,EAAE,EAAE;gBACvE,eAAe,EAAE,GAAG,CAAC,eAAe;gBACpC,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;aACxC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,QAAQ;YACR,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,eAAe,EAAE,GAAG,CAAC,eAAe;YACpC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7C,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,sEAAsE;AACtE,oCAAoC;AACpC,KAAK,UAAU,SAAS,CAAC,UAAkB;IACzC,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IACjD,OAAO,MAAM,SAAS,CAAC,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,UAAkB,EAClB,IAAY;IAEZ,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,EAAE,EAAE,eAAe,IAAI,EAAE,CAAC,CAAC;IAC3D,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,aAAa,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAsB,CAAC;IACpE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC1B,kEAAkE,CACnE,CAAC;IACF,MAAM,GAAG,GAAoB,EAAE,QAAQ,EAAE,CAAC;IAC1C,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QAChB,IAAI,EAAE,CAAC,OAAO,KAAK,IAAI;YAAE,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QAC1D,GAAG,CAAC,eAAe,GAAG,MAAM,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,EAAe,EACf,IAAY,EACZ,MAAqB,EACrB,aAAqB,EACrB,OAAgC;IAEhC,MAAM,EAAE,CAAC,IAAI,CACX,wFAAwF;QACtF,oCAAoC,EACtC,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAC/D,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,kEAAkE;AAClE,SAAS,OAAO,CAAC,GAAY;IAC3B,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;QAC/B,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC,cAAc,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;IAC5E,CAAC;IACD,MAAM,GAAG,CAAC;AACZ,CAAC;AAED,SAAS,aAAa,CACpB,aAAqB,EACrB,IAAY,EACZ,OAAe;IAEf,OAAO;QACL,MAAM,EAAE,OAAO;QACf,eAAe,EAAE,aAAa;QAC9B,IAAI;QACJ,OAAO;QACP,gBAAgB,EAAE,EAAE;KACrB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { PipelineStateView, StateGetInput, ToolHandler } from "../types.js";
2
+ export declare function createStateGetTool(): ToolHandler<StateGetInput, PipelineStateView>;
@@ -0,0 +1,176 @@
1
+ // pipeline_state_get — operator-inspection handler. Four output
2
+ // formats sit behind one entry: a compact summary keyed on the most-
3
+ // asked counters, the full PipelineState aggregate, per-table JSONL,
4
+ // and a stable-width ASCII rendering whose column widths are pinned
5
+ // so two snapshots diff cleanly.
6
+ //
7
+ // Every format reads inside a single `withReadTransaction`: one
8
+ // consistent committed snapshot per call (BEGIN DEFERRED + query_only),
9
+ // so a multi-statement inspection never sees a torn mix across an
10
+ // interleaved writer commit, and the reader never blocks the writer.
11
+ import { loadState, withReadTransaction } from "@loomfsm/kernel";
12
+ const DEFAULT_TABLE = "audit";
13
+ const DEFAULT_TABLE_LIMIT = 100;
14
+ const MAX_TABLE_LIMIT = 1000;
15
+ // Tables the caller may inspect via `jsonl` / `pretty-table`. The
16
+ // allowlist closes the surface against accidental cross-table reads
17
+ // from the same handler — the operator cannot trick the tool into
18
+ // dumping the idempotency ledger by passing `kernel_idempotency_ledger`
19
+ // as the table filter, because that table is not on the list.
20
+ const INSPECTABLE_TABLES = new Set([
21
+ "pipeline_state",
22
+ "pipeline_counters",
23
+ "pipeline_gate_counters",
24
+ "driver_state",
25
+ "phases",
26
+ "agent_records",
27
+ "pending_agents",
28
+ "agent_verdicts",
29
+ "findings",
30
+ "gates",
31
+ "audit",
32
+ "installed_extensions",
33
+ ]);
34
+ // Tables that carry a `ts` column the `since` filter can target. Other
35
+ // inspectable tables use a `recorded_at` or `started_at` column; the
36
+ // `since` filter intentionally stays narrow to keep the contract
37
+ // predictable.
38
+ const TS_FILTERED_TABLES = new Set(["audit", "findings"]);
39
+ function tsColumnFor(table) {
40
+ if (table === "audit")
41
+ return "ts";
42
+ if (table === "findings")
43
+ return "recorded_at";
44
+ return null;
45
+ }
46
+ function clampLimit(raw) {
47
+ if (raw === undefined || !Number.isFinite(raw) || raw <= 0)
48
+ return DEFAULT_TABLE_LIMIT;
49
+ if (raw > MAX_TABLE_LIMIT)
50
+ return MAX_TABLE_LIMIT;
51
+ return Math.floor(raw);
52
+ }
53
+ export function createStateGetTool() {
54
+ return async (input) => {
55
+ const format = input.format ?? "summary";
56
+ return await withReadTransaction(input.project_dir, async (tx) => {
57
+ if (format === "summary")
58
+ return await renderSummary(tx);
59
+ if (format === "json")
60
+ return { format: "json", state: await loadState(tx) };
61
+ if (format === "jsonl")
62
+ return await renderJsonl(tx, input);
63
+ return await renderPrettyTable(tx, input);
64
+ });
65
+ };
66
+ }
67
+ // ---------------------------------------------------------------------
68
+ // summary — small per-table counts. Avoids loading PipelineState so a
69
+ // state-get call against an uninitialized project still returns a
70
+ // useful envelope.
71
+ // ---------------------------------------------------------------------
72
+ async function renderSummary(tx) {
73
+ const ps = await tx.queryRow("SELECT task_id, status, owner_id FROM pipeline_state WHERE id = 1");
74
+ const pendingRow = await tx.queryRow("SELECT COUNT(*) AS c FROM pending_agents");
75
+ const gatesRow = await tx.queryRow("SELECT COUNT(*) AS c FROM gates");
76
+ const auditRow = await tx.queryRow("SELECT COUNT(*) AS c FROM audit");
77
+ const findingsRow = await tx.queryRow("SELECT COUNT(*) AS c FROM findings");
78
+ return {
79
+ format: "summary",
80
+ summary: {
81
+ task_id: ps?.task_id ?? null,
82
+ status: ps?.status ?? null,
83
+ owner_id: ps?.owner_id ?? null,
84
+ pending_agent_count: Number(pendingRow?.c ?? 0),
85
+ gate_count: Number(gatesRow?.c ?? 0),
86
+ audit_row_count: Number(auditRow?.c ?? 0),
87
+ finding_count: Number(findingsRow?.c ?? 0),
88
+ },
89
+ };
90
+ }
91
+ // ---------------------------------------------------------------------
92
+ // jsonl — each row of the requested table on its own line.
93
+ // ---------------------------------------------------------------------
94
+ async function renderJsonl(tx, input) {
95
+ const table = resolveTable(input.table);
96
+ const limit = clampLimit(input.limit);
97
+ const rows = await queryTable(tx, table, input.since, limit);
98
+ return { format: "jsonl", lines: rows.map((r) => JSON.stringify(r)) };
99
+ }
100
+ // ---------------------------------------------------------------------
101
+ // pretty-table — stable-width ASCII renderer. Widths are
102
+ // max(column name length, max cell length) per column; the same input
103
+ // rows render identically across runs so two state-get snapshots diff
104
+ // cleanly without whitespace noise.
105
+ // ---------------------------------------------------------------------
106
+ async function renderPrettyTable(tx, input) {
107
+ const limit = clampLimit(input.limit);
108
+ const tables = {};
109
+ if (input.table !== undefined) {
110
+ const table = resolveTable(input.table);
111
+ const rows = await queryTable(tx, table, input.since, limit);
112
+ tables[table] = renderTable(rows);
113
+ return { format: "pretty-table", tables };
114
+ }
115
+ const table = DEFAULT_TABLE;
116
+ const rows = await queryTable(tx, table, input.since, limit);
117
+ tables[table] = renderTable(rows);
118
+ return { format: "pretty-table", tables };
119
+ }
120
+ // ---------------------------------------------------------------------
121
+ // Per-table query helper. Honors `since` only when the table exposes a
122
+ // timestamp column on the allowlist.
123
+ // ---------------------------------------------------------------------
124
+ async function queryTable(tx, table, since, limit) {
125
+ const tsCol = tsColumnFor(table);
126
+ if (since !== undefined && tsCol !== null && TS_FILTERED_TABLES.has(table)) {
127
+ return await tx.queryAll(`SELECT * FROM ${table} WHERE ${tsCol} >= ? LIMIT ?`, [since, limit]);
128
+ }
129
+ return await tx.queryAll(`SELECT * FROM ${table} LIMIT ?`, [limit]);
130
+ }
131
+ function resolveTable(requested) {
132
+ const candidate = requested ?? DEFAULT_TABLE;
133
+ if (!INSPECTABLE_TABLES.has(candidate)) {
134
+ // Fall through to default rather than throwing: the tool is an
135
+ // operator inspection surface, and a typo on the table name should
136
+ // not nuke the call. Future work may surface this as a warning
137
+ // envelope alongside the table dump.
138
+ return DEFAULT_TABLE;
139
+ }
140
+ return candidate;
141
+ }
142
+ function renderTable(rows) {
143
+ if (rows.length === 0)
144
+ return "(empty)";
145
+ const headers = Object.keys(rows[0]);
146
+ const widths = headers.map((h) => {
147
+ let w = h.length;
148
+ for (const row of rows) {
149
+ const cell = stringifyCell(row[h]);
150
+ if (cell.length > w)
151
+ w = cell.length;
152
+ }
153
+ return w;
154
+ });
155
+ const headerLine = headers
156
+ .map((h, i) => h.padEnd(widths[i]))
157
+ .join(" | ");
158
+ const sep = widths.map((w) => "-".repeat(w)).join("-+-");
159
+ const body = rows
160
+ .map((row) => headers
161
+ .map((h, i) => stringifyCell(row[h]).padEnd(widths[i]))
162
+ .join(" | "))
163
+ .join("\n");
164
+ return `${headerLine}\n${sep}\n${body}`;
165
+ }
166
+ function stringifyCell(v) {
167
+ if (v === null || v === undefined)
168
+ return "";
169
+ if (typeof v === "string")
170
+ return v;
171
+ if (typeof v === "number" || typeof v === "boolean" || typeof v === "bigint") {
172
+ return String(v);
173
+ }
174
+ return JSON.stringify(v);
175
+ }
176
+ //# sourceMappingURL=state-get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-get.js","sourceRoot":"","sources":["../../../src/tools/state-get.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { KernelDirective } from "@loomfsm/kernel";
2
+ import type { TransportAdapter, TransportResponse } from "@loomfsm/transport-types";
3
+ export declare function createTransportAdapter(): TransportAdapter;
4
+ export declare function shape(directive: KernelDirective, ctx: {
5
+ driver_state_id: string;
6
+ }): TransportResponse;
@@ -0,0 +1,94 @@
1
+ // The MCP transport adapter — pure mapping `KernelDirective →
2
+ // TransportResponse`.
3
+ //
4
+ // No I/O, no DB reads, no clock reads: the same directive in produces a
5
+ // structurally-equal envelope out. Pushing the kernel-to-wire seam into
6
+ // one pure function lets every transport carry its own copy without
7
+ // re-implementing kernel reads, and keeps the kernel free of any
8
+ // wire-shape coupling.
9
+ //
10
+ // `runner_hint` is hard-coded to "mcp-server" on every emitted spawn
11
+ // descriptor; the hint is opaque to the kernel and lets the host
12
+ // disambiguate provider routing.
13
+ //
14
+ // `advance` is never a top-level `runFSM` result — the tick loop
15
+ // swallows it internally and only returns at a terminal directive. The
16
+ // adapter refuses the impossible with a `KERNEL_INVARIANT` error rather
17
+ // than crashing, so a kernel regression surfaces as a structured wire
18
+ // error the client can display.
19
+ const RUNNER_HINT = "mcp-server";
20
+ export function createTransportAdapter() {
21
+ return { shape };
22
+ }
23
+ export function shape(directive, ctx) {
24
+ switch (directive.kind) {
25
+ case "advance":
26
+ return {
27
+ status: "error",
28
+ driver_state_id: ctx.driver_state_id,
29
+ code: "KERNEL_INVARIANT",
30
+ message: "top-level advance directive surfaced — kernel must terminate at a non-advance kind",
31
+ recovery_options: [],
32
+ };
33
+ case "shuttle": {
34
+ const intent = directive.spawn;
35
+ return {
36
+ status: "spawn-agent",
37
+ driver_state_id: ctx.driver_state_id,
38
+ agent_run_id: intent.agent_run_id,
39
+ agent: intent.agent,
40
+ spawn_request: toSpawnRequest(intent),
41
+ };
42
+ }
43
+ case "shuttle-batch":
44
+ return {
45
+ status: "spawn-agents-parallel",
46
+ driver_state_id: ctx.driver_state_id,
47
+ spawns: directive.spawns.map((intent) => ({
48
+ agent_run_id: intent.agent_run_id,
49
+ agent: intent.agent,
50
+ spawn_request: toSpawnRequest(intent),
51
+ })),
52
+ };
53
+ case "ask-user":
54
+ return {
55
+ status: "ask-user",
56
+ driver_state_id: directive.driver_state_id,
57
+ gate: directive.gate,
58
+ gate_event_id: directive.gate_event_id,
59
+ message: directive.message,
60
+ valid_answers: directive.valid_answers,
61
+ };
62
+ case "complete":
63
+ return {
64
+ status: "complete",
65
+ task_id: directive.task_id,
66
+ verdict: directive.verdict,
67
+ summary: directive.summary,
68
+ };
69
+ case "error":
70
+ return {
71
+ status: "error",
72
+ driver_state_id: directive.driver_state_id,
73
+ code: directive.code,
74
+ message: directive.message,
75
+ recovery_options: directive.recovery_options,
76
+ };
77
+ default: {
78
+ const _exhaustive = directive;
79
+ return _exhaustive;
80
+ }
81
+ }
82
+ }
83
+ function toSpawnRequest(intent) {
84
+ const req = {
85
+ runner_hint: RUNNER_HINT,
86
+ description: `${intent.agent} (${intent.phase})`,
87
+ prompt: intent.prompt,
88
+ model: intent.model,
89
+ };
90
+ if (intent.extras !== undefined)
91
+ req.extras = intent.extras;
92
+ return req;
93
+ }
94
+ //# sourceMappingURL=transport-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-adapter.js","sourceRoot":"","sources":["../../src/transport-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,171 @@
1
+ import type { ContinueTaskInput, ExtensionKind, ExtensionManifest, PipelineStateView, StackInfo } from "@loomfsm/kernel";
2
+ import type { SpawnRequest, TransportResponse } from "@loomfsm/transport-types";
3
+ export type { PipelineStateView };
4
+ export type { ContinueTaskInput, SpawnRequest, TransportResponse };
5
+ export interface ClientCapabilities {
6
+ honors_shuttle?: boolean;
7
+ supports_sse?: boolean;
8
+ supports_streaming?: boolean;
9
+ }
10
+ export interface MetaInput {
11
+ client_identifier_unverified?: string;
12
+ client_capabilities?: ClientCapabilities;
13
+ }
14
+ export interface MetaTransports {
15
+ active: string;
16
+ available: string[];
17
+ }
18
+ export interface MetaProviders {
19
+ enabled: string[];
20
+ active_default: string;
21
+ compatible_with_client: string[];
22
+ }
23
+ export interface MetaBundle {
24
+ name: string;
25
+ version: string;
26
+ }
27
+ export interface MetaSandbox {
28
+ kind: string;
29
+ }
30
+ export interface PipelineMetaResponse {
31
+ protocol_version: string;
32
+ plugin_api_version: string;
33
+ kernel_version: string;
34
+ client_identifier_unverified: string;
35
+ flag_vocabulary: string[];
36
+ transports: MetaTransports;
37
+ providers: MetaProviders;
38
+ bundles_available: MetaBundle[];
39
+ sandbox: MetaSandbox;
40
+ }
41
+ export type StateGetFormat = "summary" | "json" | "jsonl" | "pretty-table";
42
+ export interface StateGetInput {
43
+ project_dir: string;
44
+ format?: StateGetFormat;
45
+ table?: string;
46
+ since?: string;
47
+ limit?: number;
48
+ }
49
+ export type ExtensionStatus = "enabled" | "disabled" | "failed";
50
+ export interface ExtensionsListInput {
51
+ project_dir: string;
52
+ kind?: ExtensionKind;
53
+ status?: ExtensionStatus;
54
+ include_manifest?: boolean;
55
+ }
56
+ export interface ExtensionsListEntry {
57
+ id: string;
58
+ kind: ExtensionKind;
59
+ name: string;
60
+ publisher: string;
61
+ version: string;
62
+ status: ExtensionStatus;
63
+ installed_at: string;
64
+ updated_at: string;
65
+ failure_reason?: string;
66
+ manifest?: ExtensionManifest;
67
+ }
68
+ export interface ExtensionsListResponse {
69
+ extensions: ExtensionsListEntry[];
70
+ }
71
+ export interface ParsedTaskArgs {
72
+ task: string;
73
+ policy_preset?: string;
74
+ warnings: string[];
75
+ }
76
+ export interface RunTaskInput {
77
+ project_dir: string;
78
+ task: string;
79
+ client_idempotency_uuid: string;
80
+ policy_preset?: string;
81
+ gate_policies?: Record<string, string>;
82
+ complexity_hint?: "simple" | "medium" | "complex";
83
+ tests_mode_hint?: "tdd" | "regression-only";
84
+ stack?: StackInfo;
85
+ owner_id?: string;
86
+ client_identifier_unverified?: string;
87
+ }
88
+ export interface RunTaskResponse {
89
+ response: TransportResponse;
90
+ task_id?: string;
91
+ driver_state_id?: string;
92
+ warnings?: string[];
93
+ }
94
+ export interface ContinueTaskRequestInput {
95
+ project_dir: string;
96
+ driver_state_id: string;
97
+ input: ContinueTaskInput;
98
+ client_identifier_unverified?: string;
99
+ }
100
+ export interface ContinueTaskResponse {
101
+ response: TransportResponse;
102
+ }
103
+ export type RecoveryChoiceInput = "abandon" | "force-close" | "retry" | "retry-failed" | "cancel-pending";
104
+ export interface BypassMarkerInput {
105
+ issued_at: string;
106
+ expires_at: string;
107
+ reason: string;
108
+ hmac: string;
109
+ key_id: string;
110
+ }
111
+ export interface RecoverTaskInput {
112
+ project_dir: string;
113
+ driver_state_id: string;
114
+ choice: RecoveryChoiceInput;
115
+ agent_run_ids?: string[];
116
+ recovery_id?: string;
117
+ owner_id?: string;
118
+ marker?: BypassMarkerInput;
119
+ client_identifier_unverified?: string;
120
+ }
121
+ export interface IssueCrossOwnerMarkerInput {
122
+ project_dir: string;
123
+ driver_state_id: string;
124
+ ttl_ms: number;
125
+ client_identifier_unverified?: string;
126
+ }
127
+ export interface IssueCrossOwnerMarkerResponse {
128
+ key_id: string | null;
129
+ hmac: string | null;
130
+ issued_at: string | null;
131
+ expires_at: string | null;
132
+ reason: string | null;
133
+ error?: {
134
+ code: string;
135
+ message: string;
136
+ };
137
+ }
138
+ export interface RecoverTaskResponse {
139
+ response: TransportResponse;
140
+ recovery_id: string;
141
+ }
142
+ export interface BackupInput {
143
+ project_dir: string;
144
+ to: string;
145
+ client_identifier_unverified?: string;
146
+ }
147
+ export interface BackupResponse {
148
+ bytes_written: number | null;
149
+ ts: string;
150
+ backup_path: string | null;
151
+ error?: {
152
+ code: string;
153
+ message: string;
154
+ };
155
+ }
156
+ export interface RestoreInput {
157
+ project_dir: string;
158
+ from: string;
159
+ format: "sql" | "binary";
160
+ confirm?: boolean;
161
+ client_identifier_unverified?: string;
162
+ }
163
+ export interface RestoreResponse {
164
+ restored: boolean;
165
+ ts: string;
166
+ error?: {
167
+ code: string;
168
+ message: string;
169
+ };
170
+ }
171
+ export type ToolHandler<I, O> = (input: I) => Promise<O>;
@@ -0,0 +1,9 @@
1
+ // Local envelopes returned by the read-only tools.
2
+ //
3
+ // Defined here rather than in a shared transport-types package so the
4
+ // read-only surface stays self-contained; when the mutating tools land
5
+ // and need to emit a wire-shared response shape, that work extracts a
6
+ // transport-types package and shifts these or their richer siblings
7
+ // into it.
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,sEAAsE;AACtE,uEAAuE;AACvE,sEAAsE;AACtE,oEAAoE;AACpE,WAAW"}