@handsupmin/gc-tree 0.7.18 → 0.8.0
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/integration-files.js +2 -2
- package/dist/src/scaffold.js +1 -1
- 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
|
}
|
|
@@ -166,7 +166,7 @@ export function gctreeManagedMarkdownTargets(targetDir) {
|
|
|
166
166
|
export function gctreeHookJsonTargets(targetDir) {
|
|
167
167
|
return {
|
|
168
168
|
codex: join(targetDir, '.codex', 'hooks.json'),
|
|
169
|
-
claude: join(targetDir, '.claude', '
|
|
169
|
+
claude: join(targetDir, '.claude', 'hooks', 'hooks.json'),
|
|
170
170
|
};
|
|
171
171
|
}
|
|
172
172
|
export function gctreeGlobalRoot(host) {
|
|
@@ -177,5 +177,5 @@ export function gctreeGlobalRoot(host) {
|
|
|
177
177
|
}
|
|
178
178
|
export function gctreeGlobalHookJsonTarget(host) {
|
|
179
179
|
const root = gctreeGlobalRoot(host);
|
|
180
|
-
return host === 'codex' ? join(root, 'hooks.json') : join(root, '
|
|
180
|
+
return host === 'codex' ? join(root, 'hooks.json') : join(root, 'hooks', 'hooks.json');
|
|
181
181
|
}
|
package/dist/src/scaffold.js
CHANGED
|
@@ -136,7 +136,7 @@ function renderClaudeSessionStartHook() {
|
|
|
136
136
|
return [
|
|
137
137
|
'# gctree Claude Code SessionStart note',
|
|
138
138
|
'',
|
|
139
|
-
'- gctree init installs real SessionStart/UserPromptSubmit hooks via `.claude/
|
|
139
|
+
'- gctree init installs real SessionStart/UserPromptSubmit hooks via `.claude/hooks/hooks.json`.',
|
|
140
140
|
'- At session start, use the injected hook context to confirm the active gc-branch.',
|
|
141
141
|
'- Refer to gctree branches as **gc-branches** in user-facing language.',
|
|
142
142
|
'- If hook context is missing or stale, resolve summaries before planning or implementation when branch-level context may change the answer.',
|
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
|
+
}
|