@gpc-cli/cli 0.9.64 → 0.9.65

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/README.md CHANGED
@@ -27,17 +27,17 @@ gpc doctor # 20 setup checks
27
27
 
28
28
  ## Why this over Fastlane?
29
29
 
30
- | | **GPC** | Fastlane supply |
31
- | ----------------------- | ----------------------------- | --------------- |
32
- | API coverage | **217 endpoints** | ~20 |
33
- | Runtime | Node.js or binary | Ruby + Bundler |
34
- | Cold start | <500ms | 2-3s |
35
- | Reviews & Vitals | Yes | No |
36
- | Subscriptions | Yes | No |
37
- | **Managed Google Play** | **Yes (Play Custom App API)** | No |
38
- | **AI-translated release notes** | **Yes (80+ locales, BYO key)** | No |
39
- | Preflight scanner | 9 offline checks | No |
40
- | CI/CD native | JSON + exit codes | Partial |
30
+ | | **GPC** | Fastlane supply |
31
+ | ------------------------------- | ------------------------------ | --------------- |
32
+ | API coverage | **217 endpoints** | ~20 |
33
+ | Runtime | Node.js or binary | Ruby + Bundler |
34
+ | Cold start | <500ms | 2-3s |
35
+ | Reviews & Vitals | Yes | No |
36
+ | Subscriptions | Yes | No |
37
+ | **Managed Google Play** | **Yes (Play Custom App API)** | No |
38
+ | **AI-translated release notes** | **Yes (80+ locales, BYO key)** | No |
39
+ | Preflight scanner | 9 offline checks | No |
40
+ | CI/CD native | JSON + exit codes | Partial |
41
41
 
