gitnexushub 0.4.3 → 0.4.4
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/dist/wiki/index.js
CHANGED
|
@@ -16,9 +16,8 @@ function reportError(err) {
|
|
|
16
16
|
process.exit(1);
|
|
17
17
|
}
|
|
18
18
|
export function registerWikiCommand(program) {
|
|
19
|
-
const wiki = program
|
|
20
|
-
|
|
21
|
-
.command('upload')
|
|
19
|
+
const wiki = program
|
|
20
|
+
.command('wiki')
|
|
22
21
|
.description('Generate the wiki locally with Claude Code and upload it to the Hub')
|
|
23
22
|
.option('--mode <mode>', 'full | incremental', 'full')
|
|
24
23
|
.option('--model <model>', 'Claude model to use', REAL_DEFAULT_MODEL)
|
|
@@ -28,14 +27,29 @@ export function registerWikiCommand(program) {
|
|
|
28
27
|
if (opts.model)
|
|
29
28
|
deps.model = opts.model;
|
|
30
29
|
const ac = new AbortController();
|
|
30
|
+
let sigCount = 0;
|
|
31
|
+
let forceExitTimer = null;
|
|
31
32
|
const onSig = () => {
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
sigCount++;
|
|
34
|
+
if (sigCount === 1) {
|
|
35
|
+
warn('interrupt received — cleaning up (Ctrl+C again to force quit)...');
|
|
36
|
+
ac.abort();
|
|
37
|
+
forceExitTimer = setTimeout(() => {
|
|
38
|
+
warn('cleanup timed out, forcing exit');
|
|
39
|
+
process.exit(130);
|
|
40
|
+
}, 3000);
|
|
41
|
+
forceExitTimer.unref();
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
if (forceExitTimer)
|
|
45
|
+
clearTimeout(forceExitTimer);
|
|
46
|
+
process.exit(130);
|
|
47
|
+
}
|
|
34
48
|
};
|
|
35
49
|
process.on('SIGINT', onSig);
|
|
36
50
|
process.on('SIGTERM', onSig);
|
|
37
51
|
try {
|
|
38
|
-
info(
|
|
52
|
+
info('Resolving repo context...');
|
|
39
53
|
const result = await runWikiUpload({ cwd, mode: opts.mode, model: opts.model, abortSignal: ac.signal }, deps);
|
|
40
54
|
ok(`Uploaded ${result.pagesPersisted} pages.`);
|
|
41
55
|
if (result.failedSlugs.length > 0) {
|
|
@@ -43,9 +57,15 @@ export function registerWikiCommand(program) {
|
|
|
43
57
|
}
|
|
44
58
|
}
|
|
45
59
|
catch (err) {
|
|
60
|
+
if (ac.signal.aborted) {
|
|
61
|
+
warn('aborted');
|
|
62
|
+
process.exit(130);
|
|
63
|
+
}
|
|
46
64
|
reportError(err);
|
|
47
65
|
}
|
|
48
66
|
finally {
|
|
67
|
+
if (forceExitTimer)
|
|
68
|
+
clearTimeout(forceExitTimer);
|
|
49
69
|
process.off('SIGINT', onSig);
|
|
50
70
|
process.off('SIGTERM', onSig);
|
|
51
71
|
}
|
|
@@ -4,7 +4,7 @@ export async function resolveWikiContext(deps, opts = {}) {
|
|
|
4
4
|
const repoRoot = deps.getGitRoot(deps.cwd);
|
|
5
5
|
if (!repoRoot) {
|
|
6
6
|
throw new GnxError(ErrorCode.NOT_GIT_REPO, 'not a git repository', {
|
|
7
|
-
hint: 'cd into your project, or run: gnx wiki
|
|
7
|
+
hint: 'cd into your project, or run: gnx wiki <path>',
|
|
8
8
|
});
|
|
9
9
|
}
|
|
10
10
|
const headCommit = deps.getGitHead(repoRoot);
|
package/dist/wiki/session.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export interface RunSessionDeps {
|
|
|
21
21
|
modules: ModuleNode[];
|
|
22
22
|
moduleTree: unknown;
|
|
23
23
|
generatePage: GeneratePageFn;
|
|
24
|
+
onSessionStart?: (sessionId: string) => void;
|
|
24
25
|
onPageStart?: (slug: string) => void;
|
|
25
26
|
onPageDone?: (slug: string, bytes: number) => void;
|
|
26
27
|
onPageFail?: (slug: string, err: unknown) => void;
|
package/dist/wiki/session.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { resolveWikiContext } from './resolve-context.js';
|
|
2
2
|
import { runWikiUploadSession } from './session.js';
|
|
3
3
|
import { GnxError, ErrorCode } from './errors.js';
|
|
4
|
+
import { info } from '../cli-helpers.js';
|
|
4
5
|
function slugify(name) {
|
|
5
6
|
return name
|
|
6
7
|
.toLowerCase()
|
|
@@ -115,11 +116,13 @@ export async function runWikiUpload(opts, deps) {
|
|
|
115
116
|
if (opts.abortSignal?.aborted)
|
|
116
117
|
throw new GnxError(ErrorCode.USER_ABORTED, 'aborted before session start');
|
|
117
118
|
const runner = deps.createClaudeRunner();
|
|
119
|
+
info(`Fetching graph context from Hub (${ctx.hubFullName})...`);
|
|
118
120
|
const [prompts, groupingCtx] = await Promise.all([
|
|
119
121
|
ctx.api.wikiPromptTemplates(ctx.hubRepoId),
|
|
120
122
|
ctx.api.wikiGroupingContext(ctx.hubRepoId),
|
|
121
123
|
]);
|
|
122
124
|
// Phase 1: Module tree
|
|
125
|
+
info('Phase 1/3: generating module tree with Claude Code...');
|
|
123
126
|
const groupingPrompt = fillTemplate(prompts.grouping.user, {
|
|
124
127
|
COMMUNITY_GROUPS: groupingCtx.communityGroups,
|
|
125
128
|
INTER_COMMUNITY_EDGES: groupingCtx.interCommunityEdges,
|
|
@@ -138,6 +141,7 @@ export async function runWikiUpload(opts, deps) {
|
|
|
138
141
|
const allPageNodes = [...leaves, ...parents];
|
|
139
142
|
const moduleRegistry = allPageNodes.map((m) => `- [${m.title}](${m.slug}.md)`).join('\n');
|
|
140
143
|
const generatedPages = new Map();
|
|
144
|
+
info(`Phase 2/3: generating ${leaves.length} leaf page(s) + ${parents.length} parent page(s)...`);
|
|
141
145
|
if (opts.abortSignal?.aborted)
|
|
142
146
|
throw new GnxError(ErrorCode.USER_ABORTED, 'aborted before page generation');
|
|
143
147
|
// Phase 2a: Leaf pages
|
|
@@ -279,6 +283,19 @@ export async function runWikiUpload(opts, deps) {
|
|
|
279
283
|
summary: m.summary,
|
|
280
284
|
files: m.files,
|
|
281
285
|
}));
|
|
286
|
+
info('Phase 3/3: streaming pages to Hub + generating overview...');
|
|
287
|
+
let activeSessionId = null;
|
|
288
|
+
const onAbort = async () => {
|
|
289
|
+
if (!activeSessionId)
|
|
290
|
+
return;
|
|
291
|
+
try {
|
|
292
|
+
await ctx.api.wikiUploadAbort(ctx.hubRepoId, activeSessionId);
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
/* ignore secondary errors */
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
opts.abortSignal?.addEventListener('abort', onAbort, { once: true });
|
|
282
299
|
try {
|
|
283
300
|
return await runWikiUploadSession({
|
|
284
301
|
api: ctx.api,
|
|
@@ -290,6 +307,9 @@ export async function runWikiUpload(opts, deps) {
|
|
|
290
307
|
modules: orderedModules,
|
|
291
308
|
moduleTree,
|
|
292
309
|
generatePage: generatePageByType,
|
|
310
|
+
onSessionStart: (id) => {
|
|
311
|
+
activeSessionId = id;
|
|
312
|
+
},
|
|
293
313
|
});
|
|
294
314
|
}
|
|
295
315
|
catch (err) {
|
package/package.json
CHANGED