codiedev 0.5.4 → 0.5.6
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/cli.js +8 -0
- package/dist/commands/ask.d.ts +1 -0
- package/dist/commands/ask.js +46 -0
- package/dist/mcp.js +56 -2
- package/dist/utils.js +1 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -19,6 +19,7 @@ const connect_1 = require("./connect");
|
|
|
19
19
|
const push_1 = require("./commands/push");
|
|
20
20
|
const delete_1 = require("./commands/delete");
|
|
21
21
|
const pull_1 = require("./commands/pull");
|
|
22
|
+
const ask_1 = require("./commands/ask");
|
|
22
23
|
const ping_1 = require("./commands/ping");
|
|
23
24
|
const inbox_1 = require("./commands/inbox");
|
|
24
25
|
const note_1 = require("./commands/note");
|
|
@@ -43,6 +44,10 @@ Artifacts:
|
|
|
43
44
|
codiedev delete <key> [-y] Delete every version of an artifact you
|
|
44
45
|
authored (clean up bad/test pushes).
|
|
45
46
|
Asks for confirmation; -y to skip.
|
|
47
|
+
codiedev ask "<question>" Ask a natural-language question of the
|
|
48
|
+
team's collective memory. Returns an
|
|
49
|
+
LLM-synthesized answer with citations
|
|
50
|
+
pointing at sessions + artifacts.
|
|
46
51
|
codiedev promote <artifact-id> Promote an auto-extracted artifact
|
|
47
52
|
to an authored one
|
|
48
53
|
codiedev reverse-ticket [<pr-url>] Generate a Jira ticket draft.
|
|
@@ -374,6 +379,9 @@ async function main() {
|
|
|
374
379
|
case "pull":
|
|
375
380
|
await (0, pull_1.runPull)(rest);
|
|
376
381
|
return;
|
|
382
|
+
case "ask":
|
|
383
|
+
await (0, ask_1.runAsk)(rest);
|
|
384
|
+
return;
|
|
377
385
|
case "ping":
|
|
378
386
|
await (0, ping_1.runPing)(rest);
|
|
379
387
|
return;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runAsk(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runAsk = runAsk;
|
|
4
|
+
const shared_1 = require("./shared");
|
|
5
|
+
function parseArgs(args) {
|
|
6
|
+
// Everything after the command, joined back into a question string. Allows
|
|
7
|
+
// both quoted and unquoted forms: `codiedev ask "why pg-bouncer?"` or
|
|
8
|
+
// `codiedev ask why did we drop pg-bouncer`.
|
|
9
|
+
const question = args
|
|
10
|
+
.filter((a) => !a.startsWith("--"))
|
|
11
|
+
.join(" ")
|
|
12
|
+
.trim();
|
|
13
|
+
if (!question) {
|
|
14
|
+
console.error('Usage: codiedev ask "<question>"');
|
|
15
|
+
console.error('Example: codiedev ask "why did we drop pg-bouncer?"');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
return { question };
|
|
19
|
+
}
|
|
20
|
+
async function runAsk(args) {
|
|
21
|
+
const { question } = parseArgs(args);
|
|
22
|
+
const config = (0, shared_1.requireConfig)();
|
|
23
|
+
try {
|
|
24
|
+
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/ask", {
|
|
25
|
+
config,
|
|
26
|
+
body: { question },
|
|
27
|
+
});
|
|
28
|
+
console.log("");
|
|
29
|
+
console.log(res.answer);
|
|
30
|
+
if (res.citations.length > 0) {
|
|
31
|
+
console.log("");
|
|
32
|
+
console.log("Sources:");
|
|
33
|
+
for (const c of res.citations) {
|
|
34
|
+
const label = c.kind === "artifact"
|
|
35
|
+
? `[${c.type}] ${c.title}`
|
|
36
|
+
: `[session] ${c.title}`;
|
|
37
|
+
console.log(` • ${label}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
console.log("");
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error(`Ask failed: ${err.message}`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
}
|
package/dist/mcp.js
CHANGED
|
@@ -384,7 +384,9 @@ const TOOLS = [
|
|
|
384
384
|
"when the user asks 'has anyone solved X?', 'find me the spec on Y', " +
|
|
385
385
|
"or 'look for prior work on Z'. Always search before pushing a new " +
|
|
386
386
|
"artifact so the user doesn't duplicate work. Returns ranked hits " +
|
|
387
|
-
"with title, type, filename key, and a snippet."
|
|
387
|
+
"with title, type, filename key, and a snippet. For open-ended " +
|
|
388
|
+
"questions where the user wants a synthesized answer (not just a list " +
|
|
389
|
+
"of hits), prefer codiedev_ask instead.",
|
|
388
390
|
inputSchema: {
|
|
389
391
|
type: "object",
|
|
390
392
|
properties: {
|
|
@@ -394,6 +396,32 @@ const TOOLS = [
|
|
|
394
396
|
required: ["query"],
|
|
395
397
|
},
|
|
396
398
|
},
|
|
399
|
+
{
|
|
400
|
+
name: "codiedev_ask",
|
|
401
|
+
description: "Ask a natural-language question of the team's collective memory and " +
|
|
402
|
+
"get a synthesized answer with citations. Searches across both " +
|
|
403
|
+
"auto-extracted artifacts (specs / decisions / bugfixes) AND raw " +
|
|
404
|
+
"session transcripts, then has an LLM compose an answer that cites " +
|
|
405
|
+
"the actual sources. Use when the user asks 'why did we…?', 'what " +
|
|
406
|
+
"does the team know about X?', 'has anyone done Y here before?', " +
|
|
407
|
+
"'who decided Z and why?', or any open-ended question about prior " +
|
|
408
|
+
"work where they want context, not just a hit list. For exact-match " +
|
|
409
|
+
"lookups (find me spec-x), prefer codiedev_pull. For browsing or " +
|
|
410
|
+
"filtering by kind/tag, prefer codiedev_get_library. For surfacing " +
|
|
411
|
+
"ranked hits without LLM synthesis, prefer codiedev_search.",
|
|
412
|
+
inputSchema: {
|
|
413
|
+
type: "object",
|
|
414
|
+
properties: {
|
|
415
|
+
question: {
|
|
416
|
+
type: "string",
|
|
417
|
+
description: "Natural-language question. Open-ended is fine — e.g. 'why " +
|
|
418
|
+
"did we drop pg-bouncer?' or 'how does the team think about " +
|
|
419
|
+
"feature flags?'.",
|
|
420
|
+
},
|
|
421
|
+
},
|
|
422
|
+
required: ["question"],
|
|
423
|
+
},
|
|
424
|
+
},
|
|
397
425
|
{
|
|
398
426
|
name: "codiedev_get_library",
|
|
399
427
|
description: "List artifacts in the team library — both docs (spec / decision / " +
|
|
@@ -571,6 +599,8 @@ async function dispatchTool(name, args, config) {
|
|
|
571
599
|
return await handleSendTo(args, config);
|
|
572
600
|
case "codiedev_react":
|
|
573
601
|
return await handleReact(args, config);
|
|
602
|
+
case "codiedev_ask":
|
|
603
|
+
return await handleAsk(args, config);
|
|
574
604
|
case "codiedev_search":
|
|
575
605
|
return await handleSearch(args, config);
|
|
576
606
|
case "codiedev_get_library":
|
|
@@ -621,8 +651,15 @@ async function handlePull(args, config) {
|
|
|
621
651
|
throw new Error("key required");
|
|
622
652
|
const res = await (0, shared_1.apiRequest)("GET", "/api/cli/pull", { config, query: { key, version } });
|
|
623
653
|
const a = res.artifact;
|
|
654
|
+
// Lead with the new-vocab kind. Legacy doc-shape (spec/decision/...) is
|
|
655
|
+
// surfaced as a tag list after, so callers still see it but it's no
|
|
656
|
+
// longer the primary label. Falls back to "doc" if the row pre-dates the
|
|
657
|
+
// kind field.
|
|
658
|
+
const kindLabel = a.kind ?? "doc";
|
|
659
|
+
const tagList = (a.tags ?? []).filter((t) => t).join(", ");
|
|
660
|
+
const tagSuffix = tagList ? ` · tags: ${tagList}` : "";
|
|
624
661
|
const header = `# ${a.title}\n\n` +
|
|
625
|
-
`**${
|
|
662
|
+
`**${kindLabel}** · v${a.version ?? 1} · ${a.lifecycle ?? "draft"}${tagSuffix} · ` +
|
|
626
663
|
`updated ${(0, shared_1.timeAgo)(a.updatedAt ?? a.createdAt)}\n\n---\n\n`;
|
|
627
664
|
return {
|
|
628
665
|
content: [{ type: "text", text: header + a.markdown }],
|
|
@@ -915,6 +952,23 @@ async function handleSearch(args, config) {
|
|
|
915
952
|
}
|
|
916
953
|
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
917
954
|
}
|
|
955
|
+
async function handleAsk(args, config) {
|
|
956
|
+
const question = asString(args.question);
|
|
957
|
+
if (!question)
|
|
958
|
+
throw new Error("question required");
|
|
959
|
+
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/ask", { config, body: { question } });
|
|
960
|
+
const lines = [res.answer];
|
|
961
|
+
if (res.citations && res.citations.length > 0) {
|
|
962
|
+
lines.push("", "Sources:");
|
|
963
|
+
for (const c of res.citations) {
|
|
964
|
+
const label = c.kind === "artifact"
|
|
965
|
+
? `[${c.type}] ${c.title}`
|
|
966
|
+
: `[session] ${c.title}`;
|
|
967
|
+
lines.push(` • ${label}`);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
971
|
+
}
|
|
918
972
|
async function handleGetLibrary(args, config) {
|
|
919
973
|
const scope = asStringOrUndefined(args.scope);
|
|
920
974
|
const type = asStringOrUndefined(args.type);
|
package/dist/utils.js
CHANGED
|
@@ -218,6 +218,7 @@ thought, use the \`codiedev\` CLI via Bash:**
|
|
|
218
218
|
| "share with Greg" / "give Jason access" (no notification) | MCP tool \`codiedev_share_with\` |
|
|
219
219
|
| "send this to Greg" / "ask Greg to look at this" | MCP tool \`codiedev_send_to\` |
|
|
220
220
|
| "find something about X" / "has anyone solved Y?" | MCP tool \`codiedev_search\` |
|
|
221
|
+
| "why did we…?" / "what does the team know about X?" | MCP tool \`codiedev_ask\` (synthesized answer + citations) |
|
|
221
222
|
| "show my library" / "what artifacts exist?" | MCP tool \`codiedev_get_library\` |
|
|
222
223
|
| "react 🛠 to that post" / "mark as used" | MCP tool \`codiedev_react\` |
|
|
223
224
|
|