@pruddiman/hem 0.0.1-beta-5671db0
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/LICENSE +21 -0
- package/dist/agents/arbiter-agent.d.ts +72 -0
- package/dist/agents/arbiter-agent.js +149 -0
- package/dist/agents/architecture-agent.d.ts +148 -0
- package/dist/agents/architecture-agent.js +459 -0
- package/dist/agents/base-agent.d.ts +44 -0
- package/dist/agents/base-agent.js +57 -0
- package/dist/agents/crossref-agent.d.ts +140 -0
- package/dist/agents/crossref-agent.js +560 -0
- package/dist/agents/crossref-arbiter-agent.d.ts +72 -0
- package/dist/agents/crossref-arbiter-agent.js +147 -0
- package/dist/agents/documentation-agent.d.ts +55 -0
- package/dist/agents/documentation-agent.js +159 -0
- package/dist/agents/exploration-agent.d.ts +58 -0
- package/dist/agents/exploration-agent.js +102 -0
- package/dist/agents/grouping-agent.d.ts +167 -0
- package/dist/agents/grouping-agent.js +557 -0
- package/dist/agents/index-agent.d.ts +86 -0
- package/dist/agents/index-agent.js +360 -0
- package/dist/agents/organization-agent.d.ts +144 -0
- package/dist/agents/organization-agent.js +607 -0
- package/dist/auth.d.ts +372 -0
- package/dist/auth.js +1072 -0
- package/dist/broadcast-mcp.d.ts +21 -0
- package/dist/broadcast-mcp.js +59 -0
- package/dist/changelog.d.ts +85 -0
- package/dist/changelog.js +223 -0
- package/dist/decision-queue.d.ts +173 -0
- package/dist/decision-queue.js +265 -0
- package/dist/diff-scope.d.ts +24 -0
- package/dist/diff-scope.js +28 -0
- package/dist/discovery.d.ts +54 -0
- package/dist/discovery.js +405 -0
- package/dist/grouping.d.ts +37 -0
- package/dist/grouping.js +343 -0
- package/dist/helpers/format.d.ts +5 -0
- package/dist/helpers/format.js +13 -0
- package/dist/helpers/index.d.ts +11 -0
- package/dist/helpers/index.js +11 -0
- package/dist/helpers/parsing.d.ts +52 -0
- package/dist/helpers/parsing.js +128 -0
- package/dist/helpers/paths.d.ts +41 -0
- package/dist/helpers/paths.js +67 -0
- package/dist/helpers/strings.d.ts +45 -0
- package/dist/helpers/strings.js +97 -0
- package/dist/index.d.ts +135 -0
- package/dist/index.js +1087 -0
- package/dist/merge-utils.d.ts +22 -0
- package/dist/merge-utils.js +34 -0
- package/dist/orchestrator.d.ts +194 -0
- package/dist/orchestrator.js +1169 -0
- package/dist/output.d.ts +106 -0
- package/dist/output.js +243 -0
- package/dist/progress.d.ts +228 -0
- package/dist/progress.js +644 -0
- package/dist/providers/copilot.d.ts +247 -0
- package/dist/providers/copilot.js +598 -0
- package/dist/providers/index.d.ts +15 -0
- package/dist/providers/index.js +12 -0
- package/dist/providers/opencode.d.ts +156 -0
- package/dist/providers/opencode.js +416 -0
- package/dist/providers/types.d.ts +156 -0
- package/dist/providers/types.js +16 -0
- package/dist/resources.d.ts +76 -0
- package/dist/resources.js +151 -0
- package/dist/search-index.d.ts +71 -0
- package/dist/search-index.js +187 -0
- package/dist/search-mcp.d.ts +25 -0
- package/dist/search-mcp.js +100 -0
- package/dist/server-utils.d.ts +56 -0
- package/dist/server-utils.js +135 -0
- package/dist/session.d.ts +227 -0
- package/dist/session.js +370 -0
- package/dist/types.d.ts +272 -0
- package/dist/types.js +5 -0
- package/dist/worktree.d.ts +82 -0
- package/dist/worktree.js +187 -0
- package/package.json +45 -0
package/dist/output.d.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Destination directory management and structural document generation
|
|
3
|
+
* for Hem.
|
|
4
|
+
*
|
|
5
|
+
* Provides utilities for:
|
|
6
|
+
* - Creating and resolving output paths within the destination directory
|
|
7
|
+
* - Scanning actual files on disk for TOC generation (no LLM)
|
|
8
|
+
* - Writing the table of contents (`index.md`)
|
|
9
|
+
* - Writing the architecture overview (`architecture.md`)
|
|
10
|
+
*
|
|
11
|
+
* Architecture (v2):
|
|
12
|
+
* - TOC is generated programmatically by scanning files on disk.
|
|
13
|
+
* - No more `DocumentationPlan`, `HierarchyNode`, or `PlannedTopic`.
|
|
14
|
+
* - Agents write files directly; this module only handles structural
|
|
15
|
+
* navigation documents and path utilities.
|
|
16
|
+
*
|
|
17
|
+
* All writes are strictly confined to the destination directory to
|
|
18
|
+
* ensure source files are never modified (US2 safety guarantee).
|
|
19
|
+
*
|
|
20
|
+
* Reference: spec.md US2 & US6, FR-007, FR-010.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Ensures the destination directory exists, creating it if necessary.
|
|
24
|
+
* Subdirectories are created dynamically by the doc agents.
|
|
25
|
+
*
|
|
26
|
+
* @param destinationPath - Path to the destination directory.
|
|
27
|
+
*/
|
|
28
|
+
export declare function ensureDestinationDir(destinationPath: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Scans the destination directory for all `.md` files.
|
|
31
|
+
*
|
|
32
|
+
* Used by the TOC generator and post-processing agents to discover
|
|
33
|
+
* what documentation files actually exist on disk.
|
|
34
|
+
*
|
|
35
|
+
* @param destinationPath - Absolute path to the destination directory.
|
|
36
|
+
* @returns Array of relative paths (e.g., `["features/auth.md", "layers/services.md"]`).
|
|
37
|
+
*/
|
|
38
|
+
export declare function scanDocFiles(destinationPath: string): Promise<string[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Generates the Markdown content for the table of contents (`index.md`).
|
|
41
|
+
*
|
|
42
|
+
* Scans the provided file list and produces a navigable index grouped by
|
|
43
|
+
* subdirectory. Directory names are auto-converted to section headers
|
|
44
|
+
* (e.g., `auth/` → "## Auth"). Top-level files (excluding `index.md` and
|
|
45
|
+
* `architecture.md`) are listed under "## Overview" if present.
|
|
46
|
+
*
|
|
47
|
+
* @param projectName - The project name for the title.
|
|
48
|
+
* @param docFiles - Relative paths of all documentation files.
|
|
49
|
+
* @returns The full Markdown content for `index.md`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function generateTableOfContents(projectName: string, docFiles: string[]): string;
|
|
52
|
+
/**
|
|
53
|
+
* Generates only the navigable link-list portion of the table of contents.
|
|
54
|
+
*
|
|
55
|
+
* This is the body that gets inserted into an AI-generated index.md via
|
|
56
|
+
* the `<!-- TOC -->` placeholder, or appended to the procedural fallback
|
|
57
|
+
* header by `generateTableOfContents()`.
|
|
58
|
+
*
|
|
59
|
+
* Produces:
|
|
60
|
+
* - Quick Navigation (link to architecture.md, if present)
|
|
61
|
+
* - Subdirectory sections (alphabetical)
|
|
62
|
+
* - Overview section (top-level non-special files)
|
|
63
|
+
*
|
|
64
|
+
* @param projectName - The project name (unused currently, reserved for future heading customization).
|
|
65
|
+
* @param docFiles - Relative paths of all documentation files.
|
|
66
|
+
* @returns Markdown string containing only the sectioned link list.
|
|
67
|
+
*/
|
|
68
|
+
export declare function generateTocLinkList(_projectName: string, docFiles: string[]): string;
|
|
69
|
+
/**
|
|
70
|
+
* Replaces the `<!-- TOC -->` placeholder in AI-generated index content
|
|
71
|
+
* with the procedurally generated table of contents link list.
|
|
72
|
+
*
|
|
73
|
+
* If the placeholder is not found, the link list is appended at the end
|
|
74
|
+
* as a safety fallback.
|
|
75
|
+
*
|
|
76
|
+
* @param agentContent - The AI-generated index.md content containing `<!-- TOC -->`.
|
|
77
|
+
* @param tocLinkList - The procedural link list from `generateTocLinkList()`.
|
|
78
|
+
* @returns The final index.md content with the placeholder replaced.
|
|
79
|
+
*/
|
|
80
|
+
export declare function replaceTocPlaceholder(agentContent: string, tocLinkList: string): string;
|
|
81
|
+
/**
|
|
82
|
+
* Writes the table of contents to `{destinationPath}/index.md`.
|
|
83
|
+
*
|
|
84
|
+
* @param destinationPath - Path to the destination directory.
|
|
85
|
+
* @param content - The Markdown content to write.
|
|
86
|
+
*/
|
|
87
|
+
export declare function writeTableOfContents(destinationPath: string, content: string): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Writes the architecture overview to `{destinationPath}/architecture.md`.
|
|
90
|
+
*
|
|
91
|
+
* @param destinationPath - Path to the destination directory.
|
|
92
|
+
* @param content - The Markdown content to write.
|
|
93
|
+
*/
|
|
94
|
+
export declare function writeArchitectureOverview(destinationPath: string, content: string): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Recursively removes empty subdirectories within `destinationPath`.
|
|
97
|
+
*
|
|
98
|
+
* Walks bottom-up so that nested empty directories are pruned first,
|
|
99
|
+
* allowing their parent to become empty and be pruned in turn.
|
|
100
|
+
* The root `destinationPath` itself is never removed.
|
|
101
|
+
*
|
|
102
|
+
* Silently ignores errors (permission issues, race conditions, etc.).
|
|
103
|
+
*
|
|
104
|
+
* @param destinationPath - Absolute path to the destination directory.
|
|
105
|
+
*/
|
|
106
|
+
export declare function removeEmptyDirs(destinationPath: string): Promise<void>;
|
package/dist/output.js
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Destination directory management and structural document generation
|
|
3
|
+
* for Hem.
|
|
4
|
+
*
|
|
5
|
+
* Provides utilities for:
|
|
6
|
+
* - Creating and resolving output paths within the destination directory
|
|
7
|
+
* - Scanning actual files on disk for TOC generation (no LLM)
|
|
8
|
+
* - Writing the table of contents (`index.md`)
|
|
9
|
+
* - Writing the architecture overview (`architecture.md`)
|
|
10
|
+
*
|
|
11
|
+
* Architecture (v2):
|
|
12
|
+
* - TOC is generated programmatically by scanning files on disk.
|
|
13
|
+
* - No more `DocumentationPlan`, `HierarchyNode`, or `PlannedTopic`.
|
|
14
|
+
* - Agents write files directly; this module only handles structural
|
|
15
|
+
* navigation documents and path utilities.
|
|
16
|
+
*
|
|
17
|
+
* All writes are strictly confined to the destination directory to
|
|
18
|
+
* ensure source files are never modified (US2 safety guarantee).
|
|
19
|
+
*
|
|
20
|
+
* Reference: spec.md US2 & US6, FR-007, FR-010.
|
|
21
|
+
*/
|
|
22
|
+
import { resolve, join } from "node:path";
|
|
23
|
+
import { mkdir, writeFile, readdir, rmdir } from "node:fs/promises";
|
|
24
|
+
import fg from "fast-glob";
|
|
25
|
+
import { dirToHeading, fileToTitle } from "./helpers/strings.js";
|
|
26
|
+
// ── Path Utilities ──────────────────────────────────────────────────────
|
|
27
|
+
/**
|
|
28
|
+
* Ensures the destination directory exists, creating it if necessary.
|
|
29
|
+
* Subdirectories are created dynamically by the doc agents.
|
|
30
|
+
*
|
|
31
|
+
* @param destinationPath - Path to the destination directory.
|
|
32
|
+
*/
|
|
33
|
+
export async function ensureDestinationDir(destinationPath) {
|
|
34
|
+
const absoluteDestination = resolve(destinationPath);
|
|
35
|
+
await mkdir(absoluteDestination, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
// ── Disk Scanning ──────────────────────────────────────────────────────
|
|
38
|
+
/**
|
|
39
|
+
* Scans the destination directory for all `.md` files.
|
|
40
|
+
*
|
|
41
|
+
* Used by the TOC generator and post-processing agents to discover
|
|
42
|
+
* what documentation files actually exist on disk.
|
|
43
|
+
*
|
|
44
|
+
* @param destinationPath - Absolute path to the destination directory.
|
|
45
|
+
* @returns Array of relative paths (e.g., `["features/auth.md", "layers/services.md"]`).
|
|
46
|
+
*/
|
|
47
|
+
export async function scanDocFiles(destinationPath) {
|
|
48
|
+
const absoluteDestination = resolve(destinationPath);
|
|
49
|
+
try {
|
|
50
|
+
const files = await fg("**/*.md", {
|
|
51
|
+
cwd: absoluteDestination,
|
|
52
|
+
absolute: false,
|
|
53
|
+
onlyFiles: true,
|
|
54
|
+
dot: false,
|
|
55
|
+
});
|
|
56
|
+
// Sort for deterministic output
|
|
57
|
+
return files.sort();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// ── Table of Contents ─────────────────────────────────────────────────
|
|
64
|
+
/**
|
|
65
|
+
* Generates the Markdown content for the table of contents (`index.md`).
|
|
66
|
+
*
|
|
67
|
+
* Scans the provided file list and produces a navigable index grouped by
|
|
68
|
+
* subdirectory. Directory names are auto-converted to section headers
|
|
69
|
+
* (e.g., `auth/` → "## Auth"). Top-level files (excluding `index.md` and
|
|
70
|
+
* `architecture.md`) are listed under "## Overview" if present.
|
|
71
|
+
*
|
|
72
|
+
* @param projectName - The project name for the title.
|
|
73
|
+
* @param docFiles - Relative paths of all documentation files.
|
|
74
|
+
* @returns The full Markdown content for `index.md`.
|
|
75
|
+
*/
|
|
76
|
+
export function generateTableOfContents(projectName, docFiles) {
|
|
77
|
+
const lines = [];
|
|
78
|
+
// H1 title
|
|
79
|
+
lines.push(`# ${projectName} Documentation`);
|
|
80
|
+
lines.push("");
|
|
81
|
+
// Intro paragraph
|
|
82
|
+
const pageCount = docFiles.filter((f) => f !== "index.md").length;
|
|
83
|
+
lines.push(`This documentation covers ${pageCount} pages.`);
|
|
84
|
+
lines.push("");
|
|
85
|
+
// Append the navigable link list
|
|
86
|
+
lines.push(generateTocLinkList(projectName, docFiles));
|
|
87
|
+
return lines.join("\n");
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Generates only the navigable link-list portion of the table of contents.
|
|
91
|
+
*
|
|
92
|
+
* This is the body that gets inserted into an AI-generated index.md via
|
|
93
|
+
* the `<!-- TOC -->` placeholder, or appended to the procedural fallback
|
|
94
|
+
* header by `generateTableOfContents()`.
|
|
95
|
+
*
|
|
96
|
+
* Produces:
|
|
97
|
+
* - Quick Navigation (link to architecture.md, if present)
|
|
98
|
+
* - Subdirectory sections (alphabetical)
|
|
99
|
+
* - Overview section (top-level non-special files)
|
|
100
|
+
*
|
|
101
|
+
* @param projectName - The project name (unused currently, reserved for future heading customization).
|
|
102
|
+
* @param docFiles - Relative paths of all documentation files.
|
|
103
|
+
* @returns Markdown string containing only the sectioned link list.
|
|
104
|
+
*/
|
|
105
|
+
export function generateTocLinkList(_projectName, docFiles) {
|
|
106
|
+
const lines = [];
|
|
107
|
+
// Navigation links
|
|
108
|
+
const hasArch = docFiles.includes("architecture.md");
|
|
109
|
+
if (hasArch) {
|
|
110
|
+
lines.push("## Quick navigation");
|
|
111
|
+
lines.push("");
|
|
112
|
+
lines.push("- [Architecture Overview](./architecture.md) — High-level system design and component interactions");
|
|
113
|
+
lines.push("");
|
|
114
|
+
}
|
|
115
|
+
// Bucket files by top-level directory (or "" for root-level files)
|
|
116
|
+
const buckets = new Map();
|
|
117
|
+
const reserved = new Set(["index.md", "architecture.md"]);
|
|
118
|
+
for (const file of docFiles) {
|
|
119
|
+
if (reserved.has(file))
|
|
120
|
+
continue;
|
|
121
|
+
const slashIdx = file.indexOf("/");
|
|
122
|
+
const bucket = slashIdx === -1 ? "" : file.slice(0, slashIdx);
|
|
123
|
+
if (!buckets.has(bucket)) {
|
|
124
|
+
buckets.set(bucket, []);
|
|
125
|
+
}
|
|
126
|
+
buckets.get(bucket).push(file);
|
|
127
|
+
}
|
|
128
|
+
// Sort each bucket's files
|
|
129
|
+
for (const files of buckets.values()) {
|
|
130
|
+
files.sort();
|
|
131
|
+
}
|
|
132
|
+
// Render subdirectories alphabetically, then top-level files last.
|
|
133
|
+
const topLevel = buckets.get("") ?? [];
|
|
134
|
+
const otherDirs = [...buckets.keys()]
|
|
135
|
+
.filter((k) => k !== "")
|
|
136
|
+
.sort();
|
|
137
|
+
// Subdirectory sections (alphabetical)
|
|
138
|
+
for (const dir of otherDirs) {
|
|
139
|
+
const files = buckets.get(dir);
|
|
140
|
+
lines.push(`## ${dirToHeading(dir)}`);
|
|
141
|
+
lines.push("");
|
|
142
|
+
for (const file of files) {
|
|
143
|
+
const name = fileToTitle(file);
|
|
144
|
+
lines.push(`- [${name}](./${file})`);
|
|
145
|
+
}
|
|
146
|
+
lines.push("");
|
|
147
|
+
}
|
|
148
|
+
// Top-level files
|
|
149
|
+
if (topLevel.length > 0) {
|
|
150
|
+
lines.push("## Overview");
|
|
151
|
+
lines.push("");
|
|
152
|
+
for (const file of topLevel) {
|
|
153
|
+
const name = fileToTitle(file);
|
|
154
|
+
lines.push(`- [${name}](./${file})`);
|
|
155
|
+
}
|
|
156
|
+
lines.push("");
|
|
157
|
+
}
|
|
158
|
+
return lines.join("\n");
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Replaces the `<!-- TOC -->` placeholder in AI-generated index content
|
|
162
|
+
* with the procedurally generated table of contents link list.
|
|
163
|
+
*
|
|
164
|
+
* If the placeholder is not found, the link list is appended at the end
|
|
165
|
+
* as a safety fallback.
|
|
166
|
+
*
|
|
167
|
+
* @param agentContent - The AI-generated index.md content containing `<!-- TOC -->`.
|
|
168
|
+
* @param tocLinkList - The procedural link list from `generateTocLinkList()`.
|
|
169
|
+
* @returns The final index.md content with the placeholder replaced.
|
|
170
|
+
*/
|
|
171
|
+
export function replaceTocPlaceholder(agentContent, tocLinkList) {
|
|
172
|
+
const placeholder = "<!-- TOC -->";
|
|
173
|
+
if (agentContent.includes(placeholder)) {
|
|
174
|
+
return agentContent.replace(placeholder, tocLinkList);
|
|
175
|
+
}
|
|
176
|
+
// Fallback: append TOC at the end
|
|
177
|
+
return agentContent.trimEnd() + "\n\n" + tocLinkList;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Writes the table of contents to `{destinationPath}/index.md`.
|
|
181
|
+
*
|
|
182
|
+
* @param destinationPath - Path to the destination directory.
|
|
183
|
+
* @param content - The Markdown content to write.
|
|
184
|
+
*/
|
|
185
|
+
export async function writeTableOfContents(destinationPath, content) {
|
|
186
|
+
const absoluteDestination = resolve(destinationPath);
|
|
187
|
+
const outputPath = join(absoluteDestination, "index.md");
|
|
188
|
+
await mkdir(absoluteDestination, { recursive: true });
|
|
189
|
+
await writeFile(outputPath, content, "utf-8");
|
|
190
|
+
}
|
|
191
|
+
// ── Architecture Overview ─────────────────────────────────────────────
|
|
192
|
+
/**
|
|
193
|
+
* Writes the architecture overview to `{destinationPath}/architecture.md`.
|
|
194
|
+
*
|
|
195
|
+
* @param destinationPath - Path to the destination directory.
|
|
196
|
+
* @param content - The Markdown content to write.
|
|
197
|
+
*/
|
|
198
|
+
export async function writeArchitectureOverview(destinationPath, content) {
|
|
199
|
+
const absoluteDestination = resolve(destinationPath);
|
|
200
|
+
const outputPath = join(absoluteDestination, "architecture.md");
|
|
201
|
+
await writeFile(outputPath, content, "utf-8");
|
|
202
|
+
}
|
|
203
|
+
// ── Cleanup ───────────────────────────────────────────────────────────
|
|
204
|
+
/**
|
|
205
|
+
* Recursively removes empty subdirectories within `destinationPath`.
|
|
206
|
+
*
|
|
207
|
+
* Walks bottom-up so that nested empty directories are pruned first,
|
|
208
|
+
* allowing their parent to become empty and be pruned in turn.
|
|
209
|
+
* The root `destinationPath` itself is never removed.
|
|
210
|
+
*
|
|
211
|
+
* Silently ignores errors (permission issues, race conditions, etc.).
|
|
212
|
+
*
|
|
213
|
+
* @param destinationPath - Absolute path to the destination directory.
|
|
214
|
+
*/
|
|
215
|
+
export async function removeEmptyDirs(destinationPath) {
|
|
216
|
+
const root = resolve(destinationPath);
|
|
217
|
+
async function walk(dir) {
|
|
218
|
+
let entries;
|
|
219
|
+
try {
|
|
220
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// Recurse into subdirectories first (bottom-up)
|
|
226
|
+
for (const entry of entries) {
|
|
227
|
+
if (entry.isDirectory()) {
|
|
228
|
+
await walk(join(dir, entry.name));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// After recursing, try to remove this dir if it's now empty
|
|
232
|
+
// (but never the root destination itself)
|
|
233
|
+
if (dir !== root) {
|
|
234
|
+
try {
|
|
235
|
+
await rmdir(dir); // throws ENOTEMPTY if not empty
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
// Not empty or other error — ignore
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
await walk(root);
|
|
243
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ink React components for terminal UI — auth prompts, dashboard, phase display.
|
|
3
|
+
*
|
|
4
|
+
* Components:
|
|
5
|
+
* - AuthPrompt — First-run 4-option select menu
|
|
6
|
+
* - ApiKeyInput — Provider select + API key text entry
|
|
7
|
+
* - FreeModelPicker — Free model list with data security annotations
|
|
8
|
+
* - ConfigPrompt — Project config provider/model selection
|
|
9
|
+
* - App — Root dashboard component holding ProgressState
|
|
10
|
+
* - Header — Version + model display
|
|
11
|
+
* - PhaseRow — Single pipeline phase with status indicator
|
|
12
|
+
* - GenerationDashboard — Multi-line group status during generation phase
|
|
13
|
+
* - GroupRow — Single file group with spinner/status/label
|
|
14
|
+
* - Summary — Final success/failure report with timing
|
|
15
|
+
*
|
|
16
|
+
* Reference: plan.md lines 310-351 (Terminal UI Architecture),
|
|
17
|
+
* contracts/cli-interface.md lines 93-127, 148-189.
|
|
18
|
+
*/
|
|
19
|
+
import React from "react";
|
|
20
|
+
import type { FreeModelInfo, ModelSelection, ProgressState, GroupStatus } from "./types.js";
|
|
21
|
+
/** Possible choices from the first-run auth prompt. */
|
|
22
|
+
export type AuthChoice = "oauth" | "api-key" | "free" | "exit";
|
|
23
|
+
/** Props for the AuthPrompt component. */
|
|
24
|
+
export interface AuthPromptProps {
|
|
25
|
+
/** Callback invoked when the user selects an option. */
|
|
26
|
+
onSelect: (choice: AuthChoice) => void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* First-run authentication prompt.
|
|
30
|
+
*
|
|
31
|
+
* Renders a 4-option interactive select menu using arrow keys + Enter.
|
|
32
|
+
*/
|
|
33
|
+
export declare function AuthPrompt({ onSelect }: AuthPromptProps): React.ReactElement;
|
|
34
|
+
/** Props for the ApiKeyInput component. */
|
|
35
|
+
export interface ApiKeyInputProps {
|
|
36
|
+
/** List of provider IDs the user can choose from. */
|
|
37
|
+
providers: string[];
|
|
38
|
+
/** Callback invoked when the user submits a provider + key. */
|
|
39
|
+
onSubmit: (providerId: string, key: string) => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* API key entry component.
|
|
43
|
+
*
|
|
44
|
+
* Two-step flow:
|
|
45
|
+
* 1. Select a provider from a list using arrow keys + Enter.
|
|
46
|
+
* 2. Type/paste the API key and press Enter to submit.
|
|
47
|
+
*/
|
|
48
|
+
export declare function ApiKeyInput({ providers, onSubmit, }: ApiKeyInputProps): React.ReactElement;
|
|
49
|
+
/** A provider available for OAuth authentication. */
|
|
50
|
+
export interface OAuthProviderOption {
|
|
51
|
+
/** Provider identifier (e.g., `"anthropic"`, `"openai"`). */
|
|
52
|
+
id: string;
|
|
53
|
+
/** Display name (e.g., `"Anthropic"`, `"OpenAI"`). */
|
|
54
|
+
name: string;
|
|
55
|
+
}
|
|
56
|
+
/** Props for the OAuthProviderSelect component. */
|
|
57
|
+
export interface OAuthProviderSelectProps {
|
|
58
|
+
/** List of providers available for OAuth login. */
|
|
59
|
+
providers: OAuthProviderOption[];
|
|
60
|
+
/** Callback invoked when the user selects a provider. */
|
|
61
|
+
onSelect: (provider: OAuthProviderOption) => void;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* OAuth provider selection component.
|
|
65
|
+
*/
|
|
66
|
+
export declare function OAuthProviderSelect({ providers, onSelect, }: OAuthProviderSelectProps): React.ReactElement;
|
|
67
|
+
/** Props for the OAuthWaiting component. */
|
|
68
|
+
export interface OAuthWaitingProps {
|
|
69
|
+
/** The provider the user is authenticating with. */
|
|
70
|
+
providerName: string;
|
|
71
|
+
/** The URL the user should visit to complete authentication. */
|
|
72
|
+
url: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* OAuth waiting indicator component.
|
|
76
|
+
*/
|
|
77
|
+
export declare function OAuthWaiting({ providerName, url, }: OAuthWaitingProps): React.ReactElement;
|
|
78
|
+
/** Props for the FreeModelPicker component. */
|
|
79
|
+
export interface FreeModelPickerProps {
|
|
80
|
+
/** Available free models from the Opencode catalog. */
|
|
81
|
+
models: FreeModelInfo[];
|
|
82
|
+
/** Callback invoked when the user selects a model. */
|
|
83
|
+
onSelect: (model: FreeModelInfo) => void;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Free model selection component.
|
|
87
|
+
*/
|
|
88
|
+
export declare function FreeModelPicker({ models, onSelect, }: FreeModelPickerProps): React.ReactElement;
|
|
89
|
+
/** A single option shown in the config prompt. */
|
|
90
|
+
export interface ConfigOption {
|
|
91
|
+
/** The model selection this option represents. */
|
|
92
|
+
value: ModelSelection;
|
|
93
|
+
/** Display label (e.g., "Anthropic — claude-sonnet-4"). */
|
|
94
|
+
label: string;
|
|
95
|
+
/** Optional description shown below the label. */
|
|
96
|
+
description?: string;
|
|
97
|
+
}
|
|
98
|
+
/** Props for the ConfigPrompt component. */
|
|
99
|
+
export interface ConfigPromptProps {
|
|
100
|
+
/** Available provider/model options to choose from. */
|
|
101
|
+
options: ConfigOption[];
|
|
102
|
+
/** Callback invoked when the user selects an option. */
|
|
103
|
+
onSelect: (selection: ModelSelection) => void;
|
|
104
|
+
/** Heading text shown above the option list. Defaults to "Select a provider and model for this project:". */
|
|
105
|
+
title?: string;
|
|
106
|
+
/** @internal Override auto-detected max visible items (for testing). */
|
|
107
|
+
maxVisible?: number;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Interactive provider/model selection prompt for project configuration.
|
|
111
|
+
*
|
|
112
|
+
* Renders a list of provider/model options using arrow keys + Enter,
|
|
113
|
+
* following the same navigation pattern as AuthPrompt.
|
|
114
|
+
*/
|
|
115
|
+
export declare function ConfigPrompt({ options, onSelect, title, maxVisible, }: ConfigPromptProps): React.ReactElement;
|
|
116
|
+
/** Props for the Header component. */
|
|
117
|
+
export interface HeaderProps {
|
|
118
|
+
/** Display label for the active model. */
|
|
119
|
+
modelLabel: string;
|
|
120
|
+
/** Human-readable provider display name (e.g., "Anthropic", "Opencode"). */
|
|
121
|
+
providerLabel: string;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Header component.
|
|
125
|
+
*/
|
|
126
|
+
export declare function Header({ modelLabel, providerLabel }: HeaderProps): React.ReactElement;
|
|
127
|
+
/** Props for the PhaseRow component. */
|
|
128
|
+
export interface PhaseRowProps {
|
|
129
|
+
/** Display label shown in brackets. */
|
|
130
|
+
label: string;
|
|
131
|
+
/** Description text shown after the label. */
|
|
132
|
+
description: string;
|
|
133
|
+
/** Status of this phase. */
|
|
134
|
+
status: "pending" | "active" | "done";
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Renders a single pipeline phase row with status indicator.
|
|
138
|
+
*/
|
|
139
|
+
export declare function PhaseRow({ label, description, status, }: PhaseRowProps): React.ReactElement;
|
|
140
|
+
/** Props for the GroupRow component. */
|
|
141
|
+
export interface GroupRowProps {
|
|
142
|
+
/** The group status to render. */
|
|
143
|
+
group: GroupStatus;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Renders a single file group row within the generation dashboard.
|
|
147
|
+
*
|
|
148
|
+
* Uses `groupId` as the display identifier and `label` as the description.
|
|
149
|
+
*/
|
|
150
|
+
export declare function GroupRow({ group }: GroupRowProps): React.ReactElement;
|
|
151
|
+
/** Props for the ExplorationDashboard component. */
|
|
152
|
+
export interface ExplorationDashboardProps {
|
|
153
|
+
/** Per-group status entries for exploration. */
|
|
154
|
+
explorationStatuses: GroupStatus[];
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Renders the exploration phase dashboard showing per-group exploration progress.
|
|
158
|
+
*/
|
|
159
|
+
export declare function ExplorationDashboard({ explorationStatuses, }: ExplorationDashboardProps): React.ReactElement;
|
|
160
|
+
/** Props for the GenerationDashboard component. */
|
|
161
|
+
export interface GenerationDashboardProps {
|
|
162
|
+
/** Per-group status entries. */
|
|
163
|
+
groupStatuses: GroupStatus[];
|
|
164
|
+
/** Number of completed sessions. */
|
|
165
|
+
completedSessions: number;
|
|
166
|
+
/** Total number of pages to generate. */
|
|
167
|
+
totalPages: number;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Renders the generation phase dashboard showing progress for each group.
|
|
171
|
+
*/
|
|
172
|
+
export declare function GenerationDashboard({ groupStatuses, completedSessions, totalPages, }: GenerationDashboardProps): React.ReactElement;
|
|
173
|
+
/** Props for the Summary component. */
|
|
174
|
+
export interface SummaryProps {
|
|
175
|
+
/** Total number of pages generated. */
|
|
176
|
+
totalPages: number;
|
|
177
|
+
/** Number of failed sessions. */
|
|
178
|
+
failedSessions: number;
|
|
179
|
+
/** Pipeline start timestamp (ms since epoch). */
|
|
180
|
+
startedAt: number;
|
|
181
|
+
/** Pipeline completion timestamp (ms since epoch), or undefined if not complete. */
|
|
182
|
+
completedAt: number | undefined;
|
|
183
|
+
/** Warnings to display. */
|
|
184
|
+
warnings: string[];
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Renders the final summary after pipeline completion.
|
|
188
|
+
*/
|
|
189
|
+
export declare function Summary({ totalPages, failedSessions, startedAt, completedAt, warnings, }: SummaryProps): React.ReactElement;
|
|
190
|
+
/** Props for the App component. */
|
|
191
|
+
export interface AppProps {
|
|
192
|
+
/** Initial progress state. */
|
|
193
|
+
initialState: ProgressState;
|
|
194
|
+
/** Callback to expose the setState function to the pipeline. */
|
|
195
|
+
onStateRef: (setter: (partial: Partial<ProgressState>) => void) => void;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Root dashboard component.
|
|
199
|
+
*/
|
|
200
|
+
export declare function App({ initialState, onStateRef }: AppProps): React.ReactElement;
|
|
201
|
+
/**
|
|
202
|
+
* Non-interactive log-style dashboard for piped output and CI environments.
|
|
203
|
+
*/
|
|
204
|
+
export declare class LogDashboard {
|
|
205
|
+
private state;
|
|
206
|
+
private log;
|
|
207
|
+
private verbose;
|
|
208
|
+
private loggedGroupStarts;
|
|
209
|
+
private loggedGroupCompletions;
|
|
210
|
+
private loggedExplorationStarts;
|
|
211
|
+
private loggedExplorationCompletions;
|
|
212
|
+
constructor(initialState: ProgressState, log?: (message: string) => void, verbose?: boolean);
|
|
213
|
+
updateState(partial: Partial<ProgressState>): void;
|
|
214
|
+
private logPhaseTransition;
|
|
215
|
+
private logGroupChanges;
|
|
216
|
+
private logExplorationChanges;
|
|
217
|
+
waitUntilExit(): Promise<void>;
|
|
218
|
+
}
|
|
219
|
+
/** Return type for both Ink and log-style dashboards. */
|
|
220
|
+
export interface DashboardHandle {
|
|
221
|
+
updateState: (partial: Partial<ProgressState>) => void;
|
|
222
|
+
waitUntilExit: () => Promise<void>;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Creates the progress dashboard and returns a state updater function
|
|
226
|
+
* and a `waitUntilExit` promise.
|
|
227
|
+
*/
|
|
228
|
+
export declare function renderDashboard(initialState: ProgressState, verbose?: boolean): DashboardHandle;
|