@gitpagedocs/cli 1.1.62 → 1.1.63

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 (59) hide show
  1. package/README.md +193 -193
  2. package/ai/application/ai-command.ts +24 -24
  3. package/ai/application/ai-provider-factory.ts +22 -22
  4. package/ai/application/docs-pattern.ts +68 -68
  5. package/ai/application/run-ai-cli-command.ts +167 -167
  6. package/ai/config.ts +50 -50
  7. package/ai/core/models/ai-cli-config.ts +33 -33
  8. package/ai/core/models/parse-ai-cli-config.ts +78 -78
  9. package/ai/core/ports/illm-provider.ts +32 -32
  10. package/ai/infrastructure/ai-config-file.ts +101 -101
  11. package/ai/infrastructure/file-system-adapter.ts +85 -85
  12. package/ai/infrastructure/llm/tools-llm-provider.ts +54 -54
  13. package/ai/infrastructure/version-docs-writer.ts +143 -143
  14. package/ai/presentation/ai-prompts.ts +239 -239
  15. package/application/ports/cli-runtime-ports.ts +91 -91
  16. package/application/report/config-only-reporter.mjs +64 -64
  17. package/application/use-cases/dispatch-mode.ts +18 -18
  18. package/builders/config-orchestrator.mjs +34 -34
  19. package/builders/project-links.mjs +50 -50
  20. package/builders/root-config-builder.mjs +61 -61
  21. package/builders/route-builders.mjs +136 -136
  22. package/builders/theme-template.mjs +76 -76
  23. package/builders/version-config-builder.mjs +186 -186
  24. package/content/docs-en.mjs +549 -549
  25. package/content/docs-es.mjs +462 -462
  26. package/content/docs-pt.mjs +462 -462
  27. package/contracts/doc-versions.mjs +3 -3
  28. package/data/default-site-config.mjs +321 -321
  29. package/data/i18n-langmenu.mjs +347 -347
  30. package/data/layouts.mjs +436 -436
  31. package/data/path-mappings.mjs +26 -26
  32. package/data/route-metas.mjs +93 -93
  33. package/data/theme-colors.mjs +443 -443
  34. package/data/urls.mjs +12 -12
  35. package/domain/models/cli-options.ts +33 -33
  36. package/home/constants.mjs +4 -4
  37. package/index.mjs +37 -37
  38. package/infrastructure/gitpagedocs-config-file.ts +47 -47
  39. package/infrastructure/home/runtime.mjs +37 -37
  40. package/package.json +3 -3
  41. package/presentation/commands/ai-info.ts +57 -57
  42. package/presentation/commands/config-clear.ts +23 -23
  43. package/presentation/commands/config-info.ts +24 -24
  44. package/presentation/commands/diagnostics.ts +164 -164
  45. package/presentation/commands/docs.ts +37 -37
  46. package/presentation/commands/mcp.ts +20 -20
  47. package/presentation/commands/pages.ts +101 -101
  48. package/presentation/commands/password.ts +62 -62
  49. package/presentation/commands/run-command.ts +70 -70
  50. package/presentation/index.ts +124 -124
  51. package/presentation/options/parser.ts +119 -119
  52. package/presentation/options/resolver.ts +46 -46
  53. package/presentation/ui/clack.ts +91 -91
  54. package/presentation/ui/prompts.ts +146 -146
  55. package/runtime/git-ops.mjs +110 -110
  56. package/runtime/output.mjs +159 -159
  57. package/runtime/workflow.mjs +129 -129
  58. package/start.mjs +12 -12
  59. package/ui/logger.mjs +9 -9
