coding-friend-cli 1.6.0 → 1.8.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.
Files changed (35) hide show
  1. package/README.md +2 -0
  2. package/dist/{chunk-FWHEMJS3.js → chunk-BPLN4LDL.js} +3 -5
  3. package/dist/{chunk-4PLV2ENL.js → chunk-FYGACWU6.js} +3 -2
  4. package/dist/chunk-FYHHNX7K.js +35 -0
  5. package/dist/{chunk-MRTR7TJ4.js → chunk-HFLBFX6J.js} +2 -4
  6. package/dist/{chunk-ESIIWKPD.js → chunk-JS75SVQA.js} +6 -8
  7. package/dist/{chunk-JWAJ4XPK.js → chunk-PGLUEN7D.js} +1 -1
  8. package/dist/chunk-QQ5SVZET.js +135 -0
  9. package/dist/chunk-RZRT7NGT.js +18 -0
  10. package/dist/{chunk-WHCJT7E2.js → chunk-TPRZHSFS.js} +38 -1
  11. package/dist/{chunk-6DUFTBTO.js → chunk-W5CD7WTX.js} +1 -0
  12. package/dist/config-JZEFZIPY.js +406 -0
  13. package/dist/{dev-EWSTIVM7.js → dev-U7LPXAHR.js} +9 -11
  14. package/dist/{host-SQEDE3NN.js → host-LOG5RPZ7.js} +7 -6
  15. package/dist/index.js +36 -13
  16. package/dist/init-JJATBCHC.js +512 -0
  17. package/dist/{install-RZFSIPFD.js → install-7MSZ7B5O.js} +7 -8
  18. package/dist/{mcp-QRPBL4ML.js → mcp-ORMYETXQ.js} +7 -6
  19. package/dist/postinstall.js +2 -2
  20. package/dist/session-3MWYAKKY.js +235 -0
  21. package/dist/{statusline-WGPSURDC.js → statusline-5HWRTSVL.js} +4 -5
  22. package/dist/{uninstall-KOAJFPD6.js → uninstall-HDLTWPXG.js} +8 -10
  23. package/dist/update-E4MQDRFC.js +16 -0
  24. package/lib/learn-host/CHANGELOG.md +6 -0
  25. package/lib/learn-host/package.json +1 -1
  26. package/lib/learn-host/src/app/[category]/[slug]/page.tsx +3 -1
  27. package/lib/learn-host/src/app/globals.css +20 -0
  28. package/lib/learn-host/src/components/TableOfContents.tsx +15 -1
  29. package/lib/learn-host/src/lib/docs.ts +2 -1
  30. package/package.json +1 -1
  31. package/dist/chunk-IUTXHCP7.js +0 -28
  32. package/dist/chunk-WK5YYHXM.js +0 -44
  33. package/dist/init-HX5T5DBV.js +0 -468
  34. package/dist/json-2XS56OJY.js +0 -10
  35. package/dist/update-VAFEWOLA.js +0 -17
