@handsupmin/gc-tree 0.8.17 → 0.8.18
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/markdown.js
CHANGED
|
@@ -123,14 +123,21 @@ export function renderIndexMarkdown(input) {
|
|
|
123
123
|
}
|
|
124
124
|
else {
|
|
125
125
|
const categoryOrder = ['role', 'repos', 'domain', 'workflows', 'conventions', 'infra', 'verification', 'general'];
|
|
126
|
-
|
|
126
|
+
// Group by category, then by path within category
|
|
127
|
+
const byCategory = new Map();
|
|
127
128
|
for (const doc of input.docs) {
|
|
128
129
|
const category = normalizeCategory(doc.category || deriveCategoryFromPath(doc.path));
|
|
129
|
-
if (!
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
if (!byCategory.has(category))
|
|
131
|
+
byCategory.set(category, new Map());
|
|
132
|
+
const byPath = byCategory.get(category);
|
|
133
|
+
if (!byPath.has(doc.path))
|
|
134
|
+
byPath.set(doc.path, []);
|
|
135
|
+
const label = (doc.label || doc.title).trim();
|
|
136
|
+
if (label && !byPath.get(doc.path).includes(label)) {
|
|
137
|
+
byPath.get(doc.path).push(label);
|
|
138
|
+
}
|
|
132
139
|
}
|
|
133
|
-
const categories = [...
|
|
140
|
+
const categories = [...byCategory.keys()].sort((a, b) => {
|
|
134
141
|
const ai = categoryOrder.indexOf(a);
|
|
135
142
|
const bi = categoryOrder.indexOf(b);
|
|
136
143
|
if (ai === -1 && bi === -1)
|
|
@@ -143,9 +150,12 @@ export function renderIndexMarkdown(input) {
|
|
|
143
150
|
});
|
|
144
151
|
for (const category of categories) {
|
|
145
152
|
lines.push(`## ${displayCategory(category)}`, '');
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
lines.push(
|
|
153
|
+
const byPath = byCategory.get(category);
|
|
154
|
+
for (const [path, labels] of [...byPath.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
155
|
+
lines.push(`- ${path}`);
|
|
156
|
+
for (const label of labels) {
|
|
157
|
+
lines.push(` - ${label}`);
|
|
158
|
+
}
|
|
149
159
|
}
|
|
150
160
|
lines.push('');
|
|
151
161
|
}
|
|
@@ -182,41 +192,55 @@ export function displayCategory(category) {
|
|
|
182
192
|
}
|
|
183
193
|
export function parseIndexEntries(indexContent) {
|
|
184
194
|
let currentCategory = 'general';
|
|
185
|
-
let pendingLabel = null;
|
|
195
|
+
let pendingLabel = null; // legacy: label before indented path
|
|
196
|
+
let currentPath = null; // new: path before indented labels
|
|
186
197
|
const entries = [];
|
|
187
198
|
for (const rawLine of String(indexContent || '').split(/\r?\n/)) {
|
|
188
199
|
const line = rawLine.trimEnd();
|
|
189
200
|
const trimmed = line.trim();
|
|
190
201
|
if (!trimmed) {
|
|
191
202
|
pendingLabel = null;
|
|
203
|
+
currentPath = null;
|
|
192
204
|
continue;
|
|
193
205
|
}
|
|
194
206
|
const heading = trimmed.match(/^##\s+(.+)$/);
|
|
195
207
|
if (heading) {
|
|
196
208
|
currentCategory = normalizeCategory(heading[1] || 'general');
|
|
197
209
|
pendingLabel = null;
|
|
210
|
+
currentPath = null;
|
|
198
211
|
continue;
|
|
199
212
|
}
|
|
200
213
|
if (trimmed.startsWith('- gc-branch:') || trimmed.startsWith('- summary:') || trimmed === '- No source docs yet.') {
|
|
201
214
|
pendingLabel = null;
|
|
215
|
+
currentPath = null;
|
|
202
216
|
continue;
|
|
203
217
|
}
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
218
|
+
const isIndented = /^\s{2,}/.test(rawLine);
|
|
219
|
+
const itemText = trimmed.replace(/^-\s*/, '');
|
|
220
|
+
if (!isIndented) {
|
|
221
|
+
// Top-level list item
|
|
222
|
+
if (itemText.startsWith('docs/')) {
|
|
223
|
+
// New format: path is top-level
|
|
224
|
+
currentPath = itemText;
|
|
225
|
+
pendingLabel = null;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
// Legacy format: label is top-level
|
|
229
|
+
pendingLabel = itemText;
|
|
230
|
+
currentPath = null;
|
|
231
|
+
}
|
|
215
232
|
continue;
|
|
216
233
|
}
|
|
217
|
-
|
|
218
|
-
if (
|
|
219
|
-
|
|
234
|
+
// Indented item
|
|
235
|
+
if (currentPath && !itemText.startsWith('docs/')) {
|
|
236
|
+
// New format: keyword under path
|
|
237
|
+
const category = deriveCategoryFromPath(currentPath) || currentCategory;
|
|
238
|
+
entries.push({ id: docIdFromPath(currentPath), title: itemText, label: itemText, category, path: currentPath });
|
|
239
|
+
}
|
|
240
|
+
else if (pendingLabel && itemText.startsWith('docs/')) {
|
|
241
|
+
// Legacy format: path under label
|
|
242
|
+
const category = deriveCategoryFromPath(itemText) || currentCategory;
|
|
243
|
+
entries.push({ id: docIdFromPath(itemText), title: pendingLabel, label: pendingLabel, category, path: itemText });
|
|
220
244
|
}
|
|
221
245
|
}
|
|
222
246
|
return entries;
|
|
@@ -33,11 +33,10 @@ export function onboardingProtocolLines() {
|
|
|
33
33
|
'Synthesize the interview into an encyclopedia-style context set with many small docs instead of a few broad docs.',
|
|
34
34
|
'Prefer category directories such as `docs/role/`, `docs/repos/`, `docs/domain/`, `docs/workflows/`, `docs/conventions/`, and `docs/infra/` whenever that split fits the material.',
|
|
35
35
|
'Prefer one concept, one repository, one workflow, or one convention per file when possible.',
|
|
36
|
-
'
|
|
37
|
-
'
|
|
36
|
+
'Index entries are the search surface — maximize keyword density. For each doc, generate index entries from: primary concept names, aliases, repo nicknames, workflow names, field names, command names, acronyms, related terms a developer might search for, and any term that would make someone want to open this doc. Do NOT be conservative — more keywords means more chances of being found.',
|
|
37
|
+
'The index format groups keywords under their path: top-level `- docs/path.md` with indented ` - keyword` lines under it. This keeps the index compact while allowing many keywords per doc.',
|
|
38
38
|
'Split glossary docs when a concept is likely to be searched directly, needs more than a short definition, or carries workflow/constraint details; keep only low-value leftover terms in a shared glossary.',
|
|
39
39
|
'The `## Summary` section of every doc must be actionable, not descriptive — write the actual patterns, commands, or constraints a developer needs, not a sentence about what the doc covers. Bad: "이 문서는 updateCollection 패턴을 설명합니다." Good: "updateCollection: { ...dto } spread 필수. return plainToInstance(Res, result satisfies Res). 새 필드 추가 = DTO → 서비스 → 컨트롤러 순서." The summary is injected into the AI context before every task — if it reads like a table of contents entry, it is useless.',
|
|
40
|
-
'Treat `index.md` as a human-readable dictionary-style table of contents grouped by category headings and `label -> path` entries.',
|
|
41
40
|
];
|
|
42
41
|
}
|
|
43
42
|
export function onboardingCompletionLines() {
|
|
@@ -45,9 +44,12 @@ export function onboardingCompletionLines() {
|
|
|
45
44
|
'Before you claim onboarding is complete, run `gctree verify-onboarding --branch <current-gc-branch>` and inspect the real gc-tree files.',
|
|
46
45
|
'Do not claim onboarding is complete unless verification returns `status: "complete"` **and** `quality_issues` is an empty array.',
|
|
47
46
|
'If `quality_issues` is non-empty, do **not** tell the user onboarding is done. Self-heal immediately without asking the user: (a) identify which docs have `category: "general"`, (b) assign each a correct category from `role | repos | domain | workflows | conventions | infra | verification` based on content, (c) rebuild the full onboarding JSON with every doc having an explicit `category` field set to one of those values, (d) run `gctree __apply-onboarding --input <temp-file>` again, (e) rerun `gctree verify-onboarding` and repeat until `quality_issues` is empty. Never use `"general"` as a category in the JSON — it is a fallback for missing data, not a valid category.',
|
|
48
|
-
'After quality_issues passes, perform
|
|
47
|
+
'After quality_issues passes, perform a summary quality check: read the actual `## Summary` section of each written doc file. If any summary reads like a table of contents entry ("이 문서는 X를 설명합니다", "X에 대한 패턴 모음") rather than actionable content (real patterns, commands, constraints), rewrite it in-place before continuing.',
|
|
48
|
+
'After summary check, perform an index coverage check: for every written doc, read its `## Index Entries` section and verify that the entries cover a wide range of terms a developer would search for — not just the exact document title. If a doc has fewer than 5 index entries, it almost certainly needs more. Add aliases, related terms, command names, field names, and workflow names. Re-apply if entries were added.',
|
|
49
49
|
'If verification returns `status: "incomplete"` for reasons other than quality_issues, do not tell the user onboarding is done; inspect the reported failures, heal what can be healed automatically, rerun verification, and repeat until it passes or a real blocker remains.',
|
|
50
50
|
'After applying the onboarding docs, explicitly list which durable docs were saved.',
|
|
51
|
+
'Before the final summary, run a coverage checklist and ask the user to confirm each area: (a) workflows — are the key cross-repo action sequences documented? (b) conventions — are the code patterns for each repo documented? (c) repos — is each relevant repo covered with role, paths, and cross-repo deps? (d) domain terms / glossary — are important acronyms and terms indexed? Present this as a numbered checklist and ask the user: "이 중 빠진 것이 있으면 말씀해주세요. 없으면 완료하겠습니다." Do not skip this step.',
|
|
52
|
+
'If the user identifies missing areas, gather the information and add the docs before continuing.',
|
|
51
53
|
'Then summarize what you now understand from the saved docs instead of stopping at the filenames alone.',
|
|
52
54
|
'For that final summary, do not ask an open-ended validation question first; present the summary and ask the user to choose only one structured confirmation: 1. This matches well enough. 2. Some parts are wrong. I will give the delta. 3. The frame is wrong. I will restate it.',
|
|
53
55
|
'If the user picks 2 or 3 for the final summary, ask only for the correction delta or replacement frame, then update the saved understanding instead of restarting the interview.',
|
package/dist/src/scaffold.js
CHANGED
|
@@ -116,14 +116,15 @@ function renderUpdateProtocol() {
|
|
|
116
116
|
' - `docs/infra/<topic>.md` — infra, deployment, environment config',
|
|
117
117
|
' - `docs/role/<name>.md` — team member roles, responsibilities',
|
|
118
118
|
'4. Write a `## Summary` that is actionable: actual patterns/commands/constraints a developer needs — not a sentence about what the doc covers.',
|
|
119
|
-
'5.
|
|
120
|
-
'6.
|
|
119
|
+
'5. Include a `## Index Entries` section in each doc\'s content with many keywords: aliases, related terms, command names, field names, workflow names, acronyms. More entries = more chances of being found by `gctree resolve`. Fewer than 5 entries almost always means more are needed.',
|
|
120
|
+
'6. Create a temporary JSON file with the updated `docs[]` and run `gctree __apply-update --input <temp-file>`.',
|
|
121
|
+
'7. Run `gctree verify-onboarding --branch <gc-branch>` and inspect the output:',
|
|
121
122
|
' - Check that every updated doc appears in the verified doc list.',
|
|
122
123
|
' - Check that index entries for the new content exist and are searchable (not just generic titles).',
|
|
123
124
|
' - Check that no doc has `category: "general"` — reassign to correct category if so.',
|
|
124
125
|
' - Check that important concepts from the update are present as index labels — if missing, re-apply with added index entries.',
|
|
125
126
|
' - Self-heal any issues without asking the user: fix category, add index entries, re-run `gctree __apply-update`, re-verify.',
|
|
126
|
-
'
|
|
127
|
+
'8. Show the user which docs were updated and confirm the index now covers the new content.',
|
|
127
128
|
];
|
|
128
129
|
}
|
|
129
130
|
function renderCodexUpdateSkill() {
|
package/package.json
CHANGED
package/skills/onboard/SKILL.md
CHANGED
|
@@ -43,10 +43,10 @@ Use this when a user wants to create global context for a product, company, or w
|
|
|
43
43
|
- prefer an encyclopedia-style context set with many small docs instead of a few broad docs
|
|
44
44
|
- prefer category directories like `docs/role/`, `docs/repos/`, `docs/domain/`, `docs/workflows/`, `docs/conventions/`, and `docs/infra/`
|
|
45
45
|
- prefer one concept, one repository, one workflow, or one convention per file when possible
|
|
46
|
-
- treat `index.md` as
|
|
46
|
+
- treat `index.md` as the search surface — maximize keyword density; for each doc generate entries from: primary names, aliases, nicknames, field names, command names, acronyms, related terms a developer might search for; do NOT be conservative — more keywords = more chances of being found; fewer than 5 index entries per doc almost certainly means more are needed
|
|
47
47
|
- generate index entries automatically from primary concept names, aliases, repository nicknames, and workflow labels when those are clear
|
|
48
48
|
- split glossary docs when a concept is likely to be searched directly, needs more than a short definition, or carries workflow/constraint details; keep only low-value leftover terms in a shared glossary
|
|
49
|
-
-
|
|
49
|
+
- index format: top-level `- docs/path.md` with indented ` - keyword` lines under it — groups all keywords per doc, eliminates path duplication
|
|
50
50
|
- every doc in the JSON **must** have an explicit `category` field set to one of: `role`, `repos`, `domain`, `workflows`, `conventions`, `infra`, `verification` — never use `"general"` as a category; it is a fallback for missing data, not a valid category choice
|
|
51
51
|
- use onboarding only for an empty gc-branch
|
|
52
52
|
|
|
@@ -88,12 +88,14 @@ Use this when a user wants to create global context for a product, company, or w
|
|
|
88
88
|
22. Ask for company/domain glossary terms and acronyms that should become durable context.
|
|
89
89
|
23. Ask which verification commands should be treated as defaults for this gc-branch.
|
|
90
90
|
24. Structure the durable docs as a small encyclopedia: split by category directory, keep one concept/repo/workflow/convention per file when possible, and keep a short `## Summary` at the top of each doc.
|
|
91
|
-
25. Render `index.md` as a
|
|
91
|
+
25. Render `index.md` grouped by category; within each category list each doc path as a top-level item with all its keywords as indented children. Maximize keywords per doc — aliases, related terms, command names, field names, workflow names.
|
|
92
92
|
26. Launch the guided onboarding flow with `gctree onboard [--branch <name>]`.
|
|
93
93
|
27. Before you claim onboarding is complete, run `gctree verify-onboarding --branch <current-gc-branch>` and inspect the real gc-tree files.
|
|
94
94
|
28. Do not claim onboarding is complete unless verification returns `status: "complete"` **and** `quality_issues` is an empty array.
|
|
95
95
|
29. If `quality_issues` is non-empty, do **not** tell the user onboarding is done. Self-heal immediately without prompting the user: (a) identify which docs have `category: "general"`, (b) assign each a correct category from `role | repos | domain | workflows | conventions | infra | verification` based on content, (c) rebuild the full onboarding JSON with every doc having an explicit `category` field — never use `"general"` as a category, (d) rerun `gctree __apply-onboarding --input <temp-file>`, (e) rerun `gctree verify-onboarding`, repeat until `quality_issues` is empty. If `status` is `"incomplete"` for other reasons, inspect the failures, heal them autonomously, and repeat.
|
|
96
96
|
30. After the onboarding docs are written, explicitly list which durable docs were saved.
|
|
97
|
+
30a. Run a coverage checklist before the final summary. Ask the user to confirm each area: (a) workflows — are key cross-repo action sequences documented? (b) conventions — are code patterns for each repo documented with a `## Patterns` section? (c) repos — is each relevant repo covered with role, paths, and cross-repo deps? (d) domain/glossary — are important acronyms and terms indexed with enough keywords? Present as a numbered checklist: "이 중 빠진 것이 있으면 말씀해주세요. 없으면 완료하겠습니다." If the user identifies gaps, gather and add before continuing. Do not skip this step.
|
|
98
|
+
30b. Check index keyword density: read the `## Index Entries` section of each written doc. If any doc has fewer than 5 entries, add more — aliases, related terms, command names, field names, workflow names. Re-apply if entries were added.
|
|
97
99
|
31. Summarize what you now understand from the saved docs instead of ending at the filenames alone.
|
|
98
100
|
32. For that final summary, do not ask an open-ended validation question first. Present the summary and ask the user to choose only one:
|
|
99
101
|
- 1. This matches well enough.
|