42
42
  [Migration guide](https://yasserstudio.github.io/gpc/migration/from-fastlane) with one-to-one command mapping.
43
43
 
@@ -91,7 +91,7 @@ curl -fsSL https://raw.githubusercontent.com/yasserstudio/gpc/main/scripts/insta
91
91
  - [Commands reference](https://yasserstudio.github.io/gpc/commands/)
92
92
  - [CI/CD recipes](https://yasserstudio.github.io/gpc/ci-cd/)
93
93
 
94
- Free to use. 2,076 tests. 90%+ coverage. Every write operation supports `--dry-run`.
94
+ Free to use. 2,093 tests. 90%+ coverage. Every write operation supports `--dry-run`.
95
95
 
96
96
  ## Licensing
97
97
 
package/dist/bin.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  createProgram,
4
4
  handleCliError,
5
5
  loadPlugins
6
- } from "./chunk-I3SFXLIY.js";
6
+ } from "./chunk-DQD2S5QH.js";
7
7
  import {
8
8
  checkForUpdate,
9
9
  formatUpdateNotification
@@ -57,7 +57,7 @@ if (!_isJsonMode && !_isQuiet && !_isSetupCommand && !existsSync(getUserConfigPa
57
57
  }
58
58
  await setupNetworking();
59
59
  initAudit(getConfigDir());
60
- var currentVersion = "0.9.64";
60
+ var currentVersion = "0.9.65";
61
61
  var isUpdateCommand = process.argv[2] === "update";
62
62
  var isCompletionProvider = process.argv[2] === "__complete";
63
63
  var updateCheckPromise = isUpdateCommand || isCompletionProvider ? Promise.resolve(null) : checkForUpdate(currentVersion);
@@ -347,7 +347,13 @@ function registerChangelogCommand(program) {
347
347
  `);
348
348
  }
349
349
  if (opts.apply) {
350
- const ok = await performApply({ bundle: translated, program, track: opts.track, dryRun, aiBlock });
350
+ const ok = await performApply({
351
+ bundle: translated,
352
+ program,
353
+ track: opts.track,
354
+ dryRun,
355
+ aiBlock
356
+ });
351
357
  if (!ok) return;
352
358
  }
353
359
  const hasOverflow = translated.overflows.length > 0;
@@ -362,4 +368,4 @@ function registerChangelogCommand(program) {
362
368
  export {
363
369
  registerChangelogCommand
364
370
  };
365
- //# sourceMappingURL=changelog-EHQYZP22.js.map
371
+ //# sourceMappingURL=changelog-STYBBYDC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/changelog.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport {\n fetchChangelog,\n formatChangelogEntry,\n formatOutput,\n generateChangelog,\n RENDERERS,\n renderPlayStore,\n renderPlayStoreMd,\n renderPlayStorePrompt,\n buildLocaleBundle,\n translateBundle,\n resolveAiConfig,\n createTranslator,\n fetchAggregateCost,\n formatPathLabel,\n PROVIDER_WHITELIST,\n resolveLocales,\n validateBundleForApply,\n bundleToReleaseNotes,\n applyReleaseNotes,\n GpcError,\n type OutputMode,\n type PlayStoreFormat,\n} from \"@gpc-cli/core\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { getOutputFormat } from \"../format.js\";\nimport { yellow, dim } from \"../colors.js\";\nimport { resolvePackageName, getClient } from \"../resolve.js\";\n\nconst VALID_OUTPUT_MODES: OutputMode[] = [\"md\", \"json\", \"prompt\"];\nconst VALID_TARGETS = [\"github\", \"play-store\"] as const;\ntype ChangelogTarget = (typeof VALID_TARGETS)[number];\nconst REPO_RE = /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+$/;\n\ninterface ApplyContext {\n bundle: Parameters<typeof validateBundleForApply>[0];\n program: Command;\n track: string;\n dryRun: boolean;\n aiBlock?: Record<string, unknown>;\n}\n\nasync function performApply(ctx: ApplyContext): Promise<boolean> {\n const blocked = validateBundleForApply(ctx.bundle);\n if (blocked.length > 0) {\n process.stderr.write(\n `Cannot --apply: ${blocked.length} locale(s) blocked:\\n` +\n blocked.map((b) => ` ${b}`).join(\"\\n\") +\n \"\\n\",\n );\n process.exitCode = 1;\n return false;\n }\n const notes = bundleToReleaseNotes(ctx.bundle);\n const config = await loadConfig();\n const packageName = resolvePackageName(ctx.program.opts()[\"app\"], config);\n if (ctx.dryRun) {\n const payload: Record<string, unknown> = {\n dryRun: true,\n action: \"apply release notes\",\n track: ctx.track,\n packageName,\n localeCount: notes.length,\n releaseNotes: notes,\n };\n if (ctx.aiBlock) payload[\"ai\"] = ctx.aiBlock;\n console.log(JSON.stringify(payload, null, 2));\n return false;\n }\n const client = await getClient(config);\n const result = await applyReleaseNotes(client, packageName, ctx.track, notes);\n process.stderr.write(\n `${dim(`→ Applied ${result.localeCount} locale(s) to draft on ${result.track} (${packageName})`)}\\n`,\n );\n return true;\n}\n\nexport function registerChangelogCommand(program: Command): void {\n const changelog = program\n .command(\"changelog\")\n .description(\"Show release history\")\n .option(\"-n, --limit <count>\", \"Number of releases to show\", parseInt, 5)\n .option(\"--tag <tag>\", \"Show a specific release (e.g., v0.9.43)\")\n .option(\"--all\", \"Show all releases\")\n .action(async (opts: { limit: number; tag?: string; all?: boolean }) => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n\n const entries = await fetchChangelog({\n limit: opts.all ? 100 : opts.limit,\n version: opts.tag,\n });\n\n if (entries.length === 0) {\n console.log(\"No releases found.\");\n return;\n }\n\n if (format === \"json\") {\n console.log(formatOutput(entries, \"json\"));\n return;\n }\n\n if (opts.tag || entries.length === 1) {\n console.log(formatChangelogEntry(entries[0]!));\n return;\n }\n\n const header = \"VERSION DATE TITLE\";\n const separator = \"─\".repeat(header.length);\n console.log(header);\n console.log(separator);\n for (const entry of entries) {\n const version = entry.version.padEnd(12);\n const date = entry.date.padEnd(12);\n console.log(`${version} ${date} ${entry.title}`);\n }\n console.log(\"\");\n console.log(\n `Showing ${entries.length} releases. Use --tag <tag> for details, or --all for full history.`,\n );\n });\n\n changelog\n .command(\"generate\")\n .description(\"Generate release notes from local git commits\")\n .option(\"--from <ref>\", \"Starting ref (default: latest v* tag)\")\n .option(\"--to <ref>\", \"Ending ref (default: HEAD)\")\n .option(\"--format <mode>\", \"Renderer: md, json, or prompt\", \"md\")\n .option(\"--repo <owner/name>\", \"Override auto-detected repo (e.g., yasserstudio/gpc)\")\n .option(\"--target <mode>\", \"Output target: github or play-store\", \"github\")\n .option(\n \"--locales <csv|auto>\",\n \"Comma-separated BCP 47 locales, or 'auto' (play-store target only)\",\n )\n .option(\"--ai\", \"Translate non-source locales via LLM (play-store target only, BYO key)\")\n .option(\n \"--provider <name>\",\n `AI provider (${PROVIDER_WHITELIST.join(\"|\")}). Defaults to first env key detected`,\n )\n .option(\"--model <id>\", \"Override default model for the chosen provider\")\n .option(\"--strict\", \"Exit non-zero if warnings, overflows, or translation failures occur\")\n .option(\"--apply\", \"Write notes into the draft release on --track (play-store target only)\")\n .option(\"--track <name>\", \"Play Store track for --apply (default: production)\", \"production\")\n .action(\n async (opts: {\n from?: string;\n to?: string;\n format: string;\n repo?: string;\n target: string;\n locales?: string;\n strict?: boolean;\n ai?: boolean;\n provider?: string;\n model?: string;\n apply?: boolean;\n track: string;\n }) => {\n const dryRun = !!program.opts()[\"dryRun\"];\n const mode = opts.format as OutputMode;\n if (!VALID_OUTPUT_MODES.includes(mode)) {\n process.stderr.write(\n `Invalid --format \"${opts.format}\". Valid: ${VALID_OUTPUT_MODES.join(\", \")}\\n`,\n );\n process.exitCode = 2;\n return;\n }\n if (!VALID_TARGETS.includes(opts.target as ChangelogTarget)) {\n process.stderr.write(\n `Invalid --target \"${opts.target}\". Valid: ${VALID_TARGETS.join(\", \")}\\n`,\n );\n process.exitCode = 2;\n return;\n }\n const target = opts.target as ChangelogTarget;\n if (opts.repo && !REPO_RE.test(opts.repo)) {\n process.stderr.write(\n `Invalid --repo \"${opts.repo}\". Expected \"owner/name\" (e.g., yasserstudio/gpc).\\n`,\n );\n process.exitCode = 2;\n return;\n }\n if (target === \"github\" && opts.locales) {\n process.stderr.write(\n `--locales only applies to --target play-store (current target: github)\\n`,\n );\n process.exitCode = 2;\n return;\n }\n // Only block when the AI-adjacent flags are explicitly set. The root\n // program has its own `--dry-run` flag that may already be set\n // globally by the user for unrelated reasons; we silently ignore it\n // on non-AI code paths.\n if (target === \"github\" && (opts.ai || opts.provider || opts.model)) {\n process.stderr.write(\"--ai / --provider / --model only apply to --target play-store\\n\");\n process.exitCode = 2;\n return;\n }\n // --format prompt + --ai is nonsensical outside --dry-run: it would\n // render a \"please translate this\" prompt from already-translated\n // text. Either inspect the prompt via --dry-run, or pick md/json.\n if (opts.ai && opts.format === \"prompt\" && !dryRun) {\n process.stderr.write(\n \"--ai with --format prompt only makes sense with --dry-run\\n\" +\n \" (otherwise it would re-wrap translated text in a translation prompt).\\n\" +\n \" Hint: use --format md or --format json for live translation, or add --dry-run to inspect the prompt.\\n\",\n );\n process.exitCode = 2;\n return;\n }\n if (opts.apply && target !== \"play-store\") {\n process.stderr.write(\"--apply only applies to --target play-store\\n\");\n process.exitCode = 2;\n return;\n }\n if (opts.apply && mode === \"prompt\") {\n process.stderr.write(\n \"--apply cannot be combined with --format prompt\\n\" +\n \" Hint: use --format md or --format json.\\n\",\n );\n process.exitCode = 2;\n return;\n }\n if (target === \"play-store\" && !opts.locales) {\n process.stderr.write(\n \"--target play-store requires --locales <csv|auto>\\n\" +\n \" Example: --locales en-US,fr-FR,de-DE\\n\" +\n \" Example: --locales auto (reads current Play Store listing — requires --app)\\n\",\n );\n process.exitCode = 2;\n return;\n }\n\n const generated = await generateChangelog({\n from: opts.from,\n to: opts.to,\n repo: opts.repo,\n });\n\n for (const w of generated.warnings) {\n process.stderr.write(`${yellow(\"warn:\")} ${w}\\n`);\n }\n if (generated.warnings.length > 0) {\n process.stderr.write(\n `${dim(`(${generated.warnings.length} warning${generated.warnings.length === 1 ? \"\" : \"s\"} — review before publishing)`)}\\n`,\n );\n }\n\n if (target === \"github\") {\n const output = RENDERERS[mode](generated);\n console.log(output);\n if (opts.strict && generated.warnings.length > 0) {\n process.exitCode = 1;\n }\n return;\n }\n\n // target === \"play-store\"\n let locales: string[];\n try {\n if (opts.locales === \"auto\") {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n locales = await resolveLocales(\"auto\", { client, packageName });\n } else {\n locales = await resolveLocales(opts.locales!);\n }\n } catch (error) {\n if (error instanceof GpcError) {\n process.stderr.write(`${error.message}\\n`);\n if (error.suggestion) process.stderr.write(`${dim(error.suggestion)}\\n`);\n process.exitCode = error.exitCode;\n return;\n }\n throw error;\n }\n\n const playStoreFormat = mode as PlayStoreFormat;\n\n // Non-AI path: existing v0.9.62 behavior\n if (!opts.ai) {\n const { output, bundle } = renderPlayStore(generated, {\n locales,\n format: playStoreFormat,\n });\n console.log(output);\n\n for (const lang of bundle.overflows) {\n process.stderr.write(\n `${yellow(\"warn:\")} ${lang} exceeds ${bundle.limit} chars (truncated)\\n`,\n );\n }\n\n if (opts.apply) {\n const ok = await performApply({ bundle, program, track: opts.track, dryRun });\n if (!ok) return;\n }\n\n const hasOverflow = bundle.overflows.length > 0;\n const hasWarnings = generated.warnings.length > 0;\n if (opts.strict && (hasWarnings || hasOverflow)) {\n process.exitCode = 1;\n }\n return;\n }\n\n // --ai path: resolve config, translate, render with ai block\n let aiConfig;\n try {\n aiConfig = resolveAiConfig({ provider: opts.provider, model: opts.model });\n } catch (error) {\n if (error instanceof GpcError) {\n process.stderr.write(`${error.message}\\n`);\n if (error.suggestion) process.stderr.write(`${dim(error.suggestion)}\\n`);\n process.exitCode = error.exitCode;\n return;\n }\n throw error;\n }\n\n process.stderr.write(`${dim(`→ ${formatPathLabel(aiConfig)}`)}\\n`);\n\n const baseBundle = buildLocaleBundle(generated, {\n locales,\n format: playStoreFormat,\n });\n\n if (dryRun) {\n const preview = renderPlayStorePrompt(baseBundle, generated);\n console.log(preview);\n process.stderr.write(\n `${dim(\"(--dry-run: no API call was made; the prompt above is what would be sent per locale)\")}\\n`,\n );\n return;\n }\n\n const translator = await createTranslator(aiConfig);\n let translated;\n try {\n translated = await translateBundle(baseBundle, {\n translator,\n strict: opts.strict,\n onError: ({ language, reason }) => {\n process.stderr.write(\n `${yellow(\"warn:\")} ${language} translation failed: ${reason}\\n`,\n );\n },\n });\n } catch (error) {\n if (error instanceof GpcError) {\n process.stderr.write(`${error.message}\\n`);\n if (error.suggestion) process.stderr.write(`${dim(error.suggestion)}\\n`);\n process.exitCode = error.exitCode;\n return;\n }\n throw error;\n }\n\n const costUsd =\n aiConfig.path === \"gateway\" ? await fetchAggregateCost(aiConfig.runId) : undefined;\n\n const aiBlock: Record<string, unknown> = {\n path: aiConfig.path,\n provider: aiConfig.provider,\n model: aiConfig.model,\n tokensIn: translated.tokensIn,\n tokensOut: translated.tokensOut,\n };\n if (aiConfig.path === \"gateway\") {\n aiBlock[\"runId\"] = aiConfig.runId;\n if (typeof costUsd === \"number\") aiBlock[\"costUsd\"] = costUsd;\n }\n\n if (playStoreFormat === \"json\") {\n const payload = {\n from: translated.from,\n to: translated.to,\n limit: translated.limit,\n sourceLanguage: translated.sourceLanguage,\n ai: aiBlock,\n locales: translated.locales,\n overflows: translated.overflows,\n failures: translated.failures,\n };\n console.log(JSON.stringify(payload, null, 2));\n } else if (playStoreFormat === \"prompt\") {\n console.log(renderPlayStorePrompt(translated, generated));\n } else {\n console.log(renderPlayStoreMd(translated));\n }\n\n for (const lang of translated.overflows) {\n process.stderr.write(\n `${yellow(\"warn:\")} ${lang} exceeds ${translated.limit} chars (truncated)\\n`,\n );\n }\n\n if (translated.failures.length > 0) {\n process.stderr.write(\n `${dim(`(${translated.failures.length} locale${translated.failures.length === 1 ? \"\" : \"s\"} failed — see placeholders in output)`)}\\n`,\n );\n }\n\n if (typeof costUsd === \"number\") {\n process.stderr.write(`${dim(`(run cost: $${costUsd.toFixed(4)})`)}\\n`);\n }\n\n if (opts.apply) {\n const ok = await performApply({\n bundle: translated,\n program,\n track: opts.track,\n dryRun,\n aiBlock,\n });\n if (!ok) return;\n }\n\n const hasOverflow = translated.overflows.length > 0;\n const hasWarnings = generated.warnings.length > 0;\n const hasFailures = translated.failures.length > 0;\n if (opts.strict && (hasWarnings || hasOverflow || hasFailures)) {\n process.exitCode = 1;\n }\n },\n );\n}\n"],"mappings":"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","names":["hasOverflow","hasWarnings"]}
@@ -67,25 +67,25 @@ function registerPluginCommands(program, manager) {
67
67
  import { Command } from "commander";
68
68
  async function createProgram(pluginManager) {
69
69
  const program = new Command();
70
- program.name("gpc").description("GPC \u2014 Google Play Console CLI").version("0.9.64", "-V, --version").option("-o, --output <format>", "Output format: table, json, yaml, markdown, junit").option("-v, --verbose", "Enable debug logging").option("-q, --quiet", "Suppress non-essential output").option("-a, --app <package>", "App package name").option("-p, --profile <name>", "Auth profile name").option("--no-color", "Disable colored output").option("--no-interactive", "Disable interactive prompts").option("-y, --yes", "Skip confirmation prompts").option("--dry-run", "Preview changes without executing").option("--notify [target]", "Send webhook notification on completion (slack, discord, custom)").option("--ci", "Force CI mode (JSON output, no prompts, strict exit codes)").option("-j, --json", "Shorthand for --output json").option("--apps <csv>", "Comma-separated package names for multi-app operations").showSuggestionAfterError(false);
70
+ program.name("gpc").description("GPC \u2014 Google Play Console CLI").version("0.9.65", "-V, --version").option("-o, --output <format>", "Output format: table, json, yaml, markdown, junit").option("-v, --verbose", "Enable debug logging").option("-q, --quiet", "Suppress non-essential output").option("-a, --app <package>", "App package name").option("-p, --profile <name>", "Auth profile name").option("--no-color", "Disable colored output").option("--no-interactive", "Disable interactive prompts").option("-y, --yes", "Skip confirmation prompts").option("--dry-run", "Preview changes without executing").option("--notify [target]", "Send webhook notification on completion (slack, discord, custom)").option("--ci", "Force CI mode (JSON output, no prompts, strict exit codes)").option("-j, --json", "Shorthand for --output json").option("--apps <csv>", "Comma-separated package names for multi-app operations").showSuggestionAfterError(false);
71
71
  const commandLoaders = {
72
72
  auth: async () => {
73
73
  (await import("./auth-4DRT7ZH2.js")).registerAuthCommands(program);
74
74
  },
75
75
  config: async () => {
76
- (await import("./config-SK7BOURM.js")).registerConfigCommands(program);
76
+ (await import("./config-7TY5HS4Z.js")).registerConfigCommands(program);
77
77
  },
78
78
  doctor: async () => {
79
- (await import("./doctor-FSUI44DD.js")).registerDoctorCommand(program);
79
+ (await import("./doctor-BSUL4C2Q.js")).registerDoctorCommand(program);
80
80
  },
81
81
  update: async () => {
82
- (await import("./update-E4VGHQUR.js")).registerUpdateCommand(program);
82
+ (await import("./update-POERCYHW.js")).registerUpdateCommand(program);
83
83
  },
84
84
  docs: async () => {
85
- (await import("./docs-WVJCDX5X.js")).registerDocsCommand(program);
85
+ (await import("./docs-OU6LSSJD.js")).registerDocsCommand(program);
86
86
  },
87
87
  changelog: async () => {
88
- (await import("./changelog-EHQYZP22.js")).registerChangelogCommand(program);
88
+ (await import("./changelog-STYBBYDC.js")).registerChangelogCommand(program);
89
89
  },
90
90
  completion: async () => {
91
91
  (await import("./completion-ZK7RPPFD.js")).registerCompletionCommand(program, async () => {
@@ -193,13 +193,13 @@ async function createProgram(pluginManager) {
193
193
  (await import("./verify-H4ZUVHMZ.js")).registerVerifyCommand(program);
194
194
  },
195
195
  version: async () => {
196
- (await import("./version-HXUIOHCL.js")).registerVersionCommand(program);
196
+ (await import("./version-2HT32CYP.js")).registerVersionCommand(program);
197
197
  },
198
198
  cache: async () => {
199
199
  (await import("./cache-FGNP7Y37.js")).registerCacheCommand(program);
200
200
  },
201
201
  feedback: async () => {
202
- (await import("./feedback-PDQU5E6S.js")).registerFeedbackCommand(program);
202
+ (await import("./feedback-X5BBSC5I.js")).registerFeedbackCommand(program);
203
203
  },
204
204
  quickstart: async () => {
205
205
  (await import("./quickstart-FOWM3OKT.js")).registerQuickstartCommand(program);
@@ -467,4 +467,4 @@ export {
467
467
  createProgram,
468
468
  handleCliError
469
469
  };
470
- //# sourceMappingURL=chunk-I3SFXLIY.js.map
470
+ //# sourceMappingURL=chunk-DQD2S5QH.js.map
@@ -78,7 +78,7 @@ Configuration file created: ${path}`);
78
78
  });
79
79
  console.log("\nVerifying setup...");
80
80
  try {
81
- const { registerDoctorCommand } = await import("./doctor-FSUI44DD.js");
81
+ const { registerDoctorCommand } = await import("./doctor-BSUL4C2Q.js");
82
82
  const { Command } = await import("commander");
83
83
  const doctorProgram = new Command();
84
84
  doctorProgram.option("-o, --output <format>", "Output format").option("-j, --json", "JSON mode");
@@ -107,4 +107,4 @@ Configuration file created: ${path}`);
107
107
  export {
108
108
  registerConfigCommands
109
109
  };
110
- //# sourceMappingURL=config-SK7BOURM.js.map
110
+ //# sourceMappingURL=config-7TY5HS4Z.js.map
@@ -87,7 +87,10 @@ function renderMarkdown(content) {
87
87
  function renderInline(text) {
88
88
  let result = text.replace(/\*\*(.+?)\*\*/g, (_, t) => bold(t));
89
89
  result = result.replace(/`([^`]+)`/g, (_, t) => dim(t));
90
- result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, url) => `${label} ${dim(`(${url})`)}`);
90
+ result = result.replace(
91
+ /\[([^\]]+)\]\(([^)]+)\)/g,
92
+ (_, label, url) => `${label} ${dim(`(${url})`)}`
93
+ );
91
94
  return result;
92
95
  }
93
96
  function formatSearchResult(slug, title, snippet, score) {
@@ -281,12 +284,14 @@ Run: gpc docs list` : "Run: gpc docs list"
281
284
  Search results for "${query}"
282
285
  `));
283
286
  for (const r of results) {
284
- console.log(
285
- " " + formatSearchResult(r.page.slug, r.page.title, r.snippet, r.score)
286
- );
287
+ console.log(" " + formatSearchResult(r.page.slug, r.page.title, r.snippet, r.score));
287
288
  console.log("");
288
289
  }
289
- console.log(dim(` ${results.length} result${results.length === 1 ? "" : "s"}. Use: gpc docs show <topic>`));
290
+ console.log(
291
+ dim(
292
+ ` ${results.length} result${results.length === 1 ? "" : "s"}. Use: gpc docs show <topic>`
293
+ )
294
+ );
290
295
  });
291
296
  docs.command("init").description("Create GPC.md quick-reference for AI agents in this directory").option("--force", "Overwrite existing GPC.md").option("--path <dir>", "Output directory", ".").action(async (opts) => {
292
297
  const outDir = opts.path;
@@ -309,7 +314,11 @@ Run: gpc docs list` : "Run: gpc docs list"
309
314
  const existing = await readFile(agentPath, "utf-8");
310
315
  if (!existing.includes("GPC.md")) {
311
316
  const separator = existing.endsWith("\n") ? "\n" : "\n\n";
312
- await writeFile(agentPath, existing + separator + "See also: @GPC.md for GPC CLI reference.\n", "utf-8");
317
+ await writeFile(
318
+ agentPath,
319
+ existing + separator + "See also: @GPC.md for GPC CLI reference.\n",
320
+ "utf-8"
321
+ );
313
322
  console.log(`Updated ${agentPath} (added @GPC.md reference)`);
314
323
  }
315
324
  }
@@ -375,4 +384,4 @@ function generateQuickReference(bundle) {
375
384
  export {
376
385
  registerDocsCommand
377
386
  };
378
- //# sourceMappingURL=docs-WVJCDX5X.js.map
387
+ //# sourceMappingURL=docs-OU6LSSJD.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/docs.ts","../src/docs-renderer.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport * as cp from \"node:child_process\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { renderMarkdown, formatSearchResult } from \"../docs-renderer.js\";\nimport { bold, dim } from \"../colors.js\";\nimport { getOutputFormat } from \"../format.js\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { formatOutput, GpcError } from \"@gpc-cli/core\";\nimport type { DocPage, DocsBundle } from \"../generated/docs-types.js\";\n\nlet _bundle: DocsBundle | undefined;\nlet _pageMap: Map<string, DocPage> | undefined;\n\nfunction getBundle(): DocsBundle {\n if (!_bundle) {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n // Works from src/commands/ (dev/test) and dist/ (built output)\n const candidates = [\n join(moduleDir, \"..\", \"generated\", \"docs-bundle.json\"),\n join(moduleDir, \"generated\", \"docs-bundle.json\"),\n ];\n const bundlePath = candidates.find((p) => existsSync(p));\n if (!bundlePath) {\n throw new GpcError(\n \"Embedded docs bundle not found. Run the build first.\",\n \"DOCS_BUNDLE_MISSING\",\n 1,\n \"Run: pnpm build --filter @gpc-cli/cli\",\n );\n }\n _bundle = JSON.parse(readFileSync(bundlePath, \"utf-8\")) as DocsBundle;\n }\n return _bundle;\n}\n\nfunction getPageMap(): Map<string, DocPage> {\n if (!_pageMap) {\n const bundle = getBundle();\n _pageMap = new Map<string, DocPage>();\n for (const page of bundle.pages) {\n _pageMap.set(page.slug, page);\n }\n }\n return _pageMap;\n}\n\nfunction fuzzyMatch(query: string, pages: DocPage[]): DocPage | undefined {\n const q = query.toLowerCase();\n // Exact full slug match (e.g., \"guide/authentication\")\n const exact = pages.find((p) => p.slug === q);\n if (exact) return exact;\n // Match on the filename part (e.g., \"authentication\" matches \"guide/authentication\")\n const byName = pages.find((p) => p.slug.endsWith(`/${q}`));\n if (byName) return byName;\n // Prefix match on filename part\n const prefix = pages.find((p) => {\n const name = p.slug.split(\"/\").pop() || \"\";\n return name.startsWith(q);\n });\n if (prefix) return prefix;\n // Contains match anywhere in slug\n const contains = pages.find((p) => p.slug.includes(q));\n if (contains) return contains;\n // Title match\n const titleMatch = pages.find((p) => p.title.toLowerCase().includes(q));\n if (titleMatch) return titleMatch;\n return undefined;\n}\n\nfunction searchPages(\n query: string,\n bundle: DocsBundle,\n): { page: DocPage; score: number; snippet: string }[] {\n const words = query\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, \" \")\n .split(/\\s+/)\n .filter((w) => w.length > 2);\n\n if (words.length === 0) return [];\n\n const pageMap = getPageMap();\n const scores = new Map<string, number>();\n for (const word of words) {\n const entries = bundle.searchIndex[word];\n if (!entries) continue;\n for (const entry of entries) {\n scores.set(entry.slug, (scores.get(entry.slug) || 0) + entry.score);\n }\n }\n\n const results: { page: DocPage; score: number; snippet: string }[] = [];\n for (const [slug, score] of scores) {\n const page = pageMap.get(slug);\n if (!page) continue;\n const snippet = extractSnippet(page.content, words);\n results.push({ page, score, snippet });\n }\n\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, 15);\n}\n\nfunction extractSnippet(content: string, words: string[]): string {\n const lines = content.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n const lower = lines[i]!.toLowerCase();\n if (words.some((w) => lower.includes(w))) {\n const start = Math.max(0, i - 1);\n const end = Math.min(lines.length, i + 2);\n return lines.slice(start, end).join(\"\\n\");\n }\n }\n return lines.slice(0, 3).join(\"\\n\");\n}\n\nconst DOCS_BASE = \"https://yasserstudio.github.io/gpc/\";\n\nfunction openInBrowser(url: string): void {\n const platform = process.platform;\n if (platform === \"win32\") {\n cp.exec(`start \"\" \"${url}\"`, (error) => {\n if (error) console.log(`Open in your browser: ${url}`);\n });\n } else {\n const cmd = platform === \"darwin\" ? \"open\" : \"xdg-open\";\n cp.execFile(cmd, [url], (error) => {\n if (error) console.log(`Open in your browser: ${url}`);\n });\n }\n}\n\nexport function registerDocsCommand(program: Command): void {\n const docs = program\n .command(\"docs\")\n .description(\"Access embedded documentation (list, show, search, init, web)\");\n\n docs\n .command(\"list\")\n .description(\"List all available documentation topics\")\n .action(async () => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n const bundle = getBundle();\n\n if (format === \"json\") {\n const data = bundle.pages.map((p) => ({\n slug: p.slug,\n section: p.section,\n title: p.title,\n description: p.description,\n }));\n console.log(formatOutput(data, \"json\"));\n return;\n }\n\n const bySection = new Map<string, DocPage[]>();\n for (const page of bundle.pages) {\n if (!bySection.has(page.section)) bySection.set(page.section, []);\n bySection.get(page.section)!.push(page);\n }\n\n for (const [section, pages] of bySection) {\n console.log(bold(`\\n ${section.toUpperCase()}`));\n for (const page of pages) {\n const label = page.slug.padEnd(36);\n console.log(` ${label} ${dim(page.title || page.slug)}`);\n }\n }\n console.log(\"\");\n console.log(dim(` ${bundle.pageCount} topics. Use: gpc docs show <topic>`));\n });\n\n docs\n .command(\"show <topic>\")\n .description(\"Show a documentation page in the terminal\")\n .action(async (topic: string) => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n const bundle = getBundle();\n\n const page = fuzzyMatch(topic, bundle.pages);\n if (!page) {\n const suggestions = bundle.pages\n .filter((p) => p.slug.includes(topic.toLowerCase().slice(0, 3)))\n .slice(0, 5)\n .map((p) => p.slug);\n\n throw new GpcError(\n `No documentation found for \"${topic}\"`,\n \"DOCS_NOT_FOUND\",\n 2,\n suggestions.length > 0\n ? `Did you mean: ${suggestions.join(\", \")}?\\nRun: gpc docs list`\n : \"Run: gpc docs list\",\n );\n }\n\n if (format === \"json\") {\n console.log(\n formatOutput(\n { slug: page.slug, section: page.section, title: page.title, content: page.content },\n \"json\",\n ),\n );\n return;\n }\n\n console.log(renderMarkdown(page.content));\n });\n\n docs\n .command(\"search <query>\")\n .description(\"Search documentation\")\n .action(async (query: string) => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n const bundle = getBundle();\n\n const results = searchPages(query, bundle);\n\n if (results.length === 0) {\n console.log(dim(` No results for \"${query}\".`));\n console.log(dim(\" Try a different search term, or: gpc docs list\"));\n return;\n }\n\n if (format === \"json\") {\n const data = results.map((r) => ({\n slug: r.page.slug,\n section: r.page.section,\n title: r.page.title,\n score: r.score,\n }));\n console.log(formatOutput(data, \"json\"));\n return;\n }\n\n console.log(bold(`\\n Search results for \"${query}\"\\n`));\n for (const r of results) {\n console.log(\n \" \" +\n formatSearchResult(r.page.slug, r.page.title, r.snippet, r.score),\n );\n console.log(\"\");\n }\n console.log(dim(` ${results.length} result${results.length === 1 ? \"\" : \"s\"}. Use: gpc docs show <topic>`));\n });\n\n docs\n .command(\"init\")\n .description(\"Create GPC.md quick-reference for AI agents in this directory\")\n .option(\"--force\", \"Overwrite existing GPC.md\")\n .option(\"--path <dir>\", \"Output directory\", \".\")\n .action(async (opts: { force?: boolean; path: string }) => {\n const outDir = opts.path;\n const outFile = join(outDir, \"GPC.md\");\n\n if (existsSync(outFile) && !opts.force) {\n throw new GpcError(\n `GPC.md already exists at ${outFile}`,\n \"DOCS_INIT_EXISTS\",\n 1,\n \"Use --force to overwrite.\",\n );\n }\n\n const bundle = getBundle();\n const content = generateQuickReference(bundle);\n await writeFile(outFile, content, \"utf-8\");\n console.log(`Created ${outFile} (${bundle.pageCount} topics indexed)`);\n\n for (const agentFile of [\"CLAUDE.md\", \"AGENTS.md\"]) {\n const agentPath = join(outDir, agentFile);\n if (existsSync(agentPath)) {\n const existing = await readFile(agentPath, \"utf-8\");\n if (!existing.includes(\"GPC.md\")) {\n const separator = existing.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n await writeFile(agentPath, existing + separator + \"See also: @GPC.md for GPC CLI reference.\\n\", \"utf-8\");\n console.log(`Updated ${agentPath} (added @GPC.md reference)`);\n }\n }\n }\n });\n\n docs\n .command(\"web [topic]\")\n .description(\"Open documentation in browser\")\n .action((topic?: string) => {\n const bundle = getBundle();\n if (!topic) {\n openInBrowser(DOCS_BASE);\n return;\n }\n const page = fuzzyMatch(topic, bundle.pages);\n if (page) {\n openInBrowser(`${DOCS_BASE}${page.slug}`);\n } else {\n openInBrowser(DOCS_BASE);\n console.log(dim(`Topic \"${topic}\" not found. Opened docs home page.`));\n }\n });\n}\n\nfunction generateQuickReference(bundle: DocsBundle): string {\n const lines: string[] = [\n \"# GPC Quick Reference\",\n \"\",\n \"> Auto-generated by `gpc docs init`. See full docs: https://yasserstudio.github.io/gpc/\",\n \"\",\n \"## Commands\",\n \"\",\n ];\n\n const commandPages = bundle.pages\n .filter((p) => p.section === \"commands\")\n .sort((a, b) => a.slug.localeCompare(b.slug));\n\n for (const page of commandPages) {\n const desc = page.description || page.title;\n lines.push(`- **gpc ${page.slug}** -- ${desc}`);\n }\n\n lines.push(\"\", \"## Guides\", \"\");\n\n const guidePages = bundle.pages\n .filter((p) => p.section === \"guide\")\n .sort((a, b) => a.slug.localeCompare(b.slug));\n\n for (const page of guidePages) {\n lines.push(`- **${page.title || page.slug}** -- \\`gpc docs show ${page.slug}\\``);\n }\n\n lines.push(\n \"\",\n \"## Quick Workflows\",\n \"\",\n \"```bash\",\n \"# Upload and publish\",\n \"gpc publish app.aab\",\n \"\",\n \"# Check vitals before release\",\n \"gpc preflight app.aab\",\n \"\",\n \"# Generate changelog with AI translation\",\n \"gpc changelog generate --target play-store --locales auto --ai\",\n \"\",\n \"# Staged rollout\",\n \"gpc releases rollout --fraction 0.1 --app com.example.app\",\n \"```\",\n \"\",\n `*${bundle.pageCount} docs pages available offline via \\`gpc docs show <topic>\\`*`,\n \"\",\n );\n\n return lines.join(\"\\n\");\n}\n","import { bold, dim, yellow, green, gray } from \"./colors.js\";\n\nexport function renderMarkdown(content: string): string {\n const lines = content.split(\"\\n\");\n const out: string[] = [];\n\n let inCodeBlock = false;\n\n for (const line of lines) {\n if (line.startsWith(\"```\")) {\n inCodeBlock = !inCodeBlock;\n if (inCodeBlock) {\n out.push(dim(\" ┌─────────────────────────────────────\"));\n } else {\n out.push(dim(\" └─────────────────────────────────────\"));\n }\n continue;\n }\n\n if (inCodeBlock) {\n out.push(dim(` │ ${line}`));\n continue;\n }\n\n // Headers\n const h1 = line.match(/^# (.+)$/);\n if (h1) {\n out.push(\"\");\n out.push(bold(green(` ${h1[1]}`)));\n out.push(green(\" \" + \"─\".repeat(h1[1].length)));\n out.push(\"\");\n continue;\n }\n const h2 = line.match(/^## (.+)$/);\n if (h2) {\n out.push(\"\");\n out.push(bold(yellow(` ${h2[1]}`)));\n out.push(\"\");\n continue;\n }\n const h3 = line.match(/^### (.+)$/);\n if (h3) {\n out.push(bold(` ${h3[1]}`));\n continue;\n }\n\n // Blockquotes (converted from ::: containers)\n if (line.startsWith(\"> \")) {\n out.push(dim(` │ ${renderInline(line.slice(2))}`));\n continue;\n }\n\n // Table rows\n if (line.startsWith(\"|\")) {\n if (line.match(/^\\|[\\s-|]+\\|$/)) {\n out.push(gray(\" \" + \"─\".repeat(Math.min(line.length, 60))));\n continue;\n }\n const cells = line.split(\"|\").filter(Boolean).map((c) => c.trim());\n out.push(\" \" + cells.join(\" \"));\n continue;\n }\n\n // List items\n if (line.match(/^\\s*[-*]\\s/)) {\n out.push(` ${renderInline(line)}`);\n continue;\n }\n\n // Numbered list items\n if (line.match(/^\\s*\\d+\\.\\s/)) {\n out.push(` ${renderInline(line)}`);\n continue;\n }\n\n // Regular text\n out.push(` ${renderInline(line)}`);\n }\n\n // Close unclosed code block gracefully\n if (inCodeBlock) {\n out.push(dim(\" └─────────────────────────────────────\"));\n }\n\n return out.join(\"\\n\");\n}\n\nfunction renderInline(text: string): string {\n let result = text.replace(/\\*\\*(.+?)\\*\\*/g, (_, t) => bold(t));\n result = result.replace(/`([^`]+)`/g, (_, t) => dim(t));\n result = result.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (_, label, url) => `${label} ${dim(`(${url})`)}`);\n return result;\n}\n\nexport function formatSearchResult(\n slug: string,\n title: string,\n snippet: string,\n score: number,\n): string {\n const header = bold(slug) + dim(` (score: ${score})`);\n const titleLine = ` ${title}`;\n const snippetLines = snippet\n .split(\"\\n\")\n .slice(0, 3)\n .map((l) => gray(` ${l.trim()}`))\n .join(\"\\n\");\n return `${header}\\n${titleLine}\\n${snippetLines}`;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/commands/docs.ts","../src/docs-renderer.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport * as cp from \"node:child_process\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { renderMarkdown, formatSearchResult } from \"../docs-renderer.js\";\nimport { bold, dim } from \"../colors.js\";\nimport { getOutputFormat } from \"../format.js\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { formatOutput, GpcError } from \"@gpc-cli/core\";\nimport type { DocPage, DocsBundle } from \"../generated/docs-types.js\";\n\nlet _bundle: DocsBundle | undefined;\nlet _pageMap: Map<string, DocPage> | undefined;\n\nfunction getBundle(): DocsBundle {\n if (!_bundle) {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n // Works from src/commands/ (dev/test) and dist/ (built output)\n const candidates = [\n join(moduleDir, \"..\", \"generated\", \"docs-bundle.json\"),\n join(moduleDir, \"generated\", \"docs-bundle.json\"),\n ];\n const bundlePath = candidates.find((p) => existsSync(p));\n if (!bundlePath) {\n throw new GpcError(\n \"Embedded docs bundle not found. Run the build first.\",\n \"DOCS_BUNDLE_MISSING\",\n 1,\n \"Run: pnpm build --filter @gpc-cli/cli\",\n );\n }\n _bundle = JSON.parse(readFileSync(bundlePath, \"utf-8\")) as DocsBundle;\n }\n return _bundle;\n}\n\nfunction getPageMap(): Map<string, DocPage> {\n if (!_pageMap) {\n const bundle = getBundle();\n _pageMap = new Map<string, DocPage>();\n for (const page of bundle.pages) {\n _pageMap.set(page.slug, page);\n }\n }\n return _pageMap;\n}\n\nfunction fuzzyMatch(query: string, pages: DocPage[]): DocPage | undefined {\n const q = query.toLowerCase();\n // Exact full slug match (e.g., \"guide/authentication\")\n const exact = pages.find((p) => p.slug === q);\n if (exact) return exact;\n // Match on the filename part (e.g., \"authentication\" matches \"guide/authentication\")\n const byName = pages.find((p) => p.slug.endsWith(`/${q}`));\n if (byName) return byName;\n // Prefix match on filename part\n const prefix = pages.find((p) => {\n const name = p.slug.split(\"/\").pop() || \"\";\n return name.startsWith(q);\n });\n if (prefix) return prefix;\n // Contains match anywhere in slug\n const contains = pages.find((p) => p.slug.includes(q));\n if (contains) return contains;\n // Title match\n const titleMatch = pages.find((p) => p.title.toLowerCase().includes(q));\n if (titleMatch) return titleMatch;\n return undefined;\n}\n\nfunction searchPages(\n query: string,\n bundle: DocsBundle,\n): { page: DocPage; score: number; snippet: string }[] {\n const words = query\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, \" \")\n .split(/\\s+/)\n .filter((w) => w.length > 2);\n\n if (words.length === 0) return [];\n\n const pageMap = getPageMap();\n const scores = new Map<string, number>();\n for (const word of words) {\n const entries = bundle.searchIndex[word];\n if (!entries) continue;\n for (const entry of entries) {\n scores.set(entry.slug, (scores.get(entry.slug) || 0) + entry.score);\n }\n }\n\n const results: { page: DocPage; score: number; snippet: string }[] = [];\n for (const [slug, score] of scores) {\n const page = pageMap.get(slug);\n if (!page) continue;\n const snippet = extractSnippet(page.content, words);\n results.push({ page, score, snippet });\n }\n\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, 15);\n}\n\nfunction extractSnippet(content: string, words: string[]): string {\n const lines = content.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n const lower = lines[i]!.toLowerCase();\n if (words.some((w) => lower.includes(w))) {\n const start = Math.max(0, i - 1);\n const end = Math.min(lines.length, i + 2);\n return lines.slice(start, end).join(\"\\n\");\n }\n }\n return lines.slice(0, 3).join(\"\\n\");\n}\n\nconst DOCS_BASE = \"https://yasserstudio.github.io/gpc/\";\n\nfunction openInBrowser(url: string): void {\n const platform = process.platform;\n if (platform === \"win32\") {\n cp.exec(`start \"\" \"${url}\"`, (error) => {\n if (error) console.log(`Open in your browser: ${url}`);\n });\n } else {\n const cmd = platform === \"darwin\" ? \"open\" : \"xdg-open\";\n cp.execFile(cmd, [url], (error) => {\n if (error) console.log(`Open in your browser: ${url}`);\n });\n }\n}\n\nexport function registerDocsCommand(program: Command): void {\n const docs = program\n .command(\"docs\")\n .description(\"Access embedded documentation (list, show, search, init, web)\");\n\n docs\n .command(\"list\")\n .description(\"List all available documentation topics\")\n .action(async () => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n const bundle = getBundle();\n\n if (format === \"json\") {\n const data = bundle.pages.map((p) => ({\n slug: p.slug,\n section: p.section,\n title: p.title,\n description: p.description,\n }));\n console.log(formatOutput(data, \"json\"));\n return;\n }\n\n const bySection = new Map<string, DocPage[]>();\n for (const page of bundle.pages) {\n if (!bySection.has(page.section)) bySection.set(page.section, []);\n bySection.get(page.section)!.push(page);\n }\n\n for (const [section, pages] of bySection) {\n console.log(bold(`\\n ${section.toUpperCase()}`));\n for (const page of pages) {\n const label = page.slug.padEnd(36);\n console.log(` ${label} ${dim(page.title || page.slug)}`);\n }\n }\n console.log(\"\");\n console.log(dim(` ${bundle.pageCount} topics. Use: gpc docs show <topic>`));\n });\n\n docs\n .command(\"show <topic>\")\n .description(\"Show a documentation page in the terminal\")\n .action(async (topic: string) => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n const bundle = getBundle();\n\n const page = fuzzyMatch(topic, bundle.pages);\n if (!page) {\n const suggestions = bundle.pages\n .filter((p) => p.slug.includes(topic.toLowerCase().slice(0, 3)))\n .slice(0, 5)\n .map((p) => p.slug);\n\n throw new GpcError(\n `No documentation found for \"${topic}\"`,\n \"DOCS_NOT_FOUND\",\n 2,\n suggestions.length > 0\n ? `Did you mean: ${suggestions.join(\", \")}?\\nRun: gpc docs list`\n : \"Run: gpc docs list\",\n );\n }\n\n if (format === \"json\") {\n console.log(\n formatOutput(\n { slug: page.slug, section: page.section, title: page.title, content: page.content },\n \"json\",\n ),\n );\n return;\n }\n\n console.log(renderMarkdown(page.content));\n });\n\n docs\n .command(\"search <query>\")\n .description(\"Search documentation\")\n .action(async (query: string) => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n const bundle = getBundle();\n\n const results = searchPages(query, bundle);\n\n if (results.length === 0) {\n console.log(dim(` No results for \"${query}\".`));\n console.log(dim(\" Try a different search term, or: gpc docs list\"));\n return;\n }\n\n if (format === \"json\") {\n const data = results.map((r) => ({\n slug: r.page.slug,\n section: r.page.section,\n title: r.page.title,\n score: r.score,\n }));\n console.log(formatOutput(data, \"json\"));\n return;\n }\n\n console.log(bold(`\\n Search results for \"${query}\"\\n`));\n for (const r of results) {\n console.log(\" \" + formatSearchResult(r.page.slug, r.page.title, r.snippet, r.score));\n console.log(\"\");\n }\n console.log(\n dim(\n ` ${results.length} result${results.length === 1 ? \"\" : \"s\"}. Use: gpc docs show <topic>`,\n ),\n );\n });\n\n docs\n .command(\"init\")\n .description(\"Create GPC.md quick-reference for AI agents in this directory\")\n .option(\"--force\", \"Overwrite existing GPC.md\")\n .option(\"--path <dir>\", \"Output directory\", \".\")\n .action(async (opts: { force?: boolean; path: string }) => {\n const outDir = opts.path;\n const outFile = join(outDir, \"GPC.md\");\n\n if (existsSync(outFile) && !opts.force) {\n throw new GpcError(\n `GPC.md already exists at ${outFile}`,\n \"DOCS_INIT_EXISTS\",\n 1,\n \"Use --force to overwrite.\",\n );\n }\n\n const bundle = getBundle();\n const content = generateQuickReference(bundle);\n await writeFile(outFile, content, \"utf-8\");\n console.log(`Created ${outFile} (${bundle.pageCount} topics indexed)`);\n\n for (const agentFile of [\"CLAUDE.md\", \"AGENTS.md\"]) {\n const agentPath = join(outDir, agentFile);\n if (existsSync(agentPath)) {\n const existing = await readFile(agentPath, \"utf-8\");\n if (!existing.includes(\"GPC.md\")) {\n const separator = existing.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n await writeFile(\n agentPath,\n existing + separator + \"See also: @GPC.md for GPC CLI reference.\\n\",\n \"utf-8\",\n );\n console.log(`Updated ${agentPath} (added @GPC.md reference)`);\n }\n }\n }\n });\n\n docs\n .command(\"web [topic]\")\n .description(\"Open documentation in browser\")\n .action((topic?: string) => {\n const bundle = getBundle();\n if (!topic) {\n openInBrowser(DOCS_BASE);\n return;\n }\n const page = fuzzyMatch(topic, bundle.pages);\n if (page) {\n openInBrowser(`${DOCS_BASE}${page.slug}`);\n } else {\n openInBrowser(DOCS_BASE);\n console.log(dim(`Topic \"${topic}\" not found. Opened docs home page.`));\n }\n });\n}\n\nfunction generateQuickReference(bundle: DocsBundle): string {\n const lines: string[] = [\n \"# GPC Quick Reference\",\n \"\",\n \"> Auto-generated by `gpc docs init`. See full docs: https://yasserstudio.github.io/gpc/\",\n \"\",\n \"## Commands\",\n \"\",\n ];\n\n const commandPages = bundle.pages\n .filter((p) => p.section === \"commands\")\n .sort((a, b) => a.slug.localeCompare(b.slug));\n\n for (const page of commandPages) {\n const desc = page.description || page.title;\n lines.push(`- **gpc ${page.slug}** -- ${desc}`);\n }\n\n lines.push(\"\", \"## Guides\", \"\");\n\n const guidePages = bundle.pages\n .filter((p) => p.section === \"guide\")\n .sort((a, b) => a.slug.localeCompare(b.slug));\n\n for (const page of guidePages) {\n lines.push(`- **${page.title || page.slug}** -- \\`gpc docs show ${page.slug}\\``);\n }\n\n lines.push(\n \"\",\n \"## Quick Workflows\",\n \"\",\n \"```bash\",\n \"# Upload and publish\",\n \"gpc publish app.aab\",\n \"\",\n \"# Check vitals before release\",\n \"gpc preflight app.aab\",\n \"\",\n \"# Generate changelog with AI translation\",\n \"gpc changelog generate --target play-store --locales auto --ai\",\n \"\",\n \"# Staged rollout\",\n \"gpc releases rollout --fraction 0.1 --app com.example.app\",\n \"```\",\n \"\",\n `*${bundle.pageCount} docs pages available offline via \\`gpc docs show <topic>\\`*`,\n \"\",\n );\n\n return lines.join(\"\\n\");\n}\n","import { bold, dim, yellow, green, gray } from \"./colors.js\";\n\nexport function renderMarkdown(content: string): string {\n const lines = content.split(\"\\n\");\n const out: string[] = [];\n\n let inCodeBlock = false;\n\n for (const line of lines) {\n if (line.startsWith(\"```\")) {\n inCodeBlock = !inCodeBlock;\n if (inCodeBlock) {\n out.push(dim(\" ┌─────────────────────────────────────\"));\n } else {\n out.push(dim(\" └─────────────────────────────────────\"));\n }\n continue;\n }\n\n if (inCodeBlock) {\n out.push(dim(` │ ${line}`));\n continue;\n }\n\n // Headers\n const h1 = line.match(/^# (.+)$/);\n if (h1) {\n out.push(\"\");\n out.push(bold(green(` ${h1[1]!}`)));\n out.push(green(\" \" + \"─\".repeat(h1[1]!.length)));\n out.push(\"\");\n continue;\n }\n const h2 = line.match(/^## (.+)$/);\n if (h2) {\n out.push(\"\");\n out.push(bold(yellow(` ${h2[1]}`)));\n out.push(\"\");\n continue;\n }\n const h3 = line.match(/^### (.+)$/);\n if (h3) {\n out.push(bold(` ${h3[1]}`));\n continue;\n }\n\n // Blockquotes (converted from ::: containers)\n if (line.startsWith(\"> \")) {\n out.push(dim(` │ ${renderInline(line.slice(2))}`));\n continue;\n }\n\n // Table rows\n if (line.startsWith(\"|\")) {\n if (line.match(/^\\|[\\s-|]+\\|$/)) {\n out.push(gray(\" \" + \"─\".repeat(Math.min(line.length, 60))));\n continue;\n }\n const cells = line\n .split(\"|\")\n .filter(Boolean)\n .map((c) => c.trim());\n out.push(\" \" + cells.join(\" \"));\n continue;\n }\n\n // List items\n if (line.match(/^\\s*[-*]\\s/)) {\n out.push(` ${renderInline(line)}`);\n continue;\n }\n\n // Numbered list items\n if (line.match(/^\\s*\\d+\\.\\s/)) {\n out.push(` ${renderInline(line)}`);\n continue;\n }\n\n // Regular text\n out.push(` ${renderInline(line)}`);\n }\n\n // Close unclosed code block gracefully\n if (inCodeBlock) {\n out.push(dim(\" └─────────────────────────────────────\"));\n }\n\n return out.join(\"\\n\");\n}\n\nfunction renderInline(text: string): string {\n let result = text.replace(/\\*\\*(.+?)\\*\\*/g, (_, t) => bold(t));\n result = result.replace(/`([^`]+)`/g, (_, t) => dim(t));\n result = result.replace(\n /\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n (_, label, url) => `${label} ${dim(`(${url})`)}`,\n );\n return result;\n}\n\nexport function formatSearchResult(\n slug: string,\n title: string,\n snippet: string,\n score: number,\n): string {\n const header = bold(slug) + dim(` (score: ${score})`);\n const titleLine = ` ${title}`;\n const snippetLines = snippet\n .split(\"\\n\")\n .slice(0, 3)\n .map((l) => gray(` ${l.trim()}`))\n .join(\"\\n\");\n return `${header}\\n${titleLine}\\n${snippetLines}`;\n}\n"],"mappings":";;;;;;;;;;;;;AACA,YAAY,QAAQ;AACpB,SAAS,UAAU,iBAAiB;AACpC,SAAS,MAAM,eAAe;AAC9B,SAAS,YAAY,oBAAoB;AACzC,SAAS,qBAAqB;;;ACHvB,SAAS,eAAe,SAAyB;AACtD,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAM,MAAgB,CAAC;AAEvB,MAAI,cAAc;AAElB,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,KAAK,GAAG;AAC1B,oBAAc,CAAC;AACf,UAAI,aAAa;AACf,YAAI,KAAK,IAAI,wOAA0C,CAAC;AAAA,MAC1D,OAAO;AACL,YAAI,KAAK,IAAI,wOAA0C,CAAC;AAAA,MAC1D;AACA;AAAA,IACF;AAEA,QAAI,aAAa;AACf,UAAI,KAAK,IAAI,YAAO,IAAI,EAAE,CAAC;AAC3B;AAAA,IACF;AAGA,UAAM,KAAK,KAAK,MAAM,UAAU;AAChC,QAAI,IAAI;AACN,UAAI,KAAK,EAAE;AACX,UAAI,KAAK,KAAK,MAAM,KAAK,GAAG,CAAC,CAAE,EAAE,CAAC,CAAC;AACnC,UAAI,KAAK,MAAM,OAAO,SAAI,OAAO,GAAG,CAAC,EAAG,MAAM,CAAC,CAAC;AAChD,UAAI,KAAK,EAAE;AACX;AAAA,IACF;AACA,UAAM,KAAK,KAAK,MAAM,WAAW;AACjC,QAAI,IAAI;AACN,UAAI,KAAK,EAAE;AACX,UAAI,KAAK,KAAK,OAAO,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;AACnC,UAAI,KAAK,EAAE;AACX;AAAA,IACF;AACA,UAAM,KAAK,KAAK,MAAM,YAAY;AAClC,QAAI,IAAI;AACN,UAAI,KAAK,KAAK,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;AAC3B;AAAA,IACF;AAGA,QAAI,KAAK,WAAW,IAAI,GAAG;AACzB,UAAI,KAAK,IAAI,YAAO,aAAa,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;AAClD;AAAA,IACF;AAGA,QAAI,KAAK,WAAW,GAAG,GAAG;AACxB,UAAI,KAAK,MAAM,eAAe,GAAG;AAC/B,YAAI,KAAK,KAAK,OAAO,SAAI,OAAO,KAAK,IAAI,KAAK,QAAQ,EAAE,CAAC,CAAC,CAAC;AAC3D;AAAA,MACF;AACA,YAAM,QAAQ,KACX,MAAM,GAAG,EACT,OAAO,OAAO,EACd,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACtB,UAAI,KAAK,OAAO,MAAM,KAAK,IAAI,CAAC;AAChC;AAAA,IACF;AAGA,QAAI,KAAK,MAAM,YAAY,GAAG;AAC5B,UAAI,KAAK,KAAK,aAAa,IAAI,CAAC,EAAE;AAClC;AAAA,IACF;AAGA,QAAI,KAAK,MAAM,aAAa,GAAG;AAC7B,UAAI,KAAK,KAAK,aAAa,IAAI,CAAC,EAAE;AAClC;AAAA,IACF;AAGA,QAAI,KAAK,KAAK,aAAa,IAAI,CAAC,EAAE;AAAA,EACpC;AAGA,MAAI,aAAa;AACf,QAAI,KAAK,IAAI,wOAA0C,CAAC;AAAA,EAC1D;AAEA,SAAO,IAAI,KAAK,IAAI;AACtB;AAEA,SAAS,aAAa,MAAsB;AAC1C,MAAI,SAAS,KAAK,QAAQ,kBAAkB,CAAC,GAAG,MAAM,KAAK,CAAC,CAAC;AAC7D,WAAS,OAAO,QAAQ,cAAc,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC;AACtD,WAAS,OAAO;AAAA,IACd;AAAA,IACA,CAAC,GAAG,OAAO,QAAQ,GAAG,KAAK,IAAI,IAAI,IAAI,GAAG,GAAG,CAAC;AAAA,EAChD;AACA,SAAO;AACT;AAEO,SAAS,mBACd,MACA,OACA,SACA,OACQ;AACR,QAAM,SAAS,KAAK,IAAI,IAAI,IAAI,YAAY,KAAK,GAAG;AACpD,QAAM,YAAY,KAAK,KAAK;AAC5B,QAAM,eAAe,QAClB,MAAM,IAAI,EACV,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,EAClC,KAAK,IAAI;AACZ,SAAO,GAAG,MAAM;AAAA,EAAK,SAAS;AAAA,EAAK,YAAY;AACjD;;;ADzGA,SAAS,kBAAkB;AAC3B,SAAS,cAAc,gBAAgB;AAGvC,IAAI;AACJ,IAAI;AAEJ,SAAS,YAAwB;AAC/B,MAAI,CAAC,SAAS;AACZ,UAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AAExD,UAAM,aAAa;AAAA,MACjB,KAAK,WAAW,MAAM,aAAa,kBAAkB;AAAA,MACrD,KAAK,WAAW,aAAa,kBAAkB;AAAA,IACjD;AACA,UAAM,aAAa,WAAW,KAAK,CAAC,MAAM,WAAW,CAAC,CAAC;AACvD,QAAI,CAAC,YAAY;AACf,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,cAAU,KAAK,MAAM,aAAa,YAAY,OAAO,CAAC;AAAA,EACxD;AACA,SAAO;AACT;AAEA,SAAS,aAAmC;AAC1C,MAAI,CAAC,UAAU;AACb,UAAM,SAAS,UAAU;AACzB,eAAW,oBAAI,IAAqB;AACpC,eAAW,QAAQ,OAAO,OAAO;AAC/B,eAAS,IAAI,KAAK,MAAM,IAAI;AAAA,IAC9B;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WAAW,OAAe,OAAuC;AACxE,QAAM,IAAI,MAAM,YAAY;AAE5B,QAAM,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC;AAC5C,MAAI,MAAO,QAAO;AAElB,QAAM,SAAS,MAAM,KAAK,CAAC,MAAM,EAAE,KAAK,SAAS,IAAI,CAAC,EAAE,CAAC;AACzD,MAAI,OAAQ,QAAO;AAEnB,QAAM,SAAS,MAAM,KAAK,CAAC,MAAM;AAC/B,UAAM,OAAO,EAAE,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK;AACxC,WAAO,KAAK,WAAW,CAAC;AAAA,EAC1B,CAAC;AACD,MAAI,OAAQ,QAAO;AAEnB,QAAM,WAAW,MAAM,KAAK,CAAC,MAAM,EAAE,KAAK,SAAS,CAAC,CAAC;AACrD,MAAI,SAAU,QAAO;AAErB,QAAM,aAAa,MAAM,KAAK,CAAC,MAAM,EAAE,MAAM,YAAY,EAAE,SAAS,CAAC,CAAC;AACtE,MAAI,WAAY,QAAO;AACvB,SAAO;AACT;AAEA,SAAS,YACP,OACA,QACqD;AACrD,QAAM,QAAQ,MACX,YAAY,EACZ,QAAQ,iBAAiB,GAAG,EAC5B,MAAM,KAAK,EACX,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAE7B,MAAI,MAAM,WAAW,EAAG,QAAO,CAAC;AAEhC,QAAM,UAAU,WAAW;AAC3B,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,OAAO,YAAY,IAAI;AACvC,QAAI,CAAC,QAAS;AACd,eAAW,SAAS,SAAS;AAC3B,aAAO,IAAI,MAAM,OAAO,OAAO,IAAI,MAAM,IAAI,KAAK,KAAK,MAAM,KAAK;AAAA,IACpE;AAAA,EACF;AAEA,QAAM,UAA+D,CAAC;AACtE,aAAW,CAAC,MAAM,KAAK,KAAK,QAAQ;AAClC,UAAM,OAAO,QAAQ,IAAI,IAAI;AAC7B,QAAI,CAAC,KAAM;AACX,UAAM,UAAU,eAAe,KAAK,SAAS,KAAK;AAClD,YAAQ,KAAK,EAAE,MAAM,OAAO,QAAQ,CAAC;AAAA,EACvC;AAEA,UAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACxC,SAAO,QAAQ,MAAM,GAAG,EAAE;AAC5B;AAEA,SAAS,eAAe,SAAiB,OAAyB;AAChE,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,QAAQ,MAAM,CAAC,EAAG,YAAY;AACpC,QAAI,MAAM,KAAK,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG;AACxC,YAAM,QAAQ,KAAK,IAAI,GAAG,IAAI,CAAC;AAC/B,YAAM,MAAM,KAAK,IAAI,MAAM,QAAQ,IAAI,CAAC;AACxC,aAAO,MAAM,MAAM,OAAO,GAAG,EAAE,KAAK,IAAI;AAAA,IAC1C;AAAA,EACF;AACA,SAAO,MAAM,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI;AACpC;AAEA,IAAM,YAAY;AAElB,SAAS,cAAc,KAAmB;AACxC,QAAM,WAAW,QAAQ;AACzB,MAAI,aAAa,SAAS;AACxB,IAAG,QAAK,aAAa,GAAG,KAAK,CAAC,UAAU;AACtC,UAAI,MAAO,SAAQ,IAAI,yBAAyB,GAAG,EAAE;AAAA,IACvD,CAAC;AAAA,EACH,OAAO;AACL,UAAM,MAAM,aAAa,WAAW,SAAS;AAC7C,IAAG,YAAS,KAAK,CAAC,GAAG,GAAG,CAAC,UAAU;AACjC,UAAI,MAAO,SAAQ,IAAI,yBAAyB,GAAG,EAAE;AAAA,IACvD,CAAC;AAAA,EACH;AACF;AAEO,SAAS,oBAAoB,SAAwB;AAC1D,QAAM,OAAO,QACV,QAAQ,MAAM,EACd,YAAY,+DAA+D;AAE9E,OACG,QAAQ,MAAM,EACd,YAAY,yCAAyC,EACrD,OAAO,YAAY;AAClB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAC9C,UAAM,SAAS,UAAU;AAEzB,QAAI,WAAW,QAAQ;AACrB,YAAM,OAAO,OAAO,MAAM,IAAI,CAAC,OAAO;AAAA,QACpC,MAAM,EAAE;AAAA,QACR,SAAS,EAAE;AAAA,QACX,OAAO,EAAE;AAAA,QACT,aAAa,EAAE;AAAA,MACjB,EAAE;AACF,cAAQ,IAAI,aAAa,MAAM,MAAM,CAAC;AACtC;AAAA,IACF;AAEA,UAAM,YAAY,oBAAI,IAAuB;AAC7C,eAAW,QAAQ,OAAO,OAAO;AAC/B,UAAI,CAAC,UAAU,IAAI,KAAK,OAAO,EAAG,WAAU,IAAI,KAAK,SAAS,CAAC,CAAC;AAChE,gBAAU,IAAI,KAAK,OAAO,EAAG,KAAK,IAAI;AAAA,IACxC;AAEA,eAAW,CAAC,SAAS,KAAK,KAAK,WAAW;AACxC,cAAQ,IAAI,KAAK;AAAA,IAAO,QAAQ,YAAY,CAAC,EAAE,CAAC;AAChD,iBAAW,QAAQ,OAAO;AACxB,cAAM,QAAQ,KAAK,KAAK,OAAO,EAAE;AACjC,gBAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,SAAS,KAAK,IAAI,CAAC,EAAE;AAAA,MAC1D;AAAA,IACF;AACA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,IAAI,KAAK,OAAO,SAAS,qCAAqC,CAAC;AAAA,EAC7E,CAAC;AAEH,OACG,QAAQ,cAAc,EACtB,YAAY,2CAA2C,EACvD,OAAO,OAAO,UAAkB;AAC/B,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAC9C,UAAM,SAAS,UAAU;AAEzB,UAAM,OAAO,WAAW,OAAO,OAAO,KAAK;AAC3C,QAAI,CAAC,MAAM;AACT,YAAM,cAAc,OAAO,MACxB,OAAO,CAAC,MAAM,EAAE,KAAK,SAAS,MAAM,YAAY,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,EAC9D,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,MAAM,EAAE,IAAI;AAEpB,YAAM,IAAI;AAAA,QACR,+BAA+B,KAAK;AAAA,QACpC;AAAA,QACA;AAAA,QACA,YAAY,SAAS,IACjB,iBAAiB,YAAY,KAAK,IAAI,CAAC;AAAA,sBACvC;AAAA,MACN;AAAA,IACF;AAEA,QAAI,WAAW,QAAQ;AACrB,cAAQ;AAAA,QACN;AAAA,UACE,EAAE,MAAM,KAAK,MAAM,SAAS,KAAK,SAAS,OAAO,KAAK,OAAO,SAAS,KAAK,QAAQ;AAAA,UACnF;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,YAAQ,IAAI,eAAe,KAAK,OAAO,CAAC;AAAA,EAC1C,CAAC;AAEH,OACG,QAAQ,gBAAgB,EACxB,YAAY,sBAAsB,EAClC,OAAO,OAAO,UAAkB;AAC/B,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAC9C,UAAM,SAAS,UAAU;AAEzB,UAAM,UAAU,YAAY,OAAO,MAAM;AAEzC,QAAI,QAAQ,WAAW,GAAG;AACxB,cAAQ,IAAI,IAAI,qBAAqB,KAAK,IAAI,CAAC;AAC/C,cAAQ,IAAI,IAAI,kDAAkD,CAAC;AACnE;AAAA,IACF;AAEA,QAAI,WAAW,QAAQ;AACrB,YAAM,OAAO,QAAQ,IAAI,CAAC,OAAO;AAAA,QAC/B,MAAM,EAAE,KAAK;AAAA,QACb,SAAS,EAAE,KAAK;AAAA,QAChB,OAAO,EAAE,KAAK;AAAA,QACd,OAAO,EAAE;AAAA,MACX,EAAE;AACF,cAAQ,IAAI,aAAa,MAAM,MAAM,CAAC;AACtC;AAAA,IACF;AAEA,YAAQ,IAAI,KAAK;AAAA,wBAA2B,KAAK;AAAA,CAAK,CAAC;AACvD,eAAW,KAAK,SAAS;AACvB,cAAQ,IAAI,OAAO,mBAAmB,EAAE,KAAK,MAAM,EAAE,KAAK,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC;AACpF,cAAQ,IAAI,EAAE;AAAA,IAChB;AACA,YAAQ;AAAA,MACN;AAAA,QACE,KAAK,QAAQ,MAAM,UAAU,QAAQ,WAAW,IAAI,KAAK,GAAG;AAAA,MAC9D;AAAA,IACF;AAAA,EACF,CAAC;AAEH,OACG,QAAQ,MAAM,EACd,YAAY,+DAA+D,EAC3E,OAAO,WAAW,2BAA2B,EAC7C,OAAO,gBAAgB,oBAAoB,GAAG,EAC9C,OAAO,OAAO,SAA4C;AACzD,UAAM,SAAS,KAAK;AACpB,UAAM,UAAU,KAAK,QAAQ,QAAQ;AAErC,QAAI,WAAW,OAAO,KAAK,CAAC,KAAK,OAAO;AACtC,YAAM,IAAI;AAAA,QACR,4BAA4B,OAAO;AAAA,QACnC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,UAAU;AACzB,UAAM,UAAU,uBAAuB,MAAM;AAC7C,UAAM,UAAU,SAAS,SAAS,OAAO;AACzC,YAAQ,IAAI,WAAW,OAAO,KAAK,OAAO,SAAS,kBAAkB;AAErE,eAAW,aAAa,CAAC,aAAa,WAAW,GAAG;AAClD,YAAM,YAAY,KAAK,QAAQ,SAAS;AACxC,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,WAAW,MAAM,SAAS,WAAW,OAAO;AAClD,YAAI,CAAC,SAAS,SAAS,QAAQ,GAAG;AAChC,gBAAM,YAAY,SAAS,SAAS,IAAI,IAAI,OAAO;AACnD,gBAAM;AAAA,YACJ;AAAA,YACA,WAAW,YAAY;AAAA,YACvB;AAAA,UACF;AACA,kBAAQ,IAAI,WAAW,SAAS,4BAA4B;AAAA,QAC9D;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAEH,OACG,QAAQ,aAAa,EACrB,YAAY,+BAA+B,EAC3C,OAAO,CAAC,UAAmB;AAC1B,UAAM,SAAS,UAAU;AACzB,QAAI,CAAC,OAAO;AACV,oBAAc,SAAS;AACvB;AAAA,IACF;AACA,UAAM,OAAO,WAAW,OAAO,OAAO,KAAK;AAC3C,QAAI,MAAM;AACR,oBAAc,GAAG,SAAS,GAAG,KAAK,IAAI,EAAE;AAAA,IAC1C,OAAO;AACL,oBAAc,SAAS;AACvB,cAAQ,IAAI,IAAI,UAAU,KAAK,qCAAqC,CAAC;AAAA,IACvE;AAAA,EACF,CAAC;AACL;AAEA,SAAS,uBAAuB,QAA4B;AAC1D,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,eAAe,OAAO,MACzB,OAAO,CAAC,MAAM,EAAE,YAAY,UAAU,EACtC,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAE9C,aAAW,QAAQ,cAAc;AAC/B,UAAM,OAAO,KAAK,eAAe,KAAK;AACtC,UAAM,KAAK,WAAW,KAAK,IAAI,SAAS,IAAI,EAAE;AAAA,EAChD;AAEA,QAAM,KAAK,IAAI,aAAa,EAAE;AAE9B,QAAM,aAAa,OAAO,MACvB,OAAO,CAAC,MAAM,EAAE,YAAY,OAAO,EACnC,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAE9C,aAAW,QAAQ,YAAY;AAC7B,UAAM,KAAK,OAAO,KAAK,SAAS,KAAK,IAAI,yBAAyB,KAAK,IAAI,IAAI;AAAA,EACjF;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAI,OAAO,SAAS;AAAA,IACpB;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -141,7 +141,7 @@ function checkCiEnvironment() {
141
141
  };
142
142
  }
143
143
  async function checkGpcVersion() {
144
- const currentVersion = "0.9.64";
144
+ const currentVersion = "0.9.65";
145
145
  if (currentVersion === "0.0.0") {
146
146
  return { name: "version", status: "info", message: "GPC development build" };
147
147
  }
@@ -800,4 +800,4 @@ export {
800
800
  checkVerificationDeadline,
801
801
  registerDoctorCommand
802
802
  };
803
- //# sourceMappingURL=doctor-FSUI44DD.js.map
803
+ //# sourceMappingURL=doctor-BSUL4C2Q.js.map
@@ -9,7 +9,7 @@ import { execFile } from "child_process";
9
9
  import { listAuditEvents } from "@gpc-cli/core";
10
10
  function registerFeedbackCommand(program) {
11
11
  program.command("feedback").description("Open a pre-filled GitHub issue with system diagnostics").option("--title <title>", "Issue title").option("--print", "Print the report to stdout instead of opening a browser").action(async (opts) => {
12
- const version = "0.9.64";
12
+ const version = "0.9.65";
13
13
  let lastCommand = "";
14
14
  try {
15
15
  const events = await listAuditEvents({ limit: 3 });
@@ -67,4 +67,4 @@ ${url}`);
67
67
  export {
68
68
  registerFeedbackCommand
69
69
  };
70
- //# sourceMappingURL=feedback-PDQU5E6S.js.map
70
+ //# sourceMappingURL=feedback-X5BBSC5I.js.map