@first-tree-ai/context-tree 0.1.14 → 0.1.16-alpha.202609150853

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 CHANGED
@@ -75,6 +75,12 @@ context-tree connect --tree-path /absolute/path/to/tree
75
75
  Connecting switches the current project's tree. Run these commands from the
76
76
  project directory, or add `--project-path /path/to/project`.
77
77
 
78
+ Stop using a tree without deleting it or its memory:
79
+
80
+ ```bash
81
+ context-tree disconnect
82
+ ```
83
+
78
84
  ## Cleanup and scheduling
79
85
 
80
86
  Ask your agent to remove outdated clutter and consolidate duplicate context:
@@ -102,6 +108,7 @@ lists previous runs.
102
108
  context-tree resolve # show this project's tree
103
109
  context-tree read --tree-path /path/to/tree # browse its root index
104
110
  context-tree verify --tree-path /path/to/tree # check its structure
111
+ context-tree disconnect # remove this project's connection
105
112
  context-tree install # add skills for a new agent
106
113
  context-tree install --project . # install skills for this project
107
114
  context-tree uninstall # remove Context Tree skills
@@ -113,14 +120,14 @@ including synchronization, prepared writes, and JSON output.
113
120
 
114
121
  ## Working with OpenTag
115
122
 
116
- Create or publish a tree as above, then choose it on each OpenTag Computer:
123
+ Each OpenTag Agent selects its own tree in **Agent settings → Context Tree**.
124
+ Enter a GitHub `OWNER/REPO` to connect an existing tree, create a new private
125
+ repository from the same panel, or disconnect to leave memory off. OpenTag
126
+ connects every visible and internal session for that Agent to the selection.
127
+ For a GitHub tree, GitHub authentication must work on the Agent's Computer.
117
128
 
118
- ```bash
119
- opentag context-tree connect OWNER/REPO
120
- # Or use a local tree:
121
- opentag context-tree connect my-project-context-tree
122
- ```
129
+ The former `opentag context-tree connect` command is retired and now points to
130
+ Agent settings. Existing trees, connections, and memory are preserved; after
131
+ upgrading OpenTag, select the repository again for each Agent.
123
132
 
124
- OpenTag connects each agent workspace to that tree when a session starts.
125
- Use the same read, write, and cleanup prompts in those sessions. For a GitHub tree,
126
- GitHub authentication must work on each Computer.
133
+ Use the same read, write, and cleanup prompts in OpenTag sessions.
@@ -7269,6 +7269,7 @@ const CLI_ERROR_CODES = {
7269
7269
  dirtyTree: "DIRTY_TREE",
7270
7270
  failed: "CONTEXT_TREE_FAILED",
7271
7271
  githubAuth: "GITHUB_AUTH",
7272
+ githubPermission: "GITHUB_PERMISSION",
7272
7273
  invalidTree: "INVALID_TREE",
7273
7274
  noConnection: "NO_CONNECTION",
7274
7275
  publishIncomplete: "PUBLISH_INCOMPLETE",
@@ -25710,9 +25711,9 @@ function connectProject(options, runner) {
25710
25711
  return connect(classifyCheckout(destination, runner));
25711
25712
  }
25712
25713
  const repository = githubRepositoryIdentitySchema.parse(options.target);
25713
- const repositoryName = repository.split("/")[1];
25714
- if (repositoryName === void 0) throw new Error("Repository must be OWNER/REPO.");
25715
- const name = managedName(repositoryName.toLowerCase());
25714
+ if (repository.split("/")[1] === void 0) throw new Error("Repository must be OWNER/REPO.");
25715
+ for (const candidate of listManagedTrees(runner).trees) if (candidate.tree.kind === "github" && sameRepository(candidate.tree.repository, repository)) return connect(candidate.tree);
25716
+ const name = managedName(`github-${createHash("sha256").update(repository.toLowerCase()).digest("hex")}`);
25716
25717
  const destination = join(treesRoot, name);
25717
25718
  if (existsSync(destination)) {
25718
25719
  realManagedDirectory(name, destination);
@@ -25742,9 +25743,25 @@ function connectProject(options, runner) {
25742
25743
  force: true,
25743
25744
  recursive: true
25744
25745
  });
25746
+ if (error instanceof CommandError && /gh auth login|not logged|authentication failed|http 401|bad credentials|could not read Username|terminal prompts disabled/iu.test(error.stderr)) throw new ContextTreeError(CLI_ERROR_CODES.githubAuth, "GitHub authentication failed; run gh auth login before connecting.");
25747
+ if (error instanceof CommandError && /http 403|permission denied|not authorized/iu.test(error.stderr)) throw new ContextTreeError(CLI_ERROR_CODES.githubPermission, "GitHub denied access to this repository.");
25745
25748
  throw error;
25746
25749
  }