@@ -0,0 +1,406 @@
1
+ import {
2
+ BACK,
3
+ applyDocsDirChange,
4
+ askScope,
5
+ formatScopeLabel,
6
+ getMergedValue,
7
+ getScopeLabel,
8
+ injectBackChoice,
9
+ showConfigHint
10
+ } from "./chunk-QQ5SVZET.js";
11
+ import {
12
+ DEFAULT_CONFIG
13
+ } from "./chunk-PGLUEN7D.js";
14
+ import {
15
+ run
16
+ } from "./chunk-UFGNO6CW.js";
17
+ import {
18
+ globalConfigPath,
19
+ localConfigPath,
20
+ mergeJson,
21
+ readJson,
22
+ resolvePath
23
+ } from "./chunk-TPRZHSFS.js";
24
+ import {
25
+ log
26
+ } from "./chunk-W5CD7WTX.js";
27
+
28
+ // src/commands/config.ts
29
+ import { confirm, input, select } from "@inquirer/prompts";
30
+ import chalk from "chalk";
31
+ import { existsSync } from "fs";
32
+ function getLearnFieldScope(field, globalCfg, localCfg) {
33
+ const inGlobal = globalCfg?.learn ? globalCfg.learn[field] !== void 0 : false;
34
+ const inLocal = localCfg?.learn ? localCfg.learn[field] !== void 0 : false;
35
+ if (inGlobal && inLocal) return "both";
36
+ if (inGlobal) return "global";
37
+ if (inLocal) return "local";
38
+ return "-";
39
+ }
40
+ function getMergedLearnValue(field, globalCfg, localCfg) {
41
+ const localVal = localCfg?.learn ? localCfg.learn[field] : void 0;
42
+ if (localVal !== void 0) return localVal;
43
+ const globalVal = globalCfg?.learn ? globalCfg.learn[field] : void 0;
44
+ return globalVal;
45
+ }
46
+ function writeToScope(scope, data) {
47
+ const targetPath = scope === "global" ? globalConfigPath() : localConfigPath();
48
+ mergeJson(targetPath, data);
49
+ log.success(`Saved to ${targetPath}`);
50
+ }
51
+ function writeLearnField(scope, field, value) {
52
+ const targetPath = scope === "global" ? globalConfigPath() : localConfigPath();
53
+ const existingConfig = readJson(targetPath);
54
+ const existingLearn = existingConfig?.learn ?? {};
55
+ const updated = { ...existingLearn, [field]: value };
56
+ mergeJson(targetPath, { learn: updated });
57
+ log.success(`Saved to ${targetPath}`);
58
+ }
59
+ async function editDocsDir(globalCfg, localCfg) {
60
+ const currentValue = getMergedValue("docsDir", globalCfg, localCfg);
61
+ if (currentValue) {
62
+ log.dim(`Current: ${currentValue}`);
63
+ }
64
+ const value = await input({
65
+ message: "Docs folder name:",
66
+ default: currentValue ?? DEFAULT_CONFIG.docsDir,
67
+ validate: (val) => {
68
+ if (!val) return "Folder name cannot be empty";
69
+ if (val.includes("/") || val.includes("\\"))
70
+ return "Must be a folder name, not a path (no slashes)";
71
+ return true;
72
+ }
73
+ });
74
+ const scope = await askScope();
75
+ if (scope === "back") return;
76
+ applyDocsDirChange(value, currentValue, scope);
77
+ writeToScope(scope, { docsDir: value });
78
+ }
79
+ async function editLanguage(globalCfg, localCfg) {
80
+ const currentValue = getMergedValue("language", globalCfg, localCfg);
81
+ if (currentValue) {
82
+ log.dim(`Current: ${currentValue}`);
83
+ }
84
+ const choice = await select({
85
+ message: "What language should generated docs be written in?",
86
+ choices: injectBackChoice(
87
+ [
88
+ { name: "English", value: "en" },
89
+ { name: "Vietnamese", value: "vi" },
90
+ { name: "Other", value: "_other" }
91
+ ],
92
+ "Back"
93
+ )
94
+ });
95
+ if (choice === BACK) return;
96
+ let lang = choice;
97
+ if (choice === "_other") {
98
+ lang = await input({ message: "Enter language name:" });
99
+ if (!lang) lang = "en";
100
+ }
101
+ const scope = await askScope();
102
+ if (scope === "back") return;
103
+ writeToScope(scope, { language: lang });
104
+ }
105
+ async function editLearnOutputDir(globalCfg, localCfg) {
106
+ const currentValue = getMergedLearnValue("outputDir", globalCfg, localCfg);
107
+ if (currentValue) {
108
+ log.dim(`Current: ${currentValue}`);
109
+ }
110
+ const locationChoice = await select({
111
+ message: "Where to store learning docs?",
112
+ choices: [
113
+ { name: "In this project (docs/learn/)", value: "local" },
114
+ { name: "A separate folder", value: "external" }
115
+ ]
116
+ });
117
+ let outputDir = "docs/learn";
118
+ if (locationChoice === "external") {
119
+ outputDir = await input({
120
+ message: "Enter path (absolute or ~/...):",
121
+ default: currentValue ?? void 0,
122
+ validate: (val) => val.length > 0 ? true : "Path cannot be empty"
123
+ });
124
+ const resolved = resolvePath(outputDir);
125
+ if (!existsSync(resolved)) {
126
+ const create = await confirm({
127
+ message: `Folder ${resolved} doesn't exist. Create it?`,
128
+ default: true
129
+ });
130
+ if (create) {
131
+ run("mkdir", ["-p", resolved]);
132
+ log.success(`Created ${resolved}`);
133
+ }
134
+ }
135
+ }
136
+ const scope = await askScope();
137
+ if (scope === "back") return;
138
+ writeLearnField(scope, "outputDir", outputDir);
139
+ }
140
+ async function editLearnLanguage(globalCfg, localCfg) {
141
+ const currentValue = getMergedLearnValue("language", globalCfg, localCfg);
142
+ if (currentValue) {
143
+ log.dim(`Current: ${currentValue}`);
144
+ }
145
+ const choice = await select({
146
+ message: "What language should /cf-learn notes be written in?",
147
+ choices: injectBackChoice(
148
+ [
149
+ { name: "English", value: "en" },
150
+ { name: "Vietnamese", value: "vi" },
151
+ { name: "Other", value: "_other" }
152
+ ],
153
+ "Back"
154
+ )
155
+ });
156
+ if (choice === BACK) return;
157
+ let lang = choice;
158
+ if (choice === "_other") {
159
+ lang = await input({ message: "Enter language name:" });
160
+ if (!lang) lang = "en";
161
+ }
162
+ const scope = await askScope();
163
+ if (scope === "back") return;
164
+ writeLearnField(scope, "language", lang);
165
+ }
166
+ async function editLearnCategories(globalCfg, localCfg) {
167
+ const existingCats = getMergedLearnValue(
168
+ "categories",
169
+ globalCfg,
170
+ localCfg
171
+ );
172
+ const defaultNames = DEFAULT_CONFIG.learn.categories.map((c) => c.name).join(", ");
173
+ const catChoices = [
174
+ { name: `Use defaults (${defaultNames})`, value: "defaults" }
175
+ ];
176
+ if (existingCats && existingCats.length > 0) {
177
+ const existingNames = existingCats.map((c) => c.name).join(", ");
178
+ catChoices.push({
179
+ name: `Keep current (${existingNames})`,
180
+ value: "existing"
181
+ });
182
+ }
183
+ catChoices.push({ name: "Customize", value: "custom" });
184
+ const catChoice = await select({
185
+ message: "Categories for organizing learning docs?",
186
+ choices: catChoices
187
+ });
188
+ let categories = DEFAULT_CONFIG.learn.categories;
189
+ if (catChoice === "existing" && existingCats) {
190
+ categories = existingCats;
191
+ } else if (catChoice === "custom") {
192
+ console.log();
193
+ if (existingCats && existingCats.length > 0) {
194
+ console.log("Current categories:");
195
+ for (const c of existingCats) {
196
+ log.dim(` ${c.name}: ${c.description}`);
197
+ }
198
+ console.log();
199
+ }
200
+ console.log(
201
+ 'Enter categories (format: "name: description"). Empty line to finish.'
202
+ );
203
+ console.log();
204
+ const customCats = [];
205
+ let keepGoing = true;
206
+ while (keepGoing) {
207
+ const line = await input({
208
+ message: `Category ${customCats.length + 1}:`
209
+ });
210
+ if (!line) {
211
+ keepGoing = false;
212
+ } else {
213
+ const [name, ...descParts] = line.split(":");
214
+ customCats.push({
215
+ name: name.trim(),
216
+ description: descParts.join(":").trim() || name.trim()
217
+ });
218
+ }
219
+ }
220
+ if (customCats.length > 0) categories = customCats;
221
+ }
222
+ const scope = await askScope();
223
+ if (scope === "back") return;
224
+ writeLearnField(scope, "categories", categories);
225
+ }
226
+ async function editLearnAutoCommit(globalCfg, localCfg) {
227
+ const currentValue = getMergedLearnValue(
228
+ "autoCommit",
229
+ globalCfg,
230
+ localCfg
231
+ );
232
+ if (currentValue !== void 0) {
233
+ log.dim(`Current: ${currentValue}`);
234
+ }
235
+ const value = await confirm({
236
+ message: "Auto-commit learning docs to git after each /cf-learn?",
237
+ default: currentValue ?? false
238
+ });
239
+ const scope = await askScope();
240
+ if (scope === "back") return;
241
+ writeLearnField(scope, "autoCommit", value);
242
+ }
243
+ async function editLearnReadmeIndex(globalCfg, localCfg) {
244
+ const currentValue = getMergedLearnValue(
245
+ "readmeIndex",
246
+ globalCfg,
247
+ localCfg
248
+ );
249
+ if (currentValue !== void 0) {
250
+ log.dim(`Current: ${currentValue}`);
251
+ }
252
+ const indexChoice = await select({
253
+ message: "How should learning docs be indexed?",
254
+ choices: [
255
+ { name: "No index", value: "none" },
256
+ { name: "Single README at root", value: "single" },
257
+ { name: "Per-category READMEs", value: "per-category" }
258
+ ]
259
+ });
260
+ let readmeIndex = false;
261
+ if (indexChoice === "single") readmeIndex = true;
262
+ else if (indexChoice === "per-category") readmeIndex = "per-category";
263
+ const scope = await askScope();
264
+ if (scope === "back") return;
265
+ writeLearnField(scope, "readmeIndex", readmeIndex);
266
+ }
267
+ async function learnSubMenu() {
268
+ while (true) {
269
+ const globalCfg = readJson(globalConfigPath());
270
+ const localCfg = readJson(localConfigPath());
271
+ const outputDirScope = getLearnFieldScope("outputDir", globalCfg, localCfg);
272
+ const outputDirVal = getMergedLearnValue(
273
+ "outputDir",
274
+ globalCfg,
275
+ localCfg
276
+ );
277
+ const langScope = getLearnFieldScope("language", globalCfg, localCfg);
278
+ const langVal = getMergedLearnValue("language", globalCfg, localCfg);
279
+ const catScope = getLearnFieldScope("categories", globalCfg, localCfg);
280
+ const autoCommitScope = getLearnFieldScope(
281
+ "autoCommit",
282
+ globalCfg,
283
+ localCfg
284
+ );
285
+ const autoCommitVal = getMergedLearnValue(
286
+ "autoCommit",
287
+ globalCfg,
288
+ localCfg
289
+ );
290
+ const readmeScope = getLearnFieldScope("readmeIndex", globalCfg, localCfg);
291
+ const readmeVal = getMergedLearnValue(
292
+ "readmeIndex",
293
+ globalCfg,
294
+ localCfg
295
+ );
296
+ const choice = await select({
297
+ message: "Learn settings:",
298
+ choices: injectBackChoice(
299
+ [
300
+ {
301
+ name: `Output dir ${formatScopeLabel(outputDirScope)}${outputDirVal ? ` (${outputDirVal})` : ""}`,
302
+ value: "outputDir"
303
+ },
304
+ {
305
+ name: `Language ${formatScopeLabel(langScope)}${langVal ? ` (${langVal})` : ""}`,
306
+ value: "language"
307
+ },
308
+ {
309
+ name: `Categories ${formatScopeLabel(catScope)}`,
310
+ value: "categories"
311
+ },
312
+ {
313
+ name: `Auto-commit ${formatScopeLabel(autoCommitScope)}${autoCommitVal !== void 0 ? ` (${autoCommitVal})` : ""}`,
314
+ value: "autoCommit"
315
+ },
316
+ {
317
+ name: `README index ${formatScopeLabel(readmeScope)}${readmeVal !== void 0 ? ` (${readmeVal})` : ""}`,
318
+ value: "readmeIndex"
319
+ }
320
+ ],
321
+ "Back"
322
+ )
323
+ });
324
+ if (choice === BACK) return;
325
+ switch (choice) {
326
+ case "outputDir":
327
+ await editLearnOutputDir(globalCfg, localCfg);
328
+ break;
329
+ case "language":
330
+ await editLearnLanguage(globalCfg, localCfg);
331
+ break;
332
+ case "categories":
333
+ await editLearnCategories(globalCfg, localCfg);
334
+ break;
335
+ case "autoCommit":
336
+ await editLearnAutoCommit(globalCfg, localCfg);
337
+ break;
338
+ case "readmeIndex":
339
+ await editLearnReadmeIndex(globalCfg, localCfg);
340
+ break;
341
+ }
342
+ }
343
+ }
344
+ var em = chalk.hex("#10b981");
345
+ async function configCommand() {
346
+ console.log();
347
+ console.log(em(" \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E"));
348
+ console.log(
349
+ em(" \u2502 ") + "\u2726" + em(" ") + chalk.bold.white("Coding Friend") + em(" \u2726 \u2502")
350
+ );
351
+ console.log(em(" \u2502 ") + chalk.dim("Config") + em(" \u2502"));
352
+ console.log(em(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"));
353
+ console.log(em(" \u2570\u2500\u25B8"));
354
+ console.log();
355
+ showConfigHint();
356
+ while (true) {
357
+ const globalCfg = readJson(globalConfigPath());
358
+ const localCfg = readJson(localConfigPath());
359
+ const docsDirScope = getScopeLabel("docsDir", globalCfg, localCfg);
360
+ const docsDirVal = getMergedValue("docsDir", globalCfg, localCfg);
361
+ const langScope = getScopeLabel("language", globalCfg, localCfg);
362
+ const langVal = getMergedValue("language", globalCfg, localCfg);
363
+ const learnScope = getScopeLabel("learn", globalCfg, localCfg);
364
+ const choice = await select({
365
+ message: "What to configure?",
366
+ choices: injectBackChoice(
367
+ [
368
+ {
369
+ name: `docsDir ${formatScopeLabel(docsDirScope)}${docsDirVal ? ` (${docsDirVal})` : ""}`,
370
+ value: "docsDir",
371
+ description: " Top-level folder name for plans, memory, research, and sessions"
372
+ },
373
+ {
374
+ name: `Docs language ${formatScopeLabel(langScope)}${langVal ? ` (${langVal})` : ""}`,
375
+ value: "language",
376
+ description: " Language for /cf-plan, /cf-ask, /cf-remember generated docs"
377
+ },
378
+ {
379
+ name: `Learn settings ${formatScopeLabel(learnScope)}`,
380
+ value: "learn",
381
+ description: " Output dir, language, categories, auto-commit, README index"
382
+ }
383
+ ],
384
+ "Exit"
385
+ )
386
+ });
387
+ if (choice === BACK) {
388
+ process.exit(0);
389
+ }
390
+ switch (choice) {
391
+ case "docsDir":
392
+ await editDocsDir(globalCfg, localCfg);
393
+ break;
394
+ case "language":
395
+ await editLanguage(globalCfg, localCfg);
396
+ break;
397
+ case "learn":
398
+ await learnSubMenu();
399
+ break;
400
+ }
401
+ console.log();
402
+ }
403
+ }
404
+ export {
405
+ configCommand
406
+ };
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  isMarketplaceRegistered,
3
3
  isPluginInstalled
4
- } from "./chunk-MRTR7TJ4.js";
4
+ } from "./chunk-HFLBFX6J.js";
5
5
  import {
6
6
  ensureStatusline
7
- } from "./chunk-FWHEMJS3.js";
7
+ } from "./chunk-BPLN4LDL.js";
8
8
  import {
9
9
  ensureShellCompletion
10
- } from "./chunk-4PLV2ENL.js";
11
- import "./chunk-JWAJ4XPK.js";
10
+ } from "./chunk-FYGACWU6.js";
11
+ import "./chunk-PGLUEN7D.js";
12
12
  import {
13
13
  commandExists,
14
14
  run
@@ -16,15 +16,13 @@ import {
16
16
  import {
17
17
  devStatePath,
18
18
  knownMarketplacesPath,
19
- pluginCachePath
20
- } from "./chunk-WHCJT7E2.js";
21
- import {
22
- log
23
- } from "./chunk-6DUFTBTO.js";
24
- import {
19
+ pluginCachePath,
25
20
  readJson,
26
21
  writeJson
27
- } from "./chunk-IUTXHCP7.js";
22
+ } from "./chunk-TPRZHSFS.js";
23
+ import {
24
+ log
25
+ } from "./chunk-W5CD7WTX.js";
28
26
 
29
27
  // src/commands/dev.ts
30
28
  import {
@@ -1,17 +1,18 @@
1
1
  import {
2
- getLibPath,
2
+ getLibPath
3
+ } from "./chunk-RZRT7NGT.js";
4
+ import {
3
5
  resolveDocsDir
4
- } from "./chunk-WK5YYHXM.js";
5
- import "./chunk-JWAJ4XPK.js";
6
+ } from "./chunk-FYHHNX7K.js";
7
+ import "./chunk-PGLUEN7D.js";
6
8
  import {
7
9
  run,
8
10
  streamExec
9
11
  } from "./chunk-UFGNO6CW.js";
10
- import "./chunk-WHCJT7E2.js";
12
+ import "./chunk-TPRZHSFS.js";
11
13
  import {
12
14
  log
13
- } from "./chunk-6DUFTBTO.js";
14
- import "./chunk-IUTXHCP7.js";
15
+ } from "./chunk-W5CD7WTX.js";
15
16
 
