@handsupmin/gc-tree 0.7.18 → 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 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
  }
@@ -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) {
@@ -1,7 +1,8 @@
1
- import { mkdir, writeFile } from 'node:fs/promises';
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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@handsupmin/gc-tree",
3
- "version": "0.7.18",
3
+ "version": "0.7.19",
4
4
  "description": "Global Context Tree, a lightweight branch-aware global context orchestrator for AI coding tools",
5
5
  "type": "module",
6
6
  "private": false,