@handsupmin/gc-tree 0.8.6 → 0.8.7

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.
Files changed (2) hide show
  1. package/dist/src/hook.js +34 -7
  2. package/package.json +1 -1
package/dist/src/hook.js CHANGED
@@ -42,11 +42,15 @@ function buildNoMatchContext({ gcBranch, currentRepo, cached, }) {
42
42
  return `[gc-tree] no match: gc-branch="${gcBranch}" repo="${currentRepo || 'unscoped'}"${cached ? ' cached=true' : ''}.`;
43
43
  }
44
44
  function buildMatchContext({ gcBranch, currentRepo, repoScopeStatus, matches, }) {
45
- return [
45
+ const lines = [
46
46
  `[gc-tree] USE FIRST: ${Math.min(matches.length, 3)} docs gc-branch="${gcBranch}" repo="${currentRepo || 'unscoped'}" scope=${repoScopeStatus}.`,
47
47
  formatMatches(matches),
48
48
  `Rule: apply these docs before tools; if insufficient, open full doc: gctree resolve --id <id>`,
49
- ].join('\n');
49
+ ];
50
+ if (repoScopeStatus === 'unmapped' && currentRepo) {
51
+ lines.push(`Note: repo "${currentRepo}" is unmapped. If it belongs here, offer to run: gctree set-repo-scope --branch ${gcBranch} --include`);
52
+ }
53
+ return lines.join('\n');
50
54
  }
51
55
  function buildSelfReviewAppend(promptCount) {
52
56
  return [
@@ -81,6 +85,7 @@ function nextCacheState(previous, { sessionId, gcBranch, currentRepo, repoScopeS
81
85
  branch_empty: changed ? false : previous.branch_empty,
82
86
  branch_excluded: changed ? false : previous.branch_excluded,
83
87
  no_match_signatures: changed ? [] : previous.no_match_signatures,
88
+ unmapped_shown_repos: previous?.unmapped_shown_repos ?? [],
84
89
  prompt_count: (previous?.prompt_count ?? 0) + 1,
85
90
  last_session_start_signature: previous?.last_session_start_signature,
86
91
  last_session_start_at: previous?.last_session_start_at,
@@ -119,6 +124,7 @@ export async function dispatchGcTreeHook({ event, home, payload, }) {
119
124
  branch_empty: previousCache?.branch_empty ?? false,
120
125
  branch_excluded: previousCache?.branch_excluded ?? false,
121
126
  no_match_signatures: previousCache?.no_match_signatures ?? [],
127
+ unmapped_shown_repos: previousCache?.unmapped_shown_repos ?? [],
122
128
  prompt_count: previousCache?.prompt_count ?? 0,
123
129
  last_session_start_signature: signature,
124
130
  last_session_start_at: now.toISOString(),
@@ -169,21 +175,42 @@ export async function dispatchGcTreeHook({ event, home, payload, }) {
169
175
  cache.branch_empty = true;
170
176
  additionalContext = buildEmptyBranchContext({ gcBranch, currentRepo, cached: wasCached });
171
177
  }
178
+ else if (repoScopeStatus === 'unmapped' && currentRepo && cache.unmapped_shown_repos.includes(currentRepo)) {
179
+ // Already showed context for this unmapped repo this session — skip silently.
180
+ cache.updated_at = now.toISOString();
181
+ await writeHookCache(home, cache);
182
+ return null;
183
+ }
172
184
  else {
173
- const query = currentRepo ? `${currentRepo} ${prompt}` : prompt;
185
+ // For unmapped repos: use prompt only (no repo prefix) to avoid bias; apply higher score threshold.
186
+ const isUnmapped = repoScopeStatus === 'unmapped';
187
+ const query = !isUnmapped && currentRepo ? `${currentRepo} ${prompt}` : prompt;
174
188
  const signature = hashQuery(query);
175
- if (cache.no_match_signatures.includes(signature)) {
189
+ if (!isUnmapped && cache.no_match_signatures.includes(signature)) {
176
190
  additionalContext = buildNoMatchContext({ gcBranch, currentRepo, cached: true });
177
191
  }
178
192
  else {
179
193
  const result = await resolveContext({ home, branch: gcBranch, query });
180
- if (result.matches.length === 0) {
194
+ const effectiveMatches = result.matches;
195
+ if (effectiveMatches.length === 0) {
196
+ if (isUnmapped) {
197
+ // Unmapped + no strong match: skip silently, no noise.
198
+ cache.updated_at = now.toISOString();
199
+ await writeHookCache(home, cache);
200
+ return null;
201
+ }
181
202
  cache.no_match_signatures = [...new Set([...cache.no_match_signatures, signature])];
182
203
  additionalContext = buildNoMatchContext({ gcBranch, currentRepo, cached: false });
183
204
  }
184
205
  else {
185
- cache.no_match_signatures = cache.no_match_signatures.filter((entry) => entry !== signature);
186
- additionalContext = buildMatchContext({ gcBranch, currentRepo, repoScopeStatus, matches: result.matches });
206
+ if (!isUnmapped) {
207
+ cache.no_match_signatures = cache.no_match_signatures.filter((entry) => entry !== signature);
208
+ }
209
+ else if (currentRepo) {
210
+ // Mark this unmapped repo as shown so we don't repeat next prompt.
211
+ cache.unmapped_shown_repos = [...new Set([...cache.unmapped_shown_repos, currentRepo])];
212
+ }
213
+ additionalContext = buildMatchContext({ gcBranch, currentRepo, repoScopeStatus, matches: effectiveMatches });
187
214
  }
188
215
  }
189
216
  if (cache.prompt_count > 0 && cache.prompt_count % SELF_REVIEW_INTERVAL === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@handsupmin/gc-tree",
3
- "version": "0.8.6",
3
+ "version": "0.8.7",
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,