coding-friend-cli 1.40.2 → 1.40.4
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/{chunk-CZW36H3D.js → chunk-BQ4E66ZV.js} +1 -1
- package/dist/{chunk-KT5RLAFH.js → chunk-DVWCO7K4.js} +4 -4
- package/dist/{chunk-TFF47F7P.js → chunk-HEVK3OYL.js} +1 -1
- package/dist/{chunk-4FQACYCV.js → chunk-LZPCZAGZ.js} +34 -8
- package/dist/{chunk-KG6HYBGD.js → chunk-SKEWZ2ET.js} +74 -6
- package/dist/{chunk-Z5XTSF7L.js → chunk-XLB2UAKL.js} +40 -2
- package/dist/{chunk-CGZNFAOB.js → chunk-ZEOWTLWI.js} +7 -1
- package/dist/{clean-S57BNTWM.js → clean-VD6CFY4C.js} +1 -1
- package/dist/{config-A4JIINZK.js → config-7LMHDOGW.js} +5 -5
- package/dist/{dev-E3EHPMHE.js → dev-GCVXE5TW.js} +5 -17
- package/dist/{disable-DCGVIHKG.js → disable-CN6GAG4I.js} +1 -1
- package/dist/{enable-YYWJDOYB.js → enable-MRLKTJRB.js} +1 -1
- package/dist/{host-7XKH5HLB.js → host-KGUAFN4Y.js} +1 -1
- package/dist/index.js +33 -33
- package/dist/{init-ORERNRR7.js → init-GL353JQR.js} +362 -267
- package/dist/{install-MS7SS2L5.js → install-3APP3HXQ.js} +3 -3
- package/dist/{learn-Q5YHKHQH.js → learn-ZNJ54LRO.js} +1 -1
- package/dist/{mcp-XGWHYBEN.js → mcp-TS7MOQ3A.js} +5 -5
- package/dist/{mcp-serve-7RWXY3J4.js → mcp-serve-D6BHVTCY.js} +1 -1
- package/dist/{memory-KNKGLCVG.js → memory-NAFLQ6NN.js} +5 -5
- package/dist/{permission-DDBMBFJV.js → permission-TORAVB2Y.js} +3 -3
- package/dist/{session-WU5344ZD.js → session-AOC37YNH.js} +1 -1
- package/dist/{status-WICNVD7B.js → status-Z7DB7Y2S.js} +6 -6
- package/dist/{uninstall-6QKNGLKK.js → uninstall-S5FSXBYX.js} +2 -2
- package/dist/{update-6YMGKFUB.js → update-NHI4DBZL.js} +5 -3
- package/package.json +1 -1
|
@@ -7,14 +7,14 @@ import {
|
|
|
7
7
|
getExistingRules,
|
|
8
8
|
getMissingRules,
|
|
9
9
|
logPluginScriptWarning
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-SKEWZ2ET.js";
|
|
11
11
|
import {
|
|
12
12
|
ensureMemoryBuilt,
|
|
13
13
|
isMemoryInitialized,
|
|
14
14
|
memoryInitWizard
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-DVWCO7K4.js";
|
|
16
|
+
import "./chunk-HEVK3OYL.js";
|
|
17
|
+
import "./chunk-ZEOWTLWI.js";
|
|
18
18
|
import {
|
|
19
19
|
findStatuslineHookPath,
|
|
20
20
|
getCurrentAccountEmail,
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
isMemoryMcpRegistered,
|
|
42
42
|
memoryConfigMenu,
|
|
43
43
|
registerMemoryMcp
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-BQ4E66ZV.js";
|
|
45
45
|
import {
|
|
46
46
|
deployCodexAgents,
|
|
47
47
|
findCodexAgentSourceDir,
|
|
@@ -55,16 +55,22 @@ import {
|
|
|
55
55
|
} from "./chunk-KCBMCHSA.js";
|
|
56
56
|
import {
|
|
57
57
|
BACK,
|
|
58
|
+
BackError,
|
|
58
59
|
applyDocsDirChange,
|
|
59
60
|
askScope,
|
|
60
61
|
ensureDocsFolders,
|
|
62
|
+
escCheckbox,
|
|
63
|
+
escConfirm,
|
|
64
|
+
escInput,
|
|
65
|
+
escSelect,
|
|
61
66
|
formatScopeLabel,
|
|
62
67
|
getMergedValue,
|
|
63
68
|
getScopeLabel,
|
|
64
69
|
injectBackChoice,
|
|
65
70
|
resolveHostFlags,
|
|
71
|
+
setEscArmed,
|
|
66
72
|
showConfigHint
|
|
67
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-XLB2UAKL.js";
|
|
68
74
|
import {
|
|
69
75
|
getLibPath
|
|
70
76
|
} from "./chunk-TN3Y75WG.js";
|
|
@@ -94,7 +100,6 @@ import {
|
|
|
94
100
|
} from "./chunk-NREZK463.js";
|
|
95
101
|
|
|
96
102
|
// src/commands/init.ts
|
|
97
|
-
import { checkbox, confirm, input, select } from "@inquirer/prompts";
|
|
98
103
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
99
104
|
import { homedir } from "os";
|
|
100
105
|
import { join } from "path";
|
|
@@ -118,6 +123,33 @@ function printStepHeader(label, description) {
|
|
|
118
123
|
console.log(` ${chalk.dim(description)}`);
|
|
119
124
|
}
|
|
120
125
|
console.log(`${line}`);
|
|
126
|
+
console.log(chalk.dim(" (esc: back to previous step)"));
|
|
127
|
+
}
|
|
128
|
+
async function runSteps(steps) {
|
|
129
|
+
setEscArmed(Boolean(process.stdin.isTTY));
|
|
130
|
+
try {
|
|
131
|
+
let i = 0;
|
|
132
|
+
while (i < steps.length) {
|
|
133
|
+
_stepIndex = i;
|
|
134
|
+
try {
|
|
135
|
+
await steps[i]();
|
|
136
|
+
i++;
|
|
137
|
+
} catch (err) {
|
|
138
|
+
if (!(err instanceof BackError)) throw err;
|
|
139
|
+
console.log();
|
|
140
|
+
if (i === 0) log.dim("Already at the first step.");
|
|
141
|
+
else i--;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
} finally {
|
|
145
|
+
setEscArmed(false);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function readCfgs() {
|
|
149
|
+
return {
|
|
150
|
+
globalCfg: readJson(globalConfigPath()),
|
|
151
|
+
localCfg: readJson(localConfigPath())
|
|
152
|
+
};
|
|
121
153
|
}
|
|
122
154
|
function isGitRepo() {
|
|
123
155
|
return run("git", ["rev-parse", "--is-inside-work-tree"]) === "true";
|
|
@@ -235,7 +267,7 @@ function getDocsDir(globalCfg, localCfg) {
|
|
|
235
267
|
return localCfg?.docsDir ?? globalCfg?.docsDir ?? DEFAULT_CONFIG.docsDir;
|
|
236
268
|
}
|
|
237
269
|
async function offerGlobalShortcut(globalDisplay) {
|
|
238
|
-
const choice = await
|
|
270
|
+
const choice = await escSelect({
|
|
239
271
|
message: "How to configure?",
|
|
240
272
|
choices: injectBackChoice(
|
|
241
273
|
[
|
|
@@ -275,7 +307,7 @@ async function stepDocsDir(globalCfg, localCfg) {
|
|
|
275
307
|
ensureDocsFolders(globalValue, DOCS_SUBFOLDERS2);
|
|
276
308
|
return;
|
|
277
309
|
}
|
|
278
|
-
const value = await
|
|
310
|
+
const value = await escInput({
|
|
279
311
|
message: "Docs folder name:",
|
|
280
312
|
default: currentValue ?? DEFAULT_CONFIG.docsDir,
|
|
281
313
|
validate: (val) => {
|
|
@@ -315,7 +347,7 @@ async function stepGitignore(docsDir) {
|
|
|
315
347
|
"Configure .gitignore",
|
|
316
348
|
"Keeps Coding Friend's AI-generated docs and config out of your git history. You can edit it later in .gitignore."
|
|
317
349
|
);
|
|
318
|
-
const choice = await
|
|
350
|
+
const choice = await escSelect({
|
|
319
351
|
message: "Add coding-friend artifacts to .gitignore?",
|
|
320
352
|
choices: injectBackChoice(
|
|
321
353
|
[
|
|
@@ -343,7 +375,7 @@ async function stepGitignore(docsDir) {
|
|
|
343
375
|
];
|
|
344
376
|
let entries = allEntries;
|
|
345
377
|
if (choice === "partial") {
|
|
346
|
-
entries = await
|
|
378
|
+
entries = await escCheckbox({
|
|
347
379
|
message: "Which folders to ignore?",
|
|
348
380
|
choices: allEntries.map((e) => ({ name: e, value: e }))
|
|
349
381
|
});
|
|
@@ -393,7 +425,7 @@ async function stepDocsLanguage(globalCfg, localCfg) {
|
|
|
393
425
|
writeToScope(scope, { language: lang });
|
|
394
426
|
}
|
|
395
427
|
async function selectLanguage(message) {
|
|
396
|
-
const choice = await
|
|
428
|
+
const choice = await escSelect({
|
|
397
429
|
message,
|
|
398
430
|
choices: injectBackChoice(
|
|
399
431
|
[
|
|
@@ -406,7 +438,7 @@ async function selectLanguage(message) {
|
|
|
406
438
|
});
|
|
407
439
|
handleBack(choice);
|
|
408
440
|
if (choice === "_other") {
|
|
409
|
-
const lang = await
|
|
441
|
+
const lang = await escInput({ message: "Enter language name:" });
|
|
410
442
|
return lang || "en";
|
|
411
443
|
}
|
|
412
444
|
return choice;
|
|
@@ -435,7 +467,7 @@ async function stepLearnConfig(globalCfg) {
|
|
|
435
467
|
value: "default"
|
|
436
468
|
});
|
|
437
469
|
locationChoices.push({ name: "Custom path\u2026", value: "custom" });
|
|
438
|
-
const locationChoice = await
|
|
470
|
+
const locationChoice = await escSelect({
|
|
439
471
|
message: `Current learn folder: ${currentOutputDir}`,
|
|
440
472
|
choices: injectBackChoice(locationChoices, "Cancel init")
|
|
441
473
|
});
|
|
@@ -444,7 +476,7 @@ async function stepLearnConfig(globalCfg) {
|
|
|
444
476
|
if (locationChoice === "current") {
|
|
445
477
|
outputDir = currentOutputDir;
|
|
446
478
|
} else if (locationChoice === "custom") {
|
|
447
|
-
outputDir = await
|
|
479
|
+
outputDir = await escInput({
|
|
448
480
|
message: "Enter path (absolute or ~/...):",
|
|
449
481
|
default: currentOutputDir !== defaultLearnDir ? currentOutputDir : void 0,
|
|
450
482
|
validate: (val) => {
|
|
@@ -456,7 +488,7 @@ async function stepLearnConfig(globalCfg) {
|
|
|
456
488
|
});
|
|
457
489
|
const resolved = resolvePath(outputDir);
|
|
458
490
|
if (!existsSync(resolved)) {
|
|
459
|
-
const create = await
|
|
491
|
+
const create = await escConfirm({
|
|
460
492
|
message: `Folder ${resolved} doesn't exist. Create it?`,
|
|
461
493
|
default: true
|
|
462
494
|
});
|
|
@@ -480,7 +512,7 @@ async function stepLearnConfig(globalCfg) {
|
|
|
480
512
|
});
|
|
481
513
|
}
|
|
482
514
|
catChoices.push({ name: "Customize", value: "custom" });
|
|
483
|
-
const catChoice = await
|
|
515
|
+
const catChoice = await escSelect({
|
|
484
516
|
message: "Categories for organizing learning docs?",
|
|
485
517
|
choices: injectBackChoice(catChoices, "Cancel init")
|
|
486
518
|
});
|
|
@@ -507,7 +539,7 @@ async function stepLearnConfig(globalCfg) {
|
|
|
507
539
|
const customCats = [];
|
|
508
540
|
let keepGoing = true;
|
|
509
541
|
while (keepGoing) {
|
|
510
|
-
const line = await
|
|
542
|
+
const line = await escInput({
|
|
511
543
|
message: `Category ${customCats.length + 1}:`
|
|
512
544
|
});
|
|
513
545
|
if (!line) {
|
|
@@ -532,12 +564,12 @@ async function stepLearnConfig(globalCfg) {
|
|
|
532
564
|
]);
|
|
533
565
|
const learnDirIsGit = gitInLearnDir !== null;
|
|
534
566
|
if (learnDirIsGit) {
|
|
535
|
-
autoCommit = await
|
|
567
|
+
autoCommit = await escConfirm({
|
|
536
568
|
message: "Auto-commit learning docs to git after each /cf-learn?",
|
|
537
569
|
default: globalLearn?.autoCommit ?? false
|
|
538
570
|
});
|
|
539
571
|
}
|
|
540
|
-
const indexChoice = await
|
|
572
|
+
const indexChoice = await escSelect({
|
|
541
573
|
message: "How should learning docs be indexed?",
|
|
542
574
|
choices: injectBackChoice(
|
|
543
575
|
[
|
|
@@ -644,7 +676,7 @@ async function stepMemory(docsDir, opts) {
|
|
|
644
676
|
"CF Memory",
|
|
645
677
|
"Persistent project knowledge across sessions \u2014 search tier, embeddings, MCP."
|
|
646
678
|
);
|
|
647
|
-
const choice = await
|
|
679
|
+
const choice = await escSelect({
|
|
648
680
|
message: "Set up CF Memory?",
|
|
649
681
|
choices: injectBackChoice(
|
|
650
682
|
[
|
|
@@ -682,7 +714,7 @@ async function stepTdd(globalCfg, localCfg) {
|
|
|
682
714
|
`TDD ${formatScopeLabel(scopeLabel)}${currentValue !== void 0 ? ` (${currentValue})` : ""}`,
|
|
683
715
|
"Enable TDD (RED\u2192GREEN\u2192REFACTOR) by default for all implementations."
|
|
684
716
|
);
|
|
685
|
-
const tddChoice = await
|
|
717
|
+
const tddChoice = await escConfirm({
|
|
686
718
|
message: "Enable TDD by default? (writes failing tests before code \u2014 RED \u2192 GREEN \u2192 REFACTOR)",
|
|
687
719
|
default: currentValue ?? false
|
|
688
720
|
});
|
|
@@ -702,7 +734,7 @@ async function stepAutoApprove(globalCfg, localCfg) {
|
|
|
702
734
|
`Auto-approve ${formatScopeLabel(scopeLabel)}${currentValue !== void 0 ? ` (${currentValue})` : ""}`,
|
|
703
735
|
"Same `autoApprove` key for Claude (LLM classifier), Antigravity, and Codex (deterministic)."
|
|
704
736
|
);
|
|
705
|
-
const autoApproveChoice = await
|
|
737
|
+
const autoApproveChoice = await escConfirm({
|
|
706
738
|
message: "Enable auto-approve? (Claude: LLM classifier; Antigravity/Codex: deterministic rules, no LLM)",
|
|
707
739
|
default: currentValue ?? false
|
|
708
740
|
});
|
|
@@ -717,7 +749,7 @@ async function stepAutoApprove(globalCfg, localCfg) {
|
|
|
717
749
|
if (autoApproveChoice) {
|
|
718
750
|
await afterAutoApproveEnabled(
|
|
719
751
|
log,
|
|
720
|
-
(message) =>
|
|
752
|
+
(message) => escConfirm({ message, default: true })
|
|
721
753
|
);
|
|
722
754
|
}
|
|
723
755
|
}
|
|
@@ -733,13 +765,13 @@ async function stepPlanDocs(globalCfg, localCfg) {
|
|
|
733
765
|
`Plan docs ${formatScopeLabel(scopeLabel)}`,
|
|
734
766
|
"The human overview doc /cf-plan writes next to the agent plan \u2014 enable/disable and choose format."
|
|
735
767
|
);
|
|
736
|
-
const disableChoice = await
|
|
768
|
+
const disableChoice = await escConfirm({
|
|
737
769
|
message: "Disable the /cf-plan human overview doc? (off by default)",
|
|
738
770
|
default: currentDisable ?? true
|
|
739
771
|
});
|
|
740
772
|
let formatChoice;
|
|
741
773
|
if (!disableChoice) {
|
|
742
|
-
const fmt = await
|
|
774
|
+
const fmt = await escSelect({
|
|
743
775
|
message: "Format for the human overview doc?",
|
|
744
776
|
choices: injectBackChoice(
|
|
745
777
|
[
|
|
@@ -769,7 +801,7 @@ async function stepPlanDocs(globalCfg, localCfg) {
|
|
|
769
801
|
log.success(`Saved to ${targetPath}`);
|
|
770
802
|
}
|
|
771
803
|
async function stepClaudePermissions(externalLearnDir, autoCommit) {
|
|
772
|
-
const scope = await
|
|
804
|
+
const scope = await escSelect({
|
|
773
805
|
message: "Where should permissions be saved?",
|
|
774
806
|
choices: [
|
|
775
807
|
{
|
|
@@ -813,7 +845,7 @@ async function stepClaudePermissions(externalLearnDir, autoCommit) {
|
|
|
813
845
|
logPluginScriptWarning(log, chalk);
|
|
814
846
|
}
|
|
815
847
|
console.log();
|
|
816
|
-
const ok = await
|
|
848
|
+
const ok = await escConfirm({
|
|
817
849
|
message: `Add all ${missing.length} recommended rules?`,
|
|
818
850
|
default: true
|
|
819
851
|
});
|
|
@@ -933,7 +965,7 @@ async function initMenu(gitAvailable) {
|
|
|
933
965
|
description: " Grant Coding Friend skills/hooks the permissions they need"
|
|
934
966
|
}
|
|
935
967
|
];
|
|
936
|
-
const choice = await
|
|
968
|
+
const choice = await escSelect({
|
|
937
969
|
message: "Which setting to configure?",
|
|
938
970
|
choices: injectBackChoice(choices, "Exit")
|
|
939
971
|
});
|
|
@@ -942,104 +974,113 @@ async function initMenu(gitAvailable) {
|
|
|
942
974
|
return;
|
|
943
975
|
}
|
|
944
976
|
_suppressStepHeaders = true;
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
const
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
const autoApproveChoice = await confirm({
|
|
982
|
-
message: "Enable auto-approve? (Claude: LLM classifier; Antigravity/Codex: deterministic rules, no LLM)",
|
|
983
|
-
default: autoApproveVal ?? false
|
|
984
|
-
});
|
|
985
|
-
const autoApproveTargetScope = await askScope();
|
|
986
|
-
if (autoApproveTargetScope !== "back") {
|
|
987
|
-
const targetPath = autoApproveTargetScope === "global" ? globalConfigPath() : localConfigPath();
|
|
988
|
-
mergeJson(targetPath, { autoApprove: autoApproveChoice });
|
|
989
|
-
log.success(`Saved to ${targetPath}`);
|
|
990
|
-
}
|
|
991
|
-
if (autoApproveChoice) {
|
|
992
|
-
await afterAutoApproveEnabled(
|
|
993
|
-
log,
|
|
994
|
-
(message) => confirm({ message, default: true })
|
|
995
|
-
);
|
|
977
|
+
setEscArmed(Boolean(process.stdin.isTTY));
|
|
978
|
+
try {
|
|
979
|
+
switch (choice) {
|
|
980
|
+
case "docsDir":
|
|
981
|
+
await stepDocsDir(globalCfg, localCfg);
|
|
982
|
+
break;
|
|
983
|
+
case "gitignore":
|
|
984
|
+
await stepGitignore(docsDir);
|
|
985
|
+
break;
|
|
986
|
+
case "language":
|
|
987
|
+
await stepDocsLanguage(globalCfg, localCfg);
|
|
988
|
+
break;
|
|
989
|
+
case "learn":
|
|
990
|
+
await stepLearnConfig(globalCfg);
|
|
991
|
+
break;
|
|
992
|
+
case "completion":
|
|
993
|
+
await stepShellCompletion();
|
|
994
|
+
break;
|
|
995
|
+
case "statusline":
|
|
996
|
+
await stepStatusline();
|
|
997
|
+
break;
|
|
998
|
+
case "memory":
|
|
999
|
+
await stepMemory(docsDir, { menuMode: true });
|
|
1000
|
+
break;
|
|
1001
|
+
case "tdd": {
|
|
1002
|
+
const tddChoice = await escConfirm({
|
|
1003
|
+
message: "Enable TDD by default? (writes failing tests before code \u2014 RED \u2192 GREEN \u2192 REFACTOR)",
|
|
1004
|
+
default: tddVal ?? false
|
|
1005
|
+
});
|
|
1006
|
+
const tddTargetScope = await askScope();
|
|
1007
|
+
if (tddTargetScope !== "back") {
|
|
1008
|
+
const targetPath = tddTargetScope === "global" ? globalConfigPath() : localConfigPath();
|
|
1009
|
+
mergeJson(targetPath, { tdd: tddChoice });
|
|
1010
|
+
log.success(`Saved to ${targetPath}`);
|
|
1011
|
+
}
|
|
1012
|
+
break;
|
|
996
1013
|
}
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
message: "Disable the /cf-plan human overview doc? (off by default)",
|
|
1002
|
-
default: planDocsDisableVal ?? true
|
|
1003
|
-
});
|
|
1004
|
-
let planDocsFormatChoice;
|
|
1005
|
-
if (!planDocsDisableChoice) {
|
|
1006
|
-
const fmt = await select({
|
|
1007
|
-
message: "Format for the human overview doc?",
|
|
1008
|
-
choices: injectBackChoice(
|
|
1009
|
-
[
|
|
1010
|
-
{ name: "HTML", value: "html" },
|
|
1011
|
-
{ name: "Markdown", value: "md" }
|
|
1012
|
-
],
|
|
1013
|
-
"Skip plan docs config"
|
|
1014
|
-
),
|
|
1015
|
-
default: planDocsFormatVal ?? "html"
|
|
1014
|
+
case "autoApprove": {
|
|
1015
|
+
const autoApproveChoice = await escConfirm({
|
|
1016
|
+
message: "Enable auto-approve? (Claude: LLM classifier; Antigravity/Codex: deterministic rules, no LLM)",
|
|
1017
|
+
default: autoApproveVal ?? false
|
|
1016
1018
|
});
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1019
|
+
const autoApproveTargetScope = await askScope();
|
|
1020
|
+
if (autoApproveTargetScope !== "back") {
|
|
1021
|
+
const targetPath = autoApproveTargetScope === "global" ? globalConfigPath() : localConfigPath();
|
|
1022
|
+
mergeJson(targetPath, { autoApprove: autoApproveChoice });
|
|
1023
|
+
log.success(`Saved to ${targetPath}`);
|
|
1024
|
+
}
|
|
1025
|
+
if (autoApproveChoice) {
|
|
1026
|
+
await afterAutoApproveEnabled(
|
|
1027
|
+
log,
|
|
1028
|
+
(message) => escConfirm({ message, default: true })
|
|
1029
|
+
);
|
|
1020
1030
|
}
|
|
1021
|
-
|
|
1031
|
+
break;
|
|
1022
1032
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
disableGUIPlan: planDocsDisableChoice,
|
|
1028
|
-
...planDocsFormatChoice !== void 0 ? { guiPlanFormat: planDocsFormatChoice } : {}
|
|
1033
|
+
case "planDocs": {
|
|
1034
|
+
const planDocsDisableChoice = await escConfirm({
|
|
1035
|
+
message: "Disable the /cf-plan human overview doc? (off by default)",
|
|
1036
|
+
default: planDocsDisableVal ?? true
|
|
1029
1037
|
});
|
|
1030
|
-
|
|
1038
|
+
let planDocsFormatChoice;
|
|
1039
|
+
if (!planDocsDisableChoice) {
|
|
1040
|
+
const fmt = await escSelect({
|
|
1041
|
+
message: "Format for the human overview doc?",
|
|
1042
|
+
choices: injectBackChoice(
|
|
1043
|
+
[
|
|
1044
|
+
{ name: "HTML", value: "html" },
|
|
1045
|
+
{ name: "Markdown", value: "md" }
|
|
1046
|
+
],
|
|
1047
|
+
"Skip plan docs config"
|
|
1048
|
+
),
|
|
1049
|
+
default: planDocsFormatVal ?? "html"
|
|
1050
|
+
});
|
|
1051
|
+
if (fmt === BACK) {
|
|
1052
|
+
log.dim("Skipped plan docs config.");
|
|
1053
|
+
break;
|
|
1054
|
+
}
|
|
1055
|
+
planDocsFormatChoice = fmt;
|
|
1056
|
+
}
|
|
1057
|
+
const planDocsTargetScope = await askScope();
|
|
1058
|
+
if (planDocsTargetScope !== "back") {
|
|
1059
|
+
const targetPath = planDocsTargetScope === "global" ? globalConfigPath() : localConfigPath();
|
|
1060
|
+
mergeJson(targetPath, {
|
|
1061
|
+
disableGUIPlan: planDocsDisableChoice,
|
|
1062
|
+
...planDocsFormatChoice !== void 0 ? { guiPlanFormat: planDocsFormatChoice } : {}
|
|
1063
|
+
});
|
|
1064
|
+
log.success(`Saved to ${targetPath}`);
|
|
1065
|
+
}
|
|
1066
|
+
break;
|
|
1067
|
+
}
|
|
1068
|
+
case "permissions": {
|
|
1069
|
+
const learnCfg = globalCfg?.learn;
|
|
1070
|
+
const learnOutputDir = learnCfg?.outputDir ?? DEFAULT_CONFIG.learn.outputDir;
|
|
1071
|
+
const learnAutoCommit = learnCfg?.autoCommit || false;
|
|
1072
|
+
await stepClaudePermissions(learnOutputDir, learnAutoCommit);
|
|
1073
|
+
break;
|
|
1031
1074
|
}
|
|
1032
|
-
break;
|
|
1033
|
-
}
|
|
1034
|
-
case "permissions": {
|
|
1035
|
-
const learnCfg = globalCfg?.learn;
|
|
1036
|
-
const learnOutputDir = learnCfg?.outputDir ?? DEFAULT_CONFIG.learn.outputDir;
|
|
1037
|
-
const learnAutoCommit = learnCfg?.autoCommit || false;
|
|
1038
|
-
await stepClaudePermissions(learnOutputDir, learnAutoCommit);
|
|
1039
|
-
break;
|
|
1040
1075
|
}
|
|
1076
|
+
} catch (err) {
|
|
1077
|
+
if (!(err instanceof BackError)) throw err;
|
|
1078
|
+
console.log();
|
|
1079
|
+
log.dim("Back to menu.");
|
|
1080
|
+
} finally {
|
|
1081
|
+
setEscArmed(false);
|
|
1082
|
+
_suppressStepHeaders = false;
|
|
1041
1083
|
}
|
|
1042
|
-
_suppressStepHeaders = false;
|
|
1043
1084
|
console.log();
|
|
1044
1085
|
}
|
|
1045
1086
|
}
|
|
@@ -1115,7 +1156,7 @@ async function initCommand(opts = {}) {
|
|
|
1115
1156
|
}
|
|
1116
1157
|
log.success("All settings configured!");
|
|
1117
1158
|
console.log();
|
|
1118
|
-
const proceed = await
|
|
1159
|
+
const proceed = await escConfirm({
|
|
1119
1160
|
message: "Modify settings?",
|
|
1120
1161
|
default: false
|
|
1121
1162
|
});
|
|
@@ -1138,7 +1179,7 @@ async function initCommand(opts = {}) {
|
|
|
1138
1179
|
console.log(` ${chalk.yellow("\u26A0")} ${parts.join(" \xB7 ")}`);
|
|
1139
1180
|
console.log();
|
|
1140
1181
|
}
|
|
1141
|
-
const proceed = await
|
|
1182
|
+
const proceed = await escConfirm({
|
|
1142
1183
|
message: "Run setup wizard?",
|
|
1143
1184
|
default: true
|
|
1144
1185
|
});
|
|
@@ -1147,67 +1188,100 @@ async function initCommand(opts = {}) {
|
|
|
1147
1188
|
return;
|
|
1148
1189
|
}
|
|
1149
1190
|
}
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1191
|
+
const learnCfg = globalCfg?.learn;
|
|
1192
|
+
let learn = {
|
|
1193
|
+
outputDir: learnCfg?.outputDir ?? DEFAULT_CONFIG.learn.outputDir,
|
|
1194
|
+
autoCommit: learnCfg?.autoCommit ?? false
|
|
1195
|
+
};
|
|
1196
|
+
await runSteps([
|
|
1197
|
+
// Step 1: docsDir
|
|
1198
|
+
async () => {
|
|
1199
|
+
const { globalCfg: g, localCfg: l } = readCfgs();
|
|
1200
|
+
await stepDocsDir(g, l);
|
|
1201
|
+
},
|
|
1202
|
+
// Step 2: .gitignore (only in git repos)
|
|
1203
|
+
async () => {
|
|
1204
|
+
if (!gitAvailable) {
|
|
1205
|
+
printStepHeader(
|
|
1206
|
+
`Configure .gitignore ${chalk.dim("[skipped]")}`,
|
|
1207
|
+
"Keeps AI-generated docs and config out of your git history."
|
|
1208
|
+
);
|
|
1209
|
+
log.dim("Skipped \u2014 not inside a git repo.");
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
const { globalCfg: g, localCfg: l } = readCfgs();
|
|
1213
|
+
await stepGitignore(getDocsDir(g, l));
|
|
1214
|
+
},
|
|
1215
|
+
// Step 3: Docs language
|
|
1216
|
+
async () => {
|
|
1217
|
+
const { globalCfg: g, localCfg: l } = readCfgs();
|
|
1218
|
+
await stepDocsLanguage(g, l);
|
|
1219
|
+
},
|
|
1220
|
+
// Step 4: /cf-learn config + MCP registration
|
|
1221
|
+
async () => {
|
|
1222
|
+
const { globalCfg: g } = readCfgs();
|
|
1223
|
+
learn = await stepLearnConfig(g);
|
|
1224
|
+
if (isLearnMcpRegistered()) {
|
|
1225
|
+
log.dim("coding-friend-learn: already registered");
|
|
1226
|
+
log.dim(
|
|
1227
|
+
" (If it points to an old path, run: claude mcp remove --scope user coding-friend-learn && cf mcp)"
|
|
1228
|
+
);
|
|
1229
|
+
} else if (registerLearnMcp(learn.outputDir)) {
|
|
1230
|
+
log.success(
|
|
1231
|
+
"Registered CF Learn MCP (user scope). Restart Claude Code to activate."
|
|
1232
|
+
);
|
|
1233
|
+
}
|
|
1234
|
+
if (isMemoryMcpRegistered()) {
|
|
1235
|
+
log.dim("coding-friend-memory: already registered (user scope)");
|
|
1236
|
+
log.dim(
|
|
1237
|
+
" (If it points to an old path, run: claude mcp remove --scope user coding-friend-memory && cf mcp)"
|
|
1238
|
+
);
|
|
1239
|
+
} else if (registerMemoryMcp()) {
|
|
1240
|
+
log.success(
|
|
1241
|
+
"Registered coding-friend-memory (user scope). Restart Claude Code to activate."
|
|
1242
|
+
);
|
|
1243
|
+
}
|
|
1244
|
+
},
|
|
1245
|
+
// Step 5: Shell completion
|
|
1246
|
+
stepShellCompletion,
|
|
1247
|
+
// Step 6: Statusline
|
|
1248
|
+
stepStatusline,
|
|
1249
|
+
// Step 7: CF Memory
|
|
1250
|
+
async () => {
|
|
1251
|
+
const { globalCfg: g, localCfg: l } = readCfgs();
|
|
1252
|
+
await stepMemory(getDocsDir(g, l));
|
|
1253
|
+
},
|
|
1254
|
+
// Step 8: TDD
|
|
1255
|
+
async () => {
|
|
1256
|
+
const { globalCfg: g, localCfg: l } = readCfgs();
|
|
1257
|
+
await stepTdd(g, l);
|
|
1258
|
+
},
|
|
1259
|
+
// Step 9: Auto-approve
|
|
1260
|
+
async () => {
|
|
1261
|
+
const { globalCfg: g, localCfg: l } = readCfgs();
|
|
1262
|
+
await stepAutoApprove(g, l);
|
|
1263
|
+
},
|
|
1264
|
+
// Step 10: Plan docs
|
|
1265
|
+
async () => {
|
|
1266
|
+
const { globalCfg: g, localCfg: l } = readCfgs();
|
|
1267
|
+
await stepPlanDocs(g, l);
|
|
1268
|
+
},
|
|
1269
|
+
// Step 11: Claude permissions
|
|
1270
|
+
async () => {
|
|
1271
|
+
printStepHeader(
|
|
1272
|
+
"Configure Claude permissions",
|
|
1273
|
+
"Grants Coding Friend skills/hooks the permissions they need, so you get fewer prompts."
|
|
1188
1274
|
);
|
|
1275
|
+
await stepClaudePermissions(learn.outputDir, learn.autoCommit);
|
|
1189
1276
|
}
|
|
1190
|
-
|
|
1191
|
-
await stepShellCompletion();
|
|
1192
|
-
await stepStatusline();
|
|
1193
|
-
await stepMemory(docsDir);
|
|
1194
|
-
const finalGlobal = readJson(globalConfigPath());
|
|
1195
|
-
const finalLocal = readJson(localConfigPath());
|
|
1196
|
-
await stepTdd(finalGlobal, finalLocal);
|
|
1197
|
-
await stepAutoApprove(finalGlobal, finalLocal);
|
|
1198
|
-
await stepPlanDocs(finalGlobal, finalLocal);
|
|
1199
|
-
printStepHeader(
|
|
1200
|
-
"Configure Claude permissions",
|
|
1201
|
-
"Grants Coding Friend skills/hooks the permissions they need, so you get fewer prompts."
|
|
1202
|
-
);
|
|
1203
|
-
await stepClaudePermissions(outputDir, autoCommit);
|
|
1277
|
+
]);
|
|
1204
1278
|
if (!existsSync(localConfigPath())) {
|
|
1205
1279
|
writeJson(localConfigPath(), {});
|
|
1206
1280
|
}
|
|
1207
1281
|
console.log();
|
|
1208
1282
|
log.congrats("Setup complete!");
|
|
1209
1283
|
log.dim(
|
|
1210
|
-
"Available commands: /cf-ask, /cf-plan, /cf-later-do, /cf-design, /cf-fix, /cf-commit, /cf-review, /cf-review-out, /cf-review-in, /cf-ship, /cf-optimize, /cf-scan, /cf-remember, /cf-learn, /cf-teach, /cf-research, /cf-session, /cf-warm, /cf-checkpoint, /cf-checkpoint-from, /cf-help"
|
|
1284
|
+
"Available commands: /cf-ask, /cf-plan, /cf-plan-review, /cf-later-do, /cf-design, /cf-fix, /cf-commit, /cf-review, /cf-review-out, /cf-review-in, /cf-ship, /cf-optimize, /cf-scan, /cf-remember, /cf-learn, /cf-teach, /cf-research, /cf-session, /cf-warm, /cf-checkpoint, /cf-checkpoint-from, /cf-help"
|
|
1211
1285
|
);
|
|
1212
1286
|
}
|
|
1213
1287
|
async function initCodexCommand(opts) {
|
|
@@ -1221,7 +1295,7 @@ async function initCodexCommand(opts) {
|
|
|
1221
1295
|
log.warn("Not inside a git repo -- git-related steps will be skipped.");
|
|
1222
1296
|
console.log();
|
|
1223
1297
|
}
|
|
1224
|
-
const proceed = await
|
|
1298
|
+
const proceed = await escConfirm({
|
|
1225
1299
|
message: "Run Codex setup wizard?",
|
|
1226
1300
|
default: true
|
|
1227
1301
|
});
|
|
@@ -1229,42 +1303,53 @@ async function initCodexCommand(opts) {
|
|
|
1229
1303
|
log.dim("Init cancelled. Run `cf init --agent codex` anytime to resume.");
|
|
1230
1304
|
return;
|
|
1231
1305
|
}
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1306
|
+
await runSteps([
|
|
1307
|
+
async () => {
|
|
1308
|
+
const { globalCfg, localCfg } = readCfgs();
|
|
1309
|
+
await stepDocsDir(globalCfg, localCfg);
|
|
1310
|
+
const cfgs = readCfgs();
|
|
1311
|
+
ensureDocsFolders(getDocsDir(cfgs.globalCfg, cfgs.localCfg), [
|
|
1312
|
+
"plans",
|
|
1313
|
+
"memory",
|
|
1314
|
+
"research",
|
|
1315
|
+
"sessions",
|
|
1316
|
+
"reviews",
|
|
1317
|
+
"warm"
|
|
1318
|
+
]);
|
|
1319
|
+
},
|
|
1320
|
+
async () => {
|
|
1321
|
+
if (!gitAvailable) {
|
|
1322
|
+
printStepHeader(
|
|
1323
|
+
`Configure .gitignore ${chalk.dim("[skipped]")}`,
|
|
1324
|
+
"Keeps AI-generated docs and config out of your git history."
|
|
1325
|
+
);
|
|
1326
|
+
log.dim("Skipped \u2014 not inside a git repo.");
|
|
1327
|
+
return;
|
|
1328
|
+
}
|
|
1329
|
+
const { globalCfg, localCfg } = readCfgs();
|
|
1330
|
+
await stepGitignore(getDocsDir(globalCfg, localCfg));
|
|
1331
|
+
},
|
|
1332
|
+
async () => {
|
|
1333
|
+
const { globalCfg, localCfg } = readCfgs();
|
|
1334
|
+
await stepDocsLanguage(globalCfg, localCfg);
|
|
1335
|
+
},
|
|
1336
|
+
async () => {
|
|
1337
|
+
await stepLearnConfig(readCfgs().globalCfg);
|
|
1338
|
+
log.dim(
|
|
1339
|
+
"Learn MCP is not registered into Codex config (no dedicated Codex writer). Settings are saved to Coding Friend config."
|
|
1340
|
+
);
|
|
1341
|
+
},
|
|
1342
|
+
async () => {
|
|
1343
|
+
const { globalCfg, localCfg } = readCfgs();
|
|
1344
|
+
await stepAutoApprove(globalCfg, localCfg);
|
|
1345
|
+
},
|
|
1346
|
+
async () => {
|
|
1347
|
+
const { globalCfg, localCfg } = readCfgs();
|
|
1348
|
+
await stepPrivacyBlock(globalCfg, localCfg);
|
|
1349
|
+
}
|
|
1245
1350
|
]);
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
} else {
|
|
1249
|
-
printStepHeader(
|
|
1250
|
-
`Configure .gitignore ${chalk.dim("[skipped]")}`,
|
|
1251
|
-
"Keeps AI-generated docs and config out of your git history."
|
|
1252
|
-
);
|
|
1253
|
-
log.dim("Skipped \u2014 not inside a git repo.");
|
|
1254
|
-
}
|
|
1255
|
-
await stepDocsLanguage(globalCfg, localCfg);
|
|
1256
|
-
globalCfg = readJson(globalConfigPath());
|
|
1257
|
-
localCfg = readJson(localConfigPath());
|
|
1258
|
-
await stepLearnConfig(globalCfg);
|
|
1259
|
-
log.dim(
|
|
1260
|
-
"Learn MCP is not registered into Codex config (no dedicated Codex writer). Settings are saved to Coding Friend config."
|
|
1261
|
-
);
|
|
1262
|
-
globalCfg = readJson(globalConfigPath());
|
|
1263
|
-
localCfg = readJson(localConfigPath());
|
|
1264
|
-
await stepAutoApprove(globalCfg, localCfg);
|
|
1265
|
-
globalCfg = readJson(globalConfigPath());
|
|
1266
|
-
localCfg = readJson(localConfigPath());
|
|
1267
|
-
await stepPrivacyBlock(globalCfg, localCfg);
|
|
1351
|
+
const codexCfgs = readCfgs();
|
|
1352
|
+
const docsDir = getDocsDir(codexCfgs.globalCfg, codexCfgs.localCfg);
|
|
1268
1353
|
if (!existsSync(localConfigPath())) {
|
|
1269
1354
|
writeJson(localConfigPath(), {});
|
|
1270
1355
|
}
|
|
@@ -1329,7 +1414,7 @@ async function initAgyCommand() {
|
|
|
1329
1414
|
log.warn("Not inside a git repo -- git-related steps will be skipped.");
|
|
1330
1415
|
console.log();
|
|
1331
1416
|
}
|
|
1332
|
-
const proceed = await
|
|
1417
|
+
const proceed = await escConfirm({
|
|
1333
1418
|
message: "Run Antigravity setup wizard?",
|
|
1334
1419
|
default: true
|
|
1335
1420
|
});
|
|
@@ -1337,65 +1422,74 @@ async function initAgyCommand() {
|
|
|
1337
1422
|
log.dim("Init cancelled. Run `cf init --agent agy` anytime to resume.");
|
|
1338
1423
|
return;
|
|
1339
1424
|
}
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
"Keeps AI-generated docs and config out of your git history."
|
|
1360
|
-
);
|
|
1361
|
-
log.dim("Skipped \u2014 not inside a git repo.");
|
|
1362
|
-
}
|
|
1363
|
-
await stepDocsLanguage(globalCfg, localCfg);
|
|
1364
|
-
globalCfg = readJson(globalConfigPath());
|
|
1365
|
-
localCfg = readJson(localConfigPath());
|
|
1366
|
-
const { outputDir } = await stepLearnConfig(globalCfg);
|
|
1367
|
-
if (isAgyPluginInstalled()) {
|
|
1368
|
-
if (isLearnMcpRegistered("agy")) {
|
|
1369
|
-
log.dim(
|
|
1370
|
-
"coding-friend-learn: already registered in plugin mcp_config.json"
|
|
1371
|
-
);
|
|
1372
|
-
} else {
|
|
1373
|
-
const registered = registerLearnMcp(outputDir, "agy");
|
|
1374
|
-
if (registered) {
|
|
1375
|
-
log.success(
|
|
1376
|
-
"Registered CF Learn MCP in the Antigravity plugin mcp_config.json."
|
|
1425
|
+
await runSteps([
|
|
1426
|
+
async () => {
|
|
1427
|
+
const { globalCfg, localCfg } = readCfgs();
|
|
1428
|
+
await stepDocsDir(globalCfg, localCfg);
|
|
1429
|
+
const cfgs = readCfgs();
|
|
1430
|
+
ensureDocsFolders(getDocsDir(cfgs.globalCfg, cfgs.localCfg), [
|
|
1431
|
+
"plans",
|
|
1432
|
+
"memory",
|
|
1433
|
+
"research",
|
|
1434
|
+
"sessions",
|
|
1435
|
+
"reviews",
|
|
1436
|
+
"warm"
|
|
1437
|
+
]);
|
|
1438
|
+
},
|
|
1439
|
+
async () => {
|
|
1440
|
+
if (!gitAvailable) {
|
|
1441
|
+
printStepHeader(
|
|
1442
|
+
`Configure .gitignore ${chalk.dim("[skipped]")}`,
|
|
1443
|
+
"Keeps AI-generated docs and config out of your git history."
|
|
1377
1444
|
);
|
|
1445
|
+
log.dim("Skipped \u2014 not inside a git repo.");
|
|
1446
|
+
return;
|
|
1378
1447
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
);
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
)
|
|
1448
|
+
const { globalCfg, localCfg } = readCfgs();
|
|
1449
|
+
await stepGitignore(getDocsDir(globalCfg, localCfg));
|
|
1450
|
+
},
|
|
1451
|
+
async () => {
|
|
1452
|
+
const { globalCfg, localCfg } = readCfgs();
|
|
1453
|
+
await stepDocsLanguage(globalCfg, localCfg);
|
|
1454
|
+
},
|
|
1455
|
+
async () => {
|
|
1456
|
+
const { outputDir } = await stepLearnConfig(readCfgs().globalCfg);
|
|
1457
|
+
if (isAgyPluginInstalled()) {
|
|
1458
|
+
if (isLearnMcpRegistered("agy")) {
|
|
1459
|
+
log.dim(
|
|
1460
|
+
"coding-friend-learn: already registered in plugin mcp_config.json"
|
|
1461
|
+
);
|
|
1462
|
+
} else {
|
|
1463
|
+
const registered = registerLearnMcp(outputDir, "agy");
|
|
1464
|
+
if (registered) {
|
|
1465
|
+
log.success(
|
|
1466
|
+
"Registered CF Learn MCP in the Antigravity plugin mcp_config.json."
|
|
1467
|
+
);
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
if (isMemoryMcpRegistered("agy")) {
|
|
1471
|
+
log.dim(
|
|
1472
|
+
"coding-friend-memory: already registered in plugin mcp_config.json"
|
|
1473
|
+
);
|
|
1474
|
+
} else {
|
|
1475
|
+
const registered = registerMemoryMcp("agy");
|
|
1476
|
+
if (registered) {
|
|
1477
|
+
log.success(
|
|
1478
|
+
"Registered coding-friend-memory in the Antigravity plugin mcp_config.json."
|
|
1479
|
+
);
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1390
1482
|
}
|
|
1483
|
+
},
|
|
1484
|
+
async () => {
|
|
1485
|
+
const { globalCfg, localCfg } = readCfgs();
|
|
1486
|
+
await stepAutoApprove(globalCfg, localCfg);
|
|
1487
|
+
},
|
|
1488
|
+
async () => {
|
|
1489
|
+
const { globalCfg, localCfg } = readCfgs();
|
|
1490
|
+
await stepPrivacyBlock(globalCfg, localCfg);
|
|
1391
1491
|
}
|
|
1392
|
-
|
|
1393
|
-
globalCfg = readJson(globalConfigPath());
|
|
1394
|
-
localCfg = readJson(localConfigPath());
|
|
1395
|
-
await stepAutoApprove(globalCfg, localCfg);
|
|
1396
|
-
globalCfg = readJson(globalConfigPath());
|
|
1397
|
-
localCfg = readJson(localConfigPath());
|
|
1398
|
-
await stepPrivacyBlock(globalCfg, localCfg);
|
|
1492
|
+
]);
|
|
1399
1493
|
if (!existsSync(localConfigPath())) {
|
|
1400
1494
|
writeJson(localConfigPath(), {});
|
|
1401
1495
|
}
|
|
@@ -1425,7 +1519,7 @@ async function stepPrivacyBlock(globalCfg, localCfg) {
|
|
|
1425
1519
|
`Privacy-block ${formatScopeLabel(scopeLabel)}${currentValue !== void 0 ? ` (${currentValue})` : ""}`,
|
|
1426
1520
|
"Deny reads of .env, keys, and similar secrets on PreToolUse."
|
|
1427
1521
|
);
|
|
1428
|
-
const enabled = await
|
|
1522
|
+
const enabled = await escConfirm({
|
|
1429
1523
|
message: "Keep privacy-block enabled? (deny .env / credentials / keys)",
|
|
1430
1524
|
default: enabledByDefault
|
|
1431
1525
|
});
|
|
@@ -1465,6 +1559,7 @@ function initOmpCommand(_opts) {
|
|
|
1465
1559
|
var AGENTS_MD_SKILLS = [
|
|
1466
1560
|
"cf-ask",
|
|
1467
1561
|
"cf-plan",
|
|
1562
|
+
"cf-plan-review",
|
|
1468
1563
|
"cf-later-do",
|
|
1469
1564
|
"cf-review",
|
|
1470
1565
|
"cf-review-out",
|