@bragi-gmbh/codebus 1.3.0 → 1.6.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/dist/ci-hooks/ci-hooks.js +126 -0
- package/dist/ci-hooks/ci-hooks.js.map +1 -0
- package/dist/commands/agent.js +137 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/as.js +1 -1
- package/dist/commands/as.js.map +1 -1
- package/dist/commands/ask.js +1 -1
- package/dist/commands/ask.js.map +1 -1
- package/dist/commands/ci-findings.js +129 -0
- package/dist/commands/ci-findings.js.map +1 -0
- package/dist/commands/ci-reply.js +117 -0
- package/dist/commands/ci-reply.js.map +1 -0
- package/dist/commands/ci-steer-escalate.js +65 -0
- package/dist/commands/ci-steer-escalate.js.map +1 -0
- package/dist/commands/cli-mcp-correlation.js +131 -0
- package/dist/commands/cli-mcp-correlation.js.map +1 -0
- package/dist/commands/connector-attach-detach.js +542 -0
- package/dist/commands/connector-attach-detach.js.map +1 -0
- package/dist/commands/connector.js +513 -0
- package/dist/commands/connector.js.map +1 -0
- package/dist/commands/correlation.js +194 -0
- package/dist/commands/correlation.js.map +1 -0
- package/dist/commands/decision.js +63 -0
- package/dist/commands/decision.js.map +1 -1
- package/dist/commands/digest.js +14 -3
- package/dist/commands/digest.js.map +1 -1
- package/dist/commands/do.js +127 -0
- package/dist/commands/do.js.map +1 -0
- package/dist/commands/doc.js +276 -0
- package/dist/commands/doc.js.map +1 -0
- package/dist/commands/factory-attention.js +106 -0
- package/dist/commands/factory-attention.js.map +1 -0
- package/dist/commands/factory-context-read.js +171 -0
- package/dist/commands/factory-context-read.js.map +1 -0
- package/dist/commands/factory-interventions.js +102 -0
- package/dist/commands/factory-interventions.js.map +1 -0
- package/dist/commands/factory.js +187 -0
- package/dist/commands/factory.js.map +1 -1
- package/dist/commands/graph-pull.js +130 -0
- package/dist/commands/graph-pull.js.map +1 -0
- package/dist/commands/graph.js +5 -1
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/inbox.js +7 -7
- package/dist/commands/inbox.js.map +1 -1
- package/dist/commands/ingest.js +1 -1
- package/dist/commands/ingest.js.map +1 -1
- package/dist/commands/install.js +1160 -55
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/integration-ledger.js +81 -0
- package/dist/commands/integration-ledger.js.map +1 -0
- package/dist/commands/knowledge.js +178 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/links.js +1 -1
- package/dist/commands/links.js.map +1 -1
- package/dist/commands/morning.js +50 -1
- package/dist/commands/morning.js.map +1 -1
- package/dist/commands/plan-compiler.js +260 -0
- package/dist/commands/plan-compiler.js.map +1 -0
- package/dist/commands/plan-lint.js +275 -0
- package/dist/commands/plan-lint.js.map +1 -0
- package/dist/commands/plan-score.js +203 -0
- package/dist/commands/plan-score.js.map +1 -0
- package/dist/commands/plan.js +481 -15
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/product-validity.js +168 -0
- package/dist/commands/product-validity.js.map +1 -0
- package/dist/commands/question.js +1 -1
- package/dist/commands/question.js.map +1 -1
- package/dist/commands/read-policy.js +131 -0
- package/dist/commands/read-policy.js.map +1 -0
- package/dist/commands/read.js +1 -1
- package/dist/commands/read.js.map +1 -1
- package/dist/commands/repo.js +106 -8
- package/dist/commands/repo.js.map +1 -1
- package/dist/commands/repository-protection.js +209 -0
- package/dist/commands/repository-protection.js.map +1 -0
- package/dist/commands/resolve.js +2 -2
- package/dist/commands/resolve.js.map +1 -1
- package/dist/commands/self-healing.js +26 -0
- package/dist/commands/self-healing.js.map +1 -0
- package/dist/commands/send.js +1 -1
- package/dist/commands/send.js.map +1 -1
- package/dist/commands/serial-merge.js +303 -0
- package/dist/commands/serial-merge.js.map +1 -0
- package/dist/commands/session.js +1 -1
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/task.js +92 -1
- package/dist/commands/task.js.map +1 -1
- package/dist/commands/verify.js +77 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/config/self-healing-analysis.json +158 -0
- package/dist/errors.js +18 -4
- package/dist/errors.js.map +1 -1
- package/dist/execution/client.js +53 -0
- package/dist/execution/client.js.map +1 -0
- package/dist/execution/local.js +24 -0
- package/dist/execution/local.js.map +1 -0
- package/dist/execution/ssh.js +38 -0
- package/dist/execution/ssh.js.map +1 -0
- package/dist/graph.js +78 -16
- package/dist/graph.js.map +1 -1
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -1
- package/dist/json-lite.js +248 -0
- package/dist/json-lite.js.map +1 -0
- package/dist/knowledge-drift.js +40 -0
- package/dist/knowledge-drift.js.map +1 -0
- package/dist/lint/parallelism.js +414 -0
- package/dist/lint/parallelism.js.map +1 -0
- package/dist/mail-latency.js +11 -1
- package/dist/mail-latency.js.map +1 -1
- package/dist/mcp-ci-findings.js +31 -0
- package/dist/mcp-ci-findings.js.map +1 -0
- package/dist/mcp-correlation.js +290 -0
- package/dist/mcp-correlation.js.map +1 -0
- package/dist/mcp-factory-context-read.js +81 -0
- package/dist/mcp-factory-context-read.js.map +1 -0
- package/dist/mcp-registry.js +202 -1
- package/dist/mcp-registry.js.map +1 -1
- package/dist/mcp.js +94 -5
- package/dist/mcp.js.map +1 -1
- package/dist/openrouter-reservation-guard.js +97 -0
- package/dist/openrouter-reservation-guard.js.map +1 -0
- package/dist/self-healing-analysis-loader.js +150 -0
- package/dist/self-healing-analysis-loader.js.map +1 -0
- package/dist/sender.js +11 -9
- package/dist/sender.js.map +1 -1
- package/dist/toml-lite.js +546 -0
- package/dist/toml-lite.js.map +1 -0
- package/dist/version-check.js +23 -7
- package/dist/version-check.js.map +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool Correlation Handler — shared envelope and query functions for CLI/MCP parity.
|
|
3
|
+
*
|
|
4
|
+
* Implements com.bragi.contract.cli-mcp-parity (v0.5.0-proposed): CLI and MCP share
|
|
5
|
+
* one command core with identical schema, authorization, results, errors, and T-01
|
|
6
|
+
* correlation chain snapshots.
|
|
7
|
+
*
|
|
8
|
+
* Exports wrapper and query functions used by both CLI and MCP transports.
|
|
9
|
+
*/
|
|
10
|
+
import { CodebusError } from "./errors.js";
|
|
11
|
+
/**
|
|
12
|
+
* Empty correlation chain: all fields null (used when context has no binding).
|
|
13
|
+
*/
|
|
14
|
+
export const EMPTY_CHAIN = {
|
|
15
|
+
jira_key: null,
|
|
16
|
+
plan_id: null,
|
|
17
|
+
stage_id: null,
|
|
18
|
+
child_id: null,
|
|
19
|
+
binding_id: null,
|
|
20
|
+
run_id: null,
|
|
21
|
+
pr: null,
|
|
22
|
+
receipt_id: null,
|
|
23
|
+
actor: null,
|
|
24
|
+
environment: null,
|
|
25
|
+
};
|
|
26
|
+
// ── Correlation Resolution ─────────────────────────────────────────────────
|
|
27
|
+
/**
|
|
28
|
+
* Query the database to build a complete T-01 correlation chain.
|
|
29
|
+
*
|
|
30
|
+
* Given a binding_id OR run_id (external_run_id), join:
|
|
31
|
+
* - execution_bindings (external_run_id, dispatched_by_person, executor_agent_id, provenance)
|
|
32
|
+
* - plan_revisions → plans (plan_id, stage_id)
|
|
33
|
+
* - people / agents (actor resolution)
|
|
34
|
+
*
|
|
35
|
+
* Returns EMPTY_CHAIN if no binding exists (unbound run — T-02 checks separately).
|
|
36
|
+
* Exported for testing and use by both CLI and MCP handlers.
|
|
37
|
+
*/
|
|
38
|
+
export async function resolveCorrelation(ctx, partial) {
|
|
39
|
+
// Normalize null → undefined so the optional fields are truly optional
|
|
40
|
+
const normalized = {};
|
|
41
|
+
if (partial.binding_id != null)
|
|
42
|
+
normalized.binding_id = partial.binding_id;
|
|
43
|
+
if (partial.run_id != null)
|
|
44
|
+
normalized.run_id = partial.run_id;
|
|
45
|
+
// Start with provided fields (all undefined here so EMPTY_CHAIN is clean)
|
|
46
|
+
const chain = {
|
|
47
|
+
...EMPTY_CHAIN,
|
|
48
|
+
binding_id: normalized.binding_id ?? null,
|
|
49
|
+
run_id: normalized.run_id ?? null,
|
|
50
|
+
};
|
|
51
|
+
// If neither binding_id nor run_id was supplied, return EMPTY_CHAIN.
|
|
52
|
+
if (!normalized.binding_id && !normalized.run_id) {
|
|
53
|
+
return EMPTY_CHAIN;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
let binding = null;
|
|
57
|
+
// Resolve binding by binding_id when available.
|
|
58
|
+
if (normalized.binding_id) {
|
|
59
|
+
const { data, error } = await ctx.supabase
|
|
60
|
+
.from("execution_bindings")
|
|
61
|
+
.select("id, plan_revision_id, stage_id, external_run_id, dispatched_by_person, executor_agent_id, provenance")
|
|
62
|
+
.eq("id", normalized.binding_id)
|
|
63
|
+
.single();
|
|
64
|
+
if (error || !data) {
|
|
65
|
+
// Binding not found or error — strip the caller-supplied binding_id
|
|
66
|
+
// so validateBinding cannot be fooled by an unbound/nonexistent id.
|
|
67
|
+
return { ...EMPTY_CHAIN, run_id: normalized.run_id ?? null };
|
|
68
|
+
}
|
|
69
|
+
binding = data;
|
|
70
|
+
}
|
|
71
|
+
else if (normalized.run_id) {
|
|
72
|
+
// run_id-only lookup: resolve via external_run_id column.
|
|
73
|
+
// The CLI advertises --run-id as a lookup that may resolve bindings.
|
|
74
|
+
const { data, error } = await ctx.supabase
|
|
75
|
+
.from("execution_bindings")
|
|
76
|
+
.select("id, plan_revision_id, stage_id, external_run_id, dispatched_by_person, executor_agent_id, provenance")
|
|
77
|
+
.eq("external_run_id", normalized.run_id)
|
|
78
|
+
.maybeSingle();
|
|
79
|
+
if (error || !data) {
|
|
80
|
+
// No binding for this run — return EMPTY_CHAIN with just the run_id
|
|
81
|
+
// preserved so callers know which run was queried.
|
|
82
|
+
return { ...EMPTY_CHAIN, run_id: normalized.run_id ?? null };
|
|
83
|
+
}
|
|
84
|
+
binding = data;
|
|
85
|
+
}
|
|
86
|
+
// binding is guaranteed non-null here — both branches return early on error
|
|
87
|
+
if (!binding) {
|
|
88
|
+
return { ...EMPTY_CHAIN, run_id: normalized.run_id ?? null };
|
|
89
|
+
}
|
|
90
|
+
// Resolve actor (GitHub login): try dispatched_by_person first, then executor_agent_id
|
|
91
|
+
let actor = chain.actor;
|
|
92
|
+
if (!actor) {
|
|
93
|
+
const dispatched = binding.dispatched_by_person;
|
|
94
|
+
const executor = binding.executor_agent_id;
|
|
95
|
+
if (dispatched) {
|
|
96
|
+
const { data: person } = await ctx.supabase
|
|
97
|
+
.from("people")
|
|
98
|
+
.select("github_login")
|
|
99
|
+
.eq("id", dispatched)
|
|
100
|
+
.single();
|
|
101
|
+
actor = person?.github_login || null;
|
|
102
|
+
}
|
|
103
|
+
else if (executor) {
|
|
104
|
+
const { data: agent } = await ctx.supabase
|
|
105
|
+
.from("agents")
|
|
106
|
+
.select("slug")
|
|
107
|
+
.eq("id", executor)
|
|
108
|
+
.single();
|
|
109
|
+
actor = agent?.slug || null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Fetch plan_revision → plan to resolve plan_id (stage_id lives on the binding)
|
|
113
|
+
let plan_id = chain.plan_id;
|
|
114
|
+
const stage_id = chain.stage_id || binding.stage_id || null;
|
|
115
|
+
const plan_revision_id = binding.plan_revision_id;
|
|
116
|
+
if (plan_revision_id && !plan_id) {
|
|
117
|
+
const { data: rev } = await ctx.supabase
|
|
118
|
+
.from("plan_revisions")
|
|
119
|
+
.select("plan_id")
|
|
120
|
+
.eq("id", plan_revision_id)
|
|
121
|
+
.single();
|
|
122
|
+
plan_id = rev?.plan_id || null;
|
|
123
|
+
}
|
|
124
|
+
// Extract environment and jira_key from provenance (if available)
|
|
125
|
+
const provenance = binding.provenance;
|
|
126
|
+
const environment = chain.environment || provenance?.environment || "dev";
|
|
127
|
+
const jira_key = chain.jira_key || provenance?.jira_key || null;
|
|
128
|
+
return {
|
|
129
|
+
jira_key,
|
|
130
|
+
plan_id: plan_id || chain.plan_id,
|
|
131
|
+
stage_id,
|
|
132
|
+
child_id: chain.child_id,
|
|
133
|
+
binding_id: binding.id,
|
|
134
|
+
run_id: binding.external_run_id || chain.run_id,
|
|
135
|
+
pr: chain.pr,
|
|
136
|
+
receipt_id: chain.receipt_id,
|
|
137
|
+
actor,
|
|
138
|
+
environment,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// On any error, return a clean EMPTY_CHAIN with only the run_id preserved
|
|
143
|
+
// (never the caller-supplied binding_id, which could be fabricated).
|
|
144
|
+
return { ...EMPTY_CHAIN, run_id: normalized.run_id ?? null };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// ── Handler Wrapper ─────────────────────────────────────────────────────────
|
|
148
|
+
/**
|
|
149
|
+
* Wrap a command core to produce a parity envelope.
|
|
150
|
+
*
|
|
151
|
+
* Usage in CLI: call this wrapper, render result.schema.transport="cli"
|
|
152
|
+
* Usage in MCP: call this wrapper, return result.schema.transport="mcp"
|
|
153
|
+
*
|
|
154
|
+
* The wrapper:
|
|
155
|
+
* 1. Calls the core function
|
|
156
|
+
* 2. Catches CodebusError and non-CodebusError exceptions
|
|
157
|
+
* 3. Resolves correlation from context (if available)
|
|
158
|
+
* 4. Returns identical shape on both transports
|
|
159
|
+
*
|
|
160
|
+
* @param coreFn — async function that takes (ctx, args) and returns result | throws CodebusError
|
|
161
|
+
*/
|
|
162
|
+
export async function withCorrelation(coreFn, ctx, args, opts = {
|
|
163
|
+
transport: "cli",
|
|
164
|
+
}) {
|
|
165
|
+
const errors = [];
|
|
166
|
+
let result = null;
|
|
167
|
+
let auth = { authenticated: true, authorized: true };
|
|
168
|
+
try {
|
|
169
|
+
// Call the core function
|
|
170
|
+
result = await coreFn(ctx, args);
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
// Catch errors and normalize to parity shape
|
|
174
|
+
if (err instanceof CodebusError) {
|
|
175
|
+
errors.push({
|
|
176
|
+
code: err.code || "CodebusError",
|
|
177
|
+
message: err.message,
|
|
178
|
+
details: err.details,
|
|
179
|
+
});
|
|
180
|
+
auth = { authenticated: err.code !== "AUTH_REQUIRED", authorized: err.code !== "FORBIDDEN" };
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
184
|
+
errors.push({
|
|
185
|
+
code: "UnknownError",
|
|
186
|
+
message,
|
|
187
|
+
});
|
|
188
|
+
auth = { authenticated: false, authorized: false };
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// Resolve correlation chain. Thread query params (binding_id, run_id) from
|
|
192
|
+
// args into resolveCorrelation so the envelope carries the full chain.
|
|
193
|
+
// Normalize null → undefined because resolveCorrelation's type uses
|
|
194
|
+
// string | null only on the partial, never on the result.
|
|
195
|
+
const fromArgs = {};
|
|
196
|
+
if (args && typeof args === "object") {
|
|
197
|
+
const b = args.binding_id ?? args.bindingId;
|
|
198
|
+
const r = args.run_id ?? args.runId;
|
|
199
|
+
if (typeof b === "string")
|
|
200
|
+
fromArgs.binding_id = b;
|
|
201
|
+
if (typeof r === "string")
|
|
202
|
+
fromArgs.run_id = r;
|
|
203
|
+
}
|
|
204
|
+
const correlation = await resolveCorrelation(ctx, {
|
|
205
|
+
...fromArgs,
|
|
206
|
+
...(opts.correlationPartial
|
|
207
|
+
? {
|
|
208
|
+
binding_id: opts.correlationPartial.binding_id ?? undefined,
|
|
209
|
+
run_id: opts.correlationPartial.run_id ?? undefined,
|
|
210
|
+
}
|
|
211
|
+
: {}),
|
|
212
|
+
});
|
|
213
|
+
return {
|
|
214
|
+
schema: { version: "0.5.0-proposed", transport: opts.transport },
|
|
215
|
+
auth,
|
|
216
|
+
result,
|
|
217
|
+
errors,
|
|
218
|
+
correlation,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
// ── Parity Assertions (for testing) ─────────────────────────────────────────
|
|
222
|
+
/**
|
|
223
|
+
* Deep-compare two parity envelopes for test fixture validation.
|
|
224
|
+
* Exported for use in test suite (positive fixture: equal_schema_auth_result_errors_and_full_chain).
|
|
225
|
+
*
|
|
226
|
+
* Returns { equal: boolean; diffs: string[] } where diffs lists what diverged.
|
|
227
|
+
* Used to ensure CLI and MCP outputs match byte-for-byte (transport field aside).
|
|
228
|
+
*/
|
|
229
|
+
export function assertParity(cliEnvelope, mcpEnvelope) {
|
|
230
|
+
const diffs = [];
|
|
231
|
+
// Schema version must match (transport differs by design)
|
|
232
|
+
if (cliEnvelope.schema.version !== mcpEnvelope.schema.version) {
|
|
233
|
+
diffs.push(`schema.version: "${cliEnvelope.schema.version}" vs "${mcpEnvelope.schema.version}"`);
|
|
234
|
+
}
|
|
235
|
+
// Auth must match
|
|
236
|
+
if (cliEnvelope.auth.authenticated !== mcpEnvelope.auth.authenticated) {
|
|
237
|
+
diffs.push(`auth.authenticated: ${cliEnvelope.auth.authenticated} vs ${mcpEnvelope.auth.authenticated}`);
|
|
238
|
+
}
|
|
239
|
+
if (cliEnvelope.auth.authorized !== mcpEnvelope.auth.authorized) {
|
|
240
|
+
diffs.push(`auth.authorized: ${cliEnvelope.auth.authorized} vs ${mcpEnvelope.auth.authorized}`);
|
|
241
|
+
}
|
|
242
|
+
// Result must match (deep JSON compare)
|
|
243
|
+
const cliResultJson = JSON.stringify(cliEnvelope.result, null, 0);
|
|
244
|
+
const mcpResultJson = JSON.stringify(mcpEnvelope.result, null, 0);
|
|
245
|
+
if (cliResultJson !== mcpResultJson) {
|
|
246
|
+
diffs.push(`result: CLI and MCP diverged\n CLI: ${cliResultJson.slice(0, 100)}...\n MCP: ${mcpResultJson.slice(0, 100)}...`);
|
|
247
|
+
}
|
|
248
|
+
// Errors must match
|
|
249
|
+
const cliErrorsJson = JSON.stringify(cliEnvelope.errors);
|
|
250
|
+
const mcpErrorsJson = JSON.stringify(mcpEnvelope.errors);
|
|
251
|
+
if (cliErrorsJson !== mcpErrorsJson) {
|
|
252
|
+
diffs.push(`errors: ${cliErrorsJson} vs ${mcpErrorsJson}`);
|
|
253
|
+
}
|
|
254
|
+
// Correlation chain must match exactly (full_chain fixture)
|
|
255
|
+
const cliChainJson = JSON.stringify(cliEnvelope.correlation);
|
|
256
|
+
const mcpChainJson = JSON.stringify(mcpEnvelope.correlation);
|
|
257
|
+
if (cliChainJson !== mcpChainJson) {
|
|
258
|
+
diffs.push(`correlation: ${cliChainJson} vs ${mcpChainJson}`);
|
|
259
|
+
}
|
|
260
|
+
return { equal: diffs.length === 0, diffs };
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Validate that a correlation chain has no null bindings (T-02 check for spend-bearing work).
|
|
264
|
+
* Exported for use in command handlers that require binding.
|
|
265
|
+
*
|
|
266
|
+
* Returns { valid: boolean; reason?: string }
|
|
267
|
+
*/
|
|
268
|
+
export function validateBinding(chain, requireFull = false) {
|
|
269
|
+
// T-02: spend-bearing work requires binding_id
|
|
270
|
+
if (!chain.binding_id) {
|
|
271
|
+
return {
|
|
272
|
+
valid: false,
|
|
273
|
+
reason: "T-02: spend-bearing execution requires a binding (CodeBus plan/stage/child/run context). Use 'codebus do' with --binding flag, or dispatch via run-plan.sh --binding.",
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
// Optional: full chain validation (all T-01 fields populated)
|
|
277
|
+
if (requireFull) {
|
|
278
|
+
const nullFields = Object.entries(chain)
|
|
279
|
+
.filter(([, v]) => v === null)
|
|
280
|
+
.map(([k]) => k);
|
|
281
|
+
if (nullFields.length > 0) {
|
|
282
|
+
return {
|
|
283
|
+
valid: false,
|
|
284
|
+
reason: `full chain required but missing: ${nullFields.join(", ")}`,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return { valid: true };
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=mcp-correlation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-correlation.js","sourceRoot":"","sources":["../src/mcp-correlation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAwB3C;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAqB;IAC3C,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;IACd,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,IAAI;IACZ,EAAE,EAAE,IAAI;IACR,UAAU,EAAE,IAAI;IAChB,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,IAAI;CAClB,CAAC;AA6BF,8EAA8E;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAQ,EACR,OAA+D;IAE/D,uEAAuE;IACvE,MAAM,UAAU,GAA6C,EAAE,CAAC;IAChE,IAAI,OAAO,CAAC,UAAU,IAAI,IAAI;QAAE,UAAU,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAC3E,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI;QAAE,UAAU,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAE/D,0EAA0E;IAC1E,MAAM,KAAK,GAAqB;QAC9B,GAAG,WAAW;QACd,UAAU,EAAE,UAAU,CAAC,UAAU,IAAI,IAAI;QACzC,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,IAAI;KAClC,CAAC;IAEF,qEAAqE;IACrE,IAAI,CAAC,UAAU,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QACjD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,CAAC;QACH,IAAI,OAAO,GAAmC,IAAI,CAAC;QAEnD,gDAAgD;QAChD,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;YAC1B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,GAAG,CAAC,QAAQ;iBACvC,IAAI,CAAC,oBAAoB,CAAC;iBAC1B,MAAM,CAAC,sGAAsG,CAAC;iBAC9G,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC;iBAC/B,MAAM,EAAE,CAAC;YAEZ,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;gBACnB,oEAAoE;gBACpE,oEAAoE;gBACpE,OAAO,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YAC/D,CAAC;YACD,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YAC7B,0DAA0D;YAC1D,qEAAqE;YACrE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,GAAG,CAAC,QAAQ;iBACvC,IAAI,CAAC,oBAAoB,CAAC;iBAC1B,MAAM,CAAC,sGAAsG,CAAC;iBAC9G,EAAE,CAAC,iBAAiB,EAAE,UAAU,CAAC,MAAM,CAAC;iBACxC,WAAW,EAAE,CAAC;YAEjB,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;gBACnB,oEAAoE;gBACpE,mDAAmD;gBACnD,OAAO,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YAC/D,CAAC;YACD,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;QAED,4EAA4E;QAC5E,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QAC/D,CAAC;QAED,uFAAuF;QACvF,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,UAAU,GAAG,OAAO,CAAC,oBAAiD,CAAC;YAC7E,MAAM,QAAQ,GAAG,OAAO,CAAC,iBAA8C,CAAC;YACxE,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,QAAQ;qBACxC,IAAI,CAAC,QAAQ,CAAC;qBACd,MAAM,CAAC,cAAc,CAAC;qBACtB,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC;qBACpB,MAAM,EAAE,CAAC;gBACZ,KAAK,GAAG,MAAM,EAAE,YAAY,IAAI,IAAI,CAAC;YACvC,CAAC;iBAAM,IAAI,QAAQ,EAAE,CAAC;gBACpB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,GAAG,CAAC,QAAQ;qBACvC,IAAI,CAAC,QAAQ,CAAC;qBACd,MAAM,CAAC,MAAM,CAAC;qBACd,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC;qBAClB,MAAM,EAAE,CAAC;gBACZ,KAAK,GAAG,KAAK,EAAE,IAAI,IAAI,IAAI,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,gFAAgF;QAChF,IAAI,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAK,OAAO,CAAC,QAAmB,IAAI,IAAI,CAAC;QACxE,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAsC,CAAC;QACxE,IAAI,gBAAgB,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,GAAG,CAAC,QAAQ;iBACrC,IAAI,CAAC,gBAAgB,CAAC;iBACtB,MAAM,CAAC,SAAS,CAAC;iBACjB,EAAE,CAAC,IAAI,EAAE,gBAAgB,CAAC;iBAC1B,MAAM,EAAE,CAAC;YACZ,OAAO,GAAG,GAAG,EAAE,OAAO,IAAI,IAAI,CAAC;QACjC,CAAC;QAED,kEAAkE;QAClE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAqE,CAAC;QACjG,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,UAAU,EAAE,WAAW,IAAI,KAAK,CAAC;QAC1E,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,UAAU,EAAE,QAAQ,IAAI,IAAI,CAAC;QAEhE,OAAO;YACL,QAAQ;YACR,OAAO,EAAE,OAAO,IAAI,KAAK,CAAC,OAAO;YACjC,QAAQ;YACR,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,UAAU,EAAE,OAAO,CAAC,EAAY;YAChC,MAAM,EAAG,OAAO,CAAC,eAA0B,IAAI,KAAK,CAAC,MAAM;YAC3D,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,KAAK;YACL,WAAW;SACZ,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,0EAA0E;QAC1E,qEAAqE;QACrE,OAAO,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,+EAA+E;AAE/E;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAA2C,EAC3C,GAAQ,EACR,IAAO,EACP,OAAkH;IAChH,SAAS,EAAE,KAAK;CACjB;IAED,MAAM,MAAM,GAA2D,EAAE,CAAC;IAC1E,IAAI,MAAM,GAAY,IAAI,CAAC;IAC3B,IAAI,IAAI,GAA2B,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAE7E,IAAI,CAAC;QACH,yBAAyB;QACzB,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,6CAA6C;QAC7C,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,cAAc;gBAChC,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,OAAO,EAAE,GAAG,CAAC,OAAO;aACrB,CAAC,CAAC;YACH,IAAI,GAAG,EAAE,aAAa,EAAE,GAAG,CAAC,IAAI,KAAK,eAAe,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC/F,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,cAAc;gBACpB,OAAO;aACR,CAAC,CAAC;YACH,IAAI,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QACrD,CAAC;IACH,CAAC;IAEA,2EAA2E;IAC5E,uEAAuE;IACvE,oEAAoE;IACpE,0DAA0D;IAC1D,MAAM,QAAQ,GAA6C,EAAE,CAAC;IAC9D,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,SAAS,CAAC;QAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC;QACpC,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,QAAQ,CAAC,UAAU,GAAG,CAAC,CAAC;QACnD,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE;QAChD,GAAG,QAAQ;QACX,GAAG,CAAC,IAAI,CAAC,kBAAkB;YACzB,CAAC,CAAC;gBACE,UAAU,EAAE,IAAI,CAAC,kBAAkB,CAAC,UAAU,IAAI,SAAS;gBAC3D,MAAM,EAAE,IAAI,CAAC,kBAAkB,CAAC,MAAM,IAAI,SAAS;aACpD;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CAAC;IAEH,OAAO;QACL,MAAM,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;QAChE,IAAI;QACJ,MAAM;QACN,MAAM;QACN,WAAW;KACZ,CAAC;AACJ,CAAC;AAED,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,WAA2B,EAC3B,WAA2B;IAE3B,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,0DAA0D;IAC1D,IAAI,WAAW,CAAC,MAAM,CAAC,OAAO,KAAK,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,oBAAoB,WAAW,CAAC,MAAM,CAAC,OAAO,SAAS,WAAW,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;IACnG,CAAC;IAED,kBAAkB;IAClB,IAAI,WAAW,CAAC,IAAI,CAAC,aAAa,KAAK,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QACtE,KAAK,CAAC,IAAI,CACR,uBAAuB,WAAW,CAAC,IAAI,CAAC,aAAa,OAAO,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,CAC7F,CAAC;IACJ,CAAC;IACD,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,KAAK,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChE,KAAK,CAAC,IAAI,CAAC,oBAAoB,WAAW,CAAC,IAAI,CAAC,UAAU,OAAO,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAClG,CAAC;IAED,wCAAwC;IACxC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAClE,IAAI,aAAa,KAAK,aAAa,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,wCAAwC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,eAAe,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IACjI,CAAC;IAED,oBAAoB;IACpB,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACzD,IAAI,aAAa,KAAK,aAAa,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,WAAW,aAAa,OAAO,aAAa,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,4DAA4D;IAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;IAC7D,IAAI,YAAY,KAAK,YAAY,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,gBAAgB,YAAY,OAAO,YAAY,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,KAAuB,EAAE,WAAW,GAAG,KAAK;IAI1E,+CAA+C;IAC/C,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACtB,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,uKAAuK;SAChL,CAAC;IACJ,CAAC;IAED,8DAA8D;IAC9D,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aACrC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;aAC7B,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,oCAAoC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;aACpE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool registration for factory-context-read.
|
|
3
|
+
*
|
|
4
|
+
* Shared core with CLI (A5: one command, two adapters).
|
|
5
|
+
* Tool schema and handler must be identical to CLI (parity contract).
|
|
6
|
+
*
|
|
7
|
+
* Imports from mcp-registry.ts; registration pushed to TOOL_REGISTRY.
|
|
8
|
+
*/
|
|
9
|
+
import { factoryContextReadCore } from "./commands/factory-context-read.js";
|
|
10
|
+
import { makeCtx } from "./client.js";
|
|
11
|
+
import { resolveConfig } from "./config.js";
|
|
12
|
+
import { CodebusError } from "./errors.js";
|
|
13
|
+
/**
|
|
14
|
+
* MCP handler for factory_context_read tool.
|
|
15
|
+
* Validates args (identical to CLI), calls shared core, returns JSON result.
|
|
16
|
+
*
|
|
17
|
+
* Errors: thrown as CodebusError before I/O (same as CLI path, parity contract).
|
|
18
|
+
*
|
|
19
|
+
* @param args MCP tool arguments {contentType?, repoSlug?}
|
|
20
|
+
* @returns factory context read result (identical to CLI result)
|
|
21
|
+
*/
|
|
22
|
+
export async function factoryContextReadHandler(args) {
|
|
23
|
+
// Validate and coerce args (same checks as CLI --type)
|
|
24
|
+
const contentType = args?.contentType || "taxonomy";
|
|
25
|
+
const repoSlug = args?.repoSlug;
|
|
26
|
+
// Validate content type (must match CLI allowed values, identical error)
|
|
27
|
+
const validTypes = [
|
|
28
|
+
"taxonomy",
|
|
29
|
+
"contracts",
|
|
30
|
+
"adrs",
|
|
31
|
+
"specs",
|
|
32
|
+
"knowledge",
|
|
33
|
+
"repositories",
|
|
34
|
+
"graphs",
|
|
35
|
+
"configuration",
|
|
36
|
+
];
|
|
37
|
+
if (!validTypes.includes(contentType)) {
|
|
38
|
+
throw new CodebusError(`Invalid contentType '${contentType}'. Allowed: ${validTypes.join(", ")}`);
|
|
39
|
+
}
|
|
40
|
+
// Fix #6: graphs query REQUIRES repoSlug — enforce even when omitted (matches CLI)
|
|
41
|
+
if (contentType === "graphs" && !repoSlug) {
|
|
42
|
+
throw new CodebusError("repoSlug is required for 'graphs' query");
|
|
43
|
+
}
|
|
44
|
+
// Validate repoSlug: must be non-empty string when provided
|
|
45
|
+
if (repoSlug !== undefined && (typeof repoSlug !== "string" || repoSlug.trim().length === 0)) {
|
|
46
|
+
throw new CodebusError("repoSlug must be a non-empty string or undefined");
|
|
47
|
+
}
|
|
48
|
+
// Call shared core (identical to CLI handler)
|
|
49
|
+
const ctx = await makeCtx(resolveConfig({}));
|
|
50
|
+
return factoryContextReadCore(ctx, contentType, repoSlug);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Tool definition for MCP registry (TOOL_REGISTRY in mcp-registry.ts).
|
|
54
|
+
* Schema must be identical to CLI help + command signature (parity contract).
|
|
55
|
+
*/
|
|
56
|
+
export const FACTORY_CONTEXT_READ_TOOL = {
|
|
57
|
+
name: "factory_context_read",
|
|
58
|
+
description: "Read versioned Factory context (taxonomy, contracts, ADRs, specs, knowledge, repos, graphs, configuration). " +
|
|
59
|
+
"All reads are authenticated (RLS-scoped), versioned, and reject direct-database or local-copy sources. " +
|
|
60
|
+
"Bounded non-authoritative cache is permitted (via factory-read-cache). " +
|
|
61
|
+
"Optional 'repoSlug' filters repositories/graphs queries. " +
|
|
62
|
+
"Pretest fixture: identical_version_schema_auth_result_and_errors.",
|
|
63
|
+
inputSchema: {
|
|
64
|
+
type: "object",
|
|
65
|
+
properties: {
|
|
66
|
+
contentType: {
|
|
67
|
+
type: "string",
|
|
68
|
+
enum: ["taxonomy", "contracts", "adrs", "specs", "knowledge", "repositories", "graphs", "configuration"],
|
|
69
|
+
description: "Content type to read (default: taxonomy). " +
|
|
70
|
+
"repositories/graphs accept optional repoSlug.",
|
|
71
|
+
},
|
|
72
|
+
repoSlug: {
|
|
73
|
+
type: "string",
|
|
74
|
+
description: "Optional repo slug for repositories/graphs queries (required for graphs).",
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
required: [], // contentType defaults to "taxonomy", repoSlug is optional
|
|
78
|
+
},
|
|
79
|
+
handler: factoryContextReadHandler,
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=mcp-factory-context-read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-factory-context-read.js","sourceRoot":"","sources":["../src/mcp-factory-context-read.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,sBAAsB,EAA0D,MAAM,oCAAoC,CAAC;AACpI,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,IAA6B;IAC3E,uDAAuD;IACvD,MAAM,WAAW,GAAI,IAAI,EAAE,WAAsB,IAAI,UAAU,CAAC;IAChE,MAAM,QAAQ,GAAG,IAAI,EAAE,QAA8B,CAAC;IAEtD,yEAAyE;IACzE,MAAM,UAAU,GAAyB;QACvC,UAAU;QACV,WAAW;QACX,MAAM;QACN,OAAO;QACP,WAAW;QACX,cAAc;QACd,QAAQ;QACR,eAAe;KAChB,CAAC;IACF,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,WAAiC,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,YAAY,CAAC,wBAAwB,WAAW,eAAe,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpG,CAAC;IAED,mFAAmF;IACnF,IAAI,WAAW,KAAK,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,YAAY,CAAC,yCAAyC,CAAC,CAAC;IACpE,CAAC;IACD,4DAA4D;IAC5D,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QAC7F,MAAM,IAAI,YAAY,CAAC,kDAAkD,CAAC,CAAC;IAC7E,CAAC;IAED,8CAA8C;IAC9C,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7C,OAAO,sBAAsB,CAAC,GAAG,EAAE,WAAiC,EAAE,QAAQ,CAAC,CAAC;AAClF,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EACT,8GAA8G;QAC9G,yGAAyG;QACzG,yEAAyE;QACzE,2DAA2D;QAC3D,mEAAmE;IACrE,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,eAAe,CAAC;gBACxG,WAAW,EACT,4CAA4C;oBAC5C,+CAA+C;aAClD;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,2EAA2E;aACzF;SACF;QACD,QAAQ,EAAE,EAAc,EAAE,2DAA2D;KACtF;IACD,OAAO,EAAE,yBAAyB;CACnC,CAAC"}
|
package/dist/mcp-registry.js
CHANGED
|
@@ -19,11 +19,17 @@ import { createQuestionCore, answerQuestionCore } from "./commands/question.js";
|
|
|
19
19
|
import { createTaskCore, claimTaskCore, completeTaskCore } from "./commands/task.js";
|
|
20
20
|
import { createDecisionCore, acceptDecisionCore } from "./commands/decision.js";
|
|
21
21
|
import { sendMessageCore } from "./commands/send.js";
|
|
22
|
-
import { planRollupCore, planDeliveryCore } from "./commands/plan.js";
|
|
22
|
+
import { planRollupCore, planDeliveryCore, planObjectListCore, planObjectShowCore, planObjectWhoCore, planObjectStuckCore, planCapsShowCore, planCapsProposeCore } from "./commands/plan.js";
|
|
23
|
+
import { listKnowledgeCore, showKnowledgeCore } from "./commands/knowledge.js";
|
|
24
|
+
import { makeExecutionClient, factoryRunStatusCore, factoryRunEventsCore } from "./commands/factory.js";
|
|
23
25
|
import { endSessionCore } from "./commands/session.js";
|
|
24
26
|
import { compilePackCore } from "./commands/pack.js";
|
|
25
27
|
import { resolveRefsCore } from "./commands/refs.js";
|
|
28
|
+
import { addDocCore, getDocCore } from "./commands/doc.js";
|
|
26
29
|
import { CodebusError } from "./errors.js";
|
|
30
|
+
import { correlationQueryCore } from "./commands/cli-mcp-correlation.js";
|
|
31
|
+
import { withCorrelation } from "./mcp-correlation.js";
|
|
32
|
+
import { FACTORY_CONTEXT_READ_TOOL } from "./mcp-factory-context-read.js";
|
|
27
33
|
// This module builds the tool registry only — it never touches stdio or a
|
|
28
34
|
// transport, so importing it has zero side effects on the process (no server
|
|
29
35
|
// boot). That is what lets install.ts import TOOL_REGISTRY to DERIVE the
|
|
@@ -856,4 +862,199 @@ TOOL_REGISTRY.push({
|
|
|
856
862
|
},
|
|
857
863
|
handler: resolveRefsHandler,
|
|
858
864
|
});
|
|
865
|
+
// ── doc_add / doc_get (shared documents, 0087) ─────────────────────────────
|
|
866
|
+
// One shared core, dumb clients: these wrap doc.ts's addDocCore/getDocCore —
|
|
867
|
+
// the same cores `codebus doc add|get` use — so CLI and MCP cannot diverge on
|
|
868
|
+
// validation or shape. Server-side, artifact_add (0087) is the write
|
|
869
|
+
// boundary: membership gate, producer pinned to the caller, 2 MiB cap, kind
|
|
870
|
+
// vocabulary — the tool surfaces its typed errors verbatim.
|
|
871
|
+
async function docAddHandler(args) {
|
|
872
|
+
const title = args?.title || "";
|
|
873
|
+
const body = args?.body || "";
|
|
874
|
+
if (!title)
|
|
875
|
+
throw new CodebusError("'title' parameter is required");
|
|
876
|
+
if (!body)
|
|
877
|
+
throw new CodebusError("'body' parameter is required");
|
|
878
|
+
const ctx = await makeCtx(resolveConfig({}));
|
|
879
|
+
const result = await addDocCore(ctx, { title, body, kind: args?.kind });
|
|
880
|
+
return { display_id: result.display_id, kind: result.kind, title: result.title };
|
|
881
|
+
}
|
|
882
|
+
async function docGetHandler(args) {
|
|
883
|
+
const id = args?.id || "";
|
|
884
|
+
if (!id)
|
|
885
|
+
throw new CodebusError("'id' parameter is required");
|
|
886
|
+
const ctx = await makeCtx(resolveConfig({}));
|
|
887
|
+
const doc = await getDocCore(ctx, id);
|
|
888
|
+
return {
|
|
889
|
+
display_id: doc.display_id,
|
|
890
|
+
kind: doc.kind,
|
|
891
|
+
title: doc.title,
|
|
892
|
+
producer: doc.producer,
|
|
893
|
+
created_at: doc.created_at,
|
|
894
|
+
body: doc.body,
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
TOOL_REGISTRY.push({
|
|
898
|
+
name: "doc_add",
|
|
899
|
+
description: "Store a shared text document on the bus (everyone in the workspace sees the same content). " +
|
|
900
|
+
"Returns its CB-DOC-… display_id, which any message or task can cite as evidence via refs " +
|
|
901
|
+
"(send_message ref 'CB-DOC-…'). Text only, ≤ 2 MiB. Kinds: note|doc|spec|plan|review|deck.",
|
|
902
|
+
inputSchema: {
|
|
903
|
+
type: "object",
|
|
904
|
+
properties: {
|
|
905
|
+
title: {
|
|
906
|
+
type: "string",
|
|
907
|
+
description: "Document title (required)",
|
|
908
|
+
},
|
|
909
|
+
body: {
|
|
910
|
+
type: "string",
|
|
911
|
+
description: "Full document text, UTF-8, ≤ 2 MiB (required)",
|
|
912
|
+
},
|
|
913
|
+
kind: {
|
|
914
|
+
type: "string",
|
|
915
|
+
description: "Document kind: note|doc|spec|plan|review|deck (default: doc)",
|
|
916
|
+
},
|
|
917
|
+
},
|
|
918
|
+
required: ["title", "body"],
|
|
919
|
+
},
|
|
920
|
+
handler: docAddHandler,
|
|
921
|
+
});
|
|
922
|
+
TOOL_REGISTRY.push({
|
|
923
|
+
name: "doc_get",
|
|
924
|
+
description: "Fetch a shared document by its CB-DOC-… display_id (or uuid). Returns title, kind, " +
|
|
925
|
+
"producer (person-resolved), created_at, and the full body. Read-only.",
|
|
926
|
+
inputSchema: {
|
|
927
|
+
type: "object",
|
|
928
|
+
properties: {
|
|
929
|
+
id: {
|
|
930
|
+
type: "string",
|
|
931
|
+
description: "Document display_id (CB-DOC-…) or uuid",
|
|
932
|
+
},
|
|
933
|
+
},
|
|
934
|
+
required: ["id"],
|
|
935
|
+
},
|
|
936
|
+
handler: docGetHandler,
|
|
937
|
+
});
|
|
938
|
+
// ── planning, knowledge, digest, and factory read surfaces (F14) ───────────
|
|
939
|
+
function requiredArg(args, name) {
|
|
940
|
+
const value = typeof args?.[name] === "string" ? args[name].trim() : "";
|
|
941
|
+
if (!value)
|
|
942
|
+
throw new CodebusError(`'${name}' parameter is required`);
|
|
943
|
+
return value;
|
|
944
|
+
}
|
|
945
|
+
async function readSurfaceHandler(surface, args) {
|
|
946
|
+
if (surface === "factory_run_status" || surface === "factory_run_events") {
|
|
947
|
+
const runId = requiredArg(args, "run_id");
|
|
948
|
+
const client = makeExecutionClient();
|
|
949
|
+
return surface === "factory_run_status"
|
|
950
|
+
? factoryRunStatusCore(client, runId)
|
|
951
|
+
: factoryRunEventsCore(client, runId);
|
|
952
|
+
}
|
|
953
|
+
if (surface === "plan_show") {
|
|
954
|
+
const plan = requiredArg(args, "plan");
|
|
955
|
+
return planObjectShowCore(await makeCtx(resolveConfig({})), plan);
|
|
956
|
+
}
|
|
957
|
+
if (surface === "knowledge_show") {
|
|
958
|
+
const id = requiredArg(args, "id");
|
|
959
|
+
return showKnowledgeCore(await makeCtx(resolveConfig({})), id);
|
|
960
|
+
}
|
|
961
|
+
const ctx = await makeCtx(resolveConfig({}));
|
|
962
|
+
if (surface === "plan_list")
|
|
963
|
+
return planObjectListCore(ctx);
|
|
964
|
+
if (surface === "plan_who")
|
|
965
|
+
return planObjectWhoCore(ctx);
|
|
966
|
+
if (surface === "plan_stuck")
|
|
967
|
+
return planObjectStuckCore(ctx);
|
|
968
|
+
if (surface === "knowledge_list")
|
|
969
|
+
return listKnowledgeCore(ctx, { state: args?.state, kind: args?.kind });
|
|
970
|
+
return fetchAndCacheDigest(ctx);
|
|
971
|
+
}
|
|
972
|
+
const readTool = (name, description, properties, handler, required = []) => {
|
|
973
|
+
TOOL_REGISTRY.push({ name, description, inputSchema: { type: "object", properties, required }, handler });
|
|
974
|
+
};
|
|
975
|
+
const handlerFor = (surface) => readSurfaceHandler.bind(null, surface);
|
|
976
|
+
readTool("plan_list", "List plans visible in the current workspace. Read-only.", {}, handlerFor("plan_list"));
|
|
977
|
+
readTool("plan_show", "Show one visible plan by display ID or UUID. Read-only.", { plan: { type: "string", description: "Plan display ID (CB-PLAN-...) or UUID" } }, handlerFor("plan_show"), ["plan"]);
|
|
978
|
+
readTool("plan_who", "List current plan assignments visible in the workspace. Read-only.", {}, handlerFor("plan_who"));
|
|
979
|
+
readTool("plan_stuck", "List plans currently stuck according to the plan projection. Read-only.", {}, handlerFor("plan_stuck"));
|
|
980
|
+
readTool("knowledge_list", "List knowledge items, optionally filtered by state or kind. Read-only.", {
|
|
981
|
+
state: { type: "string", enum: ["proposed", "reviewed", "ratified", "deprecated"] },
|
|
982
|
+
kind: { type: "string", enum: ["taxonomy", "contract", "principle", "adr"] },
|
|
983
|
+
}, handlerFor("knowledge_list"));
|
|
984
|
+
readTool("knowledge_show", "Show a knowledge item, its revisions, and transitions. Read-only.", { id: { type: "string" } }, handlerFor("knowledge_show"), ["id"]);
|
|
985
|
+
readTool("digest", "Fetch and cache the current deterministic attention digest. Read-only.", {}, handlerFor("digest"));
|
|
986
|
+
readTool("factory_run_status", "Get deployed factory status for a run. Read-only.", { run_id: { type: "string" } }, handlerFor("factory_run_status"), ["run_id"]);
|
|
987
|
+
readTool("factory_run_events", "Get deployed factory events for a run as JSON objects. Read-only.", { run_id: { type: "string" } }, handlerFor("factory_run_events"), ["run_id"]);
|
|
988
|
+
// ── factory_context_read (Phase 2: CLI/MCP parity read surface) ───────────────
|
|
989
|
+
TOOL_REGISTRY.push(FACTORY_CONTEXT_READ_TOOL);
|
|
990
|
+
// ── plan admission caps (owner decisions, migration 0111) ──────────────────
|
|
991
|
+
readTool("plan_caps_show", "Show effective plan admission caps: the latest approved plan-caps decision, or the defaults (150 USD, 12 stages). Read-only.", { plan: { type: "string", description: "Optional plan display ID (CB-PLAN-…) or UUID; omit for workspace-level caps" } }, async (args) => planCapsShowCore(await makeCtx(resolveConfig({})), typeof args?.plan === "string" && args.plan.trim() ? args.plan.trim() : undefined));
|
|
992
|
+
TOOL_REGISTRY.push({
|
|
993
|
+
name: "plan_caps_propose",
|
|
994
|
+
description: "Propose new plan admission caps as a PENDING plan-caps decision. " +
|
|
995
|
+
"Approval stays an owner action (decision_accept); until accepted, the defaults or the previous decision remain effective.",
|
|
996
|
+
inputSchema: {
|
|
997
|
+
type: "object",
|
|
998
|
+
properties: {
|
|
999
|
+
max_budget_usd: { type: "number", description: "Maximum plan budget in USD (> 0)" },
|
|
1000
|
+
max_stages: { type: "integer", description: "Maximum number of normal stages (>= 1)" },
|
|
1001
|
+
max_children_per_stage: { type: "integer", description: "Maximum dependent stages per stage (>= 1)" },
|
|
1002
|
+
applies_to: { type: "string", description: "'all' (default) or a plan UUID in the workspace" },
|
|
1003
|
+
expires_at: { type: "string", description: "Optional ISO timestamp after which the caps lapse" },
|
|
1004
|
+
},
|
|
1005
|
+
},
|
|
1006
|
+
handler: async (args) => {
|
|
1007
|
+
const num = (value) => value == null ? undefined : typeof value === "number" && Number.isFinite(value) ? value : (() => { throw new CodebusError("caps fields must be numbers"); })();
|
|
1008
|
+
return planCapsProposeCore(await makeCtx(resolveConfig({})), {
|
|
1009
|
+
maxBudgetUsd: num(args?.max_budget_usd),
|
|
1010
|
+
maxStages: num(args?.max_stages),
|
|
1011
|
+
maxChildrenPerStage: num(args?.max_children_per_stage),
|
|
1012
|
+
appliesTo: typeof args?.applies_to === "string" && args.applies_to.trim() ? args.applies_to.trim() : undefined,
|
|
1013
|
+
expiresAt: typeof args?.expires_at === "string" && args.expires_at.trim() ? args.expires_at.trim() : undefined,
|
|
1014
|
+
});
|
|
1015
|
+
},
|
|
1016
|
+
});
|
|
1017
|
+
// ── correlation_query (shared command core, ADR 0007) ────────────────────────
|
|
1018
|
+
// One command core (correlationQueryCore) feeds both the CLI command
|
|
1019
|
+
// (registerCorrelationCommand) and this MCP tool, satisfying the
|
|
1020
|
+
// com.bragi.contract.cli-mcp-parity contract: schema, authorization,
|
|
1021
|
+
// results, errors, and T-01 correlation snapshots match between transports.
|
|
1022
|
+
TOOL_REGISTRY.push({
|
|
1023
|
+
name: "correlation_query",
|
|
1024
|
+
description: "Query the T-01 correlation chain (Jira → Plan → Stage → Child → Binding → Run → PR → Receipt) " +
|
|
1025
|
+
"for a given binding ID or run ID. Returns a parity envelope with schema version, auth, result, " +
|
|
1026
|
+
"errors, and the full correlation chain — identical to `codebus correlation --json` on the CLI. " +
|
|
1027
|
+
"Requires either binding_id or run_id; --require-binding enforces T-02 (spend-bearing work must " +
|
|
1028
|
+
"have a binding). Read-only.",
|
|
1029
|
+
inputSchema: {
|
|
1030
|
+
type: "object",
|
|
1031
|
+
properties: {
|
|
1032
|
+
binding_id: { type: "string", description: "Binding UUID to look up (optional; one of binding_id or run_id required)" },
|
|
1033
|
+
run_id: { type: "string", description: "Run ID to look up via external_run_id (optional; one of binding_id or run_id required)" },
|
|
1034
|
+
require_binding: { type: "boolean", description: "Fail if no binding exists (T-02)" },
|
|
1035
|
+
require_full: { type: "boolean", description: "Fail if any chain field is null" },
|
|
1036
|
+
},
|
|
1037
|
+
required: [],
|
|
1038
|
+
},
|
|
1039
|
+
handler: async (args) => {
|
|
1040
|
+
const ctx = await makeCtx(resolveConfig({}));
|
|
1041
|
+
const bindingId = args?.binding_id;
|
|
1042
|
+
const runId = args?.run_id;
|
|
1043
|
+
const requireBinding = args?.require_binding;
|
|
1044
|
+
const requireFull = args?.require_full;
|
|
1045
|
+
const envelope = await withCorrelation((c) => correlationQueryCore(c, {
|
|
1046
|
+
bindingId,
|
|
1047
|
+
runId,
|
|
1048
|
+
requireBinding,
|
|
1049
|
+
requireFull,
|
|
1050
|
+
}), ctx, { bindingId, runId, requireBinding, requireFull }, {
|
|
1051
|
+
transport: "mcp",
|
|
1052
|
+
correlationPartial: {
|
|
1053
|
+
binding_id: bindingId,
|
|
1054
|
+
run_id: runId,
|
|
1055
|
+
},
|
|
1056
|
+
});
|
|
1057
|
+
return envelope;
|
|
1058
|
+
},
|
|
1059
|
+
});
|
|
859
1060
|
//# sourceMappingURL=mcp-registry.js.map
|