first-tree 0.0.3 → 0.0.5

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 (59) hide show
  1. package/README.md +78 -27
  2. package/dist/cli.js +28 -13
  3. package/dist/{help-xEI-s9iN.js → help-5-WG9QFm.js} +1 -1
  4. package/dist/{init-DtOjj0wc.js → init-CAq0Uhq6.js} +187 -25
  5. package/dist/{installer-rcZpGLnM.js → installer-UgNasLjl.js} +20 -16
  6. package/dist/onboarding-3zYUeYQb.js +2 -0
  7. package/dist/onboarding-Dd63N-V1.js +10 -0
  8. package/dist/repo-DkR12VUv.js +369 -0
  9. package/dist/upgrade-DYzuvv1k.js +140 -0
  10. package/dist/{verify-CxN6JiV9.js → verify-C0IUSkMZ.js} +66 -6
  11. package/package.json +12 -10
  12. package/skills/first-tree/SKILL.md +18 -10
  13. package/skills/first-tree/assets/framework/VERSION +1 -1
  14. package/skills/first-tree/assets/framework/examples/claude-code/README.md +2 -2
  15. package/skills/first-tree/assets/framework/examples/claude-code/settings.json +1 -1
  16. package/skills/first-tree/assets/framework/helpers/generate-codeowners.ts +1 -1
  17. package/skills/first-tree/assets/framework/helpers/inject-tree-context.sh +0 -0
  18. package/skills/first-tree/assets/framework/helpers/run-review.ts +17 -3
  19. package/skills/first-tree/assets/framework/templates/{agent.md.template → agents.md.template} +3 -2
  20. package/skills/first-tree/assets/framework/templates/members-domain.md.template +1 -1
  21. package/skills/first-tree/assets/framework/templates/root-node.md.template +9 -6
  22. package/skills/first-tree/assets/framework/workflows/codeowners.yml +1 -1
  23. package/skills/first-tree/assets/framework/workflows/pr-review.yml +1 -1
  24. package/skills/first-tree/engine/commands/init.ts +1 -1
  25. package/skills/first-tree/engine/commands/upgrade.ts +1 -1
  26. package/skills/first-tree/engine/commands/verify.ts +1 -1
  27. package/skills/first-tree/engine/init.ts +288 -18
  28. package/skills/first-tree/engine/repo.ts +220 -11
  29. package/skills/first-tree/engine/rules/agent-instructions.ts +29 -7
  30. package/skills/first-tree/engine/rules/agent-integration.ts +3 -1
  31. package/skills/first-tree/engine/rules/framework.ts +2 -2
  32. package/skills/first-tree/engine/runtime/adapters.ts +6 -2
  33. package/skills/first-tree/engine/runtime/asset-loader.ts +143 -4
  34. package/skills/first-tree/engine/runtime/installer.ts +18 -12
  35. package/skills/first-tree/engine/upgrade.ts +99 -15
  36. package/skills/first-tree/engine/validators/nodes.ts +48 -3
  37. package/skills/first-tree/engine/verify.ts +61 -3
  38. package/skills/first-tree/references/maintainer-architecture.md +1 -1
  39. package/skills/first-tree/references/maintainer-build-and-distribution.md +3 -0
  40. package/skills/first-tree/references/maintainer-thin-cli.md +1 -1
  41. package/skills/first-tree/references/onboarding.md +57 -24
  42. package/skills/first-tree/references/source-map.md +3 -3
  43. package/skills/first-tree/references/upgrade-contract.md +62 -27
  44. package/skills/first-tree/scripts/check-skill-sync.sh +1 -1
  45. package/skills/first-tree/scripts/quick_validate.py +0 -0
  46. package/skills/first-tree/scripts/run-local-cli.sh +0 -0
  47. package/skills/first-tree/tests/asset-loader.test.ts +23 -1
  48. package/skills/first-tree/tests/helpers.ts +51 -7
  49. package/skills/first-tree/tests/init.test.ts +113 -8
  50. package/skills/first-tree/tests/repo.test.ts +113 -9
  51. package/skills/first-tree/tests/rules.test.ts +35 -14
  52. package/skills/first-tree/tests/skill-artifacts.test.ts +10 -0
  53. package/skills/first-tree/tests/thin-cli.test.ts +52 -7
  54. package/skills/first-tree/tests/upgrade.test.ts +39 -6
  55. package/skills/first-tree/tests/verify.test.ts +109 -10
  56. package/dist/onboarding-6Fr5Gkrk.js +0 -2
  57. package/dist/onboarding-B9zPGvvG.js +0 -10
  58. package/dist/repo-BTJG8BU1.js +0 -187
  59. package/dist/upgrade-COGgI7Rj.js +0 -96
@@ -1,14 +1,20 @@
1
1
  import { mkdirSync, rmSync, writeFileSync } from "node:fs";
2
- import { dirname, join } from "node:path";
2
+ import { dirname, join, resolve } from "node:path";
3
3
  import { Repo } from "#skill/engine/repo.js";
