@topolo/cli 0.13.4 → 0.13.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.
@@ -10,7 +10,6 @@ import { spawn, spawnSync } from "child_process";
10
10
  import { dirname, resolve, sep } from "path";
11
11
  import { fileURLToPath } from "url";
12
12
  import { createConnection } from "net";
13
- import { tmpdir } from "os";
14
13
  import { WebSocket } from "undici";
15
14
 
16
15
  // src/lib/claude-native-pack.ts
@@ -53,6 +52,14 @@ async function nativeClaudePackOperation(manager, sidebar, plan, apply, checkpoi
53
52
  if (!plan.noEffects && member.group !== null && groups.filter((g) => g.name === member.group).length > 1)
54
53
  throw new Error("Ambiguous native sidebar group: " + member.group);
55
54
  }
55
+ const nativeDescriptor = async (member) => {
56
+ if (typeof manager.getSessionWhenLoaded !== "function") throw new Error("Qualified native session descriptor API is unavailable.");
57
+ const descriptor = await manager.getSessionWhenLoaded(member.sessionId, "topolo-agent-pack", { warnOnMiss: false });
58
+ checkDeadline();
59
+ if (!descriptor || descriptor.sessionId !== member.sessionId || descriptor.cwd !== member.cwd || descriptor.title !== member.title)
60
+ throw new Error("Owned native session descriptor identity changed: " + member.key);
61
+ return descriptor;
62
+ };
56
63
  const snapshot = async (members = plan.members) => {
57
64
  const result = [];
58
65
  for (const member of members) {
@@ -62,8 +69,13 @@ async function nativeClaudePackOperation(manager, sidebar, plan, apply, checkpoi
62
69
  throw new Error("Owned session identity or active membership changed: " + member.key);
63
70
  if (manager.hasLosableWork(member.sessionId) || session.isRunning || session.starting || session.pendingToolPermissions?.length)
64
71
  throw new Error("Session has live or pending work; no changes permitted: " + member.key);
65
- if (!plan.noEffects && (session.backend?.kind !== "local" || session.backend.remoteTarget || session.worktreePath || session.worktreeLazy || session.spawnedFrom))
66
- throw new Error("Incoming session is not a qualified local role.");
72
+ if (!plan.noEffects) {
73
+ const descriptor = await nativeDescriptor(member);
74
+ if (manager.hasLosableWork(member.sessionId) || descriptor.isRunning || descriptor.starting || descriptor.pendingToolPermissions?.length)
75
+ throw new Error("Session has live or pending work; no changes permitted: " + member.key);
76
+ if (descriptor.backend?.kind !== "local" || descriptor.backend.remoteTarget || descriptor.worktreePath || descriptor.worktreeLazy || descriptor.spawnedFrom)
77
+ throw new Error("Incoming session is not a qualified local role.");
78
+ }
67
79
  result.push({
68
80
  key: member.key,
69
81
  sessionId: session.sessionId,
@@ -92,8 +104,13 @@ async function nativeClaudePackOperation(manager, sidebar, plan, apply, checkpoi
92
104
  throw new Error("Outgoing native identity differs.");
93
105
  if (manager.hasLosableWork(member.sessionId) || session.isRunning || session.starting || session.pendingToolPermissions?.length)
94
106
  throw new Error("Outgoing session has live or pending work.");
95
- if (!plan.noEffects && (session.backend?.kind !== "local" || session.backend.remoteTarget || session.worktreePath || session.worktreeLazy || session.spawnedFrom || !manager.archiveCascadeClosureOf || manager.archiveCascadeClosureOf(session).length))
96
- throw new Error("Outgoing native archive closure is not qualified.");
107
+ if (!plan.noEffects) {
108
+ const descriptor = await nativeDescriptor(member);
109
+ if (manager.hasLosableWork(member.sessionId) || descriptor.isRunning || descriptor.starting || descriptor.pendingToolPermissions?.length)
110
+ throw new Error("Outgoing session has live or pending work.");
111
+ if (descriptor.backend?.kind !== "local" || descriptor.backend.remoteTarget || descriptor.worktreePath || descriptor.worktreeLazy || descriptor.spawnedFrom || !manager.archiveCascadeClosureOf || manager.archiveCascadeClosureOf(descriptor).length)
112
+ throw new Error("Outgoing native archive closure is not qualified.");
113
+ }
97
114
  result.push({ key: member.key, sessionId: member.sessionId, cwd: session.cwd, title: session.title, archived: session.isArchived === true });
98
115
  }
99
116
  return result;
@@ -145,7 +162,8 @@ async function nativeClaudePackOperation(manager, sidebar, plan, apply, checkpoi
145
162
  for (const member of plan.members) {
146
163
  const session = await manager.getSession(member.sessionId);
147
164
  if (session.isArchived) {
148
- if (session.backend?.kind !== "local" || session.backend.remoteTarget || session.worktreePath || session.worktreeLazy || session.spawnedFrom)
165
+ const descriptor = await nativeDescriptor(member);
166
+ if (descriptor.backend?.kind !== "local" || descriptor.backend.remoteTarget || descriptor.worktreePath || descriptor.worktreeLazy || descriptor.spawnedFrom)
149
167
  throw new Error("Incoming session is not a qualified local role.");
150
168
  await effect({ operation: "unarchive", sessionId: member.sessionId }, async () => {
151
169
  await manager.unarchiveSession(member.sessionId);
@@ -311,9 +329,13 @@ async function nativeClaudeApprovalOperation(manager, routes, operation, fingerp
311
329
  let state = manager[symbol];
312
330
  if (state?.auditFailed) throw new Error("Native approval audit unavailable; use the original native interaction.");
313
331
  const owned = async (route) => {
332
+ if (typeof manager.getSessionWhenLoaded !== "function") throw new Error("Qualified native session descriptor API is unavailable.");
333
+ const descriptor = await manager.getSessionWhenLoaded(route.sessionId, "topolo-agent-pack-approval", { warnOnMiss: false });
314
334
  const session = await manager.getSession(route.sessionId);
315
- if (!session || session.sessionId !== route.sessionId || session.cwd !== route.cwd || session.title !== route.title || session.isArchived || session.backend?.kind !== "local" || session.backend.remoteTarget || session.worktreePath || session.worktreeLazy || session.spawnedFrom)
335
+ if (!session || session.sessionId !== route.sessionId || session.cwd !== route.cwd || session.title !== route.title || session.isArchived)
316
336
  throw new Error("Native approval session identity differs: " + route.key);
337
+ if (!descriptor || descriptor.sessionId !== route.sessionId || descriptor.cwd !== route.cwd || descriptor.title !== route.title || descriptor.isArchived || descriptor.backend?.kind !== "local" || descriptor.backend.remoteTarget || descriptor.worktreePath || descriptor.worktreeLazy || descriptor.spawnedFrom)
338
+ throw new Error("Native approval session descriptor identity differs: " + route.key);
317
339
  return session;
318
340
  };
319
341
  if (state && state.identity !== identity) {
@@ -816,7 +838,7 @@ async function configureClaudePack(options, evaluate = evaluateClaudeMain, quali
816
838
  if (options.apply && plan.approvalRoutes.length) {
817
839
  const directory2 = resolve(root, "claude/private");
818
840
  mkdirSync(directory2, { recursive: true, mode: 448 });
819
- const socketDirectory = resolve(tmpdir(), "topolo-claude-pack-" + createHash("sha256").update(root).digest("hex").slice(0, 16));
841
+ const socketDirectory = resolve("/tmp", "topolo-claude-pack-" + createHash("sha256").update(root).digest("hex").slice(0, 16));
820
842
  mkdirSync(socketDirectory, { recursive: true, mode: 448 });
821
843
  for (const path of [directory2, socketDirectory]) {
822
844
  const stat = lstatSync(path);
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ function registerAgentPacksCommand(program2) {
10
10
  const packs = program2.command("agent-packs").description("Install and operate Topolo Agent Packs in supported local hosts").option("--store <path>", "Portable pack library (default ~/AgentPacks)");
11
11
  packs.command("configure").description("Qualify and configure an adopted Claude roster through its live native backend").argument("<pack>").option("--harness <name>", "Host adapter", "claude").requiredOption("--policy <path>", "Reviewed execution policy JSON").requiredOption("--endpoint <url>", "Explicit loopback main-process inspector endpoint, enabled separately with authorization").requiredOption("--pid <pid>", "Expected Claude main-process PID").option("--apply", "Apply native groups, pins, models, effort and permission modes; otherwise preflight only").action(async (pack, options) => {
12
12
  if (options.harness !== "claude") throw new Error("Native configure is currently qualified only for Claude Desktop.");
13
- const { configureClaudePack } = await import("./claude-pack-backend-5DWMIDRA.js");
13
+ const { configureClaudePack } = await import("./claude-pack-backend-AWCWJJA5.js");
14
14
  const result = await configureClaudePack({
15
15
  store: packs.opts().store ?? resolve(homedir(), "AgentPacks"),
16
16
  pack,
@@ -62,7 +62,7 @@ function registerAgentPacksCommand(program2) {
62
62
  throw new Error("Only a one-request once/deny response is supported.");
63
63
  decision = response.decision;
64
64
  }
65
- const { operateClaudeApprovals } = await import("./claude-pack-backend-5DWMIDRA.js");
65
+ const { operateClaudeApprovals } = await import("./claude-pack-backend-AWCWJJA5.js");
66
66
  console.log(JSON.stringify(await operateClaudeApprovals({
67
67
  store: packs.opts().store ?? resolve(homedir(), "AgentPacks"),
68
68
  kind: args[0],
@@ -77,7 +77,7 @@ function registerAgentPacksCommand(program2) {
77
77
  if (options.policy || options.endpoint || options.pid || options.apply) {
78
78
  if (options.harness !== "claude" || !options.policy || !options.endpoint || !options.pid || args.length !== 1)
79
79
  throw new Error("Native switch/recovery requires one Claude pack, --policy, --endpoint and --pid.");
80
- const { configureClaudePack } = await import("./claude-pack-backend-5DWMIDRA.js");
80
+ const { configureClaudePack } = await import("./claude-pack-backend-AWCWJJA5.js");
81
81
  const result2 = await configureClaudePack({
82
82
  store: packs.opts().store ?? resolve(homedir(), "AgentPacks"),
83
83
  pack: args[0],
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@topolo/cli",
3
3
  "packageManager": "pnpm@10.17.1",
4
- "version": "0.13.4",
5
- "topoloPublishedVersion": "0.13.4",
4
+ "version": "0.13.5",
5
+ "topoloPublishedVersion": "0.13.5",
6
6
  "description": "Public command-line interface for Topolo customer organizations, developers, and agents.",
7
7
  "license": "UNLICENSED",
8
8
  "author": "Topolo",