codecartographer-pi 0.22.2 → 0.22.3
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.
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface CompletionCandidate {
|
|
2
|
+
value: string;
|
|
3
|
+
label?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface CompletionItem {
|
|
7
|
+
value: string;
|
|
8
|
+
label: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Complete the last whitespace-separated token of `prefix` from `candidates`,
|
|
13
|
+
* returning items whose `value` is the full argument text Pi should put in
|
|
14
|
+
* the line — every earlier token, then the candidate. A candidate already
|
|
15
|
+
* typed as an earlier token is not offered again. Returns null when nothing
|
|
16
|
+
* matches, which is what Pi expects for "no popup".
|
|
17
|
+
*/
|
|
18
|
+
export declare function completeLastToken(prefix: string, candidates: readonly CompletionCandidate[]): CompletionItem[] | null;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Argument completion for the /codecarto-* slash commands.
|
|
2
|
+
//
|
|
3
|
+
// Pi hands `getArgumentCompletions` everything typed after the command name,
|
|
4
|
+
// and when the user accepts an item it replaces all of that text with the
|
|
5
|
+
// item's `value` (pi 0.85: `argumentText = textBeforeCursor.slice(spaceIndex
|
|
6
|
+
// + 1)` on the way in, `applyCompletion` slicing `cursorCol - prefix.length`
|
|
7
|
+
// on the way out). A completer that matches the *last* token but returns a
|
|
8
|
+
// bare flag therefore erases every flag typed before it: with the popup open,
|
|
9
|
+
// `/codecarto-next --auto --llm-steer` became `/codecarto-next --llm-steer` on
|
|
10
|
+
// Enter, the steered phase ran alone, and the auto run never started. The
|
|
11
|
+
// same shape turned `--auto --strict` into `--strict`, the one combination
|
|
12
|
+
// the parser rejects.
|
|
13
|
+
//
|
|
14
|
+
// So: match the last token, but return the whole line.
|
|
15
|
+
/**
|
|
16
|
+
* Complete the last whitespace-separated token of `prefix` from `candidates`,
|
|
17
|
+
* returning items whose `value` is the full argument text Pi should put in
|
|
18
|
+
* the line — every earlier token, then the candidate. A candidate already
|
|
19
|
+
* typed as an earlier token is not offered again. Returns null when nothing
|
|
20
|
+
* matches, which is what Pi expects for "no popup".
|
|
21
|
+
*/
|
|
22
|
+
export function completeLastToken(prefix, candidates) {
|
|
23
|
+
const tokens = prefix.split(/\s+/);
|
|
24
|
+
const last = tokens.pop() ?? "";
|
|
25
|
+
const earlier = tokens.filter((token) => token.length > 0);
|
|
26
|
+
const head = earlier.join(" ");
|
|
27
|
+
const typed = new Set(earlier);
|
|
28
|
+
const items = candidates
|
|
29
|
+
.filter((candidate) => candidate.value.startsWith(last) && !typed.has(candidate.value))
|
|
30
|
+
.map((candidate) => ({
|
|
31
|
+
value: head ? `${head} ${candidate.value}` : candidate.value,
|
|
32
|
+
label: candidate.label ?? candidate.value,
|
|
33
|
+
...(candidate.description && { description: candidate.description }),
|
|
34
|
+
}));
|
|
35
|
+
return items.length > 0 ? items : null;
|
|
36
|
+
}
|
|
@@ -6,6 +6,7 @@ import { parseDashboardFlags } from "./dashboard-flags.js";
|
|
|
6
6
|
import { narrateDashboard } from "./dashboard-narrator.js";
|
|
7
7
|
import { parseBroadsideFlags, KNOWN_BROADSIDE_TOKENS } from "./broadside-flags.js";
|
|
8
8
|
import { parseNextFlags } from "./next-flags.js";
|
|
9
|
+
import { completeLastToken } from "./completions.js";
|
|
9
10
|
import { buildPiGuideMessage } from "./guide-framing.js";
|
|
10
11
|
import { isCtxLive, notifyCtx } from "./notify.js";
|
|
11
12
|
import { phaseCompactionExtension } from "./phase-compaction.js";
|
|
@@ -432,12 +433,7 @@ export default function codeCartographerExtension(pi) {
|
|
|
432
433
|
});
|
|
433
434
|
pi.registerCommand("codecarto-init", {
|
|
434
435
|
description: "Initialize .codecarto/ in the current repository",
|
|
435
|
-
getArgumentCompletions: (prefix) => {
|
|
436
|
-
const items = Object.keys(PIPELINE_ALIASES)
|
|
437
|
-
.filter((value) => value.startsWith(prefix))
|
|
438
|
-
.map((value) => ({ value, label: value }));
|
|
439
|
-
return items.length > 0 ? items : null;
|
|
440
|
-
},
|
|
436
|
+
getArgumentCompletions: (prefix) => completeLastToken(prefix, Object.keys(PIPELINE_ALIASES).map((value) => ({ value }))),
|
|
441
437
|
handler: async (args, ctx) => {
|
|
442
438
|
const trimmedArgs = args.trim();
|
|
443
439
|
const pipelineChoice = resolvePipelineChoice(trimmedArgs);
|
|
@@ -536,12 +532,7 @@ export default function codeCartographerExtension(pi) {
|
|
|
536
532
|
});
|
|
537
533
|
pi.registerCommand("codecarto-switch-pipeline", {
|
|
538
534
|
description: "Switch the active pipeline without losing findings or progress: /codecarto-switch-pipeline <variant>",
|
|
539
|
-
getArgumentCompletions: (prefix) => {
|
|
540
|
-
const items = Object.keys(PIPELINE_ALIASES)
|
|
541
|
-
.filter((value) => value.startsWith(prefix))
|
|
542
|
-
.map((value) => ({ value, label: value }));
|
|
543
|
-
return items.length > 0 ? items : null;
|
|
544
|
-
},
|
|
535
|
+
getArgumentCompletions: (prefix) => completeLastToken(prefix, Object.keys(PIPELINE_ALIASES).map((value) => ({ value }))),
|
|
545
536
|
handler: async (args, ctx) => {
|
|
546
537
|
const trimmedArgs = args.trim();
|
|
547
538
|
if (!trimmedArgs) {
|
|
@@ -595,16 +586,17 @@ export default function codeCartographerExtension(pi) {
|
|
|
595
586
|
// --strict is offered only once --auto is present, because on its own
|
|
596
587
|
// it is rejected — suggesting it standalone invites the one error the
|
|
597
588
|
// parser has.
|
|
589
|
+
// Each item's value is the whole argument line (see completions.ts):
|
|
590
|
+
// accepting `--llm-steer` after `--auto ` keeps the `--auto`.
|
|
598
591
|
const autoAlreadyTyped = prefix.includes("--auto");
|
|
599
|
-
|
|
600
|
-
{ value: "--auto",
|
|
601
|
-
{ value: "--llm-steer",
|
|
602
|
-
{ value: "--no-llm-steer",
|
|
592
|
+
return completeLastToken(prefix, [
|
|
593
|
+
{ value: "--auto", description: "run every remaining phase back to back (recommended with --llm-steer)" },
|
|
594
|
+
{ value: "--llm-steer", description: "seed each phase from the previous phase's closeout; no effect on the first phase" },
|
|
595
|
+
{ value: "--no-llm-steer", description: "force steering off when the workspace config turns it on" },
|
|
603
596
|
...(autoAlreadyTyped
|
|
604
|
-
? [{ value: "--strict",
|
|
597
|
+
? [{ value: "--strict", description: "with --auto: stop on PASS WITH GAPS instead of advancing" }]
|
|
605
598
|
: []),
|
|
606
|
-
]
|
|
607
|
-
return items.length > 0 ? items : null;
|
|
599
|
+
]);
|
|
608
600
|
},
|
|
609
601
|
handler: async (args, ctx) => {
|
|
610
602
|
const flags = parseNextFlags(args);
|
|
@@ -967,10 +959,7 @@ export default function codeCartographerExtension(pi) {
|
|
|
967
959
|
description: "Read the packaged CodeCartographer agent guide into the session: /codecarto-guide [topic]",
|
|
968
960
|
getArgumentCompletions: async (prefix) => {
|
|
969
961
|
const topics = await listGuideTopics().catch(() => ["overview"]);
|
|
970
|
-
|
|
971
|
-
.filter((value) => value.startsWith(prefix))
|
|
972
|
-
.map((value) => ({ value, label: value }));
|
|
973
|
-
return items.length > 0 ? items : null;
|
|
962
|
+
return completeLastToken(prefix, topics.map((value) => ({ value })));
|
|
974
963
|
},
|
|
975
964
|
handler: async (args, ctx) => {
|
|
976
965
|
// The guide is packaged with the extension, not copied into a
|
|
@@ -1004,12 +993,9 @@ export default function codeCartographerExtension(pi) {
|
|
|
1004
993
|
});
|
|
1005
994
|
pi.registerCommand("codecarto-broadside", {
|
|
1006
995
|
description: "Batch reconnaissance (Broad-Side): /codecarto-broadside [submit|collect|status|models] [lenses…] [--model=ID] [--lens-model=LENS:ID] [flags]",
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
.map((value) => ({ value, label: value }));
|
|
1011
|
-
return items.length > 0 ? items : null;
|
|
1012
|
-
},
|
|
996
|
+
// Completes the token under the cursor, so lens names and flags are
|
|
997
|
+
// offered after the action too, and keeps everything typed before it.
|
|
998
|
+
getArgumentCompletions: (prefix) => completeLastToken(prefix, KNOWN_BROADSIDE_TOKENS.map((value) => ({ value }))),
|
|
1013
999
|
handler: async (args, ctx) => {
|
|
1014
1000
|
const flags = parseBroadsideFlags(args);
|
|
1015
1001
|
if (flags.unknown.length > 0) {
|
|
@@ -1439,12 +1425,7 @@ export default function codeCartographerExtension(pi) {
|
|
|
1439
1425
|
});
|
|
1440
1426
|
pi.registerCommand("codecarto-dashboard", {
|
|
1441
1427
|
description: "Regenerate .codecarto/dashboard.html (use --narrate for an LLM executive summary)",
|
|
1442
|
-
getArgumentCompletions: (prefix) => {
|
|
1443
|
-
const items = ["--narrate"]
|
|
1444
|
-
.filter((value) => value.startsWith(prefix))
|
|
1445
|
-
.map((value) => ({ value, label: value }));
|
|
1446
|
-
return items.length > 0 ? items : null;
|
|
1447
|
-
},
|
|
1428
|
+
getArgumentCompletions: (prefix) => completeLastToken(prefix, [{ value: "--narrate" }]),
|
|
1448
1429
|
handler: async (args, ctx) => {
|
|
1449
1430
|
const flags = parseDashboardFlags(args);
|
|
1450
1431
|
if (flags.unknown.length > 0) {
|
|
@@ -1515,10 +1496,7 @@ export default function codeCartographerExtension(pi) {
|
|
|
1515
1496
|
description: "Apply a post-pipeline amendment from .codecarto/scratch/amendments/, after a preview: /codecarto-amend <name | scratch/amendments/name.yaml>",
|
|
1516
1497
|
getArgumentCompletions: async (prefix) => {
|
|
1517
1498
|
const names = await listAmendmentNames(join(sessionCwd ?? process.cwd(), ".codecarto"));
|
|
1518
|
-
|
|
1519
|
-
.filter((value) => value.startsWith(prefix))
|
|
1520
|
-
.map((value) => ({ value, label: value }));
|
|
1521
|
-
return items.length > 0 ? items : null;
|
|
1499
|
+
return completeLastToken(prefix, names.map((value) => ({ value })));
|
|
1522
1500
|
},
|
|
1523
1501
|
handler: async (args, ctx) => {
|
|
1524
1502
|
const state = await ensureWorkspaceState(ctx);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codecartographer-pi",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.3",
|
|
4
4
|
"mcpName": "io.github.HuginnIndustries/codecartographer",
|
|
5
5
|
"description": "Turn an unfamiliar codebase into a validated reimplementation spec, then synthesize confirmed specs and a product vision into a traceable plan.",
|
|
6
6
|
"type": "module",
|