@gitpagedocs/cli 1.1.61 → 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.
- package/README.md +193 -191
- package/ai/application/ai-command.ts +24 -24
- package/ai/application/ai-provider-factory.ts +22 -22
- package/ai/application/docs-pattern.ts +68 -68
- package/ai/application/run-ai-cli-command.ts +167 -167
- package/ai/config.ts +50 -50
- package/ai/core/models/ai-cli-config.ts +33 -33
- package/ai/core/models/parse-ai-cli-config.ts +78 -78
- package/ai/core/ports/illm-provider.ts +32 -32
- package/ai/infrastructure/ai-config-file.ts +101 -101
- package/ai/infrastructure/file-system-adapter.ts +85 -85
- package/ai/infrastructure/llm/tools-llm-provider.ts +54 -54
- package/ai/infrastructure/version-docs-writer.ts +143 -143
- package/ai/presentation/ai-prompts.ts +239 -239
- package/application/config-only/handler.mjs +2 -0
- package/application/home/handler.mjs +2 -0
- package/application/ports/cli-runtime-ports.ts +91 -87
- package/application/report/config-only-reporter.mjs +64 -63
- package/application/use-cases/dispatch-mode.ts +18 -18
- package/builders/config-orchestrator.mjs +34 -34
- package/builders/project-links.mjs +50 -26
- package/builders/root-config-builder.d.mts +16 -0
- package/builders/root-config-builder.mjs +61 -53
- package/builders/route-builders.mjs +136 -136
- package/builders/theme-template.mjs +76 -76
- package/builders/version-config-builder.mjs +186 -186
- package/content/docs-en.mjs +549 -545
- package/content/docs-es.mjs +462 -460
- package/content/docs-pt.mjs +462 -460
- package/contracts/doc-versions.mjs +3 -3
- package/contracts/index.mjs +10 -0
- package/contracts/layouts-paths.d.mts +17 -0
- package/contracts/layouts-paths.mjs +68 -0
- package/data/default-site-config.mjs +321 -321
- package/data/i18n-langmenu.mjs +347 -347
- package/data/layouts.mjs +436 -436
- package/data/path-mappings.mjs +26 -26
- package/data/route-metas.mjs +93 -93
- package/data/theme-colors.mjs +443 -443
- package/data/urls.mjs +12 -12
- package/domain/models/cli-options.ts +33 -18
- package/domain/services/layouts-migration.d.mts +15 -0
- package/domain/services/layouts-migration.mjs +60 -0
- package/home/constants.mjs +4 -4
- package/index.mjs +37 -37
- package/infrastructure/gitpagedocs-config-file.ts +47 -47
- package/infrastructure/home/runtime.mjs +37 -37
- package/package.json +3 -3
- package/presentation/commands/ai-info.ts +57 -57
- package/presentation/commands/config-clear.ts +23 -23
- package/presentation/commands/config-info.ts +24 -24
- package/presentation/commands/diagnostics.ts +164 -164
- package/presentation/commands/docs.ts +37 -37
- package/presentation/commands/mcp.ts +20 -20
- package/presentation/commands/pages.ts +101 -101
- package/presentation/commands/password.ts +62 -62
- package/presentation/commands/run-command.ts +70 -70
- package/presentation/index.ts +124 -116
- package/presentation/options/parser.ts +119 -104
- package/presentation/options/resolver.ts +46 -48
- package/presentation/options/schema.ts +4 -0
- package/presentation/ui/clack.ts +91 -91
- package/presentation/ui/layouts-prompts.ts +124 -0
- package/presentation/ui/prompts.ts +146 -138
- package/presentation/ui/tty.ts +37 -0
- package/runtime/git-ops.mjs +110 -110
- package/runtime/layouts-migrator.d.mts +11 -0
- package/runtime/layouts-migrator.mjs +103 -0
- package/runtime/output.mjs +159 -146
- package/runtime/workflow.mjs +129 -129
- package/start.mjs +12 -12
- package/ui/logger.mjs +9 -9
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
import { NodeCryptoService, deriveDocAccessKeys } from "@gitpagedocs/tools";
|
|
2
|
-
import type { CommandContext } from "./run-command";
|
|
3
|
-
import { askPassword, note, outro } from "../ui/clack";
|
|
4
|
-
import { interactivePromptsAvailable } from "../ui/prompts";
|
|
5
|
-
import { GitPageDocsConfigRepository } from "../../infrastructure/gitpagedocs-config-file";
|
|
6
|
-
|
|
7
|
-
const MIN_PASSWORD_LENGTH = 4;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* `gitpagedocs password` — interactively set a documentation access password.
|
|
11
|
-
*
|
|
12
|
-
* Type + confirm a password, derive the double-hash key pair, write the PUBLIC
|
|
13
|
-
* key into gitpagedocs/config.json (which makes the frontend gate the docs), and
|
|
14
|
-
* print the PRIVATE key for the user to copy. The password itself is never stored.
|
|
15
|
-
*/
|
|
16
|
-
export async function runPassword(ctx: CommandContext): Promise<void> {
|
|
17
|
-
if (!interactivePromptsAvailable()) {
|
|
18
|
-
// eslint-disable-next-line no-console
|
|
19
|
-
console.log("\n `gitpagedocs password` is interactive — run it in a terminal (TTY).\n");
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const password = await askPassword({
|
|
24
|
-
message: "Documentation password:",
|
|
25
|
-
validate: (v) =>
|
|
26
|
-
v && v.trim().length >= MIN_PASSWORD_LENGTH
|
|
27
|
-
? undefined
|
|
28
|
-
: `Use at least ${MIN_PASSWORD_LENGTH} characters.`,
|
|
29
|
-
});
|
|
30
|
-
const confirmation = await askPassword({
|
|
31
|
-
message: "Confirm password:",
|
|
32
|
-
validate: (v) => (v ? undefined : "Required."),
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
if (password !== confirmation) {
|
|
36
|
-
note("Passwords do not match. Nothing was changed.", "Aborted");
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const { privateKey, publicKey } = await deriveDocAccessKeys(password, new NodeCryptoService());
|
|
41
|
-
|
|
42
|
-
let configPath: string;
|
|
43
|
-
try {
|
|
44
|
-
configPath = await new GitPageDocsConfigRepository(ctx.cwd).patchDocsAccess(publicKey);
|
|
45
|
-
} catch (error) {
|
|
46
|
-
note(error instanceof Error ? error.message : String(error), "Could not save");
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
note(
|
|
51
|
-
`Public key saved to ${configPath}\nThe documentation is now password-protected.`,
|
|
52
|
-
"Saved",
|
|
53
|
-
);
|
|
54
|
-
// eslint-disable-next-line no-console
|
|
55
|
-
console.log(
|
|
56
|
-
"\n PRIVATE KEY (copy & keep it safe — it also unlocks the docs):\n\n" +
|
|
57
|
-
` ${privateKey}\n\n` +
|
|
58
|
-
" Readers can unlock with the password OR this private key.\n" +
|
|
59
|
-
" To remove protection, set site.docsAccess.enabled to false in config.json.\n",
|
|
60
|
-
);
|
|
61
|
-
outro("Done.");
|
|
62
|
-
}
|
|
1
|
+
import { NodeCryptoService, deriveDocAccessKeys } from "@gitpagedocs/tools";
|
|
2
|
+
import type { CommandContext } from "./run-command";
|
|
3
|
+
import { askPassword, note, outro } from "../ui/clack";
|
|
4
|
+
import { interactivePromptsAvailable } from "../ui/prompts";
|
|
5
|
+
import { GitPageDocsConfigRepository } from "../../infrastructure/gitpagedocs-config-file";
|
|
6
|
+
|
|
7
|
+
const MIN_PASSWORD_LENGTH = 4;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* `gitpagedocs password` — interactively set a documentation access password.
|
|
11
|
+
*
|
|
12
|
+
* Type + confirm a password, derive the double-hash key pair, write the PUBLIC
|
|
13
|
+
* key into gitpagedocs/config.json (which makes the frontend gate the docs), and
|
|
14
|
+
* print the PRIVATE key for the user to copy. The password itself is never stored.
|
|
15
|
+
*/
|
|
16
|
+
export async function runPassword(ctx: CommandContext): Promise<void> {
|
|
17
|
+
if (!interactivePromptsAvailable()) {
|
|
18
|
+
// eslint-disable-next-line no-console
|
|
19
|
+
console.log("\n `gitpagedocs password` is interactive — run it in a terminal (TTY).\n");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const password = await askPassword({
|
|
24
|
+
message: "Documentation password:",
|
|
25
|
+
validate: (v) =>
|
|
26
|
+
v && v.trim().length >= MIN_PASSWORD_LENGTH
|
|
27
|
+
? undefined
|
|
28
|
+
: `Use at least ${MIN_PASSWORD_LENGTH} characters.`,
|
|
29
|
+
});
|
|
30
|
+
const confirmation = await askPassword({
|
|
31
|
+
message: "Confirm password:",
|
|
32
|
+
validate: (v) => (v ? undefined : "Required."),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (password !== confirmation) {
|
|
36
|
+
note("Passwords do not match. Nothing was changed.", "Aborted");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const { privateKey, publicKey } = await deriveDocAccessKeys(password, new NodeCryptoService());
|
|
41
|
+
|
|
42
|
+
let configPath: string;
|
|
43
|
+
try {
|
|
44
|
+
configPath = await new GitPageDocsConfigRepository(ctx.cwd).patchDocsAccess(publicKey);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
note(error instanceof Error ? error.message : String(error), "Could not save");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
note(
|
|
51
|
+
`Public key saved to ${configPath}\nThe documentation is now password-protected.`,
|
|
52
|
+
"Saved",
|
|
53
|
+
);
|
|
54
|
+
// eslint-disable-next-line no-console
|
|
55
|
+
console.log(
|
|
56
|
+
"\n PRIVATE KEY (copy & keep it safe — it also unlocks the docs):\n\n" +
|
|
57
|
+
` ${privateKey}\n\n` +
|
|
58
|
+
" Readers can unlock with the password OR this private key.\n" +
|
|
59
|
+
" To remove protection, set site.docsAccess.enabled to false in config.json.\n",
|
|
60
|
+
);
|
|
61
|
+
outro("Done.");
|
|
62
|
+
}
|
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* New-verb command layer (Phase 6). Intercepts the informational/utility
|
|
3
|
-
* commands that are NOT part of the legacy flag flow (version, doctor, provider,
|
|
4
|
-
* models, config, mcp, update) and routes them to thin handlers that consume
|
|
5
|
-
* @gitpagedocs/tools. Alias verbs (init, document, deploy, pages) are mapped in
|
|
6
|
-
* the parser and fall through to the legacy dispatch, so this returns false for
|
|
7
|
-
* them.
|
|
8
|
-
*/
|
|
9
|
-
export interface CommandContext {
|
|
10
|
-
argv: string[];
|
|
11
|
-
args: string[];
|
|
12
|
-
pkgRoot: string;
|
|
13
|
-
cwd: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type CommandHandler = (ctx: CommandContext) => Promise<void>;
|
|
17
|
-
|
|
18
|
-
import { runVersion, runDoctor, runUpdate } from "./diagnostics";
|
|
19
|
-
import { runProvider, runModels } from "./ai-info";
|
|
20
|
-
import { runConfig } from "./config-info";
|
|
21
|
-
import { runConfigClear } from "./config-clear";
|
|
22
|
-
import { runMcp } from "./mcp";
|
|
23
|
-
import { runDocs } from "./docs";
|
|
24
|
-
import { runPagesActions, runPagesDeploy } from "./pages";
|
|
25
|
-
import { runPassword } from "./password";
|
|
26
|
-
|
|
27
|
-
const REGISTRY: Record<string, CommandHandler> = {
|
|
28
|
-
version: runVersion,
|
|
29
|
-
"--version": runVersion,
|
|
30
|
-
"-v": runVersion,
|
|
31
|
-
doctor: runDoctor,
|
|
32
|
-
update: runUpdate,
|
|
33
|
-
provider: runProvider,
|
|
34
|
-
providers: runProvider,
|
|
35
|
-
models: runModels,
|
|
36
|
-
config: runConfig,
|
|
37
|
-
mcp: runMcp,
|
|
38
|
-
docs: runDocs,
|
|
39
|
-
password: runPassword,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
/** Returns true if a new command handled the invocation (skip legacy flow). */
|
|
43
|
-
export async function runNewCommand(argv: string[], pkgRoot: string): Promise<boolean> {
|
|
44
|
-
const args = argv.slice(2);
|
|
45
|
-
const ctx: CommandContext = { argv, args, pkgRoot, cwd: process.cwd() };
|
|
46
|
-
|
|
47
|
-
// Configure-only Pages→Actions: `--pages-actions` flag or `pages actions` verb.
|
|
48
|
-
if (args.includes("--pages-actions") || (args[0] === "pages" && args[1] === "actions")) {
|
|
49
|
-
await runPagesActions(ctx);
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
// Full deploy: `pages deploy` (detect owner/repo, confirm, run the proven
|
|
53
|
-
// push flow, print URL). Bare `pages`/`deploy` still fall through to legacy.
|
|
54
|
-
if (args[0] === "pages" && args[1] === "deploy") {
|
|
55
|
-
await runPagesDeploy(ctx);
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
// Wipe the stored AI credentials config: `config clear`.
|
|
59
|
-
if (args[0] === "config" && args[1] === "clear") {
|
|
60
|
-
await runConfigClear(ctx);
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const handler = REGISTRY[args[0] ?? ""];
|
|
65
|
-
if (!handler) return false;
|
|
66
|
-
await handler(ctx);
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export const NEW_COMMAND_NAMES = Object.keys(REGISTRY).filter((n) => !n.startsWith("-"));
|
|
1
|
+
/**
|
|
2
|
+
* New-verb command layer (Phase 6). Intercepts the informational/utility
|
|
3
|
+
* commands that are NOT part of the legacy flag flow (version, doctor, provider,
|
|
4
|
+
* models, config, mcp, update) and routes them to thin handlers that consume
|
|
5
|
+
* @gitpagedocs/tools. Alias verbs (init, document, deploy, pages) are mapped in
|
|
6
|
+
* the parser and fall through to the legacy dispatch, so this returns false for
|
|
7
|
+
* them.
|
|
8
|
+
*/
|
|
9
|
+
export interface CommandContext {
|
|
10
|
+
argv: string[];
|
|
11
|
+
args: string[];
|
|
12
|
+
pkgRoot: string;
|
|
13
|
+
cwd: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type CommandHandler = (ctx: CommandContext) => Promise<void>;
|
|
17
|
+
|
|
18
|
+
import { runVersion, runDoctor, runUpdate } from "./diagnostics";
|
|
19
|
+
import { runProvider, runModels } from "./ai-info";
|
|
20
|
+
import { runConfig } from "./config-info";
|
|
21
|
+
import { runConfigClear } from "./config-clear";
|
|
22
|
+
import { runMcp } from "./mcp";
|
|
23
|
+
import { runDocs } from "./docs";
|
|
24
|
+
import { runPagesActions, runPagesDeploy } from "./pages";
|
|
25
|
+
import { runPassword } from "./password";
|
|
26
|
+
|
|
27
|
+
const REGISTRY: Record<string, CommandHandler> = {
|
|
28
|
+
version: runVersion,
|
|
29
|
+
"--version": runVersion,
|
|
30
|
+
"-v": runVersion,
|
|
31
|
+
doctor: runDoctor,
|
|
32
|
+
update: runUpdate,
|
|
33
|
+
provider: runProvider,
|
|
34
|
+
providers: runProvider,
|
|
35
|
+
models: runModels,
|
|
36
|
+
config: runConfig,
|
|
37
|
+
mcp: runMcp,
|
|
38
|
+
docs: runDocs,
|
|
39
|
+
password: runPassword,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** Returns true if a new command handled the invocation (skip legacy flow). */
|
|
43
|
+
export async function runNewCommand(argv: string[], pkgRoot: string): Promise<boolean> {
|
|
44
|
+
const args = argv.slice(2);
|
|
45
|
+
const ctx: CommandContext = { argv, args, pkgRoot, cwd: process.cwd() };
|
|
46
|
+
|
|
47
|
+
// Configure-only Pages→Actions: `--pages-actions` flag or `pages actions` verb.
|
|
48
|
+
if (args.includes("--pages-actions") || (args[0] === "pages" && args[1] === "actions")) {
|
|
49
|
+
await runPagesActions(ctx);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
// Full deploy: `pages deploy` (detect owner/repo, confirm, run the proven
|
|
53
|
+
// push flow, print URL). Bare `pages`/`deploy` still fall through to legacy.
|
|
54
|
+
if (args[0] === "pages" && args[1] === "deploy") {
|
|
55
|
+
await runPagesDeploy(ctx);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
// Wipe the stored AI credentials config: `config clear`.
|
|
59
|
+
if (args[0] === "config" && args[1] === "clear") {
|
|
60
|
+
await runConfigClear(ctx);
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const handler = REGISTRY[args[0] ?? ""];
|
|
65
|
+
if (!handler) return false;
|
|
66
|
+
await handler(ctx);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const NEW_COMMAND_NAMES = Object.keys(REGISTRY).filter((n) => !n.startsWith("-"));
|
package/presentation/index.ts
CHANGED
|
@@ -1,116 +1,124 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { printBanner, printCredits } from "./ui/banner";
|
|
6
|
-
import { resolveOptions } from "./options/resolver";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
// cli/
|
|
33
|
-
// cli/
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { printBanner, printCredits } from "./ui/banner";
|
|
6
|
+
import { resolveOptions } from "./options/resolver";
|
|
7
|
+
import { migrateLegacyLayoutsInteractive } from "./ui/layouts-prompts";
|
|
8
|
+
import { runNewCommand } from "./commands/run-command";
|
|
9
|
+
import { dispatchMode } from "../application/use-cases/dispatch-mode";
|
|
10
|
+
import type {
|
|
11
|
+
CliRuntimeParams,
|
|
12
|
+
ConfigOnlyRuntimePort,
|
|
13
|
+
HomeRuntimePort,
|
|
14
|
+
} from "../application/ports/cli-runtime-ports";
|
|
15
|
+
// @ts-expect-error .mjs modules are runtime-only in this package.
|
|
16
|
+
import { buildConfigArtifacts } from "../builders/config-orchestrator.mjs";
|
|
17
|
+
// @ts-expect-error .mjs modules are runtime-only in this package.
|
|
18
|
+
import { createThemeTemplate } from "../builders/theme-template.mjs";
|
|
19
|
+
// @ts-expect-error .mjs modules are runtime-only in this package.
|
|
20
|
+
import { LAYOUTS } from "../data/layouts.mjs";
|
|
21
|
+
// @ts-expect-error .mjs modules are runtime-only in this package.
|
|
22
|
+
import { executeConfigOnly } from "../application/config-only/handler.mjs";
|
|
23
|
+
// @ts-expect-error .mjs modules are runtime-only in this package.
|
|
24
|
+
import { executeHome } from "../application/home/handler.mjs";
|
|
25
|
+
// @ts-expect-error .mjs modules are runtime-only in this package.
|
|
26
|
+
import { createConfigOnlyRuntime } from "../infrastructure/config-only/runtime.mjs";
|
|
27
|
+
// @ts-expect-error .mjs modules are runtime-only in this package.
|
|
28
|
+
import { createHomeRuntime } from "../infrastructure/home/runtime.mjs";
|
|
29
|
+
|
|
30
|
+
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
31
|
+
const root = process.cwd();
|
|
32
|
+
// cli/ is the published package root (bin = cli/index.mjs). scriptDir is
|
|
33
|
+
// cli/presentation, so pkgRoot = cli/ and the bundled prebuilt/ ships at
|
|
34
|
+
// cli/prebuilt — works identically in-repo and when installed via npm.
|
|
35
|
+
const pkgRoot = path.join(scriptDir, "..");
|
|
36
|
+
const prebuiltDir = path.join(pkgRoot, "prebuilt");
|
|
37
|
+
|
|
38
|
+
const params: CliRuntimeParams = {
|
|
39
|
+
root,
|
|
40
|
+
pkgRoot,
|
|
41
|
+
prebuiltDir,
|
|
42
|
+
buildConfigArtifacts,
|
|
43
|
+
createThemeTemplate,
|
|
44
|
+
layouts: LAYOUTS,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
async function main(): Promise<void> {
|
|
48
|
+
// `mcp start` owns stdout (the MCP stdio channel) — no banner/credits there.
|
|
49
|
+
const stdoutOwnedByCommand = process.argv[2] === "mcp";
|
|
50
|
+
if (!stdoutOwnedByCommand) printBanner();
|
|
51
|
+
|
|
52
|
+
// New informational/utility commands (version, doctor, provider, models,
|
|
53
|
+
// config, mcp, update) are handled before the legacy flag flow. Alias verbs
|
|
54
|
+
// (init, document, deploy, pages) are mapped in the parser and fall through.
|
|
55
|
+
if (await runNewCommand(process.argv, pkgRoot)) {
|
|
56
|
+
if (!stdoutOwnedByCommand) printCredits();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const options = await resolveOptions(process.argv, process.env);
|
|
61
|
+
|
|
62
|
+
// Layouts moved out of <outputDir>/layouts/. Offer to relocate anything left
|
|
63
|
+
// behind before generating, so the config written next points at one folder.
|
|
64
|
+
if (options.mode === "config-only") {
|
|
65
|
+
await migrateLegacyLayoutsInteractive(root, options);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const configOnlyRuntime = createConfigOnlyRuntime() as ConfigOnlyRuntimePort;
|
|
69
|
+
const homeRuntime = createHomeRuntime() as HomeRuntimePort;
|
|
70
|
+
await dispatchMode(options, params, {
|
|
71
|
+
runConfigOnly: async (context) => {
|
|
72
|
+
const safePrebuiltDir =
|
|
73
|
+
typeof context.prebuiltDir === "string"
|
|
74
|
+
? context.prebuiltDir
|
|
75
|
+
: path.join(String(context.pkgRoot ?? process.cwd()), "prebuilt");
|
|
76
|
+
await executeConfigOnly(
|
|
77
|
+
{
|
|
78
|
+
...context,
|
|
79
|
+
prebuiltDir: safePrebuiltDir,
|
|
80
|
+
},
|
|
81
|
+
configOnlyRuntime,
|
|
82
|
+
);
|
|
83
|
+
},
|
|
84
|
+
runHome: async (context) => {
|
|
85
|
+
await executeHome(context, homeRuntime);
|
|
86
|
+
},
|
|
87
|
+
runAi: async (context) => {
|
|
88
|
+
console.log("[gitpagedocs] Iniciando Módulo de IA na CLI...");
|
|
89
|
+
const safePrebuiltDir =
|
|
90
|
+
typeof context.prebuiltDir === "string"
|
|
91
|
+
? context.prebuiltDir
|
|
92
|
+
: path.join(String(context.pkgRoot ?? process.cwd()), "prebuilt");
|
|
93
|
+
// @ts-ignore
|
|
94
|
+
const { runAiCliCommand } = await import("../ai/application/run-ai-cli-command.ts");
|
|
95
|
+
const result = await runAiCliCommand({
|
|
96
|
+
cwd: process.cwd(),
|
|
97
|
+
onInfo: (message: string) => console.log(message),
|
|
98
|
+
// Scaffold the base gitpagedocs/ structure before AI pages are wired in.
|
|
99
|
+
onScaffold: async () => {
|
|
100
|
+
await executeConfigOnly({ ...context, prebuiltDir: safePrebuiltDir }, configOnlyRuntime);
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
if (result.summary.scannedFilesCount === 0) {
|
|
105
|
+
console.log("[gitpagedocs:ai] Nenhum arquivo elegível foi encontrado nos paths informados.");
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const pages = result.summary.pages ?? [];
|
|
110
|
+
console.log(
|
|
111
|
+
`\nProcesso completo. Páginas no padrão gitpagedocs: ${pages.join(", ") || "(nenhuma)"}`,
|
|
112
|
+
);
|
|
113
|
+
console.log(
|
|
114
|
+
`[gitpagedocs:ai] ${result.summary.outputs.length} arquivos markdown gerados e conectados ao config.json da versão mais recente.`,
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
printCredits();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
main().catch((err: unknown) => {
|
|
122
|
+
console.error("Failed to create Git Page Docs scaffold.", err);
|
|
123
|
+
process.exitCode = 1;
|
|
124
|
+
});
|