16
17
  // src/commands/host.ts
17
18
  import { existsSync, readdirSync } from "fs";
package/dist/index.js CHANGED
@@ -14,33 +14,56 @@ program.name("cf").description(
14
14
  "coding-friend CLI \u2014 host learning docs, setup MCP, init projects"
15
15
  ).version(pkg.version, "-v, --version");
16
16
  program.command("install").description("Install the Coding Friend plugin into Claude Code").action(async () => {
17
- const { installCommand } = await import("./install-RZFSIPFD.js");
17
+ const { installCommand } = await import("./install-7MSZ7B5O.js");
18
18
  await installCommand();
19
19
  });
20
20
  program.command("uninstall").description("Uninstall the Coding Friend plugin from Claude Code").action(async () => {
21
- const { uninstallCommand } = await import("./uninstall-KOAJFPD6.js");
21
+ const { uninstallCommand } = await import("./uninstall-HDLTWPXG.js");
22
22
  await uninstallCommand();
23
23
  });
24
24
  program.command("init").description("Initialize coding-friend in current project").action(async () => {
25
- const { initCommand } = await import("./init-HX5T5DBV.js");
25
+ const { initCommand } = await import("./init-JJATBCHC.js");
26
26
  await initCommand();
27
27
  });
28
+ program.command("config").description("Manage Coding Friend configuration").action(async () => {
29
+ const { configCommand } = await import("./config-JZEFZIPY.js");
30
+ await configCommand();
31
+ });
28
32
  program.command("host").description("Build and serve learning docs as a static website").argument("[path]", "path to docs folder").option("-p, --port <port>", "port number", "3333").action(async (path, opts) => {
29
- const { hostCommand } = await import("./host-SQEDE3NN.js");
33
+ const { hostCommand } = await import("./host-LOG5RPZ7.js");
30
34
  await hostCommand(path, opts);
31
35
  });