@@ -1,119 +1,119 @@
1
- import type { CliOptions } from "../../domain/models/cli-options";
2
- import { DEFAULTS } from "./schema";
3
- import { normalizeLayoutsDir } from "../../contracts/layouts-paths.mjs";
4
-
5
- const KNOWN_FLAGS = new Set([
6
- "--build",
7
- "--serve",
8
- "--layoutconfig",
9
- "--full",
10
- "--push",
11
- "--home",
12
- "--search",
13
- "--path",
14
- "--output",
15
- "--layouts-dir",
16
- "--interactive",
17
- "-i",
18
- "--no-interactive",
19
- "--yes",
20
- "-y",
21
- "--ai",
22
- "--pages-actions",
23
- ]);
24
-
25
- function readOptionValue(args: string[], optionName: string): string {
26
- const equalsArg = args.find((a) => a.startsWith(`${optionName}=`));
27
- if (equalsArg) return equalsArg.slice(optionName.length + 1).trim();
28
- const index = args.indexOf(optionName);
29
- if (index >= 0) {
30
- const next = args[index + 1];
31
- if (next && !next.startsWith("--")) return next.trim();
32
- }
33
- return "";
34
- }
35
-
36
- export function parseCliOptions(argv: string[], env: NodeJS.ProcessEnv): CliOptions {
37
- const args = argv.slice(2);
38
-
39
- let githubOwner = readOptionValue(args, "--owner");
40
- let githubRepo = readOptionValue(args, "--repo");
41
- const docsPath = readOptionValue(args, "--path");
42
- const outputDir = readOptionValue(args, "--output");
43
- const layoutsDir = readOptionValue(args, "--layouts-dir");
44
- const searchRaw = readOptionValue(args, "--search");
45
-
46
- const fallbackDashedArgs = args
47
- .filter((a) => a.startsWith("--"))
48
- .filter((a) => !KNOWN_FLAGS.has(a))
49
- .filter((a) => !a.startsWith("--owner"))
50
- .filter((a) => !a.startsWith("--repo"))
51
- .filter((a) => !a.startsWith("--path"))
52
- .filter((a) => !a.startsWith("--home"))
53
- .filter((a) => !a.startsWith("--output"))
54
- .filter((a) => !a.startsWith("--layouts-dir"))
55
- .filter((a) => !a.startsWith("--search"))
56
- .map((a) => a.replace(/^--/, "").trim())
57
- .filter(Boolean);
58
-
59
- if (!githubOwner && fallbackDashedArgs[0]) githubOwner = fallbackDashedArgs[0];
60
- if (!githubRepo && fallbackDashedArgs[1]) githubRepo = fallbackDashedArgs[1];
61
-
62
- // New verb aliases (Phase 6) that map onto existing modes without new modes.
63
- const command = args[0];
64
- const isDocument = command === "document" || (command?.startsWith("document:") ?? false);
65
- const isDeploy = command === "deploy" || command === "pages";
66
-
67
- const isBuild = args.includes("--build") || env.GITPAGEDOCS_BUILD === "1";
68
- const isServe = args.includes("--serve");
69
- const useLocalLayoutConfig = args.includes("--layoutconfig");
70
- const shouldPush = args.includes("--push") || isDeploy;
71
- const isHome = args.includes("--home");
72
- const isInteractive = args.includes("--interactive") || args.includes("-i");
73
- const isAi = command === "ai" || args.includes("--ai") || isDocument;
74
- const aiCommand =
75
- command === "ai"
76
- ? args[1]
77
- : command === "document"
78
- ? args[1] ?? "repo"
79
- : command?.startsWith("document:")
80
- ? command.split(":")[1]
81
- : undefined;
82
-
83
- const mode: import("../../domain/models/cli-options").CliMode = isAi ? "ai" : isHome ? "home" : args.includes("--full") ? "full" : "config-only";
84
- const repositorySearch =
85
- searchRaw === "true"
86
- ? true
87
- : searchRaw === "false"
88
- ? false
89
- : isHome
90
- ? DEFAULTS.home.repositorySearch
91
- : undefined;
92
-
93
- const normalizedPath = docsPath.trim();
94
-
95
- return {
96
- isBuild,
97
- isServe,
98
- mode,
99
- aiCommand,
100
- outputDir: outputDir || (isHome ? DEFAULTS.home.outputDir : DEFAULTS.outputDir),
101
- layoutsDir: normalizeLayoutsDir(layoutsDir || DEFAULTS.layoutsDir),
102
- useLocalLayoutConfig,
103
- shouldPush,
104
- githubOwner,
105
- githubRepo,
106
- docsPath: normalizedPath,
107
- basePath: normalizedPath,
108
- repositorySearch,
109
- isInteractive,
110
- hasArgs: args.length > 0,
111
- explicit: {
112
- useLocalLayoutConfig,
113
- layoutsDir: Boolean(layoutsDir),
114
- githubOwner: Boolean(githubOwner),
115
- githubRepo: Boolean(githubRepo),
116
- outputDir: Boolean(outputDir),
117
- },
118
- };
119
- }
1
+ import type { CliOptions } from "../../domain/models/cli-options";
2
+ import { DEFAULTS } from "./schema";
3
+ import { normalizeLayoutsDir } from "../../contracts/layouts-paths.mjs";
4
+
5
+ const KNOWN_FLAGS = new Set([
6
+ "--build",
7
+ "--serve",
8
+ "--layoutconfig",
9
+ "--full",
10
+ "--push",
11
+ "--home",
12
+ "--search",
13
+ "--path",
14
+ "--output",
15
+ "--layouts-dir",
16
+ "--interactive",
17
+ "-i",
18
+ "--no-interactive",
19
+ "--yes",
20
+ "-y",
21
+ "--ai",
22
+ "--pages-actions",
23
+ ]);
24
+
25
+ function readOptionValue(args: string[], optionName: string): string {
26
+ const equalsArg = args.find((a) => a.startsWith(`${optionName}=`));
27
+ if (equalsArg) return equalsArg.slice(optionName.length + 1).trim();
28
+ const index = args.indexOf(optionName);
29
+ if (index >= 0) {
30
+ const next = args[index + 1];
31
+ if (next && !next.startsWith("--")) return next.trim();
32
+ }
33
+ return "";
34
+ }
35
+
36
+ export function parseCliOptions(argv: string[], env: NodeJS.ProcessEnv): CliOptions {
37
+ const args = argv.slice(2);
38
+
39
+ let githubOwner = readOptionValue(args, "--owner");
40
+ let githubRepo = readOptionValue(args, "--repo");
41
+ const docsPath = readOptionValue(args, "--path");
42
+ const outputDir = readOptionValue(args, "--output");
43
+ const layoutsDir = readOptionValue(args, "--layouts-dir");
44
+ const searchRaw = readOptionValue(args, "--search");
45
+
46
+ const fallbackDashedArgs = args
47
+ .filter((a) => a.startsWith("--"))
48
+ .filter((a) => !KNOWN_FLAGS.has(a))
49
+ .filter((a) => !a.startsWith("--owner"))
50
+ .filter((a) => !a.startsWith("--repo"))
51
+ .filter((a) => !a.startsWith("--path"))
52
+ .filter((a) => !a.startsWith("--home"))
53
+ .filter((a) => !a.startsWith("--output"))
54
+ .filter((a) => !a.startsWith("--layouts-dir"))
55
+ .filter((a) => !a.startsWith("--search"))
56
+ .map((a) => a.replace(/^--/, "").trim())
57
+ .filter(Boolean);
58
+
59
+ if (!githubOwner && fallbackDashedArgs[0]) githubOwner = fallbackDashedArgs[0];
60
+ if (!githubRepo && fallbackDashedArgs[1]) githubRepo = fallbackDashedArgs[1];
61
+
62
+ // New verb aliases (Phase 6) that map onto existing modes without new modes.
63
+ const command = args[0];
64
+ const isDocument = command === "document" || (command?.startsWith("document:") ?? false);
65
+ const isDeploy = command === "deploy" || command === "pages";
66
+
67
+ const isBuild = args.includes("--build") || env.GITPAGEDOCS_BUILD === "1";
68
+ const isServe = args.includes("--serve");
69
+ const useLocalLayoutConfig = args.includes("--layoutconfig");
70
+ const shouldPush = args.includes("--push") || isDeploy;
71
+ const isHome = args.includes("--home");
72
+ const isInteractive = args.includes("--interactive") || args.includes("-i");
73
+ const isAi = command === "ai" || args.includes("--ai") || isDocument;
74
+ const aiCommand =
75
+ command === "ai"
76
+ ? args[1]
77
+ : command === "document"
78
+ ? args[1] ?? "repo"
79
+ : command?.startsWith("document:")
80
+ ? command.split(":")[1]
81
+ : undefined;
82
+
83
+ const mode: import("../../domain/models/cli-options").CliMode = isAi ? "ai" : isHome ? "home" : args.includes("--full") ? "full" : "config-only";
84
+ const repositorySearch =
85
+ searchRaw === "true"
86
+ ? true
87
+ : searchRaw === "false"
88
+ ? false
89
+ : isHome
90
+ ? DEFAULTS.home.repositorySearch
91
+ : undefined;
92
+
93
+ const normalizedPath = docsPath.trim();
94
+
95
+ return {
96
+ isBuild,
97
+ isServe,
98
+ mode,
99
+ aiCommand,
100
+ outputDir: outputDir || (isHome ? DEFAULTS.home.outputDir : DEFAULTS.outputDir),
101
+ layoutsDir: normalizeLayoutsDir(layoutsDir || DEFAULTS.layoutsDir),
102
+ useLocalLayoutConfig,
103
+ shouldPush,
104
+ githubOwner,
105
+ githubRepo,
106
+ docsPath: normalizedPath,
107
+ basePath: normalizedPath,
108
+ repositorySearch,
109
+ isInteractive,
110
+ hasArgs: args.length > 0,
111
+ explicit: {
112
+ useLocalLayoutConfig,
113
+ layoutsDir: Boolean(layoutsDir),
114
+ githubOwner: Boolean(githubOwner),
115
+ githubRepo: Boolean(githubRepo),
116
+ outputDir: Boolean(outputDir),
117
+ },
118
+ };
119
+ }
@@ -1,46 +1,46 @@
1
- import type { CliOptions } from "../../domain/models/cli-options";
2
- import { parseCliOptions } from "./parser";
3
- import {
4
- shouldRunInteractive,
5
- promptConfigOnlyOptions,
6
- promptHomeOptions,
7
- promptDeployOptions,
8
- ensureGitRepoInteractive,
9
- interactivePromptsAvailable,
10
- } from "../ui/prompts";
11
- import { DEFAULTS } from "./schema";
12
- // @ts-expect-error .mjs runtime module is type-less in this package.
13
- import { detectRepoFromGit } from "../../runtime/git-ops.mjs";
14
-
15
- export async function resolveOptions(argv: string[], env: NodeJS.ProcessEnv): Promise<CliOptions> {
16
- const parsed = parseCliOptions(argv, env);
17
-
18
- if (parsed.mode === "home") {
19
- parsed.repositorySearch = parsed.repositorySearch ?? DEFAULTS.home.repositorySearch;
20
- parsed.basePath = parsed.basePath ?? parsed.docsPath ?? DEFAULTS.home.basePath;
21
- }
22
-
23
- // `deploy` / `--push` need owner + repo AND a git repo. If anything is
24
- // missing, prompt interactively (owner/repo pre-filled from the git origin
25
- // remote; offer to `git init`) instead of throwing. In CI/non-TTY we fall
26
- // through so the explicit guards in the push flow still fire clearly.
27
- if (parsed.shouldPush && interactivePromptsAvailable()) {
28
- let resolved = parsed;
29
- if (!parsed.githubOwner || !parsed.githubRepo) {
30
- const detected = detectRepoFromGit(process.cwd()) as { owner: string; repo: string } | null;
31
- resolved = await promptDeployOptions(parsed, detected);
32
- }
33
- await ensureGitRepoInteractive(process.cwd());
34
- return resolved;
35
- }
36
-
37
- // Every command prompts in a real terminal; shouldRunInteractive owns the
38
- // CI / piped-stdin / --no-interactive opt-outs, and each prompt asks only for
39
- // what the command line left unanswered.
40
- if (!shouldRunInteractive(argv)) return parsed;
41
-
42
- if (parsed.mode === "home") return promptHomeOptions(parsed);
43
- if (parsed.mode === "config-only") return promptConfigOnlyOptions(parsed);
44
-
45
- return parsed;
46
- }
1
+ import type { CliOptions } from "../../domain/models/cli-options";
2
+ import { parseCliOptions } from "./parser";
3
+ import {
4
+ shouldRunInteractive,
5
+ promptConfigOnlyOptions,
6
+ promptHomeOptions,
7
+ promptDeployOptions,
8
+ ensureGitRepoInteractive,
9
+ interactivePromptsAvailable,
10
+ } from "../ui/prompts";
11
+ import { DEFAULTS } from "./schema";
12
+ // @ts-expect-error .mjs runtime module is type-less in this package.
13
+ import { detectRepoFromGit } from "../../runtime/git-ops.mjs";
14
+
15
+ export async function resolveOptions(argv: string[], env: NodeJS.ProcessEnv): Promise<CliOptions> {
16
+ const parsed = parseCliOptions(argv, env);
17
+
18
+ if (parsed.mode === "home") {
19
+ parsed.repositorySearch = parsed.repositorySearch ?? DEFAULTS.home.repositorySearch;
20
+ parsed.basePath = parsed.basePath ?? parsed.docsPath ?? DEFAULTS.home.basePath;
21
+ }
22
+
23
+ // `deploy` / `--push` need owner + repo AND a git repo. If anything is
24
+ // missing, prompt interactively (owner/repo pre-filled from the git origin
25
+ // remote; offer to `git init`) instead of throwing. In CI/non-TTY we fall
26
+ // through so the explicit guards in the push flow still fire clearly.
27
+ if (parsed.shouldPush && interactivePromptsAvailable()) {
28
+ let resolved = parsed;
29
+ if (!parsed.githubOwner || !parsed.githubRepo) {
30
+ const detected = detectRepoFromGit(process.cwd()) as { owner: string; repo: string } | null;
31
+ resolved = await promptDeployOptions(parsed, detected);
32
+ }
33
+ await ensureGitRepoInteractive(process.cwd());
34
+ return resolved;
35
+ }
36
+
37
+ // Every command prompts in a real terminal; shouldRunInteractive owns the
38
+ // CI / piped-stdin / --no-interactive opt-outs, and each prompt asks only for
39
+ // what the command line left unanswered.
40
+ if (!shouldRunInteractive(argv)) return parsed;
41
+
42
+ if (parsed.mode === "home") return promptHomeOptions(parsed);
43
+ if (parsed.mode === "config-only") return promptConfigOnlyOptions(parsed);
44
+
45
+ return parsed;
46
+ }
@@ -1,91 +1,91 @@
1
- /**
2
- * Thin, cancellation-aware wrappers over @clack/prompts. Centralizes the
3
- * isCancel handling so prompt modules stay declarative and a Ctrl-C exits
4
- * cleanly (mirroring the previous inquirer behaviour).
5
- */
6
- import {
7
- text,
8
- password,
9
- confirm,
10
- select,
11
- multiselect,
12
- isCancel,
13
- cancel,
14
- } from "@clack/prompts";
15
-
16
- function exitIfCancelled<T>(value: T | symbol): T {
17
- if (isCancel(value)) {
18
- cancel("Operation cancelled.");
19
- process.exit(0);
20
- }
21
- return value as T;
22
- }
23
-
24
- export interface AskTextOptions {
25
- message: string;
26
- defaultValue?: string;
27
- placeholder?: string;
28
- validate?: (value: string) => string | undefined;
29
- }
30
-
31
- export async function askText(options: AskTextOptions): Promise<string> {
32
- const result = await text({
33
- message: options.message,
34
- placeholder: options.placeholder,
35
- defaultValue: options.defaultValue,
36
- initialValue: undefined,
37
- validate: options.validate
38
- ? (value) => options.validate?.(value ?? "")
39
- : undefined,
40
- });
41
- return exitIfCancelled(result);
42
- }
43
-
44
- export interface AskPasswordOptions {
45
- message: string;
46
- validate?: (value: string) => string | undefined;
47
- }
48
-
49
- /** Masked password prompt (input hidden as the user types). */
50
- export async function askPassword(options: AskPasswordOptions): Promise<string> {
51
- const result = await password({
52
- message: options.message,
53
- validate: options.validate
54
- ? (value) => options.validate?.(value ?? "")
55
- : undefined,
56
- });
57
- return exitIfCancelled(result);
58
- }
59
-
60
- export async function askConfirm(message: string, initialValue = false): Promise<boolean> {
61
- const result = await confirm({ message, initialValue });
62
- return exitIfCancelled(result);
63
- }
64
-
65
- export interface Choice<T extends string> {
66
- value: T;
67
- label: string;
68
- hint?: string;
69
- }
70
-
71
- export async function askSelect<T extends string>(
72
- message: string,
73
- options: Choice<T>[],
74
- initialValue?: T,
75
- ): Promise<T> {
76
- // clack's Option<Value> is a conditional type TS can't match against a generic
77
- // Choice<T> (identical shape); cast at the boundary, inference flows from initialValue.
78
- const result = await select<T>({ message, options: options as never, initialValue });
79
- return exitIfCancelled(result);
80
- }
81
-
82
- export async function askMultiSelect<T extends string>(
83
- message: string,
84
- options: Choice<T>[],
85
- initialValues?: T[],
86
- ): Promise<T[]> {
87
- const result = await multiselect<T>({ message, options: options as never, initialValues, required: true });
88
- return exitIfCancelled(result);
89
- }
90
-
91
- export { intro, outro, note, spinner } from "@clack/prompts";
1
+ /**
2
+ * Thin, cancellation-aware wrappers over @clack/prompts. Centralizes the
3
+ * isCancel handling so prompt modules stay declarative and a Ctrl-C exits
4
+ * cleanly (mirroring the previous inquirer behaviour).
5
+ */
6
+ import {
7
+ text,
8
+ password,
9
+ confirm,
10
+ select,
11
+ multiselect,
12
+ isCancel,
13
+ cancel,
14
+ } from "@clack/prompts";
15
+
16
+ function exitIfCancelled<T>(value: T | symbol): T {
17
+ if (isCancel(value)) {
18
+ cancel("Operation cancelled.");
19
+ process.exit(0);
20
+ }
21
+ return value as T;
22
+ }
23
+
24
+ export interface AskTextOptions {
25
+ message: string;
26
+ defaultValue?: string;
27
+ placeholder?: string;
28
+ validate?: (value: string) => string | undefined;
29
+ }
30
+
31
+ export async function askText(options: AskTextOptions): Promise<string> {
32
+ const result = await text({
33
+ message: options.message,
34
+ placeholder: options.placeholder,
35
+ defaultValue: options.defaultValue,
36
+ initialValue: undefined,
37
+ validate: options.validate
38
+ ? (value) => options.validate?.(value ?? "")
39
+ : undefined,
40
+ });
41
+ return exitIfCancelled(result);
42
+ }
43
+
44
+ export interface AskPasswordOptions {
45
+ message: string;
46
+ validate?: (value: string) => string | undefined;
47
+ }
48
+
49
+ /** Masked password prompt (input hidden as the user types). */
50
+ export async function askPassword(options: AskPasswordOptions): Promise<string> {
51
+ const result = await password({
52
+ message: options.message,
53
+ validate: options.validate
54
+ ? (value) => options.validate?.(value ?? "")
55
+ : undefined,
56
+ });
57
+ return exitIfCancelled(result);
58
+ }
59
+
60
+ export async function askConfirm(message: string, initialValue = false): Promise<boolean> {
61
+ const result = await confirm({ message, initialValue });
62
+ return exitIfCancelled(result);
63
+ }
64
+
65
+ export interface Choice<T extends string> {
66
+ value: T;
67
+ label: string;
68
+ hint?: string;
69
+ }
70
+
71
+ export async function askSelect<T extends string>(
72
+ message: string,
73
+ options: Choice<T>[],
74
+ initialValue?: T,
75
+ ): Promise<T> {
76
+ // clack's Option<Value> is a conditional type TS can't match against a generic
77
+ // Choice<T> (identical shape); cast at the boundary, inference flows from initialValue.
78
+ const result = await select<T>({ message, options: options as never, initialValue });
79
+ return exitIfCancelled(result);
80
+ }
81
+
82
+ export async function askMultiSelect<T extends string>(
83
+ message: string,
84
+ options: Choice<T>[],
85
+ initialValues?: T[],
86
+ ): Promise<T[]> {
87
+ const result = await multiselect<T>({ message, options: options as never, initialValues, required: true });
88
+ return exitIfCancelled(result);
89
+ }
90
+
91
+ export { intro, outro, note, spinner } from "@clack/prompts";