@gitpagedocs/cli 1.1.52 → 1.1.54
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/ai/application/docs-pattern.ts +68 -68
- package/ai/infrastructure/version-docs-writer.ts +143 -143
- package/data/i18n-langmenu.mjs +305 -305
- package/data/layouts.mjs +416 -352
- package/data/theme-colors.mjs +435 -386
- package/index.mjs +38 -38
- package/infrastructure/gitpagedocs-config-file.ts +47 -47
- package/package.json +60 -60
- package/presentation/commands/password.ts +62 -62
- package/presentation/options/resolver.ts +48 -48
- package/runtime/workflow.mjs +3 -1
package/index.mjs
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { spawnSync } from "node:child_process";
|
|
6
|
-
|
|
7
|
-
const scriptPath = fileURLToPath(import.meta.url);
|
|
8
|
-
const scriptDir = path.dirname(scriptPath);
|
|
9
|
-
const tsEntry = path.join(scriptDir, "presentation", "index.ts");
|
|
10
|
-
|
|
11
|
-
// Resolve tsx from THIS package's location, not the user's cwd. `node --import
|
|
12
|
-
// tsx` would otherwise resolve the bare "tsx" specifier relative to the current
|
|
13
|
-
// working directory, which fails when the CLI is installed globally and run
|
|
14
|
-
// from a project that doesn't depend on tsx (ERR_MODULE_NOT_FOUND 'tsx').
|
|
15
|
-
let tsxLoader = "tsx";
|
|
16
|
-
try {
|
|
17
|
-
tsxLoader = import.meta.resolve("tsx");
|
|
18
|
-
} catch {
|
|
19
|
-
// Older Node without a stable import.meta.resolve — fall back to the bare
|
|
20
|
-
// specifier (works when tsx is resolvable from the cwd or globally).
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const result = spawnSync(
|
|
24
|
-
process.execPath,
|
|
25
|
-
["--import", tsxLoader, tsEntry, ...process.argv.slice(2)],
|
|
26
|
-
{
|
|
27
|
-
stdio: "inherit",
|
|
28
|
-
cwd: process.cwd(),
|
|
29
|
-
env: process.env,
|
|
30
|
-
},
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
if (result.error) {
|
|
34
|
-
console.error("[gitpagedocs] Failed to run TypeScript CLI runtime.", result.error);
|
|
35
|
-
process.exitCode = 1;
|
|
36
|
-
} else if (typeof result.status === "number" && result.status !== 0) {
|
|
37
|
-
process.exitCode = result.status;
|
|
38
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { spawnSync } from "node:child_process";
|
|
6
|
+
|
|
7
|
+
const scriptPath = fileURLToPath(import.meta.url);
|
|
8
|
+
const scriptDir = path.dirname(scriptPath);
|
|
9
|
+
const tsEntry = path.join(scriptDir, "presentation", "index.ts");
|
|
10
|
+
|
|
11
|
+
// Resolve tsx from THIS package's location, not the user's cwd. `node --import
|
|
12
|
+
// tsx` would otherwise resolve the bare "tsx" specifier relative to the current
|
|
13
|
+
// working directory, which fails when the CLI is installed globally and run
|
|
14
|
+
// from a project that doesn't depend on tsx (ERR_MODULE_NOT_FOUND 'tsx').
|
|
15
|
+
let tsxLoader = "tsx";
|
|
16
|
+
try {
|
|
17
|
+
tsxLoader = import.meta.resolve("tsx");
|
|
18
|
+
} catch {
|
|
19
|
+
// Older Node without a stable import.meta.resolve — fall back to the bare
|
|
20
|
+
// specifier (works when tsx is resolvable from the cwd or globally).
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const result = spawnSync(
|
|
24
|
+
process.execPath,
|
|
25
|
+
["--import", tsxLoader, tsEntry, ...process.argv.slice(2)],
|
|
26
|
+
{
|
|
27
|
+
stdio: "inherit",
|
|
28
|
+
cwd: process.cwd(),
|
|
29
|
+
env: process.env,
|
|
30
|
+
},
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
if (result.error) {
|
|
34
|
+
console.error("[gitpagedocs] Failed to run TypeScript CLI runtime.", result.error);
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
} else if (typeof result.status === "number" && result.status !== 0) {
|
|
37
|
+
process.exitCode = result.status;
|
|
38
|
+
}
|
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
|
-
import { defaultConfigLoader } from "@gitpagedocs/tools";
|
|
3
|
-
|
|
4
|
-
export interface DocsAccessConfig {
|
|
5
|
-
enabled: boolean;
|
|
6
|
-
publicKey: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Reads and patches the generated gitpagedocs/config.json IN PLACE, preserving
|
|
11
|
-
* every existing key (raw-JSON round-trip — it never reserializes through a typed
|
|
12
|
-
* model that could drop unknown fields). Used by interactive commands that need
|
|
13
|
-
* to persist a single value (e.g. the documentation password public key).
|
|
14
|
-
*/
|
|
15
|
-
export class GitPageDocsConfigRepository {
|
|
16
|
-
constructor(private readonly cwd: string = process.cwd()) {}
|
|
17
|
-
|
|
18
|
-
/** Absolute path to the JSON config, or throws a friendly, actionable error. */
|
|
19
|
-
async resolvePath(): Promise<string> {
|
|
20
|
-
const resolved = await defaultConfigLoader.resolveConfigPath(this.cwd);
|
|
21
|
-
if (!resolved) {
|
|
22
|
-
throw new Error("gitpagedocs config.json not found. Run `gitpagedocs` first to generate it.");
|
|
23
|
-
}
|
|
24
|
-
if (!resolved.endsWith(".json")) {
|
|
25
|
-
throw new Error(`Expected a JSON config to patch, found "${resolved}". Use a gitpagedocs/config.json.`);
|
|
26
|
-
}
|
|
27
|
-
return resolved;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Set `site.docsAccess = { enabled, publicKey }`, leaving all other config keys
|
|
32
|
-
* untouched. Returns the path that was written.
|
|
33
|
-
*/
|
|
34
|
-
async patchDocsAccess(publicKey: string, enabled = true): Promise<string> {
|
|
35
|
-
const configPath = await this.resolvePath();
|
|
36
|
-
const raw = await fs.readFile(configPath, "utf-8");
|
|
37
|
-
const config = JSON.parse(raw) as Record<string, unknown>;
|
|
38
|
-
const site =
|
|
39
|
-
config.site && typeof config.site === "object"
|
|
40
|
-
? (config.site as Record<string, unknown>)
|
|
41
|
-
: {};
|
|
42
|
-
site.docsAccess = { enabled, publicKey } satisfies DocsAccessConfig;
|
|
43
|
-
config.site = site;
|
|
44
|
-
await fs.writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf-8");
|
|
45
|
-
return configPath;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import { defaultConfigLoader } from "@gitpagedocs/tools";
|
|
3
|
+
|
|
4
|
+
export interface DocsAccessConfig {
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
publicKey: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Reads and patches the generated gitpagedocs/config.json IN PLACE, preserving
|
|
11
|
+
* every existing key (raw-JSON round-trip — it never reserializes through a typed
|
|
12
|
+
* model that could drop unknown fields). Used by interactive commands that need
|
|
13
|
+
* to persist a single value (e.g. the documentation password public key).
|
|
14
|
+
*/
|
|
15
|
+
export class GitPageDocsConfigRepository {
|
|
16
|
+
constructor(private readonly cwd: string = process.cwd()) {}
|
|
17
|
+
|
|
18
|
+
/** Absolute path to the JSON config, or throws a friendly, actionable error. */
|
|
19
|
+
async resolvePath(): Promise<string> {
|
|
20
|
+
const resolved = await defaultConfigLoader.resolveConfigPath(this.cwd);
|
|
21
|
+
if (!resolved) {
|
|
22
|
+
throw new Error("gitpagedocs config.json not found. Run `gitpagedocs` first to generate it.");
|
|
23
|
+
}
|
|
24
|
+
if (!resolved.endsWith(".json")) {
|
|
25
|
+
throw new Error(`Expected a JSON config to patch, found "${resolved}". Use a gitpagedocs/config.json.`);
|
|
26
|
+
}
|
|
27
|
+
return resolved;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Set `site.docsAccess = { enabled, publicKey }`, leaving all other config keys
|
|
32
|
+
* untouched. Returns the path that was written.
|
|
33
|
+
*/
|
|
34
|
+
async patchDocsAccess(publicKey: string, enabled = true): Promise<string> {
|
|
35
|
+
const configPath = await this.resolvePath();
|
|
36
|
+
const raw = await fs.readFile(configPath, "utf-8");
|
|
37
|
+
const config = JSON.parse(raw) as Record<string, unknown>;
|
|
38
|
+
const site =
|
|
39
|
+
config.site && typeof config.site === "object"
|
|
40
|
+
? (config.site as Record<string, unknown>)
|
|
41
|
+
: {};
|
|
42
|
+
site.docsAccess = { enabled, publicKey } satisfies DocsAccessConfig;
|
|
43
|
+
config.site = site;
|
|
44
|
+
await fs.writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf-8");
|
|
45
|
+
return configPath;
|
|
46
|
+
}
|
|
47
|
+
}
|
package/package.json
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@gitpagedocs/cli",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "CLI that scaffolds and maintains gitpagedocs documentation, generates docs with AI, configures GitHub Pages, and runs the MCP server.",
|
|
5
|
-
"bin": {
|
|
6
|
-
"gitpagedocs": "index.mjs"
|
|
7
|
-
},
|
|
8
|
-
"main": "index.mjs",
|
|
9
|
-
"files": [
|
|
10
|
-
"index.mjs",
|
|
11
|
-
"start.mjs",
|
|
12
|
-
"ai",
|
|
13
|
-
"application",
|
|
14
|
-
"builders",
|
|
15
|
-
"content",
|
|
16
|
-
"contracts",
|
|
17
|
-
"data",
|
|
18
|
-
"domain",
|
|
19
|
-
"home",
|
|
20
|
-
"infrastructure",
|
|
21
|
-
"presentation",
|
|
22
|
-
"runtime",
|
|
23
|
-
"ui",
|
|
24
|
-
"prebuilt",
|
|
25
|
-
"README.md"
|
|
26
|
-
],
|
|
27
|
-
"engines": {
|
|
28
|
-
"node": ">=20"
|
|
29
|
-
},
|
|
30
|
-
"dependencies": {
|
|
31
|
-
"@clack/prompts": "^1.5.1",
|
|
32
|
-
"@gitpagedocs/mcp": "^1.1.
|
|
33
|
-
"@gitpagedocs/tools": "^1.1.
|
|
34
|
-
"tsx": "^4.21.0"
|
|
35
|
-
},
|
|
36
|
-
"repository": {
|
|
37
|
-
"type": "git",
|
|
38
|
-
"url": "git+https://github.com/Vidigal-code/git-page-docs.git",
|
|
39
|
-
"directory": "cli"
|
|
40
|
-
},
|
|
41
|
-
"keywords": [
|
|
42
|
-
"gitpagedocs",
|
|
43
|
-
"documentation",
|
|
44
|
-
"markdown",
|
|
45
|
-
"spa",
|
|
46
|
-
"cli",
|
|
47
|
-
"github-pages",
|
|
48
|
-
"create-gitpagedocs"
|
|
49
|
-
],
|
|
50
|
-
"author": "Vidigal-code",
|
|
51
|
-
"license": "ISC",
|
|
52
|
-
"bugs": {
|
|
53
|
-
"url": "https://github.com/Vidigal-code/git-page-docs/issues"
|
|
54
|
-
},
|
|
55
|
-
"homepage": "https://vidigal-code.github.io/git-page-docs/",
|
|
56
|
-
"publishConfig": {
|
|
57
|
-
"registry": "https://registry.npmjs.org/",
|
|
58
|
-
"access": "public"
|
|
59
|
-
}
|
|
60
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@gitpagedocs/cli",
|
|
3
|
+
"version": "1.1.54",
|
|
4
|
+
"description": "CLI that scaffolds and maintains gitpagedocs documentation, generates docs with AI, configures GitHub Pages, and runs the MCP server.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"gitpagedocs": "index.mjs"
|
|
7
|
+
},
|
|
8
|
+
"main": "index.mjs",
|
|
9
|
+
"files": [
|
|
10
|
+
"index.mjs",
|
|
11
|
+
"start.mjs",
|
|
12
|
+
"ai",
|
|
13
|
+
"application",
|
|
14
|
+
"builders",
|
|
15
|
+
"content",
|
|
16
|
+
"contracts",
|
|
17
|
+
"data",
|
|
18
|
+
"domain",
|
|
19
|
+
"home",
|
|
20
|
+
"infrastructure",
|
|
21
|
+
"presentation",
|
|
22
|
+
"runtime",
|
|
23
|
+
"ui",
|
|
24
|
+
"prebuilt",
|
|
25
|
+
"README.md"
|
|
26
|
+
],
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=20"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@clack/prompts": "^1.5.1",
|
|
32
|
+
"@gitpagedocs/mcp": "^1.1.53",
|
|
33
|
+
"@gitpagedocs/tools": "^1.1.53",
|
|
34
|
+
"tsx": "^4.21.0"
|
|
35
|
+
},
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/Vidigal-code/git-page-docs.git",
|
|
39
|
+
"directory": "cli"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"gitpagedocs",
|
|
43
|
+
"documentation",
|
|
44
|
+
"markdown",
|
|
45
|
+
"spa",
|
|
46
|
+
"cli",
|
|
47
|
+
"github-pages",
|
|
48
|
+
"create-gitpagedocs"
|
|
49
|
+
],
|
|
50
|
+
"author": "Vidigal-code",
|
|
51
|
+
"license": "ISC",
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/Vidigal-code/git-page-docs/issues"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://vidigal-code.github.io/git-page-docs/",
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"registry": "https://registry.npmjs.org/",
|
|
58
|
+
"access": "public"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -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,48 +1,48 @@
|
|
|
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
|
-
const runHomeInteractive = parsed.isInteractive || (shouldRunInteractive(argv) && parsed.mode === "home");
|
|
38
|
-
if (runHomeInteractive && parsed.mode === "home") {
|
|
39
|
-
return promptHomeOptions(parsed);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const runConfigInteractive = parsed.isInteractive || (shouldRunInteractive(argv) && parsed.mode === "config-only");
|
|
43
|
-
if (runConfigInteractive && parsed.mode === "config-only") {
|
|
44
|
-
return promptConfigOnlyOptions(parsed);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return parsed;
|
|
48
|
-
}
|
|
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
|
+
const runHomeInteractive = parsed.isInteractive || (shouldRunInteractive(argv) && parsed.mode === "home");
|
|
38
|
+
if (runHomeInteractive && parsed.mode === "home") {
|
|
39
|
+
return promptHomeOptions(parsed);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const runConfigInteractive = parsed.isInteractive || (shouldRunInteractive(argv) && parsed.mode === "config-only");
|
|
43
|
+
if (runConfigInteractive && parsed.mode === "config-only") {
|
|
44
|
+
return promptConfigOnlyOptions(parsed);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return parsed;
|
|
48
|
+
}
|
package/runtime/workflow.mjs
CHANGED
|
@@ -14,6 +14,7 @@ export async function ensureGitHubPagesWorkflow(getCurrentGitBranch, writeText,
|
|
|
14
14
|
env:
|
|
15
15
|
GITHUB_ACTIONS: "true"
|
|
16
16
|
GITHUB_REPOSITORY: \${{ github.repository }}
|
|
17
|
+
GITPAGEDOCS_REPOSITORY_SEARCH: "true"
|
|
17
18
|
GITPAGEDOCS_PATH: "${pathSegment}"
|
|
18
19
|
|
|
19
20
|
- name: Relocate output to custom docs path
|
|
@@ -27,7 +28,8 @@ export async function ensureGitHubPagesWorkflow(getCurrentGitBranch, writeText,
|
|
|
27
28
|
working-directory: .gitpagedocs-runtime
|
|
28
29
|
env:
|
|
29
30
|
GITHUB_ACTIONS: "true"
|
|
30
|
-
GITHUB_REPOSITORY: \${{ github.repository }}
|
|
31
|
+
GITHUB_REPOSITORY: \${{ github.repository }}
|
|
32
|
+
GITPAGEDOCS_REPOSITORY_SEARCH: "true"`;
|
|
31
33
|
const currentBranch = getCurrentGitBranch();
|
|
32
34
|
const workflowPath = ".github/workflows/gitpagedocs-pages.yml";
|
|
33
35
|
const workflowContent = `name: Deploy GitPageDocs
|