32
36
  program.command("mcp").description("Setup MCP server for learning docs").argument("[path]", "path to docs folder").action(async (path) => {
33
- const { mcpCommand } = await import("./mcp-QRPBL4ML.js");
37
+ const { mcpCommand } = await import("./mcp-ORMYETXQ.js");
34
38
  await mcpCommand(path);
35
39
  });
36
40
  program.command("statusline").description("Setup coding-friend statusline in Claude Code").action(async () => {
37
- const { statuslineCommand } = await import("./statusline-WGPSURDC.js");
41
+ const { statuslineCommand } = await import("./statusline-5HWRTSVL.js");
38
42
  await statuslineCommand();
39
43
  });
40
44
  program.command("update").description("Update coding-friend plugin, CLI, and statusline").option("--cli", "Update only the CLI (npm package)").option("--plugin", "Update only the Claude Code plugin").option("--statusline", "Update only the statusline").action(async (opts) => {
41
- const { updateCommand } = await import("./update-VAFEWOLA.js");
45
+ const { updateCommand } = await import("./update-E4MQDRFC.js");
42
46
  await updateCommand(opts);
43
47
  });
48
+ var session = program.command("session").description("Save and load Claude Code sessions across machines");
49
+ program.addHelpText(
50
+ "after",
51
+ `
52
+ Session subcommands:
53
+ session save Save current session to sync folder (use /cf-session inside a conversation)
54
+ session load Load a saved session from sync folder and print resume command`
55
+ );
56
+ session.command("save").description("Save current Claude Code session to sync folder").option(
57
+ "-s, --session-id <id>",
58
+ "session UUID to save (default: auto-detect newest)"
59
+ ).option("-l, --label <label>", "label for this session").action(async (opts) => {
60
+ const { sessionSaveCommand } = await import("./session-3MWYAKKY.js");
61
+ await sessionSaveCommand(opts);
62
+ });
63
+ session.command("load").description("Load a saved session from sync folder").action(async () => {
64
+ const { sessionLoadCommand } = await import("./session-3MWYAKKY.js");
65
+ await sessionLoadCommand();
66
+ });
44
67
  var dev = program.command("dev").description("Development mode commands");
