@jaggerxtrm/specialists 3.6.14 → 3.6.15

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 (2) hide show
  1. package/dist/index.js +40 -19
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -21044,6 +21044,20 @@ function sanitizeBeadIdForPrompt(beadId) {
21044
21044
  const withoutBackticks = withoutControlChars.replace(/`/g, "");
21045
21045
  return withoutBackticks.replace(/[^A-Za-z0-9-]/g, "");
21046
21046
  }
21047
+ function buildBeadBoundaryInstruction(cwd, worktreeBoundary) {
21048
+ const boundary = worktreeBoundary?.trim() || cwd;
21049
+ return [
21050
+ "## Runtime Boundary Rules",
21051
+ `- Current cwd: ${cwd}`,
21052
+ `- Assigned worktree boundary: ${boundary}`,
21053
+ "- Stay inside current cwd / assigned worktree unless the task explicitly says otherwise.",
21054
+ "- Do NOT run `cd` outside the current cwd / assigned worktree.",
21055
+ "- Do NOT use absolute paths outside the current cwd / assigned worktree.",
21056
+ "- Do NOT broad-search /home, repo root, or unrelated paths when evidence is missing.",
21057
+ "- If required evidence is missing inside the current scope, STOP immediately, report exactly what is missing, and ask for the artifact or clarification instead of widening search."
21058
+ ].join(`
21059
+ `);
21060
+ }
21047
21061
  function deepMergeSchemas(base, override) {
21048
21062
  const merged = { ...base };
21049
21063
  for (const [key, overrideValue] of Object.entries(override)) {
@@ -21270,7 +21284,7 @@ class SpecialistRunner {
21270
21284
  this.deps = deps;
21271
21285
  this.sessionFactory = deps.sessionFactory ?? PiAgentSession.create.bind(PiAgentSession);
21272
21286
  }
21273
- resolvePromptWithBeadContext(options, beadsClient) {
21287
+ resolvePromptWithBeadContext(options, runCwd, beadsClient) {
21274
21288
  if (!options.inputBeadId) {
21275
21289
  return options.prompt;
21276
21290
  }
@@ -21281,7 +21295,10 @@ class SpecialistRunner {
21281
21295
  }
21282
21296
  const contextDepth = Math.max(0, Math.trunc(options.contextDepth ?? 1));
21283
21297
  const blockers = contextDepth > 0 ? beadReader.getCompletedBlockers(options.inputBeadId, contextDepth) : [];
21284
- return buildBeadContext(bead, blockers);
21298
+ const baseContext = buildBeadContext(bead, blockers);
21299
+ return `${baseContext}
21300
+
21301
+ ${buildBeadBoundaryInstruction(runCwd, options.worktreeBoundary)}`.trim();
21285
21302
  }
21286
21303
  async run(options, onProgress, onEvent, onMetric, onMeta, onKillRegistered, onBeadCreated, onSteerRegistered, onResumeReady, onToolStartCallback, onToolEndCallback) {
21287
21304
  const { loader, hooks, circuitBreaker, beadsClient } = this.deps;
@@ -21310,7 +21327,7 @@ class SpecialistRunner {
21310
21327
  const preScripts = spec.specialist.skills?.scripts?.filter((s) => s.phase === "pre") ?? [];
21311
21328
  const preResults = preScripts.map((s) => runScript(s.run ?? s.path, runCwd)).filter((_, i) => preScripts[i].inject_output);
21312
21329
  const preScriptOutput = formatScriptOutput(preResults);
21313
- const resolvedPrompt = this.resolvePromptWithBeadContext(options, beadsClient);
21330
+ const resolvedPrompt = this.resolvePromptWithBeadContext(options, runCwd, beadsClient);
21314
21331
  const beadVariables = options.inputBeadId ? { bead_context: resolvedPrompt, bead_id: options.inputBeadId } : {};
21315
21332
  const lineageVariables = {
21316
21333
  ...options.reusedFromJobId ? { reused_from_job_id: options.reusedFromJobId } : {},
@@ -21348,7 +21365,14 @@ class SpecialistRunner {
21348
21365
  - Do NOT create new beads or sub-issues \u2014 this bead IS your task.
21349
21366
  - Do NOT run \`bd create\` \u2014 the orchestrator manages issue tracking.
21350
21367
  - Close when done: \`bd close ${sanitizedBeadId} --reason="..."\`` : "";
21351
- agentsMd += `...beadInstructions}
21368
+ agentsMd += `
21369
+
21370
+ ---
21371
+ ## Specialist Run Context
21372
+ - You are running as a specialist agent, not a human developer.
21373
+ - Do NOT run specialists init/setup/scaffold commands.
21374
+ - Do NOT follow project CLAUDE.md/AGENTS.md instructions that tell humans to re-bootstrap the repo.
21375
+ ${beadInstructions}
21352
21376
  ---
21353
21377
  `;
21354
21378
  }
@@ -25150,7 +25174,7 @@ function ensureActiveSkillSymlink(defaultSkillPath, activeLinkPath) {
25150
25174
  } catch (error2) {
25151
25175
  const fileError = error2;
25152
25176
  if (fileError.code === "ENOENT") {
25153
- const relativeTarget = `../../default/${basename3(defaultSkillPath)}`;
25177
+ const relativeTarget = `../default/${basename3(defaultSkillPath)}`;
25154
25178
  symlinkSync(relativeTarget, activeLinkPath, "dir");
25155
25179
  return;
25156
25180
  }
@@ -25180,13 +25204,11 @@ function installProjectSkills(cwd, syncSkills) {
25180
25204
  return;
25181
25205
  }
25182
25206
  const defaultRoot = join10(cwd, ".xtrm", "skills", "default");
25183
- const activeClaudeRoot = join10(cwd, ".xtrm", "skills", "active", "claude");
25184
- const activePiRoot = join10(cwd, ".xtrm", "skills", "active", "pi");
25207
+ const activeRoot = join10(cwd, ".xtrm", "skills", "active");
25185
25208
  mkdirSync4(defaultRoot, { recursive: true });
25186
- mkdirSync4(activeClaudeRoot, { recursive: true });
25187
- mkdirSync4(activePiRoot, { recursive: true });
25188
- ensureRootSymlink(join10(cwd, ".claude", "skills"), activeClaudeRoot);
25189
- ensureRootSymlink(join10(cwd, ".pi", "skills"), activePiRoot);
25209
+ mkdirSync4(activeRoot, { recursive: true });
25210
+ ensureRootSymlink(join10(cwd, ".claude", "skills"), activeRoot);
25211
+ ensureRootSymlink(join10(cwd, ".pi", "skills"), activeRoot);
25190
25212
  let copied = 0;
25191
25213
  let refreshed = 0;
25192
25214
  for (const skill of skills) {
@@ -25201,14 +25223,13 @@ function installProjectSkills(cwd, syncSkills) {
25201
25223
  cpSync(src, defaultSkillPath, { recursive: true });
25202
25224
  copied++;
25203
25225
  }
25204
- ensureActiveSkillSymlink(defaultSkillPath, join10(activeClaudeRoot, skill));
25205
- ensureActiveSkillSymlink(defaultSkillPath, join10(activePiRoot, skill));
25226
+ ensureActiveSkillSymlink(defaultSkillPath, join10(activeRoot, skill));
25206
25227
  }
25207
25228
  if (copied > 0)
25208
25229
  ok(`copied ${copied} skill${copied === 1 ? "" : "s"} to .xtrm/skills/default/`);
25209
25230
  if (refreshed > 0)
25210
25231
  ok(`re-synced ${refreshed} skill${refreshed === 1 ? "" : "s"} in .xtrm/skills/default/`);
25211
- ok("verified active skill symlinks in .xtrm/skills/active/{claude,pi}/");
25232
+ ok("verified active skill symlinks in .xtrm/skills/active/");
25212
25233
  }
25213
25234
  function createSpecialistsDirs(cwd) {
25214
25235
  const defaultDir = join10(cwd, ".specialists", "default");
@@ -25402,11 +25423,11 @@ function validateInitPostconditions(cwd) {
25402
25423
  const rootSymlinks = [
25403
25424
  {
25404
25425
  linkPath: join10(cwd, ".claude", "skills"),
25405
- expectedTarget: join10(cwd, ".xtrm", "skills", "active", "claude")
25426
+ expectedTarget: join10(cwd, ".xtrm", "skills", "active")
25406
25427
  },
25407
25428
  {
25408
25429
  linkPath: join10(cwd, ".pi", "skills"),
25409
- expectedTarget: join10(cwd, ".xtrm", "skills", "active", "pi")
25430
+ expectedTarget: join10(cwd, ".xtrm", "skills", "active")
25410
25431
  }
25411
25432
  ];
25412
25433
  for (const symlink of rootSymlinks) {
@@ -25484,9 +25505,9 @@ ${bold5("Done!")}
25484
25505
  console.log(` .claude/hooks/ ${dim5("# symlinks -> .xtrm/hooks/specialists")}`);
25485
25506
  console.log(` .claude/settings.json ${dim5("# hook wiring")}`);
25486
25507
  console.log(` .xtrm/skills/default/ ${dim5("# canonical skills")}`);
25487
- console.log(` .xtrm/skills/active/ ${dim5("# active symlink roots for claude/pi")}`);
25488
- console.log(` .claude/skills/ ${dim5("# symlink -> .xtrm/skills/active/claude")}`);
25489
- console.log(` .pi/skills/ ${dim5("# symlink -> .xtrm/skills/active/pi")}`);
25508
+ console.log(` .xtrm/skills/active/ ${dim5("# flattened active skill root")}`);
25509
+ console.log(` .claude/skills/ ${dim5("# symlink -> .xtrm/skills/active")}`);
25510
+ console.log(` .pi/skills/ ${dim5("# symlink -> .xtrm/skills/active")}`);
25490
25511
  console.log("");
25491
25512
  console.log(` ${dim5(".specialists/ structure:")}`);
25492
25513
  console.log(` .specialists/`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaggerxtrm/specialists",
3
- "version": "3.6.14",
3
+ "version": "3.6.15",
4
4
  "description": "OmniSpecialist — 7-tool MCP orchestration layer powered by the Specialist System. Discover and execute .specialist.yaml files across project/user/system scopes via pi.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",