@handsupmin/gc-tree 1.1.3 → 1.1.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/src/cli.js +51 -15
- package/dist/src/hook.js +3 -3
- package/package.json +1 -1
- package/dist/src/proposals.js +0 -73
package/dist/src/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ import { dispatchGcTreeHook } from './hook.js';
|
|
|
9
9
|
import { onboardBranch } from './onboard.js';
|
|
10
10
|
import { buildProviderLaunchPlan, maybeLaunchProvider, promptLanguageSelection, promptLaunchProviderSelection, promptProviderSelection, } from './provider.js';
|
|
11
11
|
import { DEFAULT_BRANCH, branchDir, resolveHome } from './paths.js';
|
|
12
|
-
import { branchRepoMapPath,
|
|
12
|
+
import { branchRepoMapPath, detectCurrentRepoId, promptResolveScopeDecision, readBranchRepoMap, resolveBranchForRepo, setRepoScopeForBranch, } from './repo-map.js';
|
|
13
13
|
import { findRelatedDocs, getDocById, resolveContext } from './resolve.js';
|
|
14
14
|
import { scaffoldHostIntegration } from './scaffold.js';
|
|
15
15
|
import { appendScaffoldedHost, requirePreferredProvider, writeSettings, readSettings } from './settings.js';
|
|
@@ -47,14 +47,14 @@ function usage() {
|
|
|
47
47
|
gctree branches [--home DIR]
|
|
48
48
|
gctree repo-map [--home DIR]
|
|
49
49
|
gctree set-repo-scope --branch NAME [--repo NAME] [--cwd DIR] (--include|--exclude) [--home DIR]
|
|
50
|
-
gctree status [--home DIR] [--cwd DIR]
|
|
50
|
+
gctree status [--home DIR] [--branch NAME] [--cwd DIR]
|
|
51
51
|
gctree onboard [--home DIR] [--branch NAME] [--provider <codex|claude-code>] [--target DIR] [--no-launch]
|
|
52
52
|
gctree verify-onboarding [--home DIR] [--branch NAME]
|
|
53
53
|
gctree reset-gc-branch [--home DIR] [--branch NAME] --yes
|
|
54
54
|
gctree uninstall [--home DIR] [--target DIR] [--host <codex|claude-code|both>] [--keep-home] --yes
|
|
55
55
|
gctree resolve --query TEXT [--home DIR] [--branch NAME] [--cwd DIR]
|
|
56
|
-
gctree show-doc --id ID [--home DIR] [--branch NAME]
|
|
57
|
-
gctree related --id ID [--home DIR] [--branch NAME]
|
|
56
|
+
gctree show-doc --id ID [--home DIR] [--branch NAME] [--cwd DIR]
|
|
57
|
+
gctree related --id ID [--home DIR] [--branch NAME] [--cwd DIR]
|
|
58
58
|
gctree update-global-context [--home DIR] [--branch NAME] [--provider <codex|claude-code>] [--target DIR] [--no-launch]
|
|
59
59
|
gctree update-gc [--home DIR] [--branch NAME] [--provider <codex|claude-code>] [--target DIR] [--no-launch]
|
|
60
60
|
gctree ugc [--home DIR] [--branch NAME] [--provider <codex|claude-code>] [--target DIR] [--no-launch]
|
|
@@ -78,6 +78,15 @@ async function readStdinText() {
|
|
|
78
78
|
}
|
|
79
79
|
return Buffer.concat(chunks).toString('utf8');
|
|
80
80
|
}
|
|
81
|
+
async function resolveCommandBranch({ home, explicitBranch, cwd, }) {
|
|
82
|
+
const head = (await readHead(home)) || DEFAULT_BRANCH;
|
|
83
|
+
return resolveBranchForRepo({
|
|
84
|
+
home,
|
|
85
|
+
head,
|
|
86
|
+
explicitBranch,
|
|
87
|
+
cwd: cwd || process.cwd(),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
81
90
|
function compactMatchCommands(id, home, branch) {
|
|
82
91
|
const homeArg = `--home ${JSON.stringify(home)}`;
|
|
83
92
|
const branchArg = `--branch ${JSON.stringify(branch)}`;
|
|
@@ -276,22 +285,26 @@ async function main() {
|
|
|
276
285
|
return;
|
|
277
286
|
}
|
|
278
287
|
case 'status': {
|
|
279
|
-
const
|
|
288
|
+
const resolved = await resolveCommandBranch({
|
|
289
|
+
home,
|
|
290
|
+
explicitBranch: readArg('--branch') || undefined,
|
|
291
|
+
cwd: readArg('--cwd') || process.cwd(),
|
|
292
|
+
});
|
|
293
|
+
const gcBranch = resolved.gc_branch;
|
|
280
294
|
if (!existsSync(branchDir(home, gcBranch))) {
|
|
281
295
|
throw new Error('gc-tree is not initialized. Run `gctree init` first.');
|
|
282
296
|
}
|
|
283
297
|
const result = await statusForBranch(home, gcBranch);
|
|
284
298
|
const settings = await readSettings(home);
|
|
285
|
-
const mapping = await readBranchRepoMap(home);
|
|
286
|
-
const currentRepo = await detectCurrentRepoId(readArg('--cwd') || process.cwd());
|
|
287
299
|
console.log(JSON.stringify({
|
|
288
300
|
...result,
|
|
289
301
|
provider_mode: settings?.provider_mode || null,
|
|
290
302
|
preferred_provider: settings?.preferred_provider || null,
|
|
291
303
|
preferred_language: settings?.preferred_language || null,
|
|
292
|
-
current_repo:
|
|
304
|
+
current_repo: resolved.current_repo,
|
|
305
|
+
source: resolved.source,
|
|
293
306
|
branch_repo_map_path: branchRepoMapPath(home),
|
|
294
|
-
repo_scope_status:
|
|
307
|
+
repo_scope_status: resolved.scope_status,
|
|
295
308
|
}, null, 2));
|
|
296
309
|
return;
|
|
297
310
|
}
|
|
@@ -365,10 +378,8 @@ async function main() {
|
|
|
365
378
|
const query = readArg('--query');
|
|
366
379
|
if (!query)
|
|
367
380
|
usage();
|
|
368
|
-
const
|
|
369
|
-
const resolved = await resolveBranchForRepo({
|
|
381
|
+
const resolved = await resolveCommandBranch({
|
|
370
382
|
home,
|
|
371
|
-
head,
|
|
372
383
|
explicitBranch: readArg('--branch') || undefined,
|
|
373
384
|
cwd: readArg('--cwd') || process.cwd(),
|
|
374
385
|
});
|
|
@@ -491,10 +502,24 @@ async function main() {
|
|
|
491
502
|
const id = readArg('--id');
|
|
492
503
|
if (!id)
|
|
493
504
|
usage();
|
|
494
|
-
const
|
|
505
|
+
const resolved = await resolveCommandBranch({
|
|
506
|
+
home,
|
|
507
|
+
explicitBranch: readArg('--branch') || undefined,
|
|
508
|
+
cwd: readArg('--cwd') || process.cwd(),
|
|
509
|
+
});
|
|
510
|
+
const gcBranch = resolved.gc_branch;
|
|
495
511
|
const branchStatus = await statusForBranch(home, gcBranch);
|
|
496
512
|
if (branchStatus.doc_count === 0) {
|
|
497
|
-
console.log(JSON.stringify({
|
|
513
|
+
console.log(JSON.stringify({
|
|
514
|
+
status: 'empty_branch',
|
|
515
|
+
gc_branch: gcBranch,
|
|
516
|
+
id,
|
|
517
|
+
current_repo: resolved.current_repo,
|
|
518
|
+
source: resolved.source,
|
|
519
|
+
repo_scope_status: resolved.scope_status,
|
|
520
|
+
message: `gc-branch "${gcBranch}" has no docs yet.`,
|
|
521
|
+
doc: null,
|
|
522
|
+
}, null, 2));
|
|
498
523
|
return;
|
|
499
524
|
}
|
|
500
525
|
const doc = await getDocById({ home, branch: gcBranch, id });
|
|
@@ -502,6 +527,9 @@ async function main() {
|
|
|
502
527
|
status: doc ? 'matched' : 'doc_not_found',
|
|
503
528
|
gc_branch: gcBranch,
|
|
504
529
|
id,
|
|
530
|
+
current_repo: resolved.current_repo,
|
|
531
|
+
source: resolved.source,
|
|
532
|
+
repo_scope_status: resolved.scope_status,
|
|
505
533
|
message: doc ? `Loaded doc "${id}".` : `Doc "${id}" was not found in gc-branch "${gcBranch}".`,
|
|
506
534
|
doc,
|
|
507
535
|
}, null, 2));
|
|
@@ -511,12 +539,20 @@ async function main() {
|
|
|
511
539
|
const id = readArg('--id');
|
|
512
540
|
if (!id)
|
|
513
541
|
usage();
|
|
514
|
-
const
|
|
542
|
+
const resolved = await resolveCommandBranch({
|
|
543
|
+
home,
|
|
544
|
+
explicitBranch: readArg('--branch') || undefined,
|
|
545
|
+
cwd: readArg('--cwd') || process.cwd(),
|
|
546
|
+
});
|
|
547
|
+
const gcBranch = resolved.gc_branch;
|
|
515
548
|
const result = await findRelatedDocs({ home, branch: gcBranch, id });
|
|
516
549
|
console.log(JSON.stringify({
|
|
517
550
|
status: result.status,
|
|
518
551
|
gc_branch: gcBranch,
|
|
519
552
|
id,
|
|
553
|
+
current_repo: resolved.current_repo,
|
|
554
|
+
source: resolved.source,
|
|
555
|
+
repo_scope_status: resolved.scope_status,
|
|
520
556
|
message: result.status === 'matched'
|
|
521
557
|
? `Found ${result.matches.length} related docs for "${id}".`
|
|
522
558
|
: result.status === 'no_related_docs'
|
package/dist/src/hook.js
CHANGED
|
@@ -27,14 +27,14 @@ function limitMatches(matches, max = 3) {
|
|
|
27
27
|
function displayKeyword(match) {
|
|
28
28
|
return (match.label || match.title || match.id).trim();
|
|
29
29
|
}
|
|
30
|
-
function formatMatches(matches) {
|
|
30
|
+
function formatMatches(matches, gcBranch) {
|
|
31
31
|
return limitMatches(matches)
|
|
32
32
|
.map((match) => {
|
|
33
33
|
const summary = match.summary?.trim() ?? '';
|
|
34
34
|
const excerpt = match.excerpt?.trim() ?? '';
|
|
35
35
|
const context = summary || excerpt;
|
|
36
36
|
const shortContext = context.length > 180 ? `${context.slice(0, 177).trim()}...` : context;
|
|
37
|
-
const showDoc = `gctree show-doc --id "${match.id}"`;
|
|
37
|
+
const showDoc = `gctree show-doc --id "${match.id}" --branch "${gcBranch}"`;
|
|
38
38
|
return [
|
|
39
39
|
`[${displayKeyword(match)}]`,
|
|
40
40
|
shortContext,
|
|
@@ -59,7 +59,7 @@ function buildMatchContext({ gcBranch, currentRepo, repoScopeStatus, matches, })
|
|
|
59
59
|
const lines = [
|
|
60
60
|
`[gc-tree] USE FIRST: ${Math.min(matches.length, 3)} docs gc-branch="${gcBranch}" repo="${currentRepo || 'unscoped'}" scope=${repoScopeStatus}.`,
|
|
61
61
|
'',
|
|
62
|
-
formatMatches(matches),
|
|
62
|
+
formatMatches(matches, gcBranch),
|
|
63
63
|
'',
|
|
64
64
|
`Rule: 위 문서를 먼저 근거로 삼고, 부족하면 details 명령으로 세부 정보를 확인.`,
|
|
65
65
|
];
|
package/package.json
CHANGED
package/dist/src/proposals.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { mkdir, readFile, readdir, writeFile } from 'node:fs/promises';
|
|
2
|
-
import { basename, join } from 'node:path';
|
|
3
|
-
import { renderDocMarkdown, slugify } from './markdown.js';
|
|
4
|
-
import { branchDir, branchDocsDir, branchProposalsDir, DEFAULT_BRANCH } from './paths.js';
|
|
5
|
-
import { ensureBranchExists, updateBranchMeta, writeIndexFromDocs } from './store.js';
|
|
6
|
-
export async function proposeUpdate({ home, input, branch, }) {
|
|
7
|
-
const targetBranch = branch || input.branch || DEFAULT_BRANCH;
|
|
8
|
-
await ensureBranchExists(home, targetBranch);
|
|
9
|
-
await mkdir(branchProposalsDir(home, targetBranch), { recursive: true });
|
|
10
|
-
const now = new Date().toISOString();
|
|
11
|
-
const id = `${now.replace(/[:.]/g, '-')}-${slugify(input.title)}`;
|
|
12
|
-
const proposal = {
|
|
13
|
-
version: 1,
|
|
14
|
-
id,
|
|
15
|
-
status: 'proposed',
|
|
16
|
-
branch: targetBranch,
|
|
17
|
-
title: input.title.trim(),
|
|
18
|
-
summary: input.summary.trim(),
|
|
19
|
-
created_at: now,
|
|
20
|
-
changes: input.docs.map((doc) => ({
|
|
21
|
-
path: `docs/${slugify(doc.slug || doc.title)}.md`,
|
|
22
|
-
title: doc.title.trim(),
|
|
23
|
-
summary: doc.summary.trim(),
|
|
24
|
-
body: doc.body.trim(),
|
|
25
|
-
...(doc.tags?.length ? { tags: doc.tags } : {}),
|
|
26
|
-
})),
|
|
27
|
-
};
|
|
28
|
-
const proposalPath = join(branchProposalsDir(home, targetBranch), `${id}.json`);
|
|
29
|
-
await writeFile(proposalPath, `${JSON.stringify(proposal, null, 2)}\n`, 'utf8');
|
|
30
|
-
return { proposal_path: proposalPath, proposal };
|
|
31
|
-
}
|
|
32
|
-
export async function applyProposal({ home, proposalPath, }) {
|
|
33
|
-
const raw = await readFile(proposalPath, 'utf8');
|
|
34
|
-
const proposal = JSON.parse(raw);
|
|
35
|
-
await ensureBranchExists(home, proposal.branch);
|
|
36
|
-
await mkdir(branchDocsDir(home, proposal.branch), { recursive: true });
|
|
37
|
-
const updatedDocs = [];
|
|
38
|
-
for (const change of proposal.changes) {
|
|
39
|
-
const fullPath = join(branchDir(home, proposal.branch), change.path);
|
|
40
|
-
await writeFile(fullPath, renderDocMarkdown({
|
|
41
|
-
title: change.title,
|
|
42
|
-
summary: change.summary,
|
|
43
|
-
body: change.body,
|
|
44
|
-
tags: change.tags,
|
|
45
|
-
}), 'utf8');
|
|
46
|
-
updatedDocs.push(fullPath);
|
|
47
|
-
}
|
|
48
|
-
proposal.status = 'applied';
|
|
49
|
-
proposal.applied_at = new Date().toISOString();
|
|
50
|
-
await writeFile(proposalPath, `${JSON.stringify(proposal, null, 2)}\n`, 'utf8');
|
|
51
|
-
await writeIndexFromDocs(home, proposal.branch);
|
|
52
|
-
await updateBranchMeta(home, proposal.branch, {
|
|
53
|
-
summary: proposal.summary || (await readBranchSummary(home, proposal.branch)),
|
|
54
|
-
});
|
|
55
|
-
return {
|
|
56
|
-
branch: proposal.branch,
|
|
57
|
-
updated_docs: updatedDocs,
|
|
58
|
-
proposal_path: proposalPath,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
async function readBranchSummary(home, branch) {
|
|
62
|
-
const branchJson = await readFile(join(branchDir(home, branch), 'branch.json'), 'utf8');
|
|
63
|
-
return JSON.parse(branchJson).summary || '';
|
|
64
|
-
}
|
|
65
|
-
export async function listProposals(home, branch) {
|
|
66
|
-
return (await readdir(branchProposalsDir(home, branch)).catch(() => []))
|
|
67
|
-
.filter((file) => file.endsWith('.json'))
|
|
68
|
-
.sort()
|
|
69
|
-
.map((file) => join(branchProposalsDir(home, branch), file));
|
|
70
|
-
}
|
|
71
|
-
export function proposalBasename(path) {
|
|
72
|
-
return basename(path);
|
|
73
|
-
}
|