first-tree 0.0.2 → 0.0.4
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/README.md +116 -40
- package/dist/cli.js +46 -17
- package/dist/help-Dtdj91HJ.js +25 -0
- package/dist/init--VepFe6N.js +403 -0
- package/dist/installer-cH7N4RNj.js +47 -0
- package/dist/onboarding-C9cYSE6F.js +2 -0
- package/dist/onboarding-CPP8fF4D.js +10 -0
- package/dist/repo-DY57bMqr.js +318 -0
- package/dist/upgrade-Cgx_K2HM.js +135 -0
- package/dist/{verify-CSRIkuoM.js → verify-mC9ZTd1f.js} +118 -29
- package/package.json +33 -10
- package/skills/first-tree/SKILL.md +113 -0
- package/skills/first-tree/agents/openai.yaml +4 -0
- package/skills/first-tree/assets/framework/VERSION +1 -0
- package/skills/first-tree/assets/framework/examples/claude-code/README.md +14 -0
- package/skills/first-tree/assets/framework/examples/claude-code/settings.json +14 -0
- package/skills/first-tree/assets/framework/helpers/generate-codeowners.ts +224 -0
- package/skills/first-tree/assets/framework/helpers/inject-tree-context.sh +15 -0
- package/skills/first-tree/assets/framework/helpers/run-review.ts +193 -0
- package/skills/first-tree/assets/framework/manifest.json +11 -0
- package/skills/first-tree/assets/framework/prompts/pr-review.md +38 -0
- package/skills/first-tree/assets/framework/templates/agents.md.template +49 -0
- package/skills/first-tree/assets/framework/templates/member-node.md.template +18 -0
- package/skills/first-tree/assets/framework/templates/members-domain.md.template +45 -0
- package/skills/first-tree/assets/framework/templates/root-node.md.template +41 -0
- package/skills/first-tree/assets/framework/workflows/codeowners.yml +31 -0
- package/skills/first-tree/assets/framework/workflows/pr-review.yml +146 -0
- package/skills/first-tree/assets/framework/workflows/validate.yml +19 -0
- package/skills/first-tree/engine/commands/help.ts +32 -0
- package/skills/first-tree/engine/commands/init.ts +1 -0
- package/skills/first-tree/engine/commands/upgrade.ts +1 -0
- package/skills/first-tree/engine/commands/verify.ts +1 -0
- package/skills/first-tree/engine/init.ts +414 -0
- package/skills/first-tree/engine/onboarding.ts +10 -0
- package/skills/first-tree/engine/repo.ts +360 -0
- package/skills/first-tree/engine/rules/agent-instructions.ts +59 -0
- package/skills/first-tree/engine/rules/agent-integration.ts +19 -0
- package/skills/first-tree/engine/rules/ci-validation.ts +72 -0
- package/skills/first-tree/engine/rules/framework.ts +13 -0
- package/skills/first-tree/engine/rules/index.ts +41 -0
- package/skills/first-tree/engine/rules/members.ts +21 -0
- package/skills/first-tree/engine/rules/populate-tree.ts +36 -0
- package/skills/first-tree/engine/rules/root-node.ts +41 -0
- package/skills/first-tree/engine/runtime/adapters.ts +22 -0
- package/skills/first-tree/engine/runtime/asset-loader.ts +141 -0
- package/skills/first-tree/engine/runtime/installer.ts +82 -0
- package/skills/first-tree/engine/runtime/upgrader.ts +23 -0
- package/skills/first-tree/engine/upgrade.ts +233 -0
- package/skills/first-tree/engine/validators/members.ts +215 -0
- package/skills/first-tree/engine/validators/nodes.ts +559 -0
- package/skills/first-tree/engine/verify.ts +155 -0
- package/skills/first-tree/references/about.md +36 -0
- package/skills/first-tree/references/maintainer-architecture.md +59 -0
- package/skills/first-tree/references/maintainer-build-and-distribution.md +59 -0
- package/skills/first-tree/references/maintainer-testing.md +58 -0
- package/skills/first-tree/references/maintainer-thin-cli.md +38 -0
- package/skills/first-tree/references/onboarding.md +185 -0
- package/skills/first-tree/references/ownership-and-naming.md +94 -0
- package/skills/first-tree/references/principles.md +113 -0
- package/skills/first-tree/references/source-map.md +94 -0
- package/skills/first-tree/references/upgrade-contract.md +94 -0
- package/skills/first-tree/scripts/check-skill-sync.sh +133 -0
- package/skills/first-tree/scripts/quick_validate.py +95 -0
- package/skills/first-tree/scripts/run-local-cli.sh +35 -0
- package/skills/first-tree/tests/asset-loader.test.ts +75 -0
- package/skills/first-tree/tests/generate-codeowners.test.ts +94 -0
- package/skills/first-tree/tests/helpers.ts +169 -0
- package/skills/first-tree/tests/init.test.ts +250 -0
- package/skills/first-tree/tests/repo.test.ts +440 -0
- package/skills/first-tree/tests/rules.test.ts +413 -0
- package/skills/first-tree/tests/run-review.test.ts +155 -0
- package/skills/first-tree/tests/skill-artifacts.test.ts +311 -0
- package/skills/first-tree/tests/thin-cli.test.ts +104 -0
- package/skills/first-tree/tests/upgrade.test.ts +103 -0
- package/skills/first-tree/tests/validate-members.test.ts +224 -0
- package/skills/first-tree/tests/validate-nodes.test.ts +198 -0
- package/skills/first-tree/tests/verify.test.ts +241 -0
- package/dist/init-CE_944sb.js +0 -283
- package/dist/repo-BByc3VvM.js +0 -111
- package/dist/upgrade-Chr7z0CY.js +0 -82
package/dist/init-CE_944sb.js
DELETED
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
import { n as Repo, t as FRAMEWORK_END_MARKER } from "./repo-BByc3VvM.js";
|
|
2
|
-
import { execFileSync } from "node:child_process";
|
|
3
|
-
import { copyFileSync, cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
5
|
-
import { tmpdir } from "node:os";
|
|
6
|
-
//#region \0rolldown/runtime.js
|
|
7
|
-
var __defProp = Object.defineProperty;
|
|
8
|
-
var __exportAll = (all, no_symbols) => {
|
|
9
|
-
let target = {};
|
|
10
|
-
for (var name in all) __defProp(target, name, {
|
|
11
|
-
get: all[name],
|
|
12
|
-
enumerable: true
|
|
13
|
-
});
|
|
14
|
-
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
15
|
-
return target;
|
|
16
|
-
};
|
|
17
|
-
//#endregion
|
|
18
|
-
//#region src/rules/agent-instructions.ts
|
|
19
|
-
var agent_instructions_exports = /* @__PURE__ */ __exportAll({ evaluate: () => evaluate$5 });
|
|
20
|
-
function evaluate$5(repo) {
|
|
21
|
-
const tasks = [];
|
|
22
|
-
if (!repo.pathExists("AGENT.md")) tasks.push("AGENT.md is missing — create from `.context-tree/templates/agent.md.template`");
|
|
23
|
-
else if (!repo.hasAgentMdMarkers()) tasks.push("AGENT.md exists but is missing framework markers — add `<!-- BEGIN CONTEXT-TREE FRAMEWORK -->` and `<!-- END CONTEXT-TREE FRAMEWORK -->` sections");
|
|
24
|
-
else {
|
|
25
|
-
const afterMarker = (repo.readFile("AGENT.md") ?? "").split(FRAMEWORK_END_MARKER);
|
|
26
|
-
if (afterMarker.length > 1) {
|
|
27
|
-
if (afterMarker[1].trim().split("\n").filter((l) => l.trim() && !l.trim().startsWith("#") && !l.trim().startsWith("<!--")).length === 0) tasks.push("Add your project-specific instructions below the framework markers in AGENT.md");
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return {
|
|
31
|
-
group: "Agent Instructions",
|
|
32
|
-
order: 3,
|
|
33
|
-
tasks
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
//#endregion
|
|
37
|
-
//#region src/rules/agent-integration.ts
|
|
38
|
-
var agent_integration_exports = /* @__PURE__ */ __exportAll({ evaluate: () => evaluate$4 });
|
|
39
|
-
function evaluate$4(repo) {
|
|
40
|
-
const tasks = [];
|
|
41
|
-
if (repo.pathExists(".claude/settings.json")) {
|
|
42
|
-
if (!repo.fileContains(".claude/settings.json", "inject-tree-context")) tasks.push("Add SessionStart hook to `.claude/settings.json` (see `.context-tree/examples/claude-code/`)");
|
|
43
|
-
} else if (!repo.anyAgentConfig()) tasks.push("No agent configuration detected. Configure your agent to load tree context at session start. See `.context-tree/examples/` for supported agents. You can skip this and set it up later.");
|
|
44
|
-
return {
|
|
45
|
-
group: "Agent Integration",
|
|
46
|
-
order: 5,
|
|
47
|
-
tasks
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
//#endregion
|
|
51
|
-
//#region src/rules/ci-validation.ts
|
|
52
|
-
var ci_validation_exports = /* @__PURE__ */ __exportAll({ evaluate: () => evaluate$3 });
|
|
53
|
-
function evaluate$3(repo) {
|
|
54
|
-
const tasks = [];
|
|
55
|
-
let hasValidation = false;
|
|
56
|
-
const workflowsDir = join(repo.root, ".github", "workflows");
|
|
57
|
-
try {
|
|
58
|
-
if (statSync(workflowsDir).isDirectory()) for (const name of readdirSync(workflowsDir)) {
|
|
59
|
-
if (!name.endsWith(".yml") && !name.endsWith(".yaml")) continue;
|
|
60
|
-
const fullPath = join(workflowsDir, name);
|
|
61
|
-
try {
|
|
62
|
-
if (!statSync(fullPath).isFile()) continue;
|
|
63
|
-
const content = readFileSync(fullPath, "utf-8");
|
|
64
|
-
if (content.includes("validate_nodes") || content.includes("validate_members")) {
|
|
65
|
-
hasValidation = true;
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
} catch {
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
} catch {}
|
|
73
|
-
if (!hasValidation) tasks.push("No validation workflow found — copy `.context-tree/workflows/validate.yml` to `.github/workflows/validate.yml`");
|
|
74
|
-
return {
|
|
75
|
-
group: "CI / Validation",
|
|
76
|
-
order: 6,
|
|
77
|
-
tasks
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
//#endregion
|
|
81
|
-
//#region src/rules/framework.ts
|
|
82
|
-
var framework_exports = /* @__PURE__ */ __exportAll({ evaluate: () => evaluate$2 });
|
|
83
|
-
const SEED_TREE_URL$1 = "https://github.com/agent-team-foundation/seed-tree";
|
|
84
|
-
function evaluate$2(repo) {
|
|
85
|
-
const tasks = [];
|
|
86
|
-
if (!repo.hasFramework()) tasks.push(`\`.context-tree/\` not found — run \`context-tree init\` to clone the framework from ${SEED_TREE_URL$1}`);
|
|
87
|
-
return {
|
|
88
|
-
group: "Framework",
|
|
89
|
-
order: 1,
|
|
90
|
-
tasks
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
//#endregion
|
|
94
|
-
//#region src/rules/members.ts
|
|
95
|
-
var members_exports = /* @__PURE__ */ __exportAll({ evaluate: () => evaluate$1 });
|
|
96
|
-
function evaluate$1(repo) {
|
|
97
|
-
const tasks = [];
|
|
98
|
-
if (!repo.pathExists("members")) tasks.push("`members/` directory is missing — create it with a NODE.md");
|
|
99
|
-
else if (!repo.pathExists("members/NODE.md")) tasks.push("`members/NODE.md` is missing — create it from the template");
|
|
100
|
-
if (repo.hasMembers() && repo.memberCount() === 0) tasks.push("Add at least one member node for a team member or agent under `members/`");
|
|
101
|
-
else if (!repo.hasMembers()) tasks.push("Add at least one member node for a team member or agent under `members/`");
|
|
102
|
-
return {
|
|
103
|
-
group: "Members",
|
|
104
|
-
order: 4,
|
|
105
|
-
tasks
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
//#endregion
|
|
109
|
-
//#region src/rules/root-node.ts
|
|
110
|
-
var root_node_exports = /* @__PURE__ */ __exportAll({ evaluate: () => evaluate });
|
|
111
|
-
function evaluate(repo) {
|
|
112
|
-
const tasks = [];
|
|
113
|
-
if (!repo.pathExists("NODE.md")) tasks.push("NODE.md is missing — create from `.context-tree/templates/root-node.md.template`, fill in your project's domains");
|
|
114
|
-
else {
|
|
115
|
-
const fm = repo.frontmatter("NODE.md");
|
|
116
|
-
if (fm === null) tasks.push("NODE.md exists but has no frontmatter — add frontmatter with title and owners fields");
|
|
117
|
-
else {
|
|
118
|
-
if (!fm.title || fm.title.startsWith("<")) tasks.push("NODE.md has a placeholder title — replace with your organization name");
|
|
119
|
-
if (!fm.owners || fm.owners.length === 0 || fm.owners.length === 1 && fm.owners[0].startsWith("<")) tasks.push("NODE.md has placeholder owners — set owners to your GitHub username(s)");
|
|
120
|
-
}
|
|
121
|
-
if (repo.hasPlaceholderNode()) tasks.push("NODE.md has placeholder content — fill in your project's domains and description");
|
|
122
|
-
}
|
|
123
|
-
return {
|
|
124
|
-
group: "Root Node",
|
|
125
|
-
order: 2,
|
|
126
|
-
tasks
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
//#endregion
|
|
130
|
-
//#region src/rules/index.ts
|
|
131
|
-
const ALL_RULES = [
|
|
132
|
-
framework_exports,
|
|
133
|
-
root_node_exports,
|
|
134
|
-
agent_instructions_exports,
|
|
135
|
-
members_exports,
|
|
136
|
-
agent_integration_exports,
|
|
137
|
-
ci_validation_exports
|
|
138
|
-
];
|
|
139
|
-
function evaluateAll(repo) {
|
|
140
|
-
const results = [];
|
|
141
|
-
for (const rule of ALL_RULES) {
|
|
142
|
-
const result = rule.evaluate(repo);
|
|
143
|
-
if (result.tasks.length > 0) results.push(result);
|
|
144
|
-
}
|
|
145
|
-
return results.sort((a, b) => a.order - b.order);
|
|
146
|
-
}
|
|
147
|
-
//#endregion
|
|
148
|
-
//#region src/init.ts
|
|
149
|
-
const SEED_TREE_URL = "https://github.com/agent-team-foundation/seed-tree";
|
|
150
|
-
const FRAMEWORK_DIR = ".context-tree";
|
|
151
|
-
const TEMPLATE_MAP = [
|
|
152
|
-
["root-node.md.template", "NODE.md"],
|
|
153
|
-
["agent.md.template", "AGENT.md"],
|
|
154
|
-
["members-domain.md.template", "members/NODE.md"]
|
|
155
|
-
];
|
|
156
|
-
function cloneSeedTree() {
|
|
157
|
-
const tmp = mkdtempSync(join(tmpdir(), "context-tree-"));
|
|
158
|
-
console.log(`Cloning seed-tree from ${SEED_TREE_URL}...`);
|
|
159
|
-
try {
|
|
160
|
-
execFileSync("git", [
|
|
161
|
-
"clone",
|
|
162
|
-
"--depth",
|
|
163
|
-
"1",
|
|
164
|
-
SEED_TREE_URL,
|
|
165
|
-
tmp
|
|
166
|
-
], {
|
|
167
|
-
encoding: "utf-8",
|
|
168
|
-
stdio: "pipe"
|
|
169
|
-
});
|
|
170
|
-
} catch (err) {
|
|
171
|
-
const message = err instanceof Error ? err.message : "unknown error";
|
|
172
|
-
console.error(`Failed to clone seed-tree: ${message}`);
|
|
173
|
-
rmSync(tmp, {
|
|
174
|
-
recursive: true,
|
|
175
|
-
force: true
|
|
176
|
-
});
|
|
177
|
-
process.exit(1);
|
|
178
|
-
}
|
|
179
|
-
return tmp;
|
|
180
|
-
}
|
|
181
|
-
function copyFramework(source, target) {
|
|
182
|
-
const src = join(source, FRAMEWORK_DIR);
|
|
183
|
-
const dst = join(target, FRAMEWORK_DIR);
|
|
184
|
-
if (existsSync(dst)) rmSync(dst, {
|
|
185
|
-
recursive: true,
|
|
186
|
-
force: true
|
|
187
|
-
});
|
|
188
|
-
cpSync(src, dst, { recursive: true });
|
|
189
|
-
console.log(` Copied ${FRAMEWORK_DIR}/`);
|
|
190
|
-
}
|
|
191
|
-
function renderTemplates(frameworkDir, target) {
|
|
192
|
-
const templatesDir = join(frameworkDir, "templates");
|
|
193
|
-
for (const [templateName, targetPath] of TEMPLATE_MAP) {
|
|
194
|
-
const src = join(templatesDir, templateName);
|
|
195
|
-
const dst = join(target, targetPath);
|
|
196
|
-
if (existsSync(dst)) console.log(` Skipped ${targetPath} (already exists)`);
|
|
197
|
-
else if (existsSync(src)) {
|
|
198
|
-
mkdirSync(dirname(dst), { recursive: true });
|
|
199
|
-
copyFileSync(src, dst);
|
|
200
|
-
console.log(` Created ${targetPath}`);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
function addUpstreamRemote(target) {
|
|
205
|
-
try {
|
|
206
|
-
if (!execFileSync("git", ["remote"], {
|
|
207
|
-
cwd: target,
|
|
208
|
-
encoding: "utf-8"
|
|
209
|
-
}).split(/\s+/).includes("context-tree-upstream")) {
|
|
210
|
-
execFileSync("git", [
|
|
211
|
-
"remote",
|
|
212
|
-
"add",
|
|
213
|
-
"context-tree-upstream",
|
|
214
|
-
SEED_TREE_URL
|
|
215
|
-
], {
|
|
216
|
-
cwd: target,
|
|
217
|
-
encoding: "utf-8",
|
|
218
|
-
stdio: "pipe"
|
|
219
|
-
});
|
|
220
|
-
console.log(` Added git remote 'context-tree-upstream' -> ${SEED_TREE_URL}`);
|
|
221
|
-
}
|
|
222
|
-
} catch {}
|
|
223
|
-
}
|
|
224
|
-
function formatTaskList(groups) {
|
|
225
|
-
const lines = ["# Context Tree Init\n"];
|
|
226
|
-
for (const group of groups) {
|
|
227
|
-
lines.push(`## ${group.group}`);
|
|
228
|
-
for (const task of group.tasks) lines.push(`- [ ] ${task}`);
|
|
229
|
-
lines.push("");
|
|
230
|
-
}
|
|
231
|
-
lines.push("## Verification");
|
|
232
|
-
lines.push("After completing the tasks above, run `context-tree verify` to confirm:");
|
|
233
|
-
lines.push("- [ ] `.context-tree/VERSION` exists");
|
|
234
|
-
lines.push("- [ ] Root NODE.md has valid frontmatter (title, owners)");
|
|
235
|
-
lines.push("- [ ] AGENT.md exists with framework markers");
|
|
236
|
-
lines.push("- [ ] `context-tree verify` passes with no errors");
|
|
237
|
-
lines.push("- [ ] At least one member node exists");
|
|
238
|
-
lines.push("");
|
|
239
|
-
lines.push("---");
|
|
240
|
-
lines.push("");
|
|
241
|
-
lines.push("**Important:** As you complete each task, check it off in `.context-tree/progress.md` by changing `- [ ]` to `- [x]`. Run `context-tree verify` when done — it will fail if any items remain unchecked.");
|
|
242
|
-
lines.push("");
|
|
243
|
-
return lines.join("\n");
|
|
244
|
-
}
|
|
245
|
-
function writeProgress(repo, content) {
|
|
246
|
-
const progressPath = join(repo.root, ".context-tree", "progress.md");
|
|
247
|
-
mkdirSync(dirname(progressPath), { recursive: true });
|
|
248
|
-
writeFileSync(progressPath, content);
|
|
249
|
-
}
|
|
250
|
-
function runInit(repo) {
|
|
251
|
-
const r = repo ?? new Repo();
|
|
252
|
-
if (!r.isGitRepo()) {
|
|
253
|
-
console.error("Error: not a git repository. Initialize one first:\n git init");
|
|
254
|
-
return 1;
|
|
255
|
-
}
|
|
256
|
-
if (!r.hasFramework()) {
|
|
257
|
-
const seed = cloneSeedTree();
|
|
258
|
-
try {
|
|
259
|
-
console.log("Copying framework and scaffolding...");
|
|
260
|
-
copyFramework(seed, r.root);
|
|
261
|
-
renderTemplates(join(r.root, FRAMEWORK_DIR), r.root);
|
|
262
|
-
addUpstreamRemote(r.root);
|
|
263
|
-
} finally {
|
|
264
|
-
rmSync(seed, {
|
|
265
|
-
recursive: true,
|
|
266
|
-
force: true
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
console.log();
|
|
270
|
-
}
|
|
271
|
-
const groups = evaluateAll(r);
|
|
272
|
-
if (groups.length === 0) {
|
|
273
|
-
console.log("All checks passed. Your context tree is set up.");
|
|
274
|
-
return 0;
|
|
275
|
-
}
|
|
276
|
-
const output = formatTaskList(groups);
|
|
277
|
-
console.log(output);
|
|
278
|
-
writeProgress(r, output);
|
|
279
|
-
console.log("Progress file written to .context-tree/progress.md");
|
|
280
|
-
return 0;
|
|
281
|
-
}
|
|
282
|
-
//#endregion
|
|
283
|
-
export { runInit };
|
package/dist/repo-BByc3VvM.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { execFileSync } from "node:child_process";
|
|
2
|
-
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
3
|
-
import { join, resolve } from "node:path";
|
|
4
|
-
//#region src/repo.ts
|
|
5
|
-
const FRONTMATTER_RE = /^---\s*\n(.*?)\n---/s;
|
|
6
|
-
const OWNERS_RE = /^owners:\s*\[([^\]]*)\]/m;
|
|
7
|
-
const TITLE_RE = /^title:\s*['"]?(.+?)['"]?\s*$/m;
|
|
8
|
-
const FRAMEWORK_END_MARKER = "<!-- END CONTEXT-TREE FRAMEWORK -->";
|
|
9
|
-
var Repo = class {
|
|
10
|
-
root;
|
|
11
|
-
constructor(root) {
|
|
12
|
-
this.root = resolve(root ?? process.cwd());
|
|
13
|
-
}
|
|
14
|
-
pathExists(relPath) {
|
|
15
|
-
return existsSync(join(this.root, relPath));
|
|
16
|
-
}
|
|
17
|
-
fileContains(relPath, text) {
|
|
18
|
-
const fullPath = join(this.root, relPath);
|
|
19
|
-
try {
|
|
20
|
-
if (!statSync(fullPath).isFile()) return false;
|
|
21
|
-
return readFileSync(fullPath, "utf-8").includes(text);
|
|
22
|
-
} catch {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
readFile(relPath) {
|
|
27
|
-
try {
|
|
28
|
-
return readFileSync(join(this.root, relPath), "utf-8");
|
|
29
|
-
} catch {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
frontmatter(relPath) {
|
|
34
|
-
const text = this.readFile(relPath);
|
|
35
|
-
if (text === null) return null;
|
|
36
|
-
const m = text.match(FRONTMATTER_RE);
|
|
37
|
-
if (!m) return null;
|
|
38
|
-
const fm = m[1];
|
|
39
|
-
const result = {};
|
|
40
|
-
const titleM = fm.match(TITLE_RE);
|
|
41
|
-
if (titleM) result.title = titleM[1].trim();
|
|
42
|
-
const ownersM = fm.match(OWNERS_RE);
|
|
43
|
-
if (ownersM) {
|
|
44
|
-
const raw = ownersM[1].trim();
|
|
45
|
-
result.owners = raw ? raw.split(",").map((o) => o.trim()).filter(Boolean) : [];
|
|
46
|
-
}
|
|
47
|
-
return result.title !== void 0 || result.owners !== void 0 ? result : null;
|
|
48
|
-
}
|
|
49
|
-
anyAgentConfig() {
|
|
50
|
-
return [".claude/settings.json", ".codex/config.json"].some((c) => this.pathExists(c));
|
|
51
|
-
}
|
|
52
|
-
isGitRepo() {
|
|
53
|
-
try {
|
|
54
|
-
return statSync(join(this.root, ".git")).isDirectory();
|
|
55
|
-
} catch {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
hasFramework() {
|
|
60
|
-
return this.pathExists(".context-tree/VERSION");
|
|
61
|
-
}
|
|
62
|
-
readVersion() {
|
|
63
|
-
const text = this.readFile(".context-tree/VERSION");
|
|
64
|
-
return text ? text.trim() : null;
|
|
65
|
-
}
|
|
66
|
-
hasAgentMdMarkers() {
|
|
67
|
-
const text = this.readFile("AGENT.md");
|
|
68
|
-
if (text === null) return false;
|
|
69
|
-
return text.includes("<!-- BEGIN CONTEXT-TREE FRAMEWORK") && text.includes("<!-- END CONTEXT-TREE FRAMEWORK -->");
|
|
70
|
-
}
|
|
71
|
-
hasMembers() {
|
|
72
|
-
const membersDir = join(this.root, "members");
|
|
73
|
-
try {
|
|
74
|
-
if (!statSync(membersDir).isDirectory()) return false;
|
|
75
|
-
} catch {
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
return existsSync(join(membersDir, "NODE.md"));
|
|
79
|
-
}
|
|
80
|
-
memberCount() {
|
|
81
|
-
const membersDir = join(this.root, "members");
|
|
82
|
-
try {
|
|
83
|
-
if (!statSync(membersDir).isDirectory()) return 0;
|
|
84
|
-
} catch {
|
|
85
|
-
return 0;
|
|
86
|
-
}
|
|
87
|
-
let count = 0;
|
|
88
|
-
for (const entry of readdirSync(membersDir)) {
|
|
89
|
-
const childPath = join(membersDir, entry);
|
|
90
|
-
try {
|
|
91
|
-
if (statSync(childPath).isDirectory() && existsSync(join(childPath, "NODE.md"))) count++;
|
|
92
|
-
} catch {}
|
|
93
|
-
}
|
|
94
|
-
return count;
|
|
95
|
-
}
|
|
96
|
-
hasPlaceholderNode() {
|
|
97
|
-
return this.fileContains("NODE.md", "<!-- PLACEHOLDER");
|
|
98
|
-
}
|
|
99
|
-
hasUpstreamRemote() {
|
|
100
|
-
try {
|
|
101
|
-
return execFileSync("git", ["remote"], {
|
|
102
|
-
cwd: this.root,
|
|
103
|
-
encoding: "utf-8"
|
|
104
|
-
}).split(/\s+/).includes("context-tree-upstream");
|
|
105
|
-
} catch {
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
//#endregion
|
|
111
|
-
export { Repo as n, FRAMEWORK_END_MARKER as t };
|
package/dist/upgrade-Chr7z0CY.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { n as Repo } from "./repo-BByc3VvM.js";
|
|
2
|
-
import { execFileSync } from "node:child_process";
|
|
3
|
-
import { mkdirSync, writeFileSync } from "node:fs";
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
5
|
-
//#region src/upgrade.ts
|
|
6
|
-
const SEED_TREE_URL = "https://github.com/agent-team-foundation/seed-tree";
|
|
7
|
-
function getUpstreamVersion(repo) {
|
|
8
|
-
try {
|
|
9
|
-
execFileSync("git", [
|
|
10
|
-
"fetch",
|
|
11
|
-
"context-tree-upstream",
|
|
12
|
-
"--depth",
|
|
13
|
-
"1"
|
|
14
|
-
], {
|
|
15
|
-
cwd: repo.root,
|
|
16
|
-
encoding: "utf-8",
|
|
17
|
-
stdio: "pipe"
|
|
18
|
-
});
|
|
19
|
-
} catch {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
try {
|
|
23
|
-
return execFileSync("git", ["show", "context-tree-upstream/main:.context-tree/VERSION"], {
|
|
24
|
-
cwd: repo.root,
|
|
25
|
-
encoding: "utf-8",
|
|
26
|
-
stdio: "pipe"
|
|
27
|
-
}).trim();
|
|
28
|
-
} catch {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function writeProgress(repo, content) {
|
|
33
|
-
const progressPath = join(repo.root, ".context-tree", "progress.md");
|
|
34
|
-
mkdirSync(dirname(progressPath), { recursive: true });
|
|
35
|
-
writeFileSync(progressPath, content);
|
|
36
|
-
}
|
|
37
|
-
function runUpgrade() {
|
|
38
|
-
const repo = new Repo();
|
|
39
|
-
if (!repo.hasFramework()) {
|
|
40
|
-
console.error("Error: no .context-tree/ found. Run `context-tree init` first.");
|
|
41
|
-
return 1;
|
|
42
|
-
}
|
|
43
|
-
const localVersion = repo.readVersion() ?? "unknown";
|
|
44
|
-
console.log(`Local framework version: ${localVersion}\n`);
|
|
45
|
-
if (!repo.hasUpstreamRemote()) {
|
|
46
|
-
const output = [
|
|
47
|
-
"# Context Tree Upgrade\n",
|
|
48
|
-
"## Setup",
|
|
49
|
-
`- [ ] Add upstream remote: \`git remote add context-tree-upstream ${SEED_TREE_URL}\``,
|
|
50
|
-
"- [ ] Then run `context-tree upgrade` again to check for updates"
|
|
51
|
-
].join("\n");
|
|
52
|
-
console.log(output);
|
|
53
|
-
writeProgress(repo, output + "\n");
|
|
54
|
-
console.log("\nProgress file written to .context-tree/progress.md");
|
|
55
|
-
return 0;
|
|
56
|
-
}
|
|
57
|
-
const upstreamVersion = getUpstreamVersion(repo);
|
|
58
|
-
if (upstreamVersion === null) {
|
|
59
|
-
console.log("Could not fetch upstream version. Check your network and try again.");
|
|
60
|
-
return 1;
|
|
61
|
-
}
|
|
62
|
-
if (upstreamVersion === localVersion) {
|
|
63
|
-
console.log(`Already up to date (v${localVersion}).`);
|
|
64
|
-
return 0;
|
|
65
|
-
}
|
|
66
|
-
const lines = [
|
|
67
|
-
`# Context Tree Upgrade — v${localVersion} -> v${upstreamVersion}\n`,
|
|
68
|
-
"## Framework",
|
|
69
|
-
"- [ ] Pull latest from upstream: `git fetch context-tree-upstream && git merge context-tree-upstream/main`",
|
|
70
|
-
"- [ ] Resolve any conflicts in `.context-tree/` (framework files should generally take upstream version)",
|
|
71
|
-
""
|
|
72
|
-
];
|
|
73
|
-
if (repo.hasAgentMdMarkers()) lines.push("## Agent Instructions", "- [ ] Check if AGENT.md framework section needs updating — compare content between markers to the new template", "");
|
|
74
|
-
lines.push("## Verification", `- [ ] \`.context-tree/VERSION\` reads \`${upstreamVersion}\``, "- [ ] `context-tree verify` passes", "- [ ] AGENT.md framework section matches upstream", "", "---", "", "**Important:** As you complete each task, check it off in `.context-tree/progress.md` by changing `- [ ]` to `- [x]`. Run `context-tree verify` when done — it will fail if any items remain unchecked.", "");
|
|
75
|
-
const output = lines.join("\n");
|
|
76
|
-
console.log(output);
|
|
77
|
-
writeProgress(repo, output);
|
|
78
|
-
console.log("Progress file written to .context-tree/progress.md");
|
|
79
|
-
return 0;
|
|
80
|
-
}
|
|
81
|
-
//#endregion
|
|
82
|
-
export { runUpgrade };
|