45
68
  program.addHelpText(
46
69
  "after",
@@ -54,35 +77,35 @@ Dev subcommands:
54
77
  dev update [path] Update local dev plugin to latest version`
55
78
  );
56
79
  dev.command("on").description("Switch to local plugin source").argument("[path]", "path to local coding-friend repo (default: cwd)").action(async (path) => {
57
- const { devOnCommand } = await import("./dev-EWSTIVM7.js");
80
+ const { devOnCommand } = await import("./dev-U7LPXAHR.js");
58
81
  await devOnCommand(path);
59
82
  });
60
83
  dev.command("off").description("Switch back to remote marketplace").action(async () => {
61
- const { devOffCommand } = await import("./dev-EWSTIVM7.js");
84
+ const { devOffCommand } = await import("./dev-U7LPXAHR.js");
62
85
  await devOffCommand();
63
86
  });
64
87
  dev.command("status").description("Show current dev mode").action(async () => {
65
- const { devStatusCommand } = await import("./dev-EWSTIVM7.js");
88
+ const { devStatusCommand } = await import("./dev-U7LPXAHR.js");
66
89
  await devStatusCommand();
67
90
  });
68
91
  dev.command("sync").description(
69
92
  "Copy local source files to plugin cache (no version bump needed)"
70
93
  ).action(async () => {
71
- const { devSyncCommand } = await import("./dev-EWSTIVM7.js");
94
+ const { devSyncCommand } = await import("./dev-U7LPXAHR.js");
72
95
  await devSyncCommand();
73
96
  });
74
97
  dev.command("restart").description("Reinstall local dev plugin (off + on)").argument(
75
98
  "[path]",
76
99
  "path to local coding-friend repo (default: saved path or cwd)"
77
100
  ).action(async (path) => {
78
- const { devRestartCommand } = await import("./dev-EWSTIVM7.js");
101
+ const { devRestartCommand } = await import("./dev-U7LPXAHR.js");
79
102
  await devRestartCommand(path);
80
103
  });
81
104
  dev.command("update").description("Update local dev plugin to latest version (off + on)").argument(
82
105
  "[path]",
83
106
  "path to local coding-friend repo (default: saved path or cwd)"
84
107
  ).action(async (path) => {
85
- const { devUpdateCommand } = await import("./dev-EWSTIVM7.js");
108
+ const { devUpdateCommand } = await import("./dev-U7LPXAHR.js");
86
109
  await devUpdateCommand(path);
87
110
  });
88
111
  program.parse();