@tacuchi/agent-workflow-cli 23.0.0 → 25.0.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 +37 -1
- package/dist/adapters/postgres-readonly-tools.js +277 -0
- package/dist/adapters/postgres-readonly-tools.js.map +1 -0
- package/dist/application/checkpoint/markdown.js +85 -5
- package/dist/application/checkpoint/markdown.js.map +1 -1
- package/dist/application/checkpoint-service.js +7 -6
- package/dist/application/checkpoint-service.js.map +1 -1
- package/dist/application/checkpoint-write-service.js +270 -16
- package/dist/application/checkpoint-write-service.js.map +1 -1
- package/dist/application/database-mcp-server.js +168 -0
- package/dist/application/database-mcp-server.js.map +1 -0
- package/dist/application/database-mcp-stdio.js +137 -0
- package/dist/application/database-mcp-stdio.js.map +1 -0
- package/dist/application/database-tool-catalog.js +226 -0
- package/dist/application/database-tool-catalog.js.map +1 -0
- package/dist/application/dsn-reader-service.js +1 -1
- package/dist/application/flow/advance.js +60 -10
- package/dist/application/flow/advance.js.map +1 -1
- package/dist/application/flow/internal-actions.js +1 -1
- package/dist/application/flow/internal-actions.js.map +1 -1
- package/dist/application/flow/submit.js +256 -9
- package/dist/application/flow/submit.js.map +1 -1
- package/dist/application/lifecycle-target.js +16 -19
- package/dist/application/lifecycle-target.js.map +1 -1
- package/dist/application/lock-service.js +96 -31
- package/dist/application/lock-service.js.map +1 -1
- package/dist/application/logging/log-events.js +19 -3
- package/dist/application/logging/log-events.js.map +1 -1
- package/dist/application/logging/logger.js +2 -2
- package/dist/application/logging/logger.js.map +1 -1
- package/dist/application/markdown.js +6 -2
- package/dist/application/markdown.js.map +1 -1
- package/dist/application/mcp-connections-service.js +115 -41
- package/dist/application/mcp-connections-service.js.map +1 -1
- package/dist/application/mcp-doctor-service.js +98 -54
- package/dist/application/mcp-doctor-service.js.map +1 -1
- package/dist/application/mcp-entry-classification.js +60 -0
- package/dist/application/mcp-entry-classification.js.map +1 -0
- package/dist/application/mcp-host-reader.js +102 -86
- package/dist/application/mcp-host-reader.js.map +1 -1
- package/dist/application/mcp-host-receipt-service.js +399 -0
- package/dist/application/mcp-host-receipt-service.js.map +1 -0
- package/dist/application/mcp-host-receipt-store.js +122 -0
- package/dist/application/mcp-host-receipt-store.js.map +1 -0
- package/dist/application/mcp-host-receipts.js +28 -0
- package/dist/application/mcp-host-receipts.js.map +1 -0
- package/dist/application/mcp-host-writer.js +209 -38
- package/dist/application/mcp-host-writer.js.map +1 -1
- package/dist/application/mcp-launch-probe-service.js +142 -0
- package/dist/application/mcp-launch-probe-service.js.map +1 -0
- package/dist/application/mcp-migration-service.js +351 -0
- package/dist/application/mcp-migration-service.js.map +1 -0
- package/dist/application/mcp-native-host-check-service.js +154 -0
- package/dist/application/mcp-native-host-check-service.js.map +1 -0
- package/dist/application/mcp-receipt-registration-service.js +105 -0
- package/dist/application/mcp-receipt-registration-service.js.map +1 -0
- package/dist/application/mcp-receipt-removal-service.js +62 -0
- package/dist/application/mcp-receipt-removal-service.js.map +1 -0
- package/dist/application/mcp-remove-service.js +83 -24
- package/dist/application/mcp-remove-service.js.map +1 -1
- package/dist/application/mcp-scope-common.js +1 -1
- package/dist/application/mcp-scope-common.js.map +1 -1
- package/dist/application/mcp-setup-service.js +59 -24
- package/dist/application/mcp-setup-service.js.map +1 -1
- package/dist/application/mcp-stdio-probe.js +526 -0
- package/dist/application/mcp-stdio-probe.js.map +1 -0
- package/dist/application/mcp-test-connection-service.js +23 -50
- package/dist/application/mcp-test-connection-service.js.map +1 -1
- package/dist/application/parsers/spec-functional.js +220 -0
- package/dist/application/parsers/spec-functional.js.map +1 -0
- package/dist/application/parsers/spec-relation.js +142 -5
- package/dist/application/parsers/spec-relation.js.map +1 -1
- package/dist/application/paths-service.js +13 -0
- package/dist/application/paths-service.js.map +1 -1
- package/dist/application/plan-exec-decision-service.js +57 -4
- package/dist/application/plan-exec-decision-service.js.map +1 -1
- package/dist/application/reseal-service.js +300 -0
- package/dist/application/reseal-service.js.map +1 -0
- package/dist/application/self/host-states.js.map +1 -1
- package/dist/application/self/install-skill.js +4 -34
- package/dist/application/self/install-skill.js.map +1 -1
- package/dist/application/self/mcp-config.js +369 -59
- package/dist/application/self/mcp-config.js.map +1 -1
- package/dist/application/self/mcp-via-state.js +9 -6
- package/dist/application/self/mcp-via-state.js.map +1 -1
- package/dist/application/self/uninstall-skill.js +3 -18
- package/dist/application/self/uninstall-skill.js.map +1 -1
- package/dist/application/self/uninstall.js +4 -23
- package/dist/application/self/uninstall.js.map +1 -1
- package/dist/application/workline-index-service.js +64 -6
- package/dist/application/workline-index-service.js.map +1 -1
- package/dist/application/workspace-init-service.js +4 -6
- package/dist/application/workspace-init-service.js.map +1 -1
- package/dist/cli/commands/checkpoint-write.js +24 -22
- package/dist/cli/commands/checkpoint-write.js.map +1 -1
- package/dist/cli/commands/index.js +7 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/mcp.js +642 -55
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/reseal.js +140 -0
- package/dist/cli/commands/reseal.js.map +1 -0
- package/dist/cli/commands/status.js +5 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/tool.js +141 -0
- package/dist/cli/commands/tool.js.map +1 -0
- package/dist/cli/help-groups.js +7 -1
- package/dist/cli/help-groups.js.map +1 -1
- package/dist/cli/main.js +189 -57
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/parser.js +5 -1
- package/dist/cli/parser.js.map +1 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli/render.js +15 -2
- package/dist/cli/render.js.map +1 -1
- package/dist/cli/tui/components/host-admin-section.js +2 -46
- package/dist/cli/tui/components/host-admin-section.js.map +1 -1
- package/dist/cli/tui/tabs/mcp-tab-helpers.js +71 -0
- package/dist/cli/tui/tabs/mcp-tab-helpers.js.map +1 -1
- package/dist/cli/tui/tabs/mcp-tab.js +101 -42
- package/dist/cli/tui/tabs/mcp-tab.js.map +1 -1
- package/dist/domain/database-tools.js +445 -0
- package/dist/domain/database-tools.js.map +1 -0
- package/dist/domain/effective-contract.js +10 -2
- package/dist/domain/effective-contract.js.map +1 -1
- package/dist/domain/flow/answer.js +4 -0
- package/dist/domain/flow/answer.js.map +1 -1
- package/dist/domain/flow/authority.js +103 -14
- package/dist/domain/flow/authority.js.map +1 -1
- package/dist/domain/flow/directive.js +2 -0
- package/dist/domain/flow/directive.js.map +1 -1
- package/dist/domain/flow/run-state.js +42 -0
- package/dist/domain/flow/run-state.js.map +1 -1
- package/dist/domain/lineage.js +38 -11
- package/dist/domain/lineage.js.map +1 -1
- package/dist/domain/mcp-entry.js +131 -17
- package/dist/domain/mcp-entry.js.map +1 -1
- package/dist/domain/postgres-object-search.js +320 -0
- package/dist/domain/postgres-object-search.js.map +1 -0
- package/dist/domain/redaction.js +47 -0
- package/dist/domain/redaction.js.map +1 -0
- package/dist/domain/workline-mcp-entry.js +6 -9
- package/dist/domain/workline-mcp-entry.js.map +1 -1
- package/dist/ports/postgres-tools.js +10 -0
- package/dist/ports/postgres-tools.js.map +1 -0
- package/package.json +5 -1
- package/skills/w/commands/plan-exec.md +1 -1
- package/skills/w/commands/spec-new.md +6 -5
- package/skills/w/context/MANIFEST.json +1 -1
- package/skills/w/harness/HARNESS.md +1 -1
- package/skills/w/hooks/README.md +13 -9
- package/skills/w/hooks/hooks.template.json +2 -2
- package/skills/w/loops/CHASSIS.md +1 -1
- package/skills/w/loops/plan-exec-loop/LOOP.md +7 -5
- package/skills/w/loops/plan-new-loop/LOOP.md +46 -41
- package/skills/w/loops/plan-refine-loop/LOOP.md +4 -4
- package/skills/w/loops/quick-loop/LOOP.md +12 -13
- package/skills/w/loops/spec-refine-loop/LOOP.md +7 -3
- package/skills/w/modules/COMPACTION.md +1 -1
- package/skills/w/modules/PLAN-INPUT.md +3 -3
- package/skills/w/modules/PROMPT-CONTINUITY.md +1 -1
- package/dist/application/mcp-dbhub-launcher.js +0 -216
- package/dist/application/mcp-dbhub-launcher.js.map +0 -1
- package/dist/application/self/mcp-offer.js +0 -96
- package/dist/application/self/mcp-offer.js.map +0 -1
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { findActiveSessions } from "./checkpoint-service.js";
|
|
3
3
|
import { totalInScope } from "./checkpoint/files-touched.js";
|
|
4
|
-
import { formatCheckpointMd, isPristineCheckpoint } from "./checkpoint/markdown.js";
|
|
4
|
+
import { appendSealedBlock, blocksUnder, formatCheckpointMd, isPristineCheckpoint, } from "./checkpoint/markdown.js";
|
|
5
5
|
import { extractSessionState } from "./checkpoint/state-reader.js";
|
|
6
|
-
import {
|
|
6
|
+
import { localMinuteIso } from "./dates.js";
|
|
7
|
+
import { resolveLifecycleTarget, } from "./lifecycle-target.js";
|
|
8
|
+
import { parseMdValue } from "./markdown.js";
|
|
7
9
|
import { resolveWorkspaceRoot } from "./paths-service.js";
|
|
10
|
+
import { relpath } from "./paths.js";
|
|
11
|
+
import { hashContextId } from "./session-binding-service.js";
|
|
8
12
|
import { writeSessionNarrative } from "./session-narrative.js";
|
|
9
13
|
// This module deliberately owns NO placeholder marker of its own. `_[AI:` used
|
|
10
14
|
// to be declared here as well as in `checkpoint-service.ts`, with incompatible
|
|
@@ -27,18 +31,26 @@ export async function runCheckpointWrite(fs, env, git, paths, options = {}) {
|
|
|
27
31
|
// the association to land on the same one.
|
|
28
32
|
const target = await resolveLifecycleTarget(fs, paths, options, "bind");
|
|
29
33
|
if (target.outcome !== "resolved")
|
|
30
|
-
return unresolved(fs, paths, target);
|
|
34
|
+
return unresolved(fs, paths, target, options);
|
|
31
35
|
const session = target.session;
|
|
32
36
|
const cpPath = join(session.path, "CHECKPOINT.md");
|
|
33
37
|
if (await hasContentToPreserve(fs, cpPath, options.force === true)) {
|
|
38
|
+
// Adoption runs even here: preservation protects written prose from being
|
|
39
|
+
// REGENERATED, and folding a refuge in only appends to it.
|
|
40
|
+
const adopted = await adoptRefuge(fs, paths, session, adoptionScope(options));
|
|
34
41
|
return {
|
|
35
42
|
session: session.folder,
|
|
36
43
|
checkpoint_path: cpPath,
|
|
37
44
|
skipped: true,
|
|
38
45
|
preserved: true,
|
|
39
46
|
reason: PRESERVED_REASON,
|
|
47
|
+
...adoptedField(adopted.adopted),
|
|
40
48
|
};
|
|
41
49
|
}
|
|
50
|
+
// Read BEFORE the write that replaces it: an adopted refuge is not part of any
|
|
51
|
+
// template, so regenerating without carrying it across would drop the state
|
|
52
|
+
// the refuge existed to save (its file on disk is long gone).
|
|
53
|
+
const carried = await carriedAdoptions(fs, cpPath);
|
|
42
54
|
// The workspace root rather than the raw cwd. Today the two coincide by
|
|
43
55
|
// construction — session resolution already refuses to run from a
|
|
44
56
|
// subdirectory, so nothing reaches here with a deeper cwd — and what actually
|
|
@@ -48,13 +60,16 @@ export async function runCheckpointWrite(fs, env, git, paths, options = {}) {
|
|
|
48
60
|
// widen to the parent repository along with it.
|
|
49
61
|
const workspaceRoot = await resolveWorkspaceRoot(fs, env, paths);
|
|
50
62
|
const state = await extractSessionState(fs, git, workspaceRoot, session.path);
|
|
51
|
-
const md = formatCheckpointMd(state);
|
|
63
|
+
const md = withCarried(formatCheckpointMd(state), carried);
|
|
52
64
|
await fs.mkdirp(session.path);
|
|
53
65
|
await fs.writeText(cpPath, md);
|
|
54
66
|
// The CHECKPOINT is where progress lives, so writing one is exactly when the
|
|
55
67
|
// session's entry point stops being current. Refreshed here and never on a
|
|
56
68
|
// read, which is what keeps a `status` or a `resume` from rewriting history.
|
|
57
69
|
await writeSessionNarrative(fs, paths, { folder: session.folder, path: session.path });
|
|
70
|
+
// Last, never first: a refuge is folded into the checkpoint this run just
|
|
71
|
+
// produced, so the file it appends to is already there.
|
|
72
|
+
const adopted = await adoptRefuge(fs, paths, session, adoptionScope(options));
|
|
58
73
|
return {
|
|
59
74
|
session: session.folder,
|
|
60
75
|
checkpoint_path: cpPath,
|
|
@@ -63,33 +78,40 @@ export async function runCheckpointWrite(fs, env, git, paths, options = {}) {
|
|
|
63
78
|
tasks_open: state.tasks.open,
|
|
64
79
|
tasks_closed: state.tasks.closed,
|
|
65
80
|
files_touched_count: totalInScope(state.files_touched),
|
|
81
|
+
...adoptedField(adopted.adopted),
|
|
66
82
|
};
|
|
67
83
|
}
|
|
68
84
|
/**
|
|
69
85
|
* SessionEnd. It used to iterate EVERY active session, so closing one host
|
|
70
86
|
* conversation wrote checkpoints over lines belonging to others. It now
|
|
71
|
-
* checkpoints the resolved target and nothing else; with no sufficient
|
|
72
|
-
*
|
|
73
|
-
* left to answer a selection prompt: this surface always degrades, never blocks.
|
|
87
|
+
* checkpoints the resolved target and nothing else; with no sufficient identity
|
|
88
|
+
* it writes no session line at all and parks a refuge instead.
|
|
74
89
|
*/
|
|
75
90
|
export async function runAutoCompactOnClose(fs, env, git, paths, options = {}) {
|
|
76
91
|
// Does NOT bind: the host is exiting, so there is no later turn the
|
|
77
92
|
// association could serve, and establishing one is a locked write that fails
|
|
78
93
|
// the whole resolution when it cannot be taken — which would cost the
|
|
79
94
|
// checkpoint this surface exists to save.
|
|
80
|
-
const target = await resolveLifecycleTarget(fs, paths,
|
|
95
|
+
const target = await resolveLifecycleTarget(fs, paths, options, "read-only");
|
|
81
96
|
if (target.outcome !== "resolved") {
|
|
82
|
-
const detail = unresolvedDetail(target);
|
|
83
97
|
return {
|
|
84
98
|
checkpoints_written: [],
|
|
85
99
|
continuity: "degraded",
|
|
86
100
|
primary_session: null,
|
|
87
|
-
candidates:
|
|
88
|
-
action:
|
|
101
|
+
candidates: target.candidates,
|
|
102
|
+
action: target.action,
|
|
103
|
+
refuge_path: await parkRefuge(fs, paths, target, options.contextId),
|
|
89
104
|
};
|
|
90
105
|
}
|
|
91
106
|
const workspaceRoot = await resolveWorkspaceRoot(fs, env, paths);
|
|
92
107
|
const entry = await writeCheckpointForTarget(fs, git, workspaceRoot, target.session);
|
|
108
|
+
// Only over a checkpoint that exists: `writeCheckpointForTarget` reports its
|
|
109
|
+
// own failure instead of throwing, and appending a refuge to a file that was
|
|
110
|
+
// never written would file the parked state under a session line nobody wrote.
|
|
111
|
+
if (entry.error === undefined) {
|
|
112
|
+
const adopted = await adoptRefuge(fs, paths, target.session, adoptionScope(options));
|
|
113
|
+
return { checkpoints_written: [{ ...entry, ...adoptedField(adopted.adopted) }] };
|
|
114
|
+
}
|
|
93
115
|
return { checkpoints_written: [entry] };
|
|
94
116
|
}
|
|
95
117
|
async function writeCheckpointForTarget(fs, git, workspaceRoot, session) {
|
|
@@ -106,8 +128,9 @@ async function writeCheckpointForTarget(fs, git, workspaceRoot, session) {
|
|
|
106
128
|
};
|
|
107
129
|
}
|
|
108
130
|
try {
|
|
131
|
+
const carried = await carriedAdoptions(fs, cpPath);
|
|
109
132
|
const state = await extractSessionState(fs, git, workspaceRoot, session.path);
|
|
110
|
-
const md = formatCheckpointMd(state);
|
|
133
|
+
const md = withCarried(formatCheckpointMd(state), carried);
|
|
111
134
|
await fs.mkdirp(session.path);
|
|
112
135
|
await fs.writeText(cpPath, md);
|
|
113
136
|
return {
|
|
@@ -138,10 +161,23 @@ async function hasContentToPreserve(fs, cpPath, force) {
|
|
|
138
161
|
return false;
|
|
139
162
|
return !isPristineCheckpoint(await fs.readText(cpPath));
|
|
140
163
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
164
|
+
/**
|
|
165
|
+
* The refuge sections an existing CHECKPOINT already carries.
|
|
166
|
+
*
|
|
167
|
+
* Read before every regeneration and written back after it (see
|
|
168
|
+
* {@link withCarried}). "Preserve" protects somebody's prose; carrying protects
|
|
169
|
+
* the CLI's own folded-in state, which preservation deliberately does NOT cover
|
|
170
|
+
* because a checkpoint the CLI wrote must stay regenerable.
|
|
171
|
+
*/
|
|
172
|
+
async function carriedAdoptions(fs, cpPath) {
|
|
173
|
+
if (!(await fs.exists(cpPath)))
|
|
174
|
+
return [];
|
|
175
|
+
return blocksUnder(await fs.readText(cpPath), ADOPTED_HEADING);
|
|
176
|
+
}
|
|
177
|
+
function withCarried(md, carried) {
|
|
178
|
+
return carried.reduce((text, block) => appendSealedBlock(text, block), md);
|
|
179
|
+
}
|
|
180
|
+
async function unresolved(fs, paths, target, options) {
|
|
145
181
|
const actives = await findActiveSessions(fs, paths);
|
|
146
182
|
return {
|
|
147
183
|
skipped: true,
|
|
@@ -151,6 +187,224 @@ async function unresolved(fs, paths, target) {
|
|
|
151
187
|
active_sessions: actives.map((a) => a.folder),
|
|
152
188
|
candidates: target.candidates,
|
|
153
189
|
action: target.action,
|
|
190
|
+
refuge_path: await parkRefuge(fs, paths, target, options.contextId),
|
|
154
191
|
};
|
|
155
192
|
}
|
|
193
|
+
// ── the refuge: state a lifecycle surface saves when no session resolves ─────
|
|
194
|
+
//
|
|
195
|
+
// This exists because the PreCompact hook stopped being allowed to block (see
|
|
196
|
+
// `resolveLifecycleTarget`). Losing the protective pause without replacing it
|
|
197
|
+
// would mean the compaction that follows an unresolved target takes the run's
|
|
198
|
+
// context away and leaves nothing behind. So the reason, the candidates and the
|
|
199
|
+
// way out are written to a file OUTSIDE any session — nothing has to be guessed
|
|
200
|
+
// to place it — and the first invocation that does resolve the session folds it
|
|
201
|
+
// into that session's CHECKPOINT.
|
|
202
|
+
/** `- Fecha:` / `- Conversación:` — the two lines adoption reads back. */
|
|
203
|
+
const REFUGE_DATE_KEY = "Fecha";
|
|
204
|
+
const REFUGE_CONVERSATION_KEY = "Conversación";
|
|
205
|
+
/** The heading an adopted refuge lands under, inside the CHECKPOINT's sealed body. */
|
|
206
|
+
const ADOPTED_HEADING = "## Refugio adoptado";
|
|
207
|
+
/**
|
|
208
|
+
* What `- Conversación:` says — and what the file is called — when the host gave
|
|
209
|
+
* no conversation id.
|
|
210
|
+
*
|
|
211
|
+
* Such a refuge cannot be matched to anybody, so only an explicit `--code`
|
|
212
|
+
* adopts it: a person naming the session IS the missing identity. The name
|
|
213
|
+
* carries no instant on purpose: stamping it would make every compaction of
|
|
214
|
+
* every id-less invocation pile up another file in a directory nothing sweeps,
|
|
215
|
+
* where the digest case leaves exactly one. One file, latest reason, same rule.
|
|
216
|
+
*/
|
|
217
|
+
const REFUGE_NO_CONVERSATION = "desconocida";
|
|
218
|
+
/**
|
|
219
|
+
* The conversation is named by the SHA-256 of its id, never by the id.
|
|
220
|
+
*
|
|
221
|
+
* Same rule as the bindings registry (`hashContextId`): the host's opaque
|
|
222
|
+
* conversation id never reaches disk in the clear. It also makes the file name
|
|
223
|
+
* safe by construction — 64 hex characters cannot escape a directory — and
|
|
224
|
+
* stable, so a conversation that compacts five times leaves ONE refuge with its
|
|
225
|
+
* latest reason instead of five.
|
|
226
|
+
*/
|
|
227
|
+
const REFUGE_DIGEST_PREFIX = "sha256:";
|
|
228
|
+
/** Where the parked state goes, and its workspace-relative path for the caller. */
|
|
229
|
+
export async function writeRefugeCheckpoint(fs, paths, input) {
|
|
230
|
+
const now = input.now ?? new Date();
|
|
231
|
+
const digest = input.contextId !== undefined ? hashContextId(input.contextId) : null;
|
|
232
|
+
const dir = paths.cwdSessionsRefugeDir();
|
|
233
|
+
const path = join(dir, `${digest ?? REFUGE_NO_CONVERSATION}.md`);
|
|
234
|
+
await fs.mkdirp(dir);
|
|
235
|
+
await fs.writeText(path, refugeBody(input, now, digest));
|
|
236
|
+
return relpath(path, paths.workspaceDir());
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* A refuge, but ONLY when somebody could adopt it later.
|
|
240
|
+
*
|
|
241
|
+
* With no candidate at all — a workspace between runs, which is the ordinary
|
|
242
|
+
* state — the parked file would name no session anybody could resolve it to,
|
|
243
|
+
* and every compaction of every session-less conversation would leave one
|
|
244
|
+
* behind. The notice on stderr is the whole answer there.
|
|
245
|
+
*/
|
|
246
|
+
async function parkRefuge(fs, paths, target, contextId) {
|
|
247
|
+
if (target.candidates.length === 0)
|
|
248
|
+
return null;
|
|
249
|
+
return writeRefugeCheckpoint(fs, paths, {
|
|
250
|
+
reason: target.reason,
|
|
251
|
+
action: target.action,
|
|
252
|
+
candidates: target.candidates,
|
|
253
|
+
...(contextId !== undefined ? { contextId } : {}),
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Fold every refuge that belongs to this conversation into the session's
|
|
258
|
+
* CHECKPOINT, and remove it.
|
|
259
|
+
*
|
|
260
|
+
* Adding a section is what makes this safe next to the preservation guard: that
|
|
261
|
+
* guard refuses to REGENERATE a written checkpoint, and folding text in takes
|
|
262
|
+
* nothing away from one. It goes in through {@link appendSealedBlock} rather
|
|
263
|
+
* than by appending past the seal, so a checkpoint that was still the CLI's own
|
|
264
|
+
* output stays that way — otherwise the first adoption would freeze the file
|
|
265
|
+
* forever behind "there is content to preserve". Removing the refuge afterwards
|
|
266
|
+
* is not tidying: it is what keeps the next invocation from adopting the same
|
|
267
|
+
* text again — but ONLY once the block is demonstrably in the file, because two
|
|
268
|
+
* concurrent hooks read the same `existing` and the loser's append is not in
|
|
269
|
+
* what finally lands. Removing on the strength of its own write would delete the
|
|
270
|
+
* parked state from both places it existed in. A refuge left on disk costs one
|
|
271
|
+
* more adoption attempt; a refuge deleted for nothing is irrecoverable.
|
|
272
|
+
*/
|
|
273
|
+
export async function adoptRefuge(fs, paths, session, scope = {}) {
|
|
274
|
+
const wanted = digestOfContext(scope.contextId);
|
|
275
|
+
const cpPath = join(session.path, "CHECKPOINT.md");
|
|
276
|
+
const adopted = [];
|
|
277
|
+
// Nothing that happens in here may throw out of a lifecycle surface: a
|
|
278
|
+
// non-zero exit is how a host HOLDS its compaction, and holding it was the
|
|
279
|
+
// irrecoverable trap these surfaces stopped being allowed to set. A failure
|
|
280
|
+
// reports "nothing adopted" and leaves the refuge for the next invocation.
|
|
281
|
+
try {
|
|
282
|
+
for (const refuge of await listRefugeCheckpoints(fs, paths)) {
|
|
283
|
+
if (!adoptable(refuge, wanted, scope.explicitCode === true))
|
|
284
|
+
continue;
|
|
285
|
+
const block = adoptedBlock(refuge);
|
|
286
|
+
// The block as it reads BACK: the plain-append path collapses the trailing
|
|
287
|
+
// blank line, so only the text up to its last character is what both
|
|
288
|
+
// append paths leave verbatim in the file.
|
|
289
|
+
const folded = block.trimEnd();
|
|
290
|
+
const existing = (await fs.exists(cpPath)) ? await fs.readText(cpPath) : "";
|
|
291
|
+
// Already in there — an earlier run adopted it and could not remove the
|
|
292
|
+
// file, or the run this one raced got there first. The state is safe, so
|
|
293
|
+
// the refuge is spent and appending again would only duplicate it.
|
|
294
|
+
if (existing.includes(folded)) {
|
|
295
|
+
await discardRefuge(fs, refuge.path);
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
await fs.mkdirp(session.path);
|
|
299
|
+
await fs.writeText(cpPath, appendSealedBlock(existing, block));
|
|
300
|
+
if (!(await fs.readText(cpPath)).includes(folded))
|
|
301
|
+
continue;
|
|
302
|
+
await discardRefuge(fs, refuge.path);
|
|
303
|
+
adopted.push(refuge.relative);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
// Deliberately silent: the caller's contract is the checkpoint it already
|
|
308
|
+
// wrote, and `refuge_adopted` is simply absent.
|
|
309
|
+
}
|
|
310
|
+
return { adopted };
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Drop a refuge whose text is in the CHECKPOINT.
|
|
314
|
+
*
|
|
315
|
+
* Cleanup, not the adoption itself: the state is already saved, so a removal
|
|
316
|
+
* that fails must not cost the run. The next invocation finds the file again,
|
|
317
|
+
* recognises its own block and retries the removal.
|
|
318
|
+
*/
|
|
319
|
+
async function discardRefuge(fs, path) {
|
|
320
|
+
try {
|
|
321
|
+
await fs.remove(path);
|
|
322
|
+
}
|
|
323
|
+
catch {
|
|
324
|
+
// Left on disk on purpose. It is re-read, not re-adopted.
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* The refuge waiting for this conversation, for a surface that only reports.
|
|
329
|
+
*
|
|
330
|
+
* Symmetric with {@link parkRefuge} on purpose: an invocation with no
|
|
331
|
+
* conversation id parks an ANONYMOUS refuge, so that is exactly the one it must
|
|
332
|
+
* be told about. Cutting off at "no id, no answer" made the one invocation
|
|
333
|
+
* shape that can create such a refuge the only one unable to report it — and in
|
|
334
|
+
* the single channel the model reads, `refuge: null` does not say "I don't
|
|
335
|
+
* know", it says there is none.
|
|
336
|
+
*/
|
|
337
|
+
export async function findRefugeForContext(fs, paths, contextId) {
|
|
338
|
+
const wanted = digestOfContext(contextId);
|
|
339
|
+
const refuges = await listRefugeCheckpoints(fs, paths);
|
|
340
|
+
const found = refuges.find((refuge) => refuge.conversation === wanted);
|
|
341
|
+
return found !== undefined ? { path: found.relative, date: found.date } : null;
|
|
342
|
+
}
|
|
343
|
+
export async function listRefugeCheckpoints(fs, paths) {
|
|
344
|
+
const dir = paths.cwdSessionsRefugeDir();
|
|
345
|
+
if (!(await fs.exists(dir)))
|
|
346
|
+
return [];
|
|
347
|
+
const refuges = [];
|
|
348
|
+
for (const entry of await fs.list(dir)) {
|
|
349
|
+
if (entry.type !== "file" || !entry.name.endsWith(".md"))
|
|
350
|
+
continue;
|
|
351
|
+
const body = await fs.readText(entry.path);
|
|
352
|
+
const conversation = parseMdValue(body, REFUGE_CONVERSATION_KEY);
|
|
353
|
+
refuges.push({
|
|
354
|
+
path: entry.path,
|
|
355
|
+
relative: relpath(entry.path, paths.workspaceDir()),
|
|
356
|
+
date: parseMdValue(body, REFUGE_DATE_KEY) ?? "sin fecha",
|
|
357
|
+
conversation: conversation?.startsWith(REFUGE_DIGEST_PREFIX) ? conversation : null,
|
|
358
|
+
body,
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
// Deterministic order, so an adoption of several refuges reads the same way twice.
|
|
362
|
+
return refuges.sort((a, b) => a.path.localeCompare(b.path));
|
|
363
|
+
}
|
|
364
|
+
/** Whose refuge this is: the conversation's own, or anybody's under an explicit `--code`. */
|
|
365
|
+
function adoptable(refuge, wanted, explicitCode) {
|
|
366
|
+
if (refuge.conversation === null)
|
|
367
|
+
return explicitCode;
|
|
368
|
+
return refuge.conversation === wanted;
|
|
369
|
+
}
|
|
370
|
+
function digestOfContext(contextId) {
|
|
371
|
+
return contextId !== undefined && contextId.trim().length > 0
|
|
372
|
+
? `${REFUGE_DIGEST_PREFIX}${hashContextId(contextId)}`
|
|
373
|
+
: null;
|
|
374
|
+
}
|
|
375
|
+
function adoptionScope(options) {
|
|
376
|
+
return {
|
|
377
|
+
...(options.contextId !== undefined ? { contextId: options.contextId } : {}),
|
|
378
|
+
explicitCode: (options.code?.trim().length ?? 0) > 0,
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
function adoptedBlock(refuge) {
|
|
382
|
+
// The refuge's own H1 would land as a second title inside the CHECKPOINT, and
|
|
383
|
+
// the heading below already says where the text came from. Everything else
|
|
384
|
+
// goes in verbatim: an adoption that summarised would be an adoption that loses.
|
|
385
|
+
const body = refuge.body.replace(/^#[^\n]*\n/, "").trim();
|
|
386
|
+
return `${ADOPTED_HEADING} (${refuge.date})\n\n${body}\n\n`;
|
|
387
|
+
}
|
|
388
|
+
function refugeBody(input, now, digest) {
|
|
389
|
+
const candidates = input.candidates.map((c) => `${c.folder} (${c.state})`).join(" · ");
|
|
390
|
+
return `${[
|
|
391
|
+
"# CHECKPOINT de refugio",
|
|
392
|
+
"",
|
|
393
|
+
"> Lo escribió un hook de ciclo de vida (PreCompact o SessionEnd): la",
|
|
394
|
+
"> compactación —o el cierre— siguió adelante, pero no se pudo resolver a qué",
|
|
395
|
+
"> sesión pertenece esta conversación, así que su estado queda acá en vez de",
|
|
396
|
+
"> perderse. Se adopta en el CHECKPOINT.md de la sesión en cuanto alguien la",
|
|
397
|
+
"> resuelva (`aw checkpoint-write --code <NNN>`).",
|
|
398
|
+
"",
|
|
399
|
+
`- ${REFUGE_DATE_KEY}: ${localMinuteIso(now)}`,
|
|
400
|
+
`- ${REFUGE_CONVERSATION_KEY}: ${digest !== null ? `${REFUGE_DIGEST_PREFIX}${digest}` : REFUGE_NO_CONVERSATION}`,
|
|
401
|
+
`- Motivo: ${input.reason}`,
|
|
402
|
+
`- Candidatas: ${candidates.length > 0 ? candidates : "ninguna"}`,
|
|
403
|
+
`- Acción: ${input.action}`,
|
|
404
|
+
].join("\n")}\n`;
|
|
405
|
+
}
|
|
406
|
+
/** Present only when something was actually adopted — an empty list says nothing. */
|
|
407
|
+
function adoptedField(adopted) {
|
|
408
|
+
return adopted.length > 0 ? { refuge_adopted: adopted } : {};
|
|
409
|
+
}
|
|
156
410
|
//# sourceMappingURL=checkpoint-write-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint-write-service.js","sourceRoot":"","sources":["../../src/application/checkpoint-write-service.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"checkpoint-write-service.js","sourceRoot":"","sources":["../../src/application/checkpoint-write-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { encodeToolResponse, toolFailure } from "../domain/database-tools.js";
|
|
2
|
+
const PROTOCOL_VERSION = "2025-06-18";
|
|
3
|
+
/** JSON-RPC adapter over the shared catalog. It owns no tool rules. */
|
|
4
|
+
export function createDatabaseMcpServer(deps) {
|
|
5
|
+
let lifecycle = "new";
|
|
6
|
+
const activeCalls = new Map();
|
|
7
|
+
const cancelledBeforeStart = new Set();
|
|
8
|
+
function reply(id, result) {
|
|
9
|
+
if (!isJsonRpcResponseId(id))
|
|
10
|
+
return;
|
|
11
|
+
deps.send({ jsonrpc: "2.0", id, result });
|
|
12
|
+
}
|
|
13
|
+
function replyError(id, code, message) {
|
|
14
|
+
if (!isJsonRpcResponseId(id))
|
|
15
|
+
return;
|
|
16
|
+
deps.send({ jsonrpc: "2.0", id, error: { code, message } });
|
|
17
|
+
}
|
|
18
|
+
function toolResult(response) {
|
|
19
|
+
return {
|
|
20
|
+
content: [{ type: "text", text: encodeToolResponse(response), mimeType: "application/json" }],
|
|
21
|
+
...(response.success ? {} : { isError: true }),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
async function dispatchToolCall(message) {
|
|
25
|
+
const params = isRecord(message.params) ? message.params : {};
|
|
26
|
+
const name = typeof params.name === "string" ? params.name : "";
|
|
27
|
+
const requestKey = requestIdKey(message.id);
|
|
28
|
+
// tools/call is a request, not a notification. Rejecting an id-less call
|
|
29
|
+
// prevents an untracked database operation that the client cannot cancel.
|
|
30
|
+
if (requestKey === undefined) {
|
|
31
|
+
replyError(message.id, -32600, "tools/call requiere un id de solicitud válido");
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
if (cancelledBeforeStart.delete(requestKey)) {
|
|
35
|
+
reply(message.id, toolResult(toolFailure("QUERY_CANCELLED", "La consulta fue cancelada.")));
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
const controller = new AbortController();
|
|
39
|
+
activeCalls.set(requestKey, controller);
|
|
40
|
+
try {
|
|
41
|
+
const outcome = await deps.catalog.call({
|
|
42
|
+
tool: name,
|
|
43
|
+
connection: deps.connection,
|
|
44
|
+
input: params.arguments,
|
|
45
|
+
signal: controller.signal,
|
|
46
|
+
});
|
|
47
|
+
reply(message.id, toolResult(outcome.response));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
reply(message.id, toolResult(toolFailure("TOOL_EXECUTION_FAILED", "La tool no pudo completar la solicitud.")));
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
if (activeCalls.get(requestKey) === controller) {
|
|
54
|
+
activeCalls.delete(requestKey);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
async function cancelToolCall(message) {
|
|
60
|
+
const params = isRecord(message.params) ? message.params : {};
|
|
61
|
+
const key = requestIdKey(params.requestId);
|
|
62
|
+
if (key === undefined)
|
|
63
|
+
return true;
|
|
64
|
+
const active = activeCalls.get(key);
|
|
65
|
+
if (active !== undefined) {
|
|
66
|
+
active.abort();
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
// A stdio transport may receive cancellation while an earlier call keeps a
|
|
70
|
+
// later request queued. Retain bounded intent so that later call never
|
|
71
|
+
// reaches PostgreSQL once it starts.
|
|
72
|
+
cancelledBeforeStart.add(key);
|
|
73
|
+
if (cancelledBeforeStart.size > 1_000) {
|
|
74
|
+
const oldest = cancelledBeforeStart.values().next().value;
|
|
75
|
+
if (oldest !== undefined)
|
|
76
|
+
cancelledBeforeStart.delete(oldest);
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
async function initialize(message) {
|
|
81
|
+
if (lifecycle !== "new") {
|
|
82
|
+
replyError(message.id, -32600, "initialize sólo puede llamarse una vez por sesión");
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
lifecycle = "awaiting-initialized";
|
|
86
|
+
reply(message.id, {
|
|
87
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
88
|
+
capabilities: { tools: {} },
|
|
89
|
+
serverInfo: { name: "agent-workflow-db", version: "1" },
|
|
90
|
+
});
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
async function initialized() {
|
|
94
|
+
if (lifecycle === "awaiting-initialized") {
|
|
95
|
+
lifecycle = "ready";
|
|
96
|
+
await deps.onHostLoadObserved?.();
|
|
97
|
+
}
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
function readyOrReply(message) {
|
|
101
|
+
if (lifecycle === "ready")
|
|
102
|
+
return true;
|
|
103
|
+
replyError(message.id, -32002, "Server not initialized");
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
async function listTools(message) {
|
|
107
|
+
if (!readyOrReply(message))
|
|
108
|
+
return true;
|
|
109
|
+
try {
|
|
110
|
+
const list = deps.catalog.list(deps.connection);
|
|
111
|
+
reply(message.id, "tools" in list.payload ? list.payload : toolResult(list.payload));
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
reply(message.id, toolResult(toolFailure("MCP_CONNECTION_INVALID", "No se pudo resolver la conexión solicitada.")));
|
|
115
|
+
}
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
async function callTool(message) {
|
|
119
|
+
if (!readyOrReply(message))
|
|
120
|
+
return true;
|
|
121
|
+
return await dispatchToolCall(message);
|
|
122
|
+
}
|
|
123
|
+
const handlers = {
|
|
124
|
+
initialize,
|
|
125
|
+
"notifications/initialized": async () => await initialized(),
|
|
126
|
+
"notifications/cancelled": async (message) => await cancelToolCall(message),
|
|
127
|
+
"tools/list": listTools,
|
|
128
|
+
"tools/call": callTool,
|
|
129
|
+
};
|
|
130
|
+
return {
|
|
131
|
+
async handle(message) {
|
|
132
|
+
if (!isJsonRpcEnvelope(message))
|
|
133
|
+
return false;
|
|
134
|
+
const handler = handlers[message.method];
|
|
135
|
+
if (handler !== undefined)
|
|
136
|
+
return await handler(message);
|
|
137
|
+
replyError(message.id, -32601, "Method not found");
|
|
138
|
+
return true;
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/** Accept only envelopes for which every response remains valid JSON-RPC. */
|
|
143
|
+
function isJsonRpcEnvelope(value) {
|
|
144
|
+
return (isRecord(value) &&
|
|
145
|
+
value.jsonrpc === "2.0" &&
|
|
146
|
+
typeof value.method === "string" &&
|
|
147
|
+
isJsonRpcId(value.id));
|
|
148
|
+
}
|
|
149
|
+
function isJsonRpcId(value) {
|
|
150
|
+
return value === undefined || isJsonRpcResponseId(value);
|
|
151
|
+
}
|
|
152
|
+
function isJsonRpcResponseId(value) {
|
|
153
|
+
return value === null || typeof value === "string" || isFiniteId(value);
|
|
154
|
+
}
|
|
155
|
+
function isFiniteId(value) {
|
|
156
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
157
|
+
}
|
|
158
|
+
function requestIdKey(value) {
|
|
159
|
+
if (typeof value === "string")
|
|
160
|
+
return `string:${value}`;
|
|
161
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
162
|
+
return `number:${value}`;
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
function isRecord(value) {
|
|
166
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=database-mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-mcp-server.js","sourceRoot":"","sources":["../../src/application/database-mcp-server.ts"],"names":[],"mappings":"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"}
|