@handsupmin/gc-tree 0.7.17 → 0.7.19
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 +16 -7
- package/dist/src/scaffold.js +10 -2
- package/dist/src/settings.js +11 -0
- package/dist/src/update.js +35 -2
- package/package.json +1 -1
package/dist/src/cli.js
CHANGED
|
@@ -12,9 +12,9 @@ import { DEFAULT_BRANCH, branchDir, resolveHome } from './paths.js';
|
|
|
12
12
|
import { branchRepoMapPath, branchScopeStatus, 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
|
-
import { requirePreferredProvider, writeSettings, readSettings } from './settings.js';
|
|
15
|
+
import { appendScaffoldedHost, requirePreferredProvider, writeSettings, readSettings } from './settings.js';
|
|
16
16
|
import { checkoutBranch, initHome, listBranches, readHead, resetBranchContext, statusForBranch, ensureBranchExists, isBranchContextEmpty } from './store.js';
|
|
17
|
-
import { updateBranchContext } from './update.js';
|
|
17
|
+
import { selfUpdate, updateBranchContext } from './update.js';
|
|
18
18
|
import { uninstallGcTree } from './uninstall.js';
|
|
19
19
|
import { verifyOnboarding } from './verify-onboarding.js';
|
|
20
20
|
function readArg(flag) {
|
|
@@ -59,6 +59,7 @@ function usage() {
|
|
|
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]
|
|
61
61
|
gctree scaffold --host <codex|claude-code|both> [--target DIR] [--force]
|
|
62
|
+
gctree update
|
|
62
63
|
|
|
63
64
|
Internal commands:
|
|
64
65
|
gctree __apply-onboarding --input FILE [--home DIR] [--branch NAME]
|
|
@@ -102,13 +103,16 @@ function normalizeProviderMode(value) {
|
|
|
102
103
|
async function resolvePreferredProvider(home, explicitProvider) {
|
|
103
104
|
return normalizeProvider(explicitProvider) || (await requirePreferredProvider(home));
|
|
104
105
|
}
|
|
105
|
-
async function ensureScaffold({ providerMode, targetDir, force = false, scope = 'local', }) {
|
|
106
|
+
async function ensureScaffold({ providerMode, targetDir, force = false, scope = 'local', home: scaffoldHome, }) {
|
|
106
107
|
const hosts = providerMode === 'both' ? ['claude-code', 'codex'] : [providerMode];
|
|
107
108
|
const combined = { hosts: providerMode, target_dir: scope === 'global' ? '(global)' : (targetDir || process.cwd()), written: [], skipped_existing: [] };
|
|
108
109
|
for (const host of hosts) {
|
|
109
110
|
const result = await scaffoldHostIntegration({ host, targetDir, force, scope });
|
|
110
111
|
combined.written.push(...result.written);
|
|
111
112
|
combined.skipped_existing.push(...result.skipped_existing);
|
|
113
|
+
if (scaffoldHome && result.written.length > 0) {
|
|
114
|
+
await appendScaffoldedHost(scaffoldHome, { host, scope, target_dir: scope === 'local' ? (targetDir || process.cwd()) : undefined });
|
|
115
|
+
}
|
|
112
116
|
}
|
|
113
117
|
return combined;
|
|
114
118
|
}
|
|
@@ -181,9 +185,9 @@ async function main() {
|
|
|
181
185
|
preferredProvider: provider,
|
|
182
186
|
preferredLanguage,
|
|
183
187
|
});
|
|
184
|
-
const globalScaffold = await ensureScaffold({ providerMode, scope: 'global', force: hasFlag('--force') });
|
|
188
|
+
const globalScaffold = await ensureScaffold({ providerMode, scope: 'global', force: hasFlag('--force'), home });
|
|
185
189
|
const scaffold = explicitTargetDir
|
|
186
|
-
? await ensureScaffold({ providerMode, targetDir: explicitTargetDir, scope: 'local', force: hasFlag('--force') })
|
|
190
|
+
? await ensureScaffold({ providerMode, targetDir: explicitTargetDir, scope: 'local', force: hasFlag('--force'), home })
|
|
187
191
|
: null;
|
|
188
192
|
const launch = (await isBranchContextEmpty(home, result.gc_branch))
|
|
189
193
|
? await launchGuidedFlow({
|
|
@@ -285,7 +289,7 @@ async function main() {
|
|
|
285
289
|
const settings = await readSettings(home);
|
|
286
290
|
const targetDir = readArg('--target') || process.cwd();
|
|
287
291
|
const scaffold = readArg('--target')
|
|
288
|
-
? await ensureScaffold({ providerMode: settings?.provider_mode || provider, targetDir, scope: 'local', force: hasFlag('--force') })
|
|
292
|
+
? await ensureScaffold({ providerMode: settings?.provider_mode || provider, targetDir, scope: 'local', force: hasFlag('--force'), home })
|
|
289
293
|
: null;
|
|
290
294
|
const launch = await launchGuidedFlow({
|
|
291
295
|
provider,
|
|
@@ -482,7 +486,7 @@ async function main() {
|
|
|
482
486
|
const settings = await readSettings(home);
|
|
483
487
|
const targetDir = readArg('--target') || process.cwd();
|
|
484
488
|
const scaffold = readArg('--target')
|
|
485
|
-
? await ensureScaffold({ providerMode: settings?.provider_mode || provider, targetDir, scope: 'local', force: hasFlag('--force') })
|
|
489
|
+
? await ensureScaffold({ providerMode: settings?.provider_mode || provider, targetDir, scope: 'local', force: hasFlag('--force'), home })
|
|
486
490
|
: null;
|
|
487
491
|
const launch = await launchGuidedFlow({
|
|
488
492
|
provider,
|
|
@@ -532,10 +536,15 @@ async function main() {
|
|
|
532
536
|
providerMode: host,
|
|
533
537
|
...(isGlobal ? { scope: 'global' } : { targetDir: explicitTarget, scope: 'local' }),
|
|
534
538
|
force: hasFlag('--force'),
|
|
539
|
+
home,
|
|
535
540
|
});
|
|
536
541
|
console.log(JSON.stringify(result, null, 2));
|
|
537
542
|
return;
|
|
538
543
|
}
|
|
544
|
+
case 'update': {
|
|
545
|
+
await selfUpdate(home);
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
539
548
|
default:
|
|
540
549
|
usage();
|
|
541
550
|
}
|
package/dist/src/scaffold.js
CHANGED
|
@@ -8,7 +8,11 @@ function renderCodexAgentsSnippet() {
|
|
|
8
8
|
'',
|
|
9
9
|
'- Treat the active gctree branch as a **gc-branch** when you describe it to users.',
|
|
10
10
|
'- gctree init installs SessionStart and UserPromptSubmit hooks that auto-check gc-tree before work.',
|
|
11
|
-
'- When you encounter an unfamiliar term, acronym, concept, or domain word,
|
|
11
|
+
'- When you encounter an unfamiliar term, acronym, concept, or domain word, follow this protocol **before** grepping or reading code files:',
|
|
12
|
+
' 1. Run `gctree resolve --query "<term>"` — if matched, use the result directly.',
|
|
13
|
+
' 2. If no match, try broader related queries to check if the concept lives in any doc.',
|
|
14
|
+
' 3. If the concept exists in a doc but was not indexed → propose adding it as an Index Entry to that doc (so future resolves find it).',
|
|
15
|
+
' 4. If it does not exist anywhere → decide whether a new doc is needed and propose it to the user.',
|
|
12
16
|
'- When a UserPromptSubmit hook provides `[gc-tree] PRE-TASK CONTEXT`, treat it as mandatory pre-reading before any tool use.',
|
|
13
17
|
'- If the injected summaries contain enough information to answer the question or complete the task, respond directly from them **without calling any tools**. Do not grep, explore, or read code files to confirm what the summaries already cover.',
|
|
14
18
|
'- Only use tools if the summaries are clearly insufficient — meaning the answer cannot be derived from them at all.',
|
|
@@ -114,7 +118,11 @@ function renderClaudeSnippet() {
|
|
|
114
118
|
'',
|
|
115
119
|
'- Treat the active gctree branch as a **gc-branch** in user-facing language.',
|
|
116
120
|
'- gctree init installs SessionStart and UserPromptSubmit hooks that auto-inject gc-tree context before every prompt.',
|
|
117
|
-
'- When you encounter an unfamiliar term, acronym, concept, or domain word,
|
|
121
|
+
'- When you encounter an unfamiliar term, acronym, concept, or domain word, follow this protocol **before** grepping or reading code files:',
|
|
122
|
+
' 1. Run `gctree resolve --query "<term>"` — if matched, use the result directly.',
|
|
123
|
+
' 2. If no match, try broader related queries to check if the concept lives in any doc.',
|
|
124
|
+
' 3. If the concept exists in a doc but was not indexed → propose adding it as an Index Entry to that doc (so future resolves find it).',
|
|
125
|
+
' 4. If it does not exist anywhere → decide whether a new doc is needed and propose it to the user.',
|
|
118
126
|
'- When a UserPromptSubmit hook provides `[gc-tree] PRE-TASK CONTEXT`, treat it as mandatory pre-reading before any tool use.',
|
|
119
127
|
'- If the injected summaries contain enough information to answer the question or complete the task, respond directly from them **without calling any tools**. Do not grep, explore, or read code files to confirm what the summaries already cover.',
|
|
120
128
|
'- Only use tools if the summaries are clearly insufficient — meaning the answer cannot be derived from them at all.',
|
package/dist/src/settings.js
CHANGED
|
@@ -21,6 +21,17 @@ export async function writeSettings({ home, providerMode, preferredProvider, pre
|
|
|
21
21
|
await writeFile(settingsPath(home), `${JSON.stringify(settings, null, 2)}\n`, 'utf8');
|
|
22
22
|
return settings;
|
|
23
23
|
}
|
|
24
|
+
export async function appendScaffoldedHost(home, record) {
|
|
25
|
+
const settings = await readSettings(home);
|
|
26
|
+
if (!settings)
|
|
27
|
+
return;
|
|
28
|
+
const existing = settings.scaffolded_hosts || [];
|
|
29
|
+
const filtered = existing.filter((h) => !(h.host === record.host && h.scope === record.scope && h.target_dir === record.target_dir));
|
|
30
|
+
filtered.push({ ...record, scaffolded_at: new Date().toISOString() });
|
|
31
|
+
const updated = { ...settings, scaffolded_hosts: filtered, updated_at: new Date().toISOString() };
|
|
32
|
+
await mkdir(home, { recursive: true });
|
|
33
|
+
await writeFile(settingsPath(home), `${JSON.stringify(updated, null, 2)}\n`, 'utf8');
|
|
34
|
+
}
|
|
24
35
|
export async function requirePreferredProvider(home) {
|
|
25
36
|
const settings = await readSettings(home);
|
|
26
37
|
if (!settings?.preferred_provider) {
|
package/dist/src/update.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
3
|
import { dirname, join } from 'node:path';
|
|
3
4
|
import { renderDocMarkdown, slugify } from './markdown.js';
|
|
4
|
-
import { branchDocsDir, DEFAULT_BRANCH } from './paths.js';
|
|
5
|
+
import { branchDocsDir, DEFAULT_BRANCH, settingsPath } from './paths.js';
|
|
5
6
|
import { ensureBranchExists, updateBranchMeta, writeIndexFromDocs } from './store.js';
|
|
6
7
|
function docRelativePath(doc) {
|
|
7
8
|
if (doc.slug?.includes('/'))
|
|
@@ -31,3 +32,35 @@ export async function updateBranchContext({ home, input, branch, }) {
|
|
|
31
32
|
index_path: index.index_path,
|
|
32
33
|
};
|
|
33
34
|
}
|
|
35
|
+
async function readScaffoldedHosts(home) {
|
|
36
|
+
try {
|
|
37
|
+
const raw = await readFile(settingsPath(home), 'utf8');
|
|
38
|
+
const settings = JSON.parse(raw);
|
|
39
|
+
return settings.scaffolded_hosts || [];
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export async function selfUpdate(home) {
|
|
46
|
+
const hosts = await readScaffoldedHosts(home);
|
|
47
|
+
if (hosts.length === 0) {
|
|
48
|
+
process.stderr.write('No scaffolded providers found in settings. Run `gctree scaffold --host <host>` first.\n');
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
process.stderr.write(`Found ${hosts.length} scaffolded provider(s): ${hosts.map((h) => `${h.host}(${h.scope})`).join(', ')}\n`);
|
|
52
|
+
}
|
|
53
|
+
process.stderr.write('\nUpdating gctree to latest...\n');
|
|
54
|
+
execSync('npm install -g @handsupmin/gc-tree@latest', { stdio: 'inherit' });
|
|
55
|
+
if (hosts.length > 0) {
|
|
56
|
+
process.stderr.write('\nRe-scaffolding providers with new version...\n');
|
|
57
|
+
for (const record of hosts) {
|
|
58
|
+
const args = ['gctree', 'scaffold', '--host', record.host, '--force'];
|
|
59
|
+
if (record.scope === 'local' && record.target_dir)
|
|
60
|
+
args.push('--target', record.target_dir);
|
|
61
|
+
process.stderr.write(` ${args.join(' ')}\n`);
|
|
62
|
+
execSync(args.join(' '), { stdio: 'inherit' });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
process.stderr.write('\ngctree update complete.\n');
|
|
66
|
+
}
|