@first-tree-ai/context-tree 0.1.8-alpha.202609010928 → 0.1.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@first-tree-ai/context-tree",
3
- "version": "0.1.8-alpha.202609010928",
3
+ "version": "0.1.8",
4
4
  "description": "Durable, structured project context for coding agents: a CLI plus framework-neutral skills.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -5,20 +5,32 @@
5
5
  // A failure must never fail `npm install`: the CLI is still usable, and
6
6
  // `context-tree install` can be run by hand afterwards.
7
7
  //
8
- // Only a global install writes to the home directory. Adding this package as a local
9
- // dependency including this repository's own `pnpm install` must not silently
10
- // modify the developer's agent configuration, so it just prints the command.
8
+ // Only a direct global install writes to the home directory; anything else just prints the
9
+ // command, so installing this package as a dependency never touches a developer's own agents.
11
10
 
12
11
  import { spawnSync } from "node:child_process";
13
- import { dirname, resolve } from "node:path";
12
+ import { existsSync } from "node:fs";
13
+ import { basename, dirname, join, resolve } from "node:path";
14
14
  import { fileURLToPath } from "node:url";
15
15
 
16
- if (process.env.npm_config_global !== "true") {
16
+ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
17
+
18
+ // npm sets npm_config_global for a global install's dependencies too, so the flag alone does not
19
+ // identify the install target. A dependency copy sits inside the owning package's node_modules; a
20
+ // directly installed one sits in npm's own prefix, which is not a package.
21
+ function ownedByAnotherPackage(directory) {
22
+ const parent = dirname(directory);
23
+ if (parent === directory) return false;
24
+ if (basename(directory) === "node_modules") return existsSync(join(parent, "package.json"));
25
+ return ownedByAnotherPackage(parent);
26
+ }
27
+
28
+ if (process.env.npm_config_global !== "true" || ownedByAnotherPackage(packageRoot)) {
17
29
  process.stdout.write("Context Tree: run `context-tree install` to add the skills to your agent.\n");
18
30
  process.exit(0);
19
31
  }
20
32
 
21
- const cli = resolve(dirname(fileURLToPath(import.meta.url)), "..", "dist", "cli", "index.mjs");
33
+ const cli = join(packageRoot, "dist", "cli", "index.mjs");
22
34
  const result = spawnSync(process.execPath, [cli, "install"], { encoding: "utf8" });
23
35
 
24
36
  if (result.error !== undefined || result.status !== 0) {