25747
25750
  }
25751
+ /** Remove only the project record, even if its tree is no longer usable. */
25752
+ function disconnectProject(projectPath, runner) {
25753
+ const canonical = canonicalProjectRoot(projectPath, runner);
25754
+ const stored = loadConnections(false);
25755
+ const remaining = stored.connections.filter((connection) => connection.projectPath !== canonical);
25756
+ if (remaining.length !== stored.connections.length) saveConnections({
25757
+ ...stored,
25758
+ connections: remaining
25759
+ });
25760
+ return {
25761
+ schemaVersion: 1,
25762
+ disconnected: remaining.length !== stored.connections.length
25763
+ };
25764
+ }
25748
25765
  //#endregion
25749
25766
  //#region src/core/internal/packaged-resource.ts
25750
25767
  const PACKAGE_NAME = "@first-tree-ai/context-tree";
@@ -27180,6 +27197,8 @@ function authenticatedAccount(runner) {
27180
27197
  return login.trim();
27181
27198
  }
27182
27199
  function classifyCreationFailure(stderr) {
27200
+ if (/gh auth login|not logged|authentication failed|http 401|bad credentials/iu.test(stderr)) return new ContextTreeError(CLI_ERROR_CODES.githubAuth, "GitHub authentication failed; run gh auth login before publishing.");
27201
+ if (/http 403|permission denied|not authorized|resource not accessible/iu.test(stderr)) return new ContextTreeError(CLI_ERROR_CODES.githubPermission, "GitHub denied permission to create this repository.");
27183
27202
  if (/already exists/iu.test(stderr)) return new ContextTreeError(CLI_ERROR_CODES.repositoryExists, "A GitHub repository with this name already exists; choose an explicit OWNER/REPO override.");
27184
27203
  return new ContextTreeError(CLI_ERROR_CODES.publishIncomplete, "GitHub repository creation has an uncertain or partial result; do not retry automatically.");
27185
27204
  }
@@ -27395,6 +27414,7 @@ const defaultIo = {
27395
27414
  const TEXT_DEFAULT_COMMANDS = new Set([
27396
27415
  "create",
27397
27416
  "connect",
27417
+ "disconnect",
27398
27418
  "list",
27399
27419
  "resolve",
27400
27420
  "publish",
@@ -27439,6 +27459,9 @@ function createContextTreeCli(io = defaultIo) {
27439
27459
  }
27440
27460
  throw new Error("Connect requires a managed tree name, GitHub OWNER/REPO, or --tree-path.");
27441
27461
  });
27462
+ program.command("disconnect").description("Remove this project's connection, preserving its Context Tree and repository.").option("--project-path <path>", "project directory", ".").option(...jsonOption).action((options) => {
27463
+ emit(io, options.json, disconnectProject(resolve(io.cwd(), options.projectPath)), (result) => result.disconnected ? "Context Tree disconnected." : "No Context Tree connection.");
27464
+ });
27442
27465
  program.command("list").description("List valid clean managed Context Trees.").option(...jsonOption).action((options) => {
27443
27466
  emit(io, options.json, listManagedTrees(), formatList);
27444
27467
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@first-tree-ai/context-tree",
3
- "version": "0.1.14",
3
+ "version": "0.1.16-alpha.202609150853",
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",