impel-cli 0.14.0 → 0.14.1

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
@@ -630,8 +630,8 @@ every managed profile. This catalog is separate from automatic specialists: it
630
630
  may include truthfully declared write-capable agents, but those agents require
631
631
  explicit user selection before the server will start a run.
632
632
 
633
- - Claude Code: `<CLAUDE_CONFIG_DIR>/agents/impel-managed/*.md`
634
- - Codex / ChatGPT Codex mode: `<CODEX_HOME>/agents/impel-managed/*.toml`
633
+ - Claude Code / Claude Desktop: `<CLAUDE_CONFIG_DIR>/agents/<agent-name>.md`
634
+ - Codex / ChatGPT Codex mode: `<CODEX_HOME>/agents/impel-<tenant>-<agent-id>.toml`
635
635
 
636
636
  Each generated agent is bound to one exact `agentId` and
637
637
  `scopeParam`. It verifies that the exact agent is still available, starts one
@@ -643,8 +643,8 @@ when invoked.
643
643
 
644
644
  Visible agent names come from the registry title. Codex keeps that title as the
645
645
  custom-agent name; Claude uses the lowercase, hyphenated form required by its
646
- native agent schema. The generated filenames remain stable tenant-and-agent
647
- identifiers so title changes update in place without colliding with user files.
646
+ native agent schema and Desktop's `@` picker requires the Markdown filename to
647
+ match that name. Codex filenames remain stable tenant-and-agent identifiers.
648
648
  Duplicate or built-in-reserved titles receive a deterministic disambiguator.
649
649
 
650
650
  The sync writes atomically and records a manifest beside the generated files.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "impel-cli",
3
- "version": "0.14.0",
3
+ "version": "0.14.1",
4
4
  "description": "Configure Claude Code and Codex CLI to talk to Impel's gateway, authenticated by an Impel Personal Access Token",
5
5
  "type": "module",
6
6
  "bin": {
package/src/agents.js CHANGED
@@ -398,10 +398,16 @@ export function renderManagedAgents(client, tenantId, agents, invocation = impel
398
398
  return agents.map((agent, index) => {
399
399
  const name = names[index];
400
400
  const extension = client === "claude" ? ".md" : ".toml";
401
+ // Claude Desktop decides whether an SDK-reported agent is user-defined by
402
+ // comparing its reported name with the Markdown filename (without .md).
403
+ // A stable tenant/agent filename causes Desktop to classify the agent as a
404
+ // builtin and remove it from the @ mention picker. Claude names are already
405
+ // collision-safe, filesystem-safe identifiers, so use them as filenames.
406
+ const fileStem = client === "claude" ? name : fileStems[index];
401
407
  const contents = client === "claude"
402
408
  ? renderClaudeAgent({ tenantId: normalizedTenant, agent, name, invocation })
403
409
  : renderCodexAgent({ tenantId: normalizedTenant, agent, name, invocation });
404
- return { agentId: agent.agentId, name, fileName: `${fileStems[index]}${extension}`, contents };
410
+ return { agentId: agent.agentId, name, fileName: `${fileStem}${extension}`, contents };
405
411
  });
406
412
  }
407
413
 
@@ -432,7 +438,7 @@ function readManifest(manifestPath) {
432
438
 
433
439
  function profileIsFresh(profile, tenantId, now, ttlMs) {
434
440
  const manifest = readManifest(path.join(profile.root, "agents", MANAGED_AGENT_DIRECTORY, MANAGED_AGENT_MANIFEST));
435
- if (!manifest || manifest.version !== 2 || manifest.tenantId !== tenantId) return false;
441
+ if (!manifest || manifest.version !== 3 || manifest.tenantId !== tenantId) return false;
436
442
  const syncedAt = Date.parse(manifest.syncedAt || "");
437
443
  if (!Number.isFinite(syncedAt) || now - syncedAt >= ttlMs) return false;
438
444
  return manifest.files.every((fileName) =>
@@ -455,7 +461,7 @@ export function syncAgentProfile({ client, root, label, tenantId, agents, now =
455
461
  const prior = readManifest(manifestPath);
456
462
  const rendered = renderManagedAgents(client, tenantId, agents);
457
463
  const priorFiles = new Set(prior?.files || []);
458
- const priorUsesDiscoveryRoot = prior?.version === 2;
464
+ const priorUsesDiscoveryRoot = prior?.version === 2 || prior?.version === 3;
459
465
 
460
466
  // Native clients discover standalone definitions directly under `agents/`.
461
467
  // Preflight every destination before writing so an unmanaged file with the
@@ -497,7 +503,7 @@ export function syncAgentProfile({ client, root, label, tenantId, agents, now =
497
503
  }
498
504
  }
499
505
  atomicPrivateWrite(manifestPath, `${JSON.stringify({
500
- version: 2,
506
+ version: 3,
501
507
  tenantId,
502
508
  client,
503
509
  syncedAt: new Date(now).toISOString(),