ccjk 5.2.0 → 5.2.2
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/chunks/api.mjs +6 -6
- package/dist/chunks/auto-updater.mjs +80 -133
- package/dist/chunks/ccm.mjs +7 -7
- package/dist/chunks/ccr.mjs +7 -4
- package/dist/chunks/ccu.mjs +6 -6
- package/dist/chunks/check-updates.mjs +3 -3
- package/dist/chunks/claude-code-incremental-manager.mjs +38 -38
- package/dist/chunks/cloud-v5.mjs +1651 -0
- package/dist/chunks/codex.mjs +70 -70
- package/dist/chunks/commands.mjs +25 -25
- package/dist/chunks/commit.mjs +16 -16
- package/dist/chunks/config-consolidator.mjs +9 -9
- package/dist/chunks/config-switch.mjs +39 -39
- package/dist/chunks/config.mjs +5 -5
- package/dist/chunks/config2.mjs +85 -85
- package/dist/chunks/context.mjs +2 -2
- package/dist/chunks/doctor.mjs +31 -31
- package/dist/chunks/features.mjs +84 -83
- package/dist/chunks/help.mjs +116 -116
- package/dist/chunks/index4.mjs +46 -46
- package/dist/chunks/init.mjs +214 -191
- package/dist/chunks/interview.mjs +102 -102
- package/dist/chunks/manager.mjs +238 -0
- package/dist/chunks/marketplace.mjs +59 -59
- package/dist/chunks/mcp.mjs +82 -82
- package/dist/chunks/menu.mjs +441 -379
- package/dist/chunks/notification.mjs +112 -112
- package/dist/chunks/onboarding.mjs +7 -7
- package/dist/chunks/package.mjs +1 -1
- package/dist/chunks/permission-manager.mjs +8 -8
- package/dist/chunks/plugin.mjs +100 -100
- package/dist/chunks/prompts.mjs +15 -15
- package/dist/chunks/providers.mjs +65 -65
- package/dist/chunks/session.mjs +83 -83
- package/dist/chunks/skills-sync.mjs +72 -72
- package/dist/chunks/skills.mjs +88 -88
- package/dist/chunks/team.mjs +6 -6
- package/dist/chunks/uninstall.mjs +35 -35
- package/dist/chunks/update.mjs +6 -6
- package/dist/chunks/upgrade-manager.mjs +4 -4
- package/dist/chunks/workflows2.mjs +13 -13
- package/dist/cli.mjs +21 -0
- package/dist/i18n/locales/en/menu.json +16 -1
- package/dist/i18n/locales/en/skills.json +29 -0
- package/dist/i18n/locales/zh-CN/menu.json +16 -1
- package/dist/i18n/locales/zh-CN/skills.json +29 -0
- package/dist/index.mjs +4 -4
- package/dist/shared/{ccjk.f40us0yY.mjs → ccjk.BiJujy5w.mjs} +4 -4
- package/dist/shared/{ccjk.CQzwtnZ1.mjs → ccjk.C_3BYaWc.mjs} +50 -50
- package/dist/shared/{ccjk.Zwx-YR_P.mjs → ccjk.DjD9Rzxq.mjs} +32 -32
- package/dist/shared/{ccjk.DtWIPt8E.mjs → ccjk.XgW1H2t3.mjs} +68 -68
- package/dist/shared/{ccjk.BlPCiSHj.mjs → ccjk.tI4PJA0c.mjs} +30 -30
- package/package.json +3 -3
|
@@ -2,10 +2,10 @@ import { existsSync } from 'node:fs';
|
|
|
2
2
|
import { writeFile, mkdir, readFile } from 'node:fs/promises';
|
|
3
3
|
import { resolve, dirname, join } from 'node:path';
|
|
4
4
|
import process__default from 'node:process';
|
|
5
|
-
import
|
|
5
|
+
import ansis__default from 'ansis';
|
|
6
6
|
import inquirer from 'inquirer';
|
|
7
7
|
import { i18n } from './index2.mjs';
|
|
8
|
-
import { a as handleExitPromptError, h as handleGeneralError } from '../shared/ccjk.
|
|
8
|
+
import { a as handleExitPromptError, h as handleGeneralError } from '../shared/ccjk.BiJujy5w.mjs';
|
|
9
9
|
import { randomUUID } from 'node:crypto';
|
|
10
10
|
import 'node:url';
|
|
11
11
|
import 'i18next';
|
|
@@ -2309,14 +2309,14 @@ function createSpecGenerator(language = "en") {
|
|
|
2309
2309
|
function displayInterviewBanner(compact = false) {
|
|
2310
2310
|
console.log("");
|
|
2311
2311
|
if (compact) {
|
|
2312
|
-
console.log(
|
|
2313
|
-
console.log(
|
|
2312
|
+
console.log(ansis__default.green.bold(" \u{1F3A4} Interview-Driven Development"));
|
|
2313
|
+
console.log(ansis__default.gray(' "Interview first. Spec second. Code last."'));
|
|
2314
2314
|
} else {
|
|
2315
|
-
console.log(
|
|
2316
|
-
console.log(
|
|
2317
|
-
console.log(
|
|
2318
|
-
console.log(
|
|
2319
|
-
console.log(
|
|
2315
|
+
console.log(ansis__default.green("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
2316
|
+
console.log(ansis__default.green("\u2551") + ansis__default.bold.white(" \u{1F3A4} Interview-Driven Development (IDD) ") + ansis__default.green("\u2551"));
|
|
2317
|
+
console.log(ansis__default.green("\u2551") + ansis__default.gray(' "Interview first. Spec second. Code last." ') + ansis__default.green("\u2551"));
|
|
2318
|
+
console.log(ansis__default.green("\u2551") + ansis__default.gray(" Based on Thariq (@trq212) workflow from Anthropic ") + ansis__default.green("\u2551"));
|
|
2319
|
+
console.log(ansis__default.green("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
2320
2320
|
}
|
|
2321
2321
|
console.log("");
|
|
2322
2322
|
}
|
|
@@ -2349,22 +2349,22 @@ function displayProgressBar(session) {
|
|
|
2349
2349
|
const barWidth = 30;
|
|
2350
2350
|
const filled = Math.round(percentage / 100 * barWidth);
|
|
2351
2351
|
const empty = barWidth - filled;
|
|
2352
|
-
const bar =
|
|
2352
|
+
const bar = ansis__default.green("\u2588".repeat(filled)) + ansis__default.gray("\u2591".repeat(empty));
|
|
2353
2353
|
console.log("");
|
|
2354
|
-
console.log(
|
|
2354
|
+
console.log(ansis__default.gray(` Progress: [${bar}] ${percentage}%`));
|
|
2355
2355
|
}
|
|
2356
2356
|
function displayCategoryBreadcrumb(session) {
|
|
2357
2357
|
const breadcrumb = session.progress.map((p) => {
|
|
2358
2358
|
const category = getCategoryById(p.categoryId);
|
|
2359
2359
|
const icon = category?.icon || "\u{1F4CC}";
|
|
2360
2360
|
if (p.isComplete) {
|
|
2361
|
-
return
|
|
2361
|
+
return ansis__default.green(`${icon} ${p.name} \u2713`);
|
|
2362
2362
|
}
|
|
2363
2363
|
if (p.isCurrent) {
|
|
2364
|
-
return
|
|
2364
|
+
return ansis__default.green.bold(`${icon} ${p.name} \u25C0`);
|
|
2365
2365
|
}
|
|
2366
|
-
return
|
|
2367
|
-
}).join(
|
|
2366
|
+
return ansis__default.gray(`${icon} ${p.name}`);
|
|
2367
|
+
}).join(ansis__default.gray(" \u2192 "));
|
|
2368
2368
|
console.log("");
|
|
2369
2369
|
console.log(` ${breadcrumb}`);
|
|
2370
2370
|
}
|
|
@@ -2372,26 +2372,26 @@ function displayQuestion(display, lang) {
|
|
|
2372
2372
|
const questionText = display.question.question[lang];
|
|
2373
2373
|
const headerText = display.question.header[lang];
|
|
2374
2374
|
console.log("");
|
|
2375
|
-
console.log(
|
|
2375
|
+
console.log(ansis__default.gray("\u2500".repeat(65)));
|
|
2376
2376
|
console.log("");
|
|
2377
|
-
console.log(
|
|
2377
|
+
console.log(ansis__default.green.bold(` Q${display.questionNumber}`) + ansis__default.gray(` of ~${display.estimatedTotal}`) + ansis__default.gray(` \u2502 `) + ansis__default.yellow(headerText));
|
|
2378
2378
|
console.log("");
|
|
2379
|
-
console.log(
|
|
2379
|
+
console.log(ansis__default.white.bold(` ${questionText}`));
|
|
2380
2380
|
console.log("");
|
|
2381
2381
|
}
|
|
2382
2382
|
async function askQuestion(display, lang) {
|
|
2383
2383
|
displayQuestion(display, lang);
|
|
2384
2384
|
const choices = display.options.map((opt, index) => {
|
|
2385
|
-
const label = opt.isRecommended ? `${opt.label} ${
|
|
2385
|
+
const label = opt.isRecommended ? `${opt.label} ${ansis__default.green("(Recommended)")}` : opt.label;
|
|
2386
2386
|
return {
|
|
2387
|
-
name: `${
|
|
2388
|
-
${
|
|
2387
|
+
name: `${ansis__default.green(`${index + 1}.`)} ${label}
|
|
2388
|
+
${ansis__default.gray(opt.description)}`,
|
|
2389
2389
|
value: opt.value,
|
|
2390
2390
|
short: opt.label
|
|
2391
2391
|
};
|
|
2392
2392
|
});
|
|
2393
2393
|
choices.push({
|
|
2394
|
-
name: `${
|
|
2394
|
+
name: `${ansis__default.green(`${choices.length + 1}.`)} ${ansis__default.italic("Type something else...")}`,
|
|
2395
2395
|
value: "__custom__",
|
|
2396
2396
|
short: "Custom"
|
|
2397
2397
|
});
|
|
@@ -2400,7 +2400,7 @@ async function askQuestion(display, lang) {
|
|
|
2400
2400
|
const { selected } = await inquirer.prompt({
|
|
2401
2401
|
type: "checkbox",
|
|
2402
2402
|
name: "selected",
|
|
2403
|
-
message:
|
|
2403
|
+
message: ansis__default.gray("Select all that apply (space to select, enter to confirm):"),
|
|
2404
2404
|
choices: choices.map((c) => ({
|
|
2405
2405
|
name: c.name,
|
|
2406
2406
|
value: c.value,
|
|
@@ -2412,7 +2412,7 @@ async function askQuestion(display, lang) {
|
|
|
2412
2412
|
const { customValue } = await inquirer.prompt({
|
|
2413
2413
|
type: "input",
|
|
2414
2414
|
name: "customValue",
|
|
2415
|
-
message:
|
|
2415
|
+
message: ansis__default.gray("Enter your custom answer:")
|
|
2416
2416
|
});
|
|
2417
2417
|
const filtered = selected.filter((s) => s !== "__custom__");
|
|
2418
2418
|
return { values: filtered, customInput: customValue };
|
|
@@ -2422,7 +2422,7 @@ async function askQuestion(display, lang) {
|
|
|
2422
2422
|
const { selected } = await inquirer.prompt({
|
|
2423
2423
|
type: "list",
|
|
2424
2424
|
name: "selected",
|
|
2425
|
-
message:
|
|
2425
|
+
message: ansis__default.gray("Select one:"),
|
|
2426
2426
|
choices,
|
|
2427
2427
|
pageSize: 10
|
|
2428
2428
|
});
|
|
@@ -2430,7 +2430,7 @@ async function askQuestion(display, lang) {
|
|
|
2430
2430
|
const { customValue } = await inquirer.prompt({
|
|
2431
2431
|
type: "input",
|
|
2432
2432
|
name: "customValue",
|
|
2433
|
-
message:
|
|
2433
|
+
message: ansis__default.gray("Enter your custom answer:")
|
|
2434
2434
|
});
|
|
2435
2435
|
return { values: [], customInput: customValue };
|
|
2436
2436
|
}
|
|
@@ -2442,12 +2442,12 @@ async function askQuestion(display, lang) {
|
|
|
2442
2442
|
}
|
|
2443
2443
|
async function selectTemplate(lang) {
|
|
2444
2444
|
console.log("");
|
|
2445
|
-
console.log(
|
|
2445
|
+
console.log(ansis__default.green.bold(" \u{1F4CB} Select Interview Template"));
|
|
2446
2446
|
console.log("");
|
|
2447
2447
|
const choices = INTERVIEW_TEMPLATES.map((template, index) => ({
|
|
2448
|
-
name: `${
|
|
2449
|
-
${
|
|
2450
|
-
${
|
|
2448
|
+
name: `${ansis__default.green(`${index + 1}.`)} ${ansis__default.bold(template.name[lang])}
|
|
2449
|
+
${ansis__default.gray(template.description[lang])}
|
|
2450
|
+
${ansis__default.gray(`~${template.estimatedQuestions} questions, ${template.defaultDepth} depth`)}`,
|
|
2451
2451
|
value: template.id,
|
|
2452
2452
|
short: template.name[lang]
|
|
2453
2453
|
}));
|
|
@@ -2455,7 +2455,7 @@ async function selectTemplate(lang) {
|
|
|
2455
2455
|
const { templateId } = await inquirer.prompt({
|
|
2456
2456
|
type: "list",
|
|
2457
2457
|
name: "templateId",
|
|
2458
|
-
message:
|
|
2458
|
+
message: ansis__default.gray("Choose a template:"),
|
|
2459
2459
|
choices,
|
|
2460
2460
|
pageSize: 10
|
|
2461
2461
|
});
|
|
@@ -2467,32 +2467,32 @@ async function selectTemplate(lang) {
|
|
|
2467
2467
|
async function quickStartConfig(_lang) {
|
|
2468
2468
|
const detectedType = await detectProjectType();
|
|
2469
2469
|
const detectedTemplate = getTemplateById(detectedType);
|
|
2470
|
-
console.log(
|
|
2470
|
+
console.log(ansis__default.gray(` Detected project type: ${ansis__default.white(detectedType)}`));
|
|
2471
2471
|
console.log("");
|
|
2472
|
-
console.log(
|
|
2472
|
+
console.log(ansis__default.green.bold(" How would you like to proceed?"));
|
|
2473
2473
|
console.log("");
|
|
2474
2474
|
const quickChoices = [
|
|
2475
2475
|
{
|
|
2476
|
-
name: `${
|
|
2477
|
-
${
|
|
2476
|
+
name: `${ansis__default.green("1.")} ${ansis__default.green("\u26A1 Quick Start")} ${ansis__default.gray("(Recommended)")}
|
|
2477
|
+
${ansis__default.gray(`Use ${detectedType} template, ~${detectedTemplate?.estimatedQuestions || 25} questions \u2192 SPEC.md`)}`,
|
|
2478
2478
|
value: "quick-start",
|
|
2479
2479
|
short: "Quick Start"
|
|
2480
2480
|
},
|
|
2481
2481
|
{
|
|
2482
|
-
name: `${
|
|
2483
|
-
${
|
|
2482
|
+
name: `${ansis__default.green("2.")} ${ansis__default.yellow("\u{1F52C} Deep Dive")}
|
|
2483
|
+
${ansis__default.gray("40+ comprehensive questions for complex features")}`,
|
|
2484
2484
|
value: "deep",
|
|
2485
2485
|
short: "Deep Dive"
|
|
2486
2486
|
},
|
|
2487
2487
|
{
|
|
2488
|
-
name: `${
|
|
2489
|
-
${
|
|
2488
|
+
name: `${ansis__default.green("3.")} ${ansis__default.green("\u2699\uFE0F Custom Setup")}
|
|
2489
|
+
${ansis__default.gray("Choose template, depth, and output file")}`,
|
|
2490
2490
|
value: "custom",
|
|
2491
2491
|
short: "Custom"
|
|
2492
2492
|
},
|
|
2493
2493
|
{
|
|
2494
|
-
name: `${
|
|
2495
|
-
${
|
|
2494
|
+
name: `${ansis__default.green("4.")} ${ansis__default.magenta("\u{1F4A8} Express Mode")}
|
|
2495
|
+
${ansis__default.gray("~10 essential questions only")}`,
|
|
2496
2496
|
value: "express",
|
|
2497
2497
|
short: "Express"
|
|
2498
2498
|
}
|
|
@@ -2501,7 +2501,7 @@ async function quickStartConfig(_lang) {
|
|
|
2501
2501
|
const { mode } = await inquirer.prompt({
|
|
2502
2502
|
type: "list",
|
|
2503
2503
|
name: "mode",
|
|
2504
|
-
message:
|
|
2504
|
+
message: ansis__default.gray("Select mode (press number or use arrows):"),
|
|
2505
2505
|
choices: quickChoices,
|
|
2506
2506
|
pageSize: 8
|
|
2507
2507
|
});
|
|
@@ -2538,7 +2538,7 @@ async function getSpecFilePath(defaultPath) {
|
|
|
2538
2538
|
const { specFile } = await inquirer.prompt({
|
|
2539
2539
|
type: "input",
|
|
2540
2540
|
name: "specFile",
|
|
2541
|
-
message:
|
|
2541
|
+
message: ansis__default.gray("Spec file path (where to save the specification):"),
|
|
2542
2542
|
default: defaultPath,
|
|
2543
2543
|
validate: (value) => {
|
|
2544
2544
|
if (!value.trim()) {
|
|
@@ -2560,42 +2560,42 @@ function displayCompletionSummary(session, specFile) {
|
|
|
2560
2560
|
(session.lastActivityAt.getTime() - session.startedAt.getTime()) / 1e3 / 60
|
|
2561
2561
|
);
|
|
2562
2562
|
console.log("");
|
|
2563
|
-
console.log(
|
|
2563
|
+
console.log(ansis__default.green("\u2550".repeat(65)));
|
|
2564
2564
|
console.log("");
|
|
2565
|
-
console.log(
|
|
2565
|
+
console.log(ansis__default.green.bold(" \u2713 Interview Complete!"));
|
|
2566
2566
|
console.log("");
|
|
2567
|
-
console.log(` ${
|
|
2568
|
-
console.log(` ${
|
|
2569
|
-
console.log(` ${
|
|
2567
|
+
console.log(` ${ansis__default.gray("Questions answered:")} ${ansis__default.white(String(session.questionsAsked))}`);
|
|
2568
|
+
console.log(` ${ansis__default.gray("Duration:")} ${ansis__default.white(`${duration} minutes`)}`);
|
|
2569
|
+
console.log(` ${ansis__default.gray("Spec file:")} ${ansis__default.green(specFile)}`);
|
|
2570
2570
|
console.log("");
|
|
2571
|
-
console.log(
|
|
2571
|
+
console.log(ansis__default.gray(" Category Summary:"));
|
|
2572
2572
|
for (const progress of session.progress) {
|
|
2573
2573
|
const category = getCategoryById(progress.categoryId);
|
|
2574
2574
|
const icon = category?.icon || "\u{1F4CC}";
|
|
2575
|
-
const status = progress.isComplete ?
|
|
2575
|
+
const status = progress.isComplete ? ansis__default.green("\u2713") : ansis__default.yellow("\u25CB");
|
|
2576
2576
|
console.log(` ${status} ${icon} ${progress.name}: ${progress.answered}/${progress.total}`);
|
|
2577
2577
|
}
|
|
2578
2578
|
console.log("");
|
|
2579
|
-
console.log(
|
|
2579
|
+
console.log(ansis__default.green("\u2550".repeat(65)));
|
|
2580
2580
|
console.log("");
|
|
2581
|
-
console.log(
|
|
2582
|
-
console.log(
|
|
2583
|
-
console.log(
|
|
2584
|
-
console.log(
|
|
2581
|
+
console.log(ansis__default.green(" Next steps:"));
|
|
2582
|
+
console.log(ansis__default.gray(` 1. Review the spec: ${ansis__default.white(`cat ${specFile}`)}`));
|
|
2583
|
+
console.log(ansis__default.gray(` 2. Start planning: ${ansis__default.white("/plan")}`));
|
|
2584
|
+
console.log(ansis__default.gray(` 3. Begin coding: ${ansis__default.white("Use the spec as context")}`));
|
|
2585
2585
|
console.log("");
|
|
2586
2586
|
}
|
|
2587
2587
|
function listTemplates(lang) {
|
|
2588
2588
|
console.log("");
|
|
2589
|
-
console.log(
|
|
2589
|
+
console.log(ansis__default.green.bold(" Available Interview Templates:"));
|
|
2590
2590
|
console.log("");
|
|
2591
2591
|
for (const template of INTERVIEW_TEMPLATES) {
|
|
2592
|
-
console.log(
|
|
2593
|
-
console.log(` ${
|
|
2594
|
-
console.log(` ${
|
|
2595
|
-
console.log(` ${
|
|
2592
|
+
console.log(ansis__default.green(` ${template.id}`));
|
|
2593
|
+
console.log(` ${ansis__default.white(template.name[lang])}`);
|
|
2594
|
+
console.log(` ${ansis__default.gray(template.description[lang])}`);
|
|
2595
|
+
console.log(` ${ansis__default.gray(`~${template.estimatedQuestions} questions, ${template.defaultDepth} depth`)}`);
|
|
2596
2596
|
console.log("");
|
|
2597
2597
|
}
|
|
2598
|
-
console.log(
|
|
2598
|
+
console.log(ansis__default.gray(" Usage: ccjk interview --template <template-id> [SPEC.md]"));
|
|
2599
2599
|
console.log("");
|
|
2600
2600
|
}
|
|
2601
2601
|
async function interview(options = {}) {
|
|
@@ -2619,13 +2619,13 @@ async function interview(options = {}) {
|
|
|
2619
2619
|
} else {
|
|
2620
2620
|
const selectedTemplate = await selectTemplate(lang);
|
|
2621
2621
|
if (!selectedTemplate) {
|
|
2622
|
-
console.log(
|
|
2622
|
+
console.log(ansis__default.yellow("\n Interview cancelled.\n"));
|
|
2623
2623
|
return;
|
|
2624
2624
|
}
|
|
2625
2625
|
templateId = selectedTemplate;
|
|
2626
2626
|
const template2 = getTemplateById(templateId);
|
|
2627
2627
|
if (!template2) {
|
|
2628
|
-
console.log(
|
|
2628
|
+
console.log(ansis__default.red(`
|
|
2629
2629
|
Template not found: ${templateId}
|
|
2630
2630
|
`));
|
|
2631
2631
|
return;
|
|
@@ -2633,20 +2633,20 @@ async function interview(options = {}) {
|
|
|
2633
2633
|
const { selectedDepth } = await inquirer.prompt({
|
|
2634
2634
|
type: "list",
|
|
2635
2635
|
name: "selectedDepth",
|
|
2636
|
-
message:
|
|
2636
|
+
message: ansis__default.gray("Interview depth:"),
|
|
2637
2637
|
choices: [
|
|
2638
2638
|
{
|
|
2639
|
-
name: `${
|
|
2639
|
+
name: `${ansis__default.green("1.")} \u26A1 Quick (~10 questions)`,
|
|
2640
2640
|
value: "quick",
|
|
2641
2641
|
short: "Quick"
|
|
2642
2642
|
},
|
|
2643
2643
|
{
|
|
2644
|
-
name: `${
|
|
2644
|
+
name: `${ansis__default.green("2.")} \u{1F4CA} Standard (~25 questions) ${template2.defaultDepth === "standard" ? ansis__default.green("(Recommended)") : ""}`,
|
|
2645
2645
|
value: "standard",
|
|
2646
2646
|
short: "Standard"
|
|
2647
2647
|
},
|
|
2648
2648
|
{
|
|
2649
|
-
name: `${
|
|
2649
|
+
name: `${ansis__default.green("3.")} \u{1F52C} Deep (~40+ questions) ${template2.defaultDepth === "deep" ? ansis__default.green("(Recommended)") : ""}`,
|
|
2650
2650
|
value: "deep",
|
|
2651
2651
|
short: "Deep"
|
|
2652
2652
|
}
|
|
@@ -2657,7 +2657,7 @@ async function interview(options = {}) {
|
|
|
2657
2657
|
depth = selectedDepth;
|
|
2658
2658
|
const selectedSpecFile = await getSpecFilePath("SPEC.md");
|
|
2659
2659
|
if (!selectedSpecFile) {
|
|
2660
|
-
console.log(
|
|
2660
|
+
console.log(ansis__default.yellow("\n Interview cancelled.\n"));
|
|
2661
2661
|
return;
|
|
2662
2662
|
}
|
|
2663
2663
|
specFile = selectedSpecFile;
|
|
@@ -2669,23 +2669,23 @@ async function interview(options = {}) {
|
|
|
2669
2669
|
}
|
|
2670
2670
|
const template = getTemplateById(templateId);
|
|
2671
2671
|
if (!template) {
|
|
2672
|
-
console.log(
|
|
2672
|
+
console.log(ansis__default.red(`
|
|
2673
2673
|
Template not found: ${templateId}
|
|
2674
2674
|
`));
|
|
2675
|
-
console.log(
|
|
2676
|
-
INTERVIEW_TEMPLATES.forEach((t) => console.log(
|
|
2675
|
+
console.log(ansis__default.gray(" Available templates:"));
|
|
2676
|
+
INTERVIEW_TEMPLATES.forEach((t) => console.log(ansis__default.gray(` - ${t.id}`)));
|
|
2677
2677
|
return;
|
|
2678
2678
|
}
|
|
2679
2679
|
const absoluteSpecFile = resolve(process__default.cwd(), specFile);
|
|
2680
2680
|
console.log("");
|
|
2681
|
-
console.log(
|
|
2682
|
-
console.log(` ${
|
|
2683
|
-
console.log(` ${
|
|
2684
|
-
console.log(` ${
|
|
2685
|
-
console.log(
|
|
2681
|
+
console.log(ansis__default.gray("\u2500".repeat(50)));
|
|
2682
|
+
console.log(` ${ansis__default.gray("Template:")} ${ansis__default.white(template.name[lang])}`);
|
|
2683
|
+
console.log(` ${ansis__default.gray("Depth:")} ${ansis__default.white(depth)} ${ansis__default.gray(`(~${depth === "quick" ? 10 : depth === "standard" ? 25 : 40}+ questions)`)}`);
|
|
2684
|
+
console.log(` ${ansis__default.gray("Output:")} ${ansis__default.green(specFile)}`);
|
|
2685
|
+
console.log(ansis__default.gray("\u2500".repeat(50)));
|
|
2686
2686
|
console.log("");
|
|
2687
|
-
console.log(
|
|
2688
|
-
console.log(
|
|
2687
|
+
console.log(ansis__default.green(" Starting interview..."));
|
|
2688
|
+
console.log(ansis__default.gray(" Press Ctrl+C to pause | Enter to select | Type for custom"));
|
|
2689
2689
|
console.log("");
|
|
2690
2690
|
const engine = createInterviewEngine(lang);
|
|
2691
2691
|
const session = await engine.startInterview(absoluteSpecFile, {
|
|
@@ -2703,7 +2703,7 @@ async function interview(options = {}) {
|
|
|
2703
2703
|
const answer = await askQuestion(questionDisplay, lang);
|
|
2704
2704
|
if (answer === null) {
|
|
2705
2705
|
console.log("");
|
|
2706
|
-
console.log(
|
|
2706
|
+
console.log(ansis__default.yellow(" Interview paused."));
|
|
2707
2707
|
try {
|
|
2708
2708
|
const { saveProgress } = await inquirer.prompt({
|
|
2709
2709
|
type: "confirm",
|
|
@@ -2717,8 +2717,8 @@ async function interview(options = {}) {
|
|
|
2717
2717
|
if (sessionJson) {
|
|
2718
2718
|
const sessionFile = absoluteSpecFile.replace(".md", ".session.json");
|
|
2719
2719
|
await writeFile(sessionFile, sessionJson, "utf-8");
|
|
2720
|
-
console.log(
|
|
2721
|
-
console.log(
|
|
2720
|
+
console.log(ansis__default.gray(` Session saved to: ${sessionFile}`));
|
|
2721
|
+
console.log(ansis__default.gray(` Resume with: ccjk interview --resume`));
|
|
2722
2722
|
}
|
|
2723
2723
|
}
|
|
2724
2724
|
} catch {
|
|
@@ -2735,7 +2735,7 @@ async function interview(options = {}) {
|
|
|
2735
2735
|
questionDisplay = await engine.getNextQuestion(session.id);
|
|
2736
2736
|
}
|
|
2737
2737
|
console.log("");
|
|
2738
|
-
console.log(
|
|
2738
|
+
console.log(ansis__default.green(" Generating specification..."));
|
|
2739
2739
|
const specGenerator = createSpecGenerator(lang);
|
|
2740
2740
|
const spec = await specGenerator.generateSpec(session);
|
|
2741
2741
|
const specDir = dirname(absoluteSpecFile);
|
|
@@ -2779,18 +2779,18 @@ async function resumeInterview(sessionFile, options = {}) {
|
|
|
2779
2779
|
}
|
|
2780
2780
|
}
|
|
2781
2781
|
if (sessions.length === 0) {
|
|
2782
|
-
console.log(
|
|
2783
|
-
console.log(
|
|
2782
|
+
console.log(ansis__default.yellow("\n No saved sessions found.\n"));
|
|
2783
|
+
console.log(ansis__default.gray(" Start a new interview with: ccjk interview"));
|
|
2784
2784
|
return;
|
|
2785
2785
|
}
|
|
2786
2786
|
sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
2787
2787
|
const { selectedSession } = await inquirer.prompt({
|
|
2788
2788
|
type: "list",
|
|
2789
2789
|
name: "selectedSession",
|
|
2790
|
-
message:
|
|
2790
|
+
message: ansis__default.gray("Select a session to resume:"),
|
|
2791
2791
|
choices: sessions.map((s, i) => ({
|
|
2792
|
-
name: `${
|
|
2793
|
-
${
|
|
2792
|
+
name: `${ansis__default.green(`${i + 1}.`)} ${ansis__default.white(s.name)}
|
|
2793
|
+
${ansis__default.gray(`Modified: ${s.modified.toLocaleString()}`)}`,
|
|
2794
2794
|
value: s.path,
|
|
2795
2795
|
short: s.name
|
|
2796
2796
|
})),
|
|
@@ -2799,7 +2799,7 @@ async function resumeInterview(sessionFile, options = {}) {
|
|
|
2799
2799
|
targetSessionFile = selectedSession;
|
|
2800
2800
|
}
|
|
2801
2801
|
if (!existsSync(targetSessionFile)) {
|
|
2802
|
-
console.log(
|
|
2802
|
+
console.log(ansis__default.red(`
|
|
2803
2803
|
Session file not found: ${targetSessionFile}
|
|
2804
2804
|
`));
|
|
2805
2805
|
return;
|
|
@@ -2808,17 +2808,17 @@ async function resumeInterview(sessionFile, options = {}) {
|
|
|
2808
2808
|
const engine = createInterviewEngine(lang);
|
|
2809
2809
|
const session = engine.importSession(sessionJson);
|
|
2810
2810
|
if (!session) {
|
|
2811
|
-
console.log(
|
|
2811
|
+
console.log(ansis__default.red("\n Failed to load session file.\n"));
|
|
2812
2812
|
return;
|
|
2813
2813
|
}
|
|
2814
2814
|
displayInterviewBanner();
|
|
2815
|
-
console.log(
|
|
2816
|
-
console.log(
|
|
2817
|
-
console.log(
|
|
2815
|
+
console.log(ansis__default.green(" Resuming interview session..."));
|
|
2816
|
+
console.log(ansis__default.gray(` Session ID: ${session.id}`));
|
|
2817
|
+
console.log(ansis__default.gray(` Progress: ${session.questionsAsked} questions answered`));
|
|
2818
2818
|
console.log("");
|
|
2819
2819
|
const resumed = await engine.resumeInterview(session.id);
|
|
2820
2820
|
if (!resumed) {
|
|
2821
|
-
console.log(
|
|
2821
|
+
console.log(ansis__default.red("\n Failed to resume session.\n"));
|
|
2822
2822
|
return;
|
|
2823
2823
|
}
|
|
2824
2824
|
let questionDisplay = await engine.getNextQuestion(session.id);
|
|
@@ -2828,12 +2828,12 @@ async function resumeInterview(sessionFile, options = {}) {
|
|
|
2828
2828
|
const answer = await askQuestion(questionDisplay, lang);
|
|
2829
2829
|
if (answer === null) {
|
|
2830
2830
|
console.log("");
|
|
2831
|
-
console.log(
|
|
2831
|
+
console.log(ansis__default.yellow(" Interview paused."));
|
|
2832
2832
|
await engine.pauseInterview(session.id);
|
|
2833
2833
|
const updatedSessionJson = engine.exportSession(session.id);
|
|
2834
2834
|
if (updatedSessionJson) {
|
|
2835
2835
|
await writeFile(targetSessionFile, updatedSessionJson, "utf-8");
|
|
2836
|
-
console.log(
|
|
2836
|
+
console.log(ansis__default.gray(` Progress saved to: ${targetSessionFile}`));
|
|
2837
2837
|
}
|
|
2838
2838
|
return;
|
|
2839
2839
|
}
|
|
@@ -2847,7 +2847,7 @@ async function resumeInterview(sessionFile, options = {}) {
|
|
|
2847
2847
|
questionDisplay = await engine.getNextQuestion(session.id);
|
|
2848
2848
|
}
|
|
2849
2849
|
console.log("");
|
|
2850
|
-
console.log(
|
|
2850
|
+
console.log(ansis__default.green(" Generating specification..."));
|
|
2851
2851
|
const specGenerator = createSpecGenerator(lang);
|
|
2852
2852
|
const spec = await specGenerator.generateSpec(session);
|
|
2853
2853
|
await specGenerator.writeSpecToFile(spec, session.specFile);
|
|
@@ -2881,7 +2881,7 @@ async function listInterviewSessions() {
|
|
|
2881
2881
|
const { readdir, stat } = await import('node:fs/promises');
|
|
2882
2882
|
const { homedir } = await import('node:os');
|
|
2883
2883
|
console.log("");
|
|
2884
|
-
console.log(
|
|
2884
|
+
console.log(ansis__default.green.bold(" Saved Interview Sessions:"));
|
|
2885
2885
|
console.log("");
|
|
2886
2886
|
const searchDirs = [
|
|
2887
2887
|
process__default.cwd(),
|
|
@@ -2896,9 +2896,9 @@ async function listInterviewSessions() {
|
|
|
2896
2896
|
const filePath = join(dir, file);
|
|
2897
2897
|
const fileStats = await stat(filePath);
|
|
2898
2898
|
const modified = fileStats.mtime.toLocaleString();
|
|
2899
|
-
console.log(` ${
|
|
2900
|
-
console.log(` ${
|
|
2901
|
-
console.log(` ${
|
|
2899
|
+
console.log(` ${ansis__default.green("\u2022")} ${ansis__default.white(file)}`);
|
|
2900
|
+
console.log(` ${ansis__default.gray("Path:")} ${filePath}`);
|
|
2901
|
+
console.log(` ${ansis__default.gray("Modified:")} ${modified}`);
|
|
2902
2902
|
console.log("");
|
|
2903
2903
|
foundAny = true;
|
|
2904
2904
|
}
|
|
@@ -2906,9 +2906,9 @@ async function listInterviewSessions() {
|
|
|
2906
2906
|
}
|
|
2907
2907
|
}
|
|
2908
2908
|
if (!foundAny) {
|
|
2909
|
-
console.log(
|
|
2909
|
+
console.log(ansis__default.gray(" No saved sessions found."));
|
|
2910
2910
|
console.log("");
|
|
2911
|
-
console.log(
|
|
2911
|
+
console.log(ansis__default.gray(" Start a new interview with: ccjk interview"));
|
|
2912
2912
|
}
|
|
2913
2913
|
console.log("");
|
|
2914
2914
|
}
|