@gitpagedocs/cli 1.1.62 → 1.1.64
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 -193
- 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/ports/cli-runtime-ports.ts +91 -91
- package/application/report/config-only-reporter.mjs +64 -64
- package/application/use-cases/dispatch-mode.ts +18 -18
- package/builders/config-orchestrator.mjs +34 -34
- package/builders/project-links.mjs +50 -50
- package/builders/root-config-builder.mjs +61 -61
- 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 -549
- package/content/docs-es.mjs +462 -462
- package/content/docs-pt.mjs +462 -462
- package/contracts/doc-versions.mjs +3 -3
- 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 -33
- 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 -124
- package/presentation/options/parser.ts +119 -119
- package/presentation/options/resolver.ts +46 -46
- package/presentation/ui/clack.ts +91 -91
- package/presentation/ui/prompts.ts +146 -146
- package/runtime/git-ops.mjs +110 -110
- package/runtime/output.mjs +159 -159
- package/runtime/workflow.mjs +129 -129
- package/start.mjs +12 -12
- package/ui/logger.mjs +9 -9
package/README.md
CHANGED
|
@@ -1,193 +1,193 @@
|
|
|
1
|
-
# @gitpagedocs/cli
|
|
2
|
-
|
|
3
|
-
The **published npm package** of the [Git Page Docs](../README.md) monorepo (the command it installs is `gitpagedocs`). It scaffolds the `gitpagedocs/` docs contract, generates docs with AI, configures GitHub Pages, and runs the MCP server.
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
npm install -g @gitpagedocs/cli # global (installs the `gitpagedocs` command)
|
|
7
|
-
gitpagedocs # generate gitpagedocs/ config (config-only)
|
|
8
|
-
|
|
9
|
-
# or one-off, no install:
|
|
10
|
-
npx @gitpagedocs/cli
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
> This package ships its TypeScript sources and runs them via `tsx`; it depends on the workspace packages `@gitpagedocs/tools` and `@gitpagedocs/mcp` (published alongside it).
|
|
14
|
-
|
|
15
|
-
## Commands
|
|
16
|
-
|
|
17
|
-
| Command | Description |
|
|
18
|
-
|---|---|
|
|
19
|
-
| `gitpagedocs` | Generate `gitpagedocs/` config + versioned docs (config-only) |
|
|
20
|
-
| `gitpagedocs --layoutconfig` | Also emit local layout templates in `gitpagelayouts/` |
|
|
21
|
-
| `gitpagedocs --layouts-dir <dir>` | Folder for local layouts (default: `gitpagelayouts`) |
|
|
22
|
-
| `gitpagedocs --no-interactive` / `-y` | Never prompt; use flags and defaults |
|
|
23
|
-
| `gitpagedocs --push --owner <o> --repo <r> [--path <sub>]` | Generate, configure Pages, create workflow, commit + push |
|
|
24
|
-
| `gitpagedocs --home` | Standalone distribution (`gitpagedocshome/`: static site + .env + Dockerfile) |
|
|
25
|
-
| `gitpagedocs -i` / `--interactive` | Interactive prompts |
|
|
26
|
-
| `gitpagedocs ai` | Interactive AI documentation generator — writes pages in the gitpagedocs pattern (see below) |
|
|
27
|
-
| `gitpagedocs provider [id]` · `models [provider]` | List AI providers / catalog models |
|
|
28
|
-
| `gitpagedocs document[:repo\|:file\|:folder]` | Generate documentation with AI in the gitpagedocs pattern |
|
|
29
|
-
| `gitpagedocs password` | Set a documentation access password (writes the public key to `config.json`, prints the private key) |
|
|
30
|
-
| `gitpagedocs deploy` / `pages [actions\|deploy]` | Configure GitHub Pages via Actions + push |
|
|
31
|
-
| `gitpagedocs docs` | Refresh managed regions of README/CONTRIBUTING/SECURITY |
|
|
32
|
-
| `gitpagedocs config clear` | Delete the stored `.gitpagedocsconfig` (wipes saved AI credentials) |
|
|
33
|
-
| `gitpagedocs doctor` · `version` · `update` | Diagnostics / version / registry update check |
|
|
34
|
-
| `gitpagedocs mcp start` | Start the MCP server over stdio |
|
|
35
|
-
|
|
36
|
-
The AI-CLI implementation lives in `cli/ai/` (relocated from the frontend so the published package is self-contained).
|
|
37
|
-
|
|
38
|
-
# CLI Architecture (Clean Architecture + SOLID)
|
|
39
|
-
|
|
40
|
-
## Layer Overview
|
|
41
|
-
|
|
42
|
-
```
|
|
43
|
-
cli/
|
|
44
|
-
|-- index.mjs # Node entry (bootstraps TS presentation via tsx)
|
|
45
|
-
|-- package.json # the published `gitpagedocs` package
|
|
46
|
-
|-- ai/ # AI documentation CLI (provider/model/paths → markdown)
|
|
47
|
-
|-- contracts/ # Stable contracts for external tooling
|
|
48
|
-
| `-- doc-versions.mjs
|
|
49
|
-
|
|
|
50
|
-
|-- presentation/ # Interface/composition root
|
|
51
|
-
| |-- index.ts
|
|
52
|
-
| |-- options/
|
|
53
|
-
| `-- ui/
|
|
54
|
-
|
|
|
55
|
-
|-- application/ # Use-cases and ports
|
|
56
|
-
| |-- config-only/handler.mjs
|
|
57
|
-
| |-- home/handler.mjs
|
|
58
|
-
| |-- report/config-only-reporter.mjs
|
|
59
|
-
| |-- use-cases/dispatch-mode.ts
|
|
60
|
-
| `-- ports/cli-runtime-ports.ts
|
|
61
|
-
|
|
|
62
|
-
|-- domain/ # Business rules
|
|
63
|
-
| `-- services/sanitize-segment.mjs
|
|
64
|
-
|
|
|
65
|
-
|-- infrastructure/ # Side effects and adapters
|
|
66
|
-
| |-- config-only/runtime.mjs
|
|
67
|
-
| `-- home/runtime.mjs
|
|
68
|
-
|
|
|
69
|
-
|-- builders/ # Pure config builders
|
|
70
|
-
|-- data/ # Constants and metadata
|
|
71
|
-
|-- content/ # Static docs content
|
|
72
|
-
|-- runtime/ # Low-level runtime helpers
|
|
73
|
-
`-- home/ # Home templates/files
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## SOLID Principles
|
|
77
|
-
|
|
78
|
-
| Principle | Application |
|
|
79
|
-
|-----------|-------------|
|
|
80
|
-
| **SRP** | `application/report` only formats messages; handlers only orchestrate |
|
|
81
|
-
| **OCP** | New runtime implementations can be injected through ports |
|
|
82
|
-
| **LSP** | `dispatch-mode` works with any runner implementing `CliCommandRunner` |
|
|
83
|
-
| **ISP** | Split runtime contracts (`ConfigOnlyRuntimePort`, `HomeRuntimePort`) |
|
|
84
|
-
| **DIP** | Use-cases depend on `application/ports`, not concrete fs/git/exec |
|
|
85
|
-
|
|
86
|
-
## Clean Architecture
|
|
87
|
-
|
|
88
|
-
- **Interfaces/Presentation**: parse CLI args, resolve mode, wire dependencies in `presentation/index.ts`
|
|
89
|
-
- **Application**: orchestrate flows with explicit ports, without direct fs/git/exec imports
|
|
90
|
-
- **Domain**: sanitize and core rules with no infrastructure dependencies
|
|
91
|
-
- **Infrastructure**: concrete adapters for runtime side effects
|
|
92
|
-
- **Contracts**: `tools/smoke` consumes `cli/contracts` instead of internal CLI modules
|
|
93
|
-
|
|
94
|
-
## Authorized Routes Pipeline
|
|
95
|
-
|
|
96
|
-
The CLI now generates authorized-route docs and config entries in PT/EN/ES.
|
|
97
|
-
|
|
98
|
-
- Source content: `cli/content/docs.mjs` (`authorizedRoutes` key per language)
|
|
99
|
-
- Route metadata: `cli/data/route-metas.mjs` (`ROUTE_META_ID6`)
|
|
100
|
-
- Route path mapping: `cli/data/path-mappings.mjs` (`authorized-routes.md`)
|
|
101
|
-
- Version config composition: `cli/builders/version-config-builder.mjs`
|
|
102
|
-
- Doc key resolution: `cli/runtime/doc-path-resolver.mjs`
|
|
103
|
-
|
|
104
|
-
Generated artifacts include:
|
|
105
|
-
|
|
106
|
-
- `gitpagedocs/docs/versions/<version>/config.json` with `auth` and route `authorization`
|
|
107
|
-
- `gitpagedocs/docs/versions/<version>/{pt,en,es}/authorized-routes.md`
|
|
108
|
-
- `menus-header-md` entry dedicated to Authorized Routes
|
|
109
|
-
|
|
110
|
-
## GitHub Pages Push Paths
|
|
111
|
-
|
|
112
|
-
- Default project-site publish (`--push` without `--path`) targets `/<repo>/`.
|
|
113
|
-
- Custom project subpath publish (`--push --path <segment>`) targets `/<repo>/<segment>/`.
|
|
114
|
-
- `--path` accepts a single sanitized segment (letters, numbers, `.`, `_`, `-`).
|
|
115
|
-
|
|
116
|
-
Example:
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
npx @gitpagedocs/cli --owner vidigal-code --repo energy-bill-ai-parser --path git-docs --push
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Expected URL after deployment:
|
|
123
|
-
|
|
124
|
-
```text
|
|
125
|
-
https://vidigal-code.github.io/energy-bill-ai-parser/git-docs/
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
## AI CLI (interactive + config file)
|
|
129
|
-
|
|
130
|
-
The CLI now includes a dedicated interactive AI mode:
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
npx @gitpagedocs/cli ai
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### What it does
|
|
137
|
-
|
|
138
|
-
- asks provider (`openai`, `claude`, `gemini`, `ollama`)
|
|
139
|
-
- asks API key or Ollama URL
|
|
140
|
-
- asks paths to scan (supports one or many paths, including other repositories)
|
|
141
|
-
- generates documentation in `pt`, `en`, `es` **in the gitpagedocs pattern**
|
|
142
|
-
- optionally persists config in `.gitpagedocsconfig`
|
|
143
|
-
|
|
144
|
-
### gitpagedocs pattern output
|
|
145
|
-
|
|
146
|
-
The model is given a gitpagedocs-aware system prompt and returns documentation split into
|
|
147
|
-
pages (delimited by `=== PAGE: <slug> | <Title> ===`). The CLI scaffolds the base
|
|
148
|
-
`gitpagedocs/` structure first, then writes each page to
|
|
149
|
-
`gitpagedocs/docs/versions/<latest>/<lang>/<slug>.md` for every language and **wires it into
|
|
150
|
-
that version's `config.json`** (`routes-md` + `menus-header-md`) so the pages render in the
|
|
151
|
-
viewer menu. Entries are tagged `aiGenerated` and idempotent (re-running replaces them). A
|
|
152
|
-
later plain `gitpagedocs` rebuild drops the wiring — re-run `gitpagedocs ai` to restore.
|
|
153
|
-
|
|
154
|
-
### `.gitpagedocsconfig` (manual mode)
|
|
155
|
-
|
|
156
|
-
The file lives in the per-user OS config directory (never inside the repository, so
|
|
157
|
-
the API key cannot be committed by accident) and is written with owner-only
|
|
158
|
-
permissions on POSIX systems:
|
|
159
|
-
|
|
160
|
-
- Windows: `%APPDATA%\gitpagedocs\.gitpagedocsconfig`
|
|
161
|
-
- macOS: `~/Library/Application Support/gitpagedocs/.gitpagedocsconfig`
|
|
162
|
-
- Linux: `$XDG_CONFIG_HOME/gitpagedocs/.gitpagedocsconfig` (or `~/.config/gitpagedocs/.gitpagedocsconfig`)
|
|
163
|
-
|
|
164
|
-
Set `GITPAGEDOCS_CONFIG_DIR` to override the directory; delete the stored file
|
|
165
|
-
and its credentials with `gitpagedocs config clear`; a legacy
|
|
166
|
-
`.gitpagedocsconfig` in the repository root is migrated automatically on the next
|
|
167
|
-
run. You can create/edit this file manually and then run `npx @gitpagedocs/cli ai`:
|
|
168
|
-
|
|
169
|
-
```json
|
|
170
|
-
{
|
|
171
|
-
"version": 1,
|
|
172
|
-
"ai": {
|
|
173
|
-
"provider": "openai",
|
|
174
|
-
"model": "gpt-4o-mini",
|
|
175
|
-
"apiKey": "<YOUR_API_KEY>",
|
|
176
|
-
"paths": ["src", "cli", "../another-repo/src"],
|
|
177
|
-
"languages": ["pt", "en", "es"],
|
|
178
|
-
"outputDir": "gitpagedocs/docs",
|
|
179
|
-
"filePrefix": "ai-generated",
|
|
180
|
-
"contextPrompt": "Você é um redator técnico sênior..."
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
For Ollama, use `baseUrl` instead of `apiKey`.
|
|
186
|
-
|
|
187
|
-
### Interactive fallback
|
|
188
|
-
|
|
189
|
-
If a directory is not found, CLI offers fallback choices:
|
|
190
|
-
|
|
191
|
-
- fix paths and retry
|
|
192
|
-
- skip missing paths and continue
|
|
193
|
-
- abort safely
|
|
1
|
+
# @gitpagedocs/cli
|
|
2
|
+
|
|
3
|
+
The **published npm package** of the [Git Page Docs](../README.md) monorepo (the command it installs is `gitpagedocs`). It scaffolds the `gitpagedocs/` docs contract, generates docs with AI, configures GitHub Pages, and runs the MCP server.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install -g @gitpagedocs/cli # global (installs the `gitpagedocs` command)
|
|
7
|
+
gitpagedocs # generate gitpagedocs/ config (config-only)
|
|
8
|
+
|
|
9
|
+
# or one-off, no install:
|
|
10
|
+
npx @gitpagedocs/cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> This package ships its TypeScript sources and runs them via `tsx`; it depends on the workspace packages `@gitpagedocs/tools` and `@gitpagedocs/mcp` (published alongside it).
|
|
14
|
+
|
|
15
|
+
## Commands
|
|
16
|
+
|
|
17
|
+
| Command | Description |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `gitpagedocs` | Generate `gitpagedocs/` config + versioned docs (config-only) |
|
|
20
|
+
| `gitpagedocs --layoutconfig` | Also emit local layout templates in `gitpagelayouts/` |
|
|
21
|
+
| `gitpagedocs --layouts-dir <dir>` | Folder for local layouts (default: `gitpagelayouts`) |
|
|
22
|
+
| `gitpagedocs --no-interactive` / `-y` | Never prompt; use flags and defaults |
|
|
23
|
+
| `gitpagedocs --push --owner <o> --repo <r> [--path <sub>]` | Generate, configure Pages, create workflow, commit + push |
|
|
24
|
+
| `gitpagedocs --home` | Standalone distribution (`gitpagedocshome/`: static site + .env + Dockerfile) |
|
|
25
|
+
| `gitpagedocs -i` / `--interactive` | Interactive prompts |
|
|
26
|
+
| `gitpagedocs ai` | Interactive AI documentation generator — writes pages in the gitpagedocs pattern (see below) |
|
|
27
|
+
| `gitpagedocs provider [id]` · `models [provider]` | List AI providers / catalog models |
|
|
28
|
+
| `gitpagedocs document[:repo\|:file\|:folder]` | Generate documentation with AI in the gitpagedocs pattern |
|
|
29
|
+
| `gitpagedocs password` | Set a documentation access password (writes the public key to `config.json`, prints the private key) |
|
|
30
|
+
| `gitpagedocs deploy` / `pages [actions\|deploy]` | Configure GitHub Pages via Actions + push |
|
|
31
|
+
| `gitpagedocs docs` | Refresh managed regions of README/CONTRIBUTING/SECURITY |
|
|
32
|
+
| `gitpagedocs config clear` | Delete the stored `.gitpagedocsconfig` (wipes saved AI credentials) |
|
|
33
|
+
| `gitpagedocs doctor` · `version` · `update` | Diagnostics / version / registry update check |
|
|
34
|
+
| `gitpagedocs mcp start` | Start the MCP server over stdio |
|
|
35
|
+
|
|
36
|
+
The AI-CLI implementation lives in `cli/ai/` (relocated from the frontend so the published package is self-contained).
|
|
37
|
+
|
|
38
|
+
# CLI Architecture (Clean Architecture + SOLID)
|
|
39
|
+
|
|
40
|
+
## Layer Overview
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
cli/
|
|
44
|
+
|-- index.mjs # Node entry (bootstraps TS presentation via tsx)
|
|
45
|
+
|-- package.json # the published `gitpagedocs` package
|
|
46
|
+
|-- ai/ # AI documentation CLI (provider/model/paths → markdown)
|
|
47
|
+
|-- contracts/ # Stable contracts for external tooling
|
|
48
|
+
| `-- doc-versions.mjs
|
|
49
|
+
|
|
|
50
|
+
|-- presentation/ # Interface/composition root
|
|
51
|
+
| |-- index.ts
|
|
52
|
+
| |-- options/
|
|
53
|
+
| `-- ui/
|
|
54
|
+
|
|
|
55
|
+
|-- application/ # Use-cases and ports
|
|
56
|
+
| |-- config-only/handler.mjs
|
|
57
|
+
| |-- home/handler.mjs
|
|
58
|
+
| |-- report/config-only-reporter.mjs
|
|
59
|
+
| |-- use-cases/dispatch-mode.ts
|
|
60
|
+
| `-- ports/cli-runtime-ports.ts
|
|
61
|
+
|
|
|
62
|
+
|-- domain/ # Business rules
|
|
63
|
+
| `-- services/sanitize-segment.mjs
|
|
64
|
+
|
|
|
65
|
+
|-- infrastructure/ # Side effects and adapters
|
|
66
|
+
| |-- config-only/runtime.mjs
|
|
67
|
+
| `-- home/runtime.mjs
|
|
68
|
+
|
|
|
69
|
+
|-- builders/ # Pure config builders
|
|
70
|
+
|-- data/ # Constants and metadata
|
|
71
|
+
|-- content/ # Static docs content
|
|
72
|
+
|-- runtime/ # Low-level runtime helpers
|
|
73
|
+
`-- home/ # Home templates/files
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## SOLID Principles
|
|
77
|
+
|
|
78
|
+
| Principle | Application |
|
|
79
|
+
|-----------|-------------|
|
|
80
|
+
| **SRP** | `application/report` only formats messages; handlers only orchestrate |
|
|
81
|
+
| **OCP** | New runtime implementations can be injected through ports |
|
|
82
|
+
| **LSP** | `dispatch-mode` works with any runner implementing `CliCommandRunner` |
|
|
83
|
+
| **ISP** | Split runtime contracts (`ConfigOnlyRuntimePort`, `HomeRuntimePort`) |
|
|
84
|
+
| **DIP** | Use-cases depend on `application/ports`, not concrete fs/git/exec |
|
|
85
|
+
|
|
86
|
+
## Clean Architecture
|
|
87
|
+
|
|
88
|
+
- **Interfaces/Presentation**: parse CLI args, resolve mode, wire dependencies in `presentation/index.ts`
|
|
89
|
+
- **Application**: orchestrate flows with explicit ports, without direct fs/git/exec imports
|
|
90
|
+
- **Domain**: sanitize and core rules with no infrastructure dependencies
|
|
91
|
+
- **Infrastructure**: concrete adapters for runtime side effects
|
|
92
|
+
- **Contracts**: `tools/smoke` consumes `cli/contracts` instead of internal CLI modules
|
|
93
|
+
|
|
94
|
+
## Authorized Routes Pipeline
|
|
95
|
+
|
|
96
|
+
The CLI now generates authorized-route docs and config entries in PT/EN/ES.
|
|
97
|
+
|
|
98
|
+
- Source content: `cli/content/docs.mjs` (`authorizedRoutes` key per language)
|
|
99
|
+
- Route metadata: `cli/data/route-metas.mjs` (`ROUTE_META_ID6`)
|
|
100
|
+
- Route path mapping: `cli/data/path-mappings.mjs` (`authorized-routes.md`)
|
|
101
|
+
- Version config composition: `cli/builders/version-config-builder.mjs`
|
|
102
|
+
- Doc key resolution: `cli/runtime/doc-path-resolver.mjs`
|
|
103
|
+
|
|
104
|
+
Generated artifacts include:
|
|
105
|
+
|
|
106
|
+
- `gitpagedocs/docs/versions/<version>/config.json` with `auth` and route `authorization`
|
|
107
|
+
- `gitpagedocs/docs/versions/<version>/{pt,en,es}/authorized-routes.md`
|
|
108
|
+
- `menus-header-md` entry dedicated to Authorized Routes
|
|
109
|
+
|
|
110
|
+
## GitHub Pages Push Paths
|
|
111
|
+
|
|
112
|
+
- Default project-site publish (`--push` without `--path`) targets `/<repo>/`.
|
|
113
|
+
- Custom project subpath publish (`--push --path <segment>`) targets `/<repo>/<segment>/`.
|
|
114
|
+
- `--path` accepts a single sanitized segment (letters, numbers, `.`, `_`, `-`).
|
|
115
|
+
|
|
116
|
+
Example:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npx @gitpagedocs/cli --owner vidigal-code --repo energy-bill-ai-parser --path git-docs --push
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Expected URL after deployment:
|
|
123
|
+
|
|
124
|
+
```text
|
|
125
|
+
https://vidigal-code.github.io/energy-bill-ai-parser/git-docs/
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## AI CLI (interactive + config file)
|
|
129
|
+
|
|
130
|
+
The CLI now includes a dedicated interactive AI mode:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npx @gitpagedocs/cli ai
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### What it does
|
|
137
|
+
|
|
138
|
+
- asks provider (`openai`, `claude`, `gemini`, `ollama`)
|
|
139
|
+
- asks API key or Ollama URL
|
|
140
|
+
- asks paths to scan (supports one or many paths, including other repositories)
|
|
141
|
+
- generates documentation in `pt`, `en`, `es` **in the gitpagedocs pattern**
|
|
142
|
+
- optionally persists config in `.gitpagedocsconfig`
|
|
143
|
+
|
|
144
|
+
### gitpagedocs pattern output
|
|
145
|
+
|
|
146
|
+
The model is given a gitpagedocs-aware system prompt and returns documentation split into
|
|
147
|
+
pages (delimited by `=== PAGE: <slug> | <Title> ===`). The CLI scaffolds the base
|
|
148
|
+
`gitpagedocs/` structure first, then writes each page to
|
|
149
|
+
`gitpagedocs/docs/versions/<latest>/<lang>/<slug>.md` for every language and **wires it into
|
|
150
|
+
that version's `config.json`** (`routes-md` + `menus-header-md`) so the pages render in the
|
|
151
|
+
viewer menu. Entries are tagged `aiGenerated` and idempotent (re-running replaces them). A
|
|
152
|
+
later plain `gitpagedocs` rebuild drops the wiring — re-run `gitpagedocs ai` to restore.
|
|
153
|
+
|
|
154
|
+
### `.gitpagedocsconfig` (manual mode)
|
|
155
|
+
|
|
156
|
+
The file lives in the per-user OS config directory (never inside the repository, so
|
|
157
|
+
the API key cannot be committed by accident) and is written with owner-only
|
|
158
|
+
permissions on POSIX systems:
|
|
159
|
+
|
|
160
|
+
- Windows: `%APPDATA%\gitpagedocs\.gitpagedocsconfig`
|
|
161
|
+
- macOS: `~/Library/Application Support/gitpagedocs/.gitpagedocsconfig`
|
|
162
|
+
- Linux: `$XDG_CONFIG_HOME/gitpagedocs/.gitpagedocsconfig` (or `~/.config/gitpagedocs/.gitpagedocsconfig`)
|
|
163
|
+
|
|
164
|
+
Set `GITPAGEDOCS_CONFIG_DIR` to override the directory; delete the stored file
|
|
165
|
+
and its credentials with `gitpagedocs config clear`; a legacy
|
|
166
|
+
`.gitpagedocsconfig` in the repository root is migrated automatically on the next
|
|
167
|
+
run. You can create/edit this file manually and then run `npx @gitpagedocs/cli ai`:
|
|
168
|
+
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"version": 1,
|
|
172
|
+
"ai": {
|
|
173
|
+
"provider": "openai",
|
|
174
|
+
"model": "gpt-4o-mini",
|
|
175
|
+
"apiKey": "<YOUR_API_KEY>",
|
|
176
|
+
"paths": ["src", "cli", "../another-repo/src"],
|
|
177
|
+
"languages": ["pt", "en", "es"],
|
|
178
|
+
"outputDir": "gitpagedocs/docs",
|
|
179
|
+
"filePrefix": "ai-generated",
|
|
180
|
+
"contextPrompt": "Você é um redator técnico sênior..."
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
For Ollama, use `baseUrl` instead of `apiKey`.
|
|
186
|
+
|
|
187
|
+
### Interactive fallback
|
|
188
|
+
|
|
189
|
+
If a directory is not found, CLI offers fallback choices:
|
|
190
|
+
|
|
191
|
+
- fix paths and retry
|
|
192
|
+
- skip missing paths and continue
|
|
193
|
+
- abort safely
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file ai-command.ts
|
|
3
|
-
* @description Application service for running AI commands. Decoupled from concrete LLMs.
|
|
4
|
-
*/
|
|
5
|
-
import { ILLMProvider } from '../core/ports/illm-provider';
|
|
6
|
-
|
|
7
|
-
export class AiCommandService {
|
|
8
|
-
constructor(private provider: ILLMProvider) { }
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Executes the AI Documentation Generation for a specific content
|
|
12
|
-
*/
|
|
13
|
-
async runGeneration(content: string, contextPrompt?: string): Promise<string> {
|
|
14
|
-
return await this.provider.generateDocumentation(content, contextPrompt);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Executes a CLI chat prompt
|
|
19
|
-
*/
|
|
20
|
-
async runChat(prompt: string): Promise<string> {
|
|
21
|
-
const messages = [{ role: 'user' as const, content: prompt }];
|
|
22
|
-
return await this.provider.chat(messages);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @file ai-command.ts
|
|
3
|
+
* @description Application service for running AI commands. Decoupled from concrete LLMs.
|
|
4
|
+
*/
|
|
5
|
+
import { ILLMProvider } from '../core/ports/illm-provider';
|
|
6
|
+
|
|
7
|
+
export class AiCommandService {
|
|
8
|
+
constructor(private provider: ILLMProvider) { }
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Executes the AI Documentation Generation for a specific content
|
|
12
|
+
*/
|
|
13
|
+
async runGeneration(content: string, contextPrompt?: string): Promise<string> {
|
|
14
|
+
return await this.provider.generateDocumentation(content, contextPrompt);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Executes a CLI chat prompt
|
|
19
|
+
*/
|
|
20
|
+
async runChat(prompt: string): Promise<string> {
|
|
21
|
+
const messages = [{ role: 'user' as const, content: prompt }];
|
|
22
|
+
return await this.provider.chat(messages);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import type { AiProviderId } from "../config";
|
|
2
|
-
import type { ILLMProvider } from "../core/ports/illm-provider";
|
|
3
|
-
import { ToolsLlmProvider } from "../infrastructure/llm/tools-llm-provider";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Creates the CLI LLM provider. Backed by the shared @gitpagedocs/tools AI core
|
|
7
|
-
* (one registry-driven implementation for every provider) — no per-provider
|
|
8
|
-
* switch. The legacy provider id (openai/claude/gemini/ollama) is mapped to the
|
|
9
|
-
* catalog inside ToolsLlmProvider.
|
|
10
|
-
*/
|
|
11
|
-
export function createAiProvider(input: {
|
|
12
|
-
provider: AiProviderId;
|
|
13
|
-
model: string;
|
|
14
|
-
apiKey?: string;
|
|
15
|
-
baseUrl?: string;
|
|
16
|
-
}): ILLMProvider {
|
|
17
|
-
return new ToolsLlmProvider(input.provider, {
|
|
18
|
-
model: input.model,
|
|
19
|
-
apiKey: input.apiKey,
|
|
20
|
-
baseUrl: input.baseUrl,
|
|
21
|
-
});
|
|
22
|
-
}
|
|
1
|
+
import type { AiProviderId } from "../config";
|
|
2
|
+
import type { ILLMProvider } from "../core/ports/illm-provider";
|
|
3
|
+
import { ToolsLlmProvider } from "../infrastructure/llm/tools-llm-provider";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates the CLI LLM provider. Backed by the shared @gitpagedocs/tools AI core
|
|
7
|
+
* (one registry-driven implementation for every provider) — no per-provider
|
|
8
|
+
* switch. The legacy provider id (openai/claude/gemini/ollama) is mapped to the
|
|
9
|
+
* catalog inside ToolsLlmProvider.
|
|
10
|
+
*/
|
|
11
|
+
export function createAiProvider(input: {
|
|
12
|
+
provider: AiProviderId;
|
|
13
|
+
model: string;
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
}): ILLMProvider {
|
|
17
|
+
return new ToolsLlmProvider(input.provider, {
|
|
18
|
+
model: input.model,
|
|
19
|
+
apiKey: input.apiKey,
|
|
20
|
+
baseUrl: input.baseUrl,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parse an AI documentation response into gitpagedocs pages.
|
|
3
|
-
*
|
|
4
|
-
* The model is instructed (see GITPAGEDOCS_DOC_SYSTEM_PROMPT) to delimit each
|
|
5
|
-
* page with a line `=== PAGE: <slug> | <Title> ===`. This splits that response
|
|
6
|
-
* into individual pages. If the model ignored the format, the whole response is
|
|
7
|
-
* returned as a single "ai-overview" page so content is never lost.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
export interface AiDocPage {
|
|
11
|
-
/** lowercase-kebab, English, identical across languages (used as the filename) */
|
|
12
|
-
slug: string;
|
|
13
|
-
title: string;
|
|
14
|
-
body: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const PAGE_DELIMITER = /^===\s*PAGE:\s*(.+?)\s*\|\s*(.*?)\s*===\s*$/;
|
|
18
|
-
|
|
19
|
-
/** Turn an arbitrary heading into a safe lowercase-kebab slug. */
|
|
20
|
-
export function slugify(raw: string): string {
|
|
21
|
-
const slug = (raw ?? "")
|
|
22
|
-
.toLowerCase()
|
|
23
|
-
.normalize("NFKD")
|
|
24
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
25
|
-
.replace(/^-+|-+$/g, "")
|
|
26
|
-
.slice(0, 60);
|
|
27
|
-
return slug || "page";
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function parseAiPages(markdown: string): AiDocPage[] {
|
|
31
|
-
const text = (markdown ?? "").replace(/\r\n/g, "\n").trim();
|
|
32
|
-
if (!text) return [];
|
|
33
|
-
|
|
34
|
-
const pages: AiDocPage[] = [];
|
|
35
|
-
let current: { slug: string; title: string; body: string[] } | null = null;
|
|
36
|
-
|
|
37
|
-
const flush = () => {
|
|
38
|
-
if (current) {
|
|
39
|
-
pages.push({ slug: current.slug, title: current.title, body: current.body.join("\n").trim() });
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
for (const line of text.split("\n")) {
|
|
44
|
-
const match = line.match(PAGE_DELIMITER);
|
|
45
|
-
if (match) {
|
|
46
|
-
flush();
|
|
47
|
-
const rawSlug = match[1].trim();
|
|
48
|
-
const title = match[2].trim() || rawSlug;
|
|
49
|
-
current = { slug: slugify(rawSlug), title, body: [] };
|
|
50
|
-
} else if (current) {
|
|
51
|
-
current.body.push(line);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
flush();
|
|
55
|
-
|
|
56
|
-
const withBody = pages.filter((page) => page.body.length > 0);
|
|
57
|
-
if (withBody.length === 0) {
|
|
58
|
-
return [{ slug: "ai-overview", title: "Overview", body: text }];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// De-duplicate slugs within a single response (suffix later collisions).
|
|
62
|
-
const seen = new Map<string, number>();
|
|
63
|
-
return withBody.map((page) => {
|
|
64
|
-
const count = seen.get(page.slug) ?? 0;
|
|
65
|
-
seen.set(page.slug, count + 1);
|
|
66
|
-
return count === 0 ? page : { ...page, slug: `${page.slug}-${count + 1}` };
|
|
67
|
-
});
|
|
68
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Parse an AI documentation response into gitpagedocs pages.
|
|
3
|
+
*
|
|
4
|
+
* The model is instructed (see GITPAGEDOCS_DOC_SYSTEM_PROMPT) to delimit each
|
|
5
|
+
* page with a line `=== PAGE: <slug> | <Title> ===`. This splits that response
|
|
6
|
+
* into individual pages. If the model ignored the format, the whole response is
|
|
7
|
+
* returned as a single "ai-overview" page so content is never lost.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export interface AiDocPage {
|
|
11
|
+
/** lowercase-kebab, English, identical across languages (used as the filename) */
|
|
12
|
+
slug: string;
|
|
13
|
+
title: string;
|
|
14
|
+
body: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const PAGE_DELIMITER = /^===\s*PAGE:\s*(.+?)\s*\|\s*(.*?)\s*===\s*$/;
|
|
18
|
+
|
|
19
|
+
/** Turn an arbitrary heading into a safe lowercase-kebab slug. */
|
|
20
|
+
export function slugify(raw: string): string {
|
|
21
|
+
const slug = (raw ?? "")
|
|
22
|
+
.toLowerCase()
|
|
23
|
+
.normalize("NFKD")
|
|
24
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
25
|
+
.replace(/^-+|-+$/g, "")
|
|
26
|
+
.slice(0, 60);
|
|
27
|
+
return slug || "page";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function parseAiPages(markdown: string): AiDocPage[] {
|
|
31
|
+
const text = (markdown ?? "").replace(/\r\n/g, "\n").trim();
|
|
32
|
+
if (!text) return [];
|
|
33
|
+
|
|
34
|
+
const pages: AiDocPage[] = [];
|
|
35
|
+
let current: { slug: string; title: string; body: string[] } | null = null;
|
|
36
|
+
|
|
37
|
+
const flush = () => {
|
|
38
|
+
if (current) {
|
|
39
|
+
pages.push({ slug: current.slug, title: current.title, body: current.body.join("\n").trim() });
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
for (const line of text.split("\n")) {
|
|
44
|
+
const match = line.match(PAGE_DELIMITER);
|
|
45
|
+
if (match) {
|
|
46
|
+
flush();
|
|
47
|
+
const rawSlug = match[1].trim();
|
|
48
|
+
const title = match[2].trim() || rawSlug;
|
|
49
|
+
current = { slug: slugify(rawSlug), title, body: [] };
|
|
50
|
+
} else if (current) {
|
|
51
|
+
current.body.push(line);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
flush();
|
|
55
|
+
|
|
56
|
+
const withBody = pages.filter((page) => page.body.length > 0);
|
|
57
|
+
if (withBody.length === 0) {
|
|
58
|
+
return [{ slug: "ai-overview", title: "Overview", body: text }];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// De-duplicate slugs within a single response (suffix later collisions).
|
|
62
|
+
const seen = new Map<string, number>();
|
|
63
|
+
return withBody.map((page) => {
|
|
64
|
+
const count = seen.get(page.slug) ?? 0;
|
|
65
|
+
seen.set(page.slug, count + 1);
|
|
66
|
+
return count === 0 ? page : { ...page, slug: `${page.slug}-${count + 1}` };
|
|
67
|
+
});
|
|
68
|
+
}
|