4
4
  import {
5
+ AGENT_INSTRUCTIONS_FILE,
6
+ AGENT_INSTRUCTIONS_TEMPLATE,
7
+ CLAUDE_SKILL_ROOT,
5
8
  FRAMEWORK_WORKFLOWS_DIR,
6
9
  FRAMEWORK_TEMPLATES_DIR,
7
10
  FRAMEWORK_VERSION,
8
11
  INSTALLED_PROGRESS,
12
+ LEGACY_AGENT_INSTRUCTIONS_FILE,
9
13
  LEGACY_FRAMEWORK_ROOT,
14
+ LEGACY_REPO_SKILL_ROOT,
10
15
  LEGACY_SKILL_ROOT,
11
16
  SKILL_ROOT,
17
+ installedSkillRootsDisplay,
12
18
  type FrameworkLayout,
13
19
  } from "#skill/engine/runtime/asset-loader.js";
14
20
  import {
@@ -20,6 +26,13 @@ import {
20
26
  readSourceVersion,
21
27
  } from "#skill/engine/runtime/upgrader.js";
22
28
 
29
+ export const UPGRADE_USAGE = `usage: context-tree upgrade [--tree-path PATH]
30
+
31
+ Options:
32
+ --tree-path PATH Upgrade a tree repo from another working directory
33
+ --help Show this help message
34
+ `;
35
+
23
36
  function writeProgress(repo: Repo, content: string): void {
24
37
  const progressPath = join(repo.root, repo.preferredProgressPath());
25
38
  mkdirSync(dirname(progressPath), { recursive: true });
@@ -35,32 +48,52 @@ function formatUpgradeTaskList(
35
48
  const lines: string[] = [
36
49
  `# Context Tree Upgrade — v${localVersion} -> v${packagedVersion}\n`,
37
50
  "## Installed Skill",
38
- `- [ ] Review local customizations under \`${SKILL_ROOT}/\` and reapply them if needed`,
51
+ `- [ ] Review local customizations under ${installedSkillRootsDisplay()} and reapply them if needed`,
39
52
  `- [ ] Re-copy any workflow updates you want from \`${FRAMEWORK_WORKFLOWS_DIR}/\` into \`.github/workflows/\``,
40
- `- [ ] Re-check any local agent setup that references \`${SKILL_ROOT}/assets/framework/examples/\` or \`${SKILL_ROOT}/assets/framework/helpers/\``,
53
+ `- [ ] Re-check any local agent setup that references \`${CLAUDE_SKILL_ROOT}/assets/framework/examples/\` or \`${CLAUDE_SKILL_ROOT}/assets/framework/helpers/\``,
54
+ `- [ ] Re-check any repo scripts or workflow files that reference \`${SKILL_ROOT}/assets/framework/\``,
41
55
  "",
42
56
  ];
43
57
 
58
+ const migrationTasks: string[] = [];
44
59
  if (layout === "legacy") {
60
+ migrationTasks.push(
61
+ "- [ ] Remove any stale `.context-tree/` references from repo-specific docs, scripts, or workflow files",
62
+ );
63
+ }
64
+
65
+ if (layout === "legacy-repo-skill") {
45
66
  lines.push(
46
67
  "## Migration",
47
- "- [ ] Remove any stale `.context-tree/` references from repo-specific docs, scripts, or workflow files",
68
+ `- [ ] Remove any stale \`${LEGACY_REPO_SKILL_ROOT}/\` references from repo-specific docs, scripts, workflow files, or agent config`,
48
69
  "",
49
70
  );
50
71
  }
51
72
 
52
73
  if (layout === "legacy-skill") {
53
- lines.push(
54
- "## Migration",
74
+ migrationTasks.push(
55
75
  `- [ ] Remove any stale \`${LEGACY_SKILL_ROOT}/\` references from repo-specific docs, scripts, workflow files, or agent config`,
56
- "",
57
76
  );
58
77
  }
59
78
 
60
- if (repo.hasAgentMdMarkers()) {
79
+ if (repo.hasCanonicalAgentInstructionsFile() && repo.hasLegacyAgentInstructionsFile()) {
80
+ migrationTasks.push(
81
+ `- [ ] Merge any remaining user-authored content from \`${LEGACY_AGENT_INSTRUCTIONS_FILE}\` into \`${AGENT_INSTRUCTIONS_FILE}\`, then delete the legacy file`,
82
+ );
83
+ } else if (repo.hasLegacyAgentInstructionsFile()) {
84
+ migrationTasks.push(
85
+ `- [ ] Rename \`${LEGACY_AGENT_INSTRUCTIONS_FILE}\` to \`${AGENT_INSTRUCTIONS_FILE}\` to use the canonical agent instructions filename`,
86
+ );
87
+ }
88
+
89
+ if (migrationTasks.length > 0) {
90
+ lines.push("## Migration", ...migrationTasks, "");
91
+ }
92
+
93
+ if (repo.hasAgentInstructionsMarkers()) {
61
94
  lines.push(
62
95
  "## Agent Instructions",
63
- `- [ ] Compare the framework section in \`AGENT.md\` with \`${FRAMEWORK_TEMPLATES_DIR}/agent.md.template\` and update the content between the markers if needed`,
96
+ `- [ ] Compare the framework section in \`${AGENT_INSTRUCTIONS_FILE}\` with \`${FRAMEWORK_TEMPLATES_DIR}/${AGENT_INSTRUCTIONS_TEMPLATE}\` and update the content between the markers if needed`,
64
97
  "",
65
98
  );
66
99
  }
@@ -89,6 +122,13 @@ export interface UpgradeOptions {
89
122
  export function runUpgrade(repo?: Repo, options?: UpgradeOptions): number {
90
123
  const workingRepo = repo ?? new Repo();
91
124
 
125
+ if (workingRepo.isLikelySourceRepo() && !workingRepo.looksLikeTreeRepo()) {
126
+ console.error(
127
+ "Error: no installed framework skill found here. This looks like a source/workspace repo. Run `context-tree init` to create a dedicated tree repo, or pass `--tree-path` to upgrade an existing tree repo.",
128
+ );
129
+ return 1;
130
+ }
131
+
92
132
  if (!workingRepo.hasFramework()) {
93
133
  console.error(
94
134
  "Error: no installed framework skill found. Run `context-tree init` first.",
@@ -137,7 +177,12 @@ export function runUpgrade(repo?: Repo, options?: UpgradeOptions): number {
137
177
  return 1;
138
178
  }
139
179
 
140
- if (layout === "skill" && packagedVersion === localVersion) {
180
+ const missingInstalledRoots = workingRepo.missingInstalledSkillRoots();
181
+ if (
182
+ layout === "skill" &&
183
+ missingInstalledRoots.length === 0 &&
184
+ packagedVersion === localVersion
185
+ ) {
141
186
  console.log(
142
187
  `Already up to date with the bundled skill (${FRAMEWORK_VERSION} = ${localVersion}).`,
143
188
  );
@@ -151,16 +196,26 @@ export function runUpgrade(repo?: Repo, options?: UpgradeOptions): number {
151
196
  force: true,
152
197
  });
153
198
  console.log(
154
- "Migrated legacy .context-tree/ layout to skills/first-tree/.",
199
+ `Migrated legacy .context-tree/ layout to ${installedSkillRootsDisplay()}.`,
155
200
  );
156
- } else if (layout === "legacy-skill") {
201
+ } else if (layout === "legacy-repo-skill") {
157
202
  console.log(
158
- "Migrated skills/first-tree-cli-framework/ to skills/first-tree/.",
203
+ `Migrated legacy ${LEGACY_REPO_SKILL_ROOT}/ layout to ${installedSkillRootsDisplay()}.`,
159
204
  );
160
- } else {
205
+ } else if (layout === "legacy-skill") {
161
206
  console.log(
162
- "Refreshed skills/first-tree/ from the bundled first-tree package.",
207
+ `Migrated ${LEGACY_SKILL_ROOT}/ to ${installedSkillRootsDisplay()}.`,
163
208
  );
209
+ } else {
210
+ if (missingInstalledRoots.length > 0) {
211
+ console.log(
212
+ `Repaired missing installed skill roots (${missingInstalledRoots.map((root) => `${root}/`).join(", ")}) and refreshed ${installedSkillRootsDisplay()} from the bundled first-tree package.`,
213
+ );
214
+ } else {
215
+ console.log(
216
+ `Refreshed ${installedSkillRootsDisplay()} from the bundled first-tree package.`,
217
+ );
218
+ }
164
219
  }
165
220
 
166
221
  const output = formatUpgradeTaskList(
@@ -174,3 +229,32 @@ export function runUpgrade(repo?: Repo, options?: UpgradeOptions): number {
174
229
  console.log(`Progress file written to ${workingRepo.preferredProgressPath()}`);
175
230
  return 0;
176
231
  }
232
+
233
+ export function runUpgradeCli(args: string[] = []): number {
234
+ if (args.includes("--help") || args.includes("-h")) {
235
+ console.log(UPGRADE_USAGE);
236
+ return 0;
237
+ }
238
+
239
+ let treePath: string | undefined;
240
+ for (let index = 0; index < args.length; index += 1) {
241
+ const arg = args[index];
242
+ if (arg === "--tree-path") {
243
+ const value = args[index + 1];
244
+ if (!value) {
245
+ console.error("Missing value for --tree-path");
246
+ console.log(UPGRADE_USAGE);
247
+ return 1;
248
+ }
249
+ treePath = value;
250
+ index += 1;
251
+ continue;
252
+ }
253
+
254
+ console.error(`Unknown upgrade option: ${arg}`);
255
+ console.log(UPGRADE_USAGE);
256
+ return 1;
257
+ }
258
+
259
+ return runUpgrade(treePath ? new Repo(resolve(process.cwd(), treePath)) : undefined);
260
+ }
@@ -1,5 +1,13 @@
1
1
  import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
2
2
  import { join, relative, posix } from "node:path";
3
+ import {
4
+ AGENT_INSTRUCTIONS_FILE,
5
+ LEGACY_AGENT_INSTRUCTIONS_FILE,
6
+ LEGACY_SKILL_NAME,
7
+ LEGACY_SKILL_ROOT,
8
+ SKILL_NAME,
9
+ SKILL_ROOT,
10
+ } from "#skill/engine/runtime/asset-loader.js";
3
11
 
4
12
  const FRONTMATTER_RE = /^---\s*\n(.*?)\n---/s;
5
13
  const OWNERS_RE = /^owners:\s*\[([^\]]*)\]/m;
@@ -11,7 +19,11 @@ const MD_LINK_RE = /\[.*?\]\(([^)]+\.md)\)/g;
11
19
  const DOMAIN_LINK_RE = /\[(\w[\w-]*)\/?\]\((\w[\w-]*)\/NODE\.md\)/g;
12
20
 
13
21
  const SKIP = new Set(["node_modules", "__pycache__"]);
14
- const SKIP_FILES = new Set(["AGENT.md", "CLAUDE.md"]);
22
+ const SKIP_FILES = new Set([
23
+ AGENT_INSTRUCTIONS_FILE,
24
+ LEGACY_AGENT_INSTRUCTIONS_FILE,
25
+ "CLAUDE.md",
26
+ ]);
15
27
  const MIN_BODY_LENGTH = 20;
16
28
 
17
29
  export class Findings {
@@ -75,9 +87,42 @@ function rel(path: string): string {
75
87
  return relative(treeRoot, path);
76
88
  }
77
89
 
90
+ function isInstalledSkillPath(relPath: string): boolean {
91
+ return (
92
+ relPath === SKILL_ROOT ||
93
+ relPath.startsWith(`${SKILL_ROOT}/`) ||
94
+ relPath === LEGACY_SKILL_ROOT ||
95
+ relPath.startsWith(`${LEGACY_SKILL_ROOT}/`)
96
+ );
97
+ }
98
+
99
+ function isFrameworkContainerDir(relPath: string, fullPath: string): boolean {
100
+ if (relPath !== "skills") {
101
+ return false;
102
+ }
103
+
104
+ try {
105
+ const entries = readdirSync(fullPath).filter((entry) => !entry.startsWith("."));
106
+ if (entries.length === 0) {
107
+ return false;
108
+ }
109
+ return entries.every(
110
+ (entry) => entry === SKILL_NAME || entry === LEGACY_SKILL_NAME,
111
+ );
112
+ } catch {
113
+ return false;
114
+ }
115
+ }
116
+
78
117
  function shouldSkip(path: string): boolean {
79
- const parts = relative(treeRoot, path).split("/");
80
- return parts.some((part) => SKIP.has(part) || part.startsWith("."));
118
+ const relPath = relative(treeRoot, path);
119
+ const parts = relPath.split("/");
120
+
121
+ if (parts.some((part) => SKIP.has(part) || part.startsWith("."))) {
122
+ return true;
123
+ }
124
+
125
+ return isInstalledSkillPath(relPath) || isFrameworkContainerDir(relPath, path);
81
126
  }
82
127
 
83
128
  function readText(path: string): string | null {
@@ -1,8 +1,19 @@
1
+ import { resolve } from "node:path";
1
2
  import { Repo } from "#skill/engine/repo.js";
3
+ import {
4
+ AGENT_INSTRUCTIONS_FILE,
5
+ LEGACY_AGENT_INSTRUCTIONS_FILE,
6
+ } from "#skill/engine/runtime/asset-loader.js";
2
7
  import { runValidateMembers } from "#skill/engine/validators/members.js";
3
8
  import { runValidateNodes } from "#skill/engine/validators/nodes.js";
4
9
 
5
10
  const UNCHECKED_RE = /^- \[ \] (.+)$/gm;
11
+ export const VERIFY_USAGE = `usage: context-tree verify [--tree-path PATH]
12
+
13
+ Options:
14
+ --tree-path PATH Verify a tree repo from another working directory
15
+ --help Show this help message
16
+ `;
6
17
 
7
18
  export function check(label: string, passed: boolean): boolean {
8
19
  const icon = passed ? "\u2713" : "\u2717";
@@ -38,6 +49,14 @@ function defaultNodeValidator(root: string): ValidateNodesResult {
38
49
  export function runVerify(repo?: Repo, nodeValidator?: NodeValidator): number {
39
50
  const r = repo ?? new Repo();
40
51
  const validate = nodeValidator ?? defaultNodeValidator;
52
+
53
+ if (r.isLikelySourceRepo() && !r.looksLikeTreeRepo()) {
54
+ console.error(
55
+ "Error: no installed framework skill found here. This looks like a source/workspace repo. Run `context-tree init` to create a dedicated tree repo, or pass `--tree-path` to verify an existing tree repo.",
56
+ );
57
+ return 1;
58
+ }
59
+
41
60
  let allPassed = true;
42
61
  const progressPath = r.progressPath() ?? r.preferredProgressPath();
43
62
  const frameworkVersionPath = r.frameworkVersionPath();
@@ -73,10 +92,20 @@ export function runVerify(repo?: Repo, nodeValidator?: NodeValidator): number {
73
92
  hasValidNode,
74
93
  ) && allPassed;
75
94
 
76
- // 3. AGENT.md exists with framework markers
95
+ // 3. AGENTS.md is canonical and contains framework markers
96
+ const hasCanonicalAgentInstructions = r.hasCanonicalAgentInstructionsFile();
97
+ const hasLegacyAgentInstructions = r.hasLegacyAgentInstructionsFile();
98
+ if (hasLegacyAgentInstructions) {
99
+ const followUp = hasCanonicalAgentInstructions
100
+ ? `Remove legacy \`${LEGACY_AGENT_INSTRUCTIONS_FILE}\` after confirming its contents are in \`${AGENT_INSTRUCTIONS_FILE}\`.`
101
+ : `Rename \`${LEGACY_AGENT_INSTRUCTIONS_FILE}\` to \`${AGENT_INSTRUCTIONS_FILE}\`.`;
102
+ console.log(` Legacy agent instructions detected. ${followUp}\n`);
103
+ }
77
104
  allPassed = check(
78
- "AGENT.md exists with framework markers",
79
- r.hasAgentMdMarkers(),
105
+ `${AGENT_INSTRUCTIONS_FILE} is the only agent instructions file and has framework markers`,
106
+ hasCanonicalAgentInstructions &&
107
+ !hasLegacyAgentInstructions &&
108
+ r.hasAgentInstructionsMarkers(),
80
109
  ) && allPassed;
81
110
 
82
111
  // 4. Node validation
@@ -95,3 +124,32 @@ export function runVerify(repo?: Repo, nodeValidator?: NodeValidator): number {
95
124
  }
96
125
  return allPassed ? 0 : 1;
97
126
  }
127
+
128
+ export function runVerifyCli(args: string[] = []): number {
129
+ if (args.includes("--help") || args.includes("-h")) {
130
+ console.log(VERIFY_USAGE);
131
+ return 0;
132
+ }
133
+
134
+ let treePath: string | undefined;
135
+ for (let index = 0; index < args.length; index += 1) {
136
+ const arg = args[index];
137
+ if (arg === "--tree-path") {
138
+ const value = args[index + 1];
139
+ if (!value) {
140
+ console.error("Missing value for --tree-path");
141
+ console.log(VERIFY_USAGE);
142
+ return 1;
143
+ }
144
+ treePath = value;
145
+ index += 1;
146
+ continue;
147
+ }
148
+
149
+ console.error(`Unknown verify option: ${arg}`);
150
+ console.log(VERIFY_USAGE);
151
+ return 1;
152
+ }
153
+
154
+ return runVerify(treePath ? new Repo(resolve(process.cwd(), treePath)) : undefined);
155
+ }
@@ -33,7 +33,7 @@ that install the framework.
33
33
  - Treat `skills/first-tree/` as the only canonical source.
34
34
  - If a maintainer needs information to safely change behavior, move that
35
35
  information into `references/`; do not leave it only in root `README.md`,
36
- `AGENT.md`, CI comments, or PR descriptions.
36
+ `AGENTS.md`, CI comments, or PR descriptions.
37
37
  - Keep runtime assets generic. They are copied into every user tree.
38
38
  - Keep the CLI thin. Command semantics, upgrade rules, layout contracts, and
39
39
  maintainer guidance should belong to the skill.
@@ -50,6 +50,9 @@ another skill reference, not only in the files themselves.
50
50
  with the package rather than copying that information into root docs.
51
51
  - Normal `context-tree init` / `context-tree upgrade` flows must install from
52
52
  the skill bundled in the running package, not by cloning the source repo.
53
+ - Default dedicated-tree-repo creation must stay local-only. It may create a
54
+ sibling git repo on disk, but it must not require remote repo creation or
55
+ source-repo cloning.
53
56
  - If you change anything that gets copied into user repos, bump
54
57
  `assets/framework/VERSION` and keep the upgrade task text in sync.
55
58
  - If packaging changes alter what gets installed into user repos, update
@@ -26,7 +26,7 @@ These root files are shell code, not canonical knowledge stores:
26
26
  - `vitest.config.ts`
27
27
  - `vitest.eval.config.ts` (repo-only maintainer eval entrypoint)
28
28
  - `.github/workflows/ci.yml`
29
- - root `README.md` and `AGENT.md`
29
+ - root `README.md` and `AGENTS.md`
30
30
 
31
31
  ## Rules For Shell Changes
32
32
 
@@ -53,35 +53,59 @@ Information an agent needs to **decide** on an approach — not to execute it.
53
53
 
54
54
  ### Prerequisites
55
55
 
56
- - A Git repository for your tree (separate from your code repos)
56
+ - A source/workspace Git repository, or an already-created dedicated tree repo
57
57
  - Node.js 18+
58
58
  - The npm package is `first-tree`, the installed CLI command is
59
- `context-tree`, and the installed skill directory in the tree is
60
- `skills/first-tree/`
59
+ `context-tree`.
60
+ - `context-tree init` installs the framework skill into
61
+ `.agents/skills/first-tree/` and `.claude/skills/first-tree/`.
61
62
  - Use `npx first-tree init` for one-off runs, or `npm install -g first-tree`
62
63
  to add the `context-tree` command to your PATH
63
64
 
64
65
  ### Step 1: Initialize
65
66
 
67
+ Recommended workflow: run `context-tree init` from your source or workspace repo.
68
+ The CLI will create a sibling dedicated tree repo named `<repo>-context` by
69
+ default and install the framework there.
70
+
66
71
  ```bash
67
- mkdir my-org-tree && cd my-org-tree
68
- git init
72
+ cd my-org
69
73
  context-tree init
74
+ cd ../my-org-context
75
+ ```
76
+
77
+ If you already created a dedicated tree repo manually, initialize it in place:
78
+
79
+ ```bash
80
+ mkdir my-org-context && cd my-org-context
81
+ git init
82
+ context-tree init --here
70
83
  ```
71
84
 
72
- This installs the framework skill into `skills/first-tree/`, renders scaffolding (`NODE.md`, `AGENT.md`, `members/NODE.md`), and generates a task list in `skills/first-tree/progress.md`.
85
+ Either way, the framework installs into `.agents/skills/first-tree/` and
86
+ `.claude/skills/first-tree/`, renders scaffolding (`NODE.md`, `AGENTS.md`,
87
+ `members/NODE.md`), and generates a task list in
88
+ `.agents/skills/first-tree/progress.md`.
89
+
90
+ Publishing tip: keep the tree repo in the same GitHub organization as the
91
+ source repo unless you have a reason not to.
73
92
 
74
93
  ### Step 2: Work Through the Task List
75
94
 
76
- Read `skills/first-tree/progress.md`. It contains a checklist tailored to the current state of the repo. Complete each task:
95
+ Read `.agents/skills/first-tree/progress.md`. It contains a checklist tailored
96
+ to the current state of the repo. Complete each task:
77
97
 
78
98
  - Fill in `NODE.md` with your organization name, owners, and domains
79
- - Add project-specific instructions to `AGENT.md` below the framework markers
99
+ - Add project-specific instructions to `AGENTS.md` below the framework markers
80
100
  - Create member nodes under `members/`
81
- - Optionally configure agent integration (e.g., Claude Code session hooks)
82
- - Copy validation workflows from `skills/first-tree/assets/framework/workflows/` to `.github/workflows/`
101
+ - Optionally configure agent integration (for Claude Code, the installed hook
102
+ assets live under `.claude/skills/first-tree/`)
103
+ - Copy validation workflows from
104
+ `.agents/skills/first-tree/assets/framework/workflows/` to
105
+ `.github/workflows/`
83
106
 
84
- As you complete each task, check it off in `skills/first-tree/progress.md` by changing `- [ ]` to `- [x]`.
107
+ As you complete each task, check it off in
108
+ `.agents/skills/first-tree/progress.md` by changing `- [ ]` to `- [x]`.
85
109
 
86
110
  ### Step 3: Verify
87
111
 
@@ -89,7 +113,15 @@ As you complete each task, check it off in `skills/first-tree/progress.md` by ch
89
113
  context-tree verify
90
114
  ```
91
115
 
92
- This fails if any items in `skills/first-tree/progress.md` remain unchecked, and runs deterministic checks (valid frontmatter, node structure, member nodes exist).
116
+ Or, from your source/workspace repo:
117
+
118
+ ```bash
119
+ context-tree verify --tree-path ../my-org-context
120
+ ```
121
+
122
+ This fails if any items in `.agents/skills/first-tree/progress.md` remain
123
+ unchecked, and runs deterministic checks (valid frontmatter, node structure,
124
+ member nodes exist).
93
125
 
94
126
  ### Step 4: Design Your Domains
95
127
 
@@ -126,9 +158,9 @@ The tree doesn't duplicate source code — it captures what connects things and
126
158
 
127
159
  | Command | Description |
128
160
  |---------|-------------|
129
- | `context-tree init` | Bootstrap a new tree. Installs the framework skill, renders templates, generates a task list. |
130
- | `context-tree verify` | Check the installed progress file for unchecked items + run deterministic validation. |
131
- | `context-tree upgrade` | Refresh the installed framework skill from the currently running `first-tree` npm package and generate follow-up tasks. |
161
+ | `context-tree init` | Create or refresh a dedicated tree repo. By default, running in a source/workspace repo creates a sibling `<repo>-context`; use `--here` to initialize the current repo in place. |
162
+ | `context-tree verify` | Check the installed progress file for unchecked items + run deterministic validation. Use `--tree-path` when invoking from another working directory. |
163
+ | `context-tree upgrade` | Refresh the installed framework skill from the currently running `first-tree` npm package and generate follow-up tasks. Use `--tree-path` when invoking from another working directory. |
132
164
  | `context-tree help onboarding` | Print this onboarding guide. |
133
165
 
134
166
  ---
@@ -141,13 +173,14 @@ When the framework updates:
141
173
  context-tree upgrade
142
174
  ```
143
175
 
144
- `context-tree upgrade` refreshes `skills/first-tree/` from the
145
- skill bundled with the currently running `first-tree` npm package, preserves your
146
- tree content, and generates follow-up tasks in
147
- `skills/first-tree/progress.md`.
176
+ `context-tree upgrade` refreshes `.agents/skills/first-tree/` and
177
+ `.claude/skills/first-tree/` from the skill bundled with the currently running
178
+ `first-tree` npm package, preserves your tree content, and generates follow-up
179
+ tasks in `.agents/skills/first-tree/progress.md`.
148
180
 
149
- If your repo still uses the older `skills/first-tree-cli-framework/` path,
150
- `context-tree upgrade` will migrate it to `skills/first-tree/` first.
181
+ If your repo still uses the older `skills/first-tree/`,
182
+ `skills/first-tree-cli-framework/`, or `.context-tree/` layouts,
183
+ `context-tree upgrade` will migrate it to the current installed layout first.
151
184
 
152
185
  To pick up a newer framework release, first run a newer package version, for
153
186
  example `npx first-tree@latest upgrade`, or update your global `first-tree`
@@ -157,6 +190,6 @@ install before running `context-tree upgrade`.
157
190
 
158
191
  ## Further Reading
159
192
 
160
- - `skills/first-tree/references/principles.md` — Core principles with detailed examples
161
- - `skills/first-tree/references/ownership-and-naming.md` — How nodes are named and owned
162
- - `AGENT.md` in your tree — The before/during/after workflow for every task
193
+ - `.agents/skills/first-tree/references/principles.md` — Core principles with detailed examples
194
+ - `.agents/skills/first-tree/references/ownership-and-naming.md` — How nodes are named and owned
195
+ - `AGENTS.md` in your tree — The before/during/after workflow for every task
@@ -43,7 +43,7 @@ These skill-owned files implement the framework behavior.
43
43
  | `engine/commands/` | Stable command entrypoints that the thin CLI imports |
44
44
  | `engine/init.ts` / `engine/verify.ts` / `engine/upgrade.ts` | Command implementations for install, verify, and upgrade |
45
45
  | `engine/onboarding.ts` | Canonical onboarding text loader |
46
- | `engine/repo.ts` | Repo inspection and layout helpers |
46
+ | `engine/repo.ts` | Repo inspection, source-vs-tree heuristics, and worktree-aware git-root helpers |
47
47
  | `engine/rules/` | Situation-aware task generation after `init` |
48
48
  | `engine/validators/` | Deterministic tree and member validation |
49
49
  | `engine/runtime/asset-loader.ts` | Path constants plus legacy-layout detection |
@@ -66,7 +66,7 @@ not become the only place important maintainer knowledge lives.
66
66
  | `vitest.config.ts` | Unit-test entrypoints |
67
67
  | `.github/workflows/ci.yml` | Thin CI shell |
68
68
  | `README.md` | Thin distribution overview |
69
- | `AGENT.md` | Thin maintainer pointer for agent sessions |
69
+ | `AGENTS.md` | Thin maintainer pointer for agent sessions |
70
70
 
71
71
  ## Validation
72
72
 
@@ -89,6 +89,6 @@ not become the only place important maintainer knowledge lives.
89
89
  - Legacy `.context-tree/...` paths still matter only for migrating existing
90
90
  user repos; the compatibility logic lives in
91
91
  `engine/runtime/asset-loader.ts` and `engine/upgrade.ts`.
92
- - Root `README.md` and `AGENT.md` are intentionally brief. Important
92
+ - Root `README.md` and `AGENTS.md` are intentionally brief. Important
93
93
  information must live in the skill references instead.
94
94
  - If you change `references/` or `assets/framework/`, run `pnpm validate:skill`.
@@ -1,8 +1,8 @@
1
1
  # Upgrade Contract
2
2
 
3
3
  This file describes the current installed-layout contract and the compatibility
4
- rules we keep for legacy `skills/first-tree-cli-framework/` and
5
- `.context-tree/` repos.
4
+ rules we keep for legacy `skills/first-tree/`,
5
+ `skills/first-tree-cli-framework/`, and `.context-tree/` repos.
6
6
 
7
7
  ## Canonical Source
8
8
 
@@ -19,34 +19,56 @@ rules we keep for legacy `skills/first-tree-cli-framework/` and
19
19
  The current installed layout in a user repo is:
20
20
 
21
21
  ```text
22
- skills/
23
- first-tree/
24
- SKILL.md
25
- progress.md
26
- references/
27
- assets/
28
- framework/
29
- manifest.json
30
- VERSION
31
- templates/
32
- workflows/
33
- prompts/
34
- examples/
35
- helpers/
22
+ .agents/
23
+ skills/
24
+ first-tree/
25
+ SKILL.md
26
+ progress.md
27
+ references/
28
+ assets/
29
+ framework/
30
+ manifest.json
31
+ VERSION
32
+ templates/
33
+ workflows/
34
+ prompts/
35
+ examples/
36
+ helpers/
37
+ .claude/
38
+ skills/
39
+ first-tree/
40
+ SKILL.md
41
+ references/
42
+ assets/
43
+ framework/
44
+ manifest.json
45
+ VERSION
46
+ templates/
47
+ workflows/
48
+ prompts/
49
+ examples/
50
+ helpers/
36
51
  ```
37
52
 
38
53
  The tree content still lives outside the skill:
39
54
 
40
55
  - `NODE.md`
41
- - `AGENT.md`
56
+ - `AGENTS.md`
42
57
  - `members/`
43
58
 
59
+ The repo-owned `.agents/skills/first-tree/` path is the primary installed root
60
+ for progress state, workflow references, and helper scripts. The matching
61
+ `.claude/skills/first-tree/` path mirrors the same payload for Claude-facing
62
+ skill discovery and hooks.
63
+
44
64
  ## Command Intent
45
65
 
46
66
  - `context-tree init`
47
- - installs the skill into the target repo
67
+ - when run in a source/workspace repo, creates or reuses a sibling dedicated
68
+ tree repo by default
69
+ - installs the skill into the target tree repo
48
70
  - renders top-level tree scaffolding from the skill templates
49
- - writes progress state to `skills/first-tree/progress.md`
71
+ - writes progress state to `.agents/skills/first-tree/progress.md`
50
72
  - `context-tree verify`
51
73
  - checks progress state from the installed skill
52
74
  - validates root/frontmatter/agent markers
@@ -55,23 +77,36 @@ The tree content still lives outside the skill:
55
77
  - compares the installed skill payload version to the skill bundled with the
56
78
  currently running `first-tree` package
57
79
  - refreshes the installed skill payload without overwriting tree content
80
+ - migrates repos that still use the previous `skills/first-tree/` path onto
81
+ `.agents/skills/first-tree/` and `.claude/skills/first-tree/`
58
82
  - migrates repos that still use the previous
59
- `skills/first-tree-cli-framework/` path onto `skills/first-tree/`
83
+ `skills/first-tree-cli-framework/` path onto `.agents/skills/first-tree/`
84
+ and `.claude/skills/first-tree/`
60
85
  - migrates legacy `.context-tree/` repos onto the installed skill layout
61
- - preserves user-authored sections such as the editable part of `AGENT.md`
86
+ - preserves user-authored sections such as the editable part of `AGENTS.md`
62
87
 
63
88
  ## Compatibility Rules For Legacy Trees
64
89
 
65
- - `context-tree init` only installs the skill layout; it never creates a new
66
- `.context-tree/`.
90
+ - `context-tree init` never creates a new `.context-tree/`.
91
+ - `context-tree init --here` preserves the explicit in-place bootstrap path for
92
+ already-created tree repos.
93
+ - Default dedicated-tree-repo creation is local-only. The CLI may create a new
94
+ sibling git repo on disk, but it must not clone the source repo or depend on
95
+ network access.
67
96
  - Normal `context-tree init` and `context-tree upgrade` flows do not clone the
68
97
  source repo or require network access.
69
98
  - `context-tree verify` may still read a legacy
70
- `skills/first-tree-cli-framework/...` or `.context-tree/...` layout in an
71
- existing user repo so the repo can be upgraded in place.
99
+ `.claude/skills/first-tree/...`, `skills/first-tree/...`,
100
+ `skills/first-tree-cli-framework/...`, or `.context-tree/...` layout in an
101
+ existing user repo so the repo can be repaired or upgraded in place.
72
102
  - `context-tree upgrade` must migrate either legacy layout onto
73
- `skills/first-tree/` and remove the old directory afterward.
74
- - When both layouts are present, prefer the installed skill layout.
103
+ `.agents/skills/first-tree/` and `.claude/skills/first-tree/`, and remove
104
+ old skill directories afterward.
105
+ - When both current and legacy layouts are present, prefer the
106
+ `.agents/skills/first-tree/` layout.
107
+ - Existing repos may still have a legacy `AGENT.md`; `init` and `upgrade`
108
+ must not silently overwrite it, and follow-up tasks should direct users to
109
+ rename or merge it into `AGENTS.md`.
75
110
 
76
111
  ## Invariants
77
112