thoth-agents 0.2.0 → 0.2.2

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.
@@ -546,7 +546,8 @@ function spawn(command, options = {}) {
546
546
  options.stdin ?? "pipe",
547
547
  options.stdout ?? "pipe",
548
548
  options.stderr ?? "pipe"
549
- ]
549
+ ],
550
+ shell: options.shell
550
551
  });
551
552
  const managed = {
552
553
  stdin: child.stdin ?? fallbackStdin(),
@@ -577,7 +578,8 @@ function spawnSync(command, options = {}) {
577
578
  options.stdin ?? "ignore",
578
579
  options.stdout ?? "pipe",
579
580
  options.stderr ?? "pipe"
580
- ]
581
+ ],
582
+ shell: options.shell
581
583
  });
582
584
  return { exitCode: result.status };
583
585
  }
@@ -585,6 +587,25 @@ function spawnSync(command, options = {}) {
585
587
  // src/cli/system.ts
586
588
  import { statSync } from "fs";
587
589
  var cachedOpenCodePath = null;
590
+ function quoteWindowsShellCommand(command) {
591
+ if (!/[\s&()^<>"|]/.test(command)) {
592
+ return command;
593
+ }
594
+ return `"${command.replace(/"/g, '\\"')}"`;
595
+ }
596
+ function getOpenCodeVersionInvocation(opencodePath, platform = process.platform) {
597
+ const options = {
598
+ stdout: "pipe",
599
+ stderr: "pipe"
600
+ };
601
+ if (platform === "win32") {
602
+ return {
603
+ command: [`${quoteWindowsShellCommand(opencodePath)} --version`],
604
+ options: { ...options, shell: true }
605
+ };
606
+ }
607
+ return { command: [opencodePath, "--version"], options };
608
+ }
588
609
  function getOpenCodePaths() {
589
610
  const home = process.env.HOME || process.env.USERPROFILE || "";
590
611
  return [
@@ -651,10 +672,8 @@ async function isOpenCodeInstalled() {
651
672
  const paths = getOpenCodePaths();
652
673
  for (const opencodePath of paths) {
653
674
  try {
654
- const proc = spawn([opencodePath, "--version"], {
655
- stdout: "pipe",
656
- stderr: "pipe"
657
- });
675
+ const invocation = getOpenCodeVersionInvocation(opencodePath);
676
+ const proc = spawn(invocation.command, invocation.options);
658
677
  await proc.exited;
659
678
  if (proc.exitCode === 0) {
660
679
  cachedOpenCodePath = opencodePath;
@@ -668,10 +687,8 @@ async function isOpenCodeInstalled() {
668
687
  async function getOpenCodeVersion() {
669
688
  const opencodePath = resolveOpenCodePath();
670
689
  try {
671
- const proc = spawn([opencodePath, "--version"], {
672
- stdout: "pipe",
673
- stderr: "pipe"
674
- });
690
+ const invocation = getOpenCodeVersionInvocation(opencodePath);
691
+ const proc = spawn(invocation.command, invocation.options);
675
692
  const output = await new Response(proc.stdout).text();
676
693
  await proc.exited;
677
694
  if (proc.exitCode === 0) {
@@ -2462,12 +2462,6 @@ var CLAUDE_CODE_SUBAGENT_DEFAULT_MODELS = {
2462
2462
  quick: "haiku",
2463
2463
  deep: "sonnet"
2464
2464
  };
2465
- var READ_ONLY_ROLE_TOOLS = {
2466
- explorer: "Read, Grep, Glob",
2467
- librarian: "Read, Grep, Glob, WebSearch, WebFetch",
2468
- oracle: "Read, Grep, Glob"
2469
- };
2470
- var WRITE_CAPABLE_ROLE_TOOLS = "Read, Edit, Write, Bash, Grep, Glob";
2471
2465
  function isClaudeCodeSubagentName(name) {
2472
2466
  return name in CLAUDE_CODE_SUBAGENT_DEFAULT_MODELS;
2473
2467
  }
@@ -2477,10 +2471,6 @@ function getClaudeCodeAgentModel(role, config) {
2477
2471
  if (override && isClaudeCodeModel(override)) return override;
2478
2472
  return CLAUDE_CODE_SUBAGENT_DEFAULT_MODELS[role.name];
2479
2473
  }
2480
- function toolsForRole(role) {
2481
- if (role.canMutateWorkspace) return WRITE_CAPABLE_ROLE_TOOLS;
2482
- return READ_ONLY_ROLE_TOOLS[role.name] ?? "Read, Grep, Glob";
2483
- }
2484
2474
  function claudeCodePromptSections(roleName) {
2485
2475
  switch (roleName) {
2486
2476
  case "orchestrator":
@@ -2532,7 +2522,7 @@ function claudeCodeRoleInstructions(role) {
2532
2522
  `- Responsibility: ${role.responsibility}`,
2533
2523
  "- Use AskUserQuestion for local blocking decisions.",
2534
2524
  `- ${role.name} runs as an auto-discovered Claude Code plugin subagent invoked via Task(subagent_type: ${claudeCodeSubagentType(role.name)}); plugin subagents are namespaced with the plugin name. The orchestrator is the main Claude Code session.`,
2535
- "- Role permissions are enforced by this subagent's frontmatter `tools` allowlist; read-only roles cannot mutate the workspace.",
2525
+ "- This subagent inherits ALL of the main thread's tools, including MCP servers (thoth-mem, context7, exa, grep_app); read-only roles (explorer, librarian, oracle) MUST NOT mutate the workspace per this operational contract (instruction-level, not tooling-enforced).",
2536
2526
  ...role.toolGovernance.map((rule) => `- ${rule}`),
2537
2527
  ...role.verification.map((rule) => `- ${rule}`),
2538
2528
  "</role-operational-contract>"
@@ -2566,7 +2556,7 @@ function renderClaudeCodeRootInstructions(config) {
2566
2556
  '- Before delegating after meaningful context changes, refresh the handoff body with root-owned mem_session(action="summary") or mem_save(kind="session_summary") when available.',
2567
2557
  "- Use AskUserQuestion for blocking user decisions; do not ask those questions in plain prose.",
2568
2558
  "- Track progress with TodoWrite; subagents do not own progress checkboxes or root-only memory.",
2569
- "- Role permissions are enforced at runtime by each subagent's frontmatter `tools` allowlist.",
2559
+ "- Subagents inherit all of your tools (including MCP servers); role permissions are instruction-level, so read-only roles (explorer, librarian, oracle) must not mutate the workspace per their operational contract.",
2570
2560
  "</claude-code-runtime>"
2571
2561
  ].join("\n");
2572
2562
  }
@@ -2622,7 +2612,6 @@ function renderSubagentArtifacts(config) {
2622
2612
  const content = renderClaudeCodeSubagent({
2623
2613
  name: role.name,
2624
2614
  description: role.responsibility,
2625
- tools: toolsForRole(role),
2626
2615
  model: getClaudeCodeAgentModel(role, config),
2627
2616
  instructions: roleInstructions2(role, config)
2628
2617
  });
@@ -2835,7 +2824,7 @@ function buildClaudeCodeSetupPlan(config) {
2835
2824
  ],
2836
2825
  disclaimers: [
2837
2826
  "The orchestrator agent is the Claude Code main thread (plugin settings.json `agent` key); while enabled it replaces the default system prompt for every session in scope.",
2838
- "Role permissions are enforced by each specialist subagent frontmatter `tools` allowlist; the orchestrator inherits all tools.",
2827
+ "Every subagent inherits all main-thread tools, including MCP servers; read-only roles must not mutate the workspace per their operational contract (instruction-level, not tooling-enforced).",
2839
2828
  "Subagent models accept only sonnet, opus, haiku, or inherit.",
2840
2829
  "User-scope skills-directory plugins load hooks and MCP servers without extra approval; project-scope requires accepting the workspace trust dialog."
2841
2830
  ]
@@ -3025,7 +3014,7 @@ function claudeCodeConfig(context = { cwd: process.cwd() }, dryRun) {
3025
3014
  function claudeCodeDisclaimers() {
3026
3015
  return [
3027
3016
  {
3028
- message: "Role permissions are enforced by subagent frontmatter tools; the orchestrator is the main session, injected via the SessionStart hook.",
3017
+ message: "Subagents inherit all main-thread tools (including MCP servers); read-only roles must not mutate the workspace per their operational contract (instruction-level, not tooling-enforced). The orchestrator is the main session.",
3029
3018
  code: "claude-code-first-class"
3030
3019
  },
3031
3020
  {
package/dist/cli/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  getOpenCodeVersion,
5
5
  isOpenCodeInstalled,
6
6
  opencodeAdapter
7
- } from "../chunk-4WYCZ5Z7.js";
7
+ } from "../chunk-3SQ4ZQ57.js";
8
8
  import {
9
9
  CODEX_ROLE_NAMES,
10
10
  RECOMMENDED_SKILLS,
@@ -36,7 +36,7 @@ import {
36
36
  getOperationHarness,
37
37
  installRecommendedSkill,
38
38
  listOperationHarnesses
39
- } from "../chunk-WH3F3GWE.js";
39
+ } from "../chunk-FRZZ25ND.js";
40
40
  import {
41
41
  ALL_AGENT_NAMES,
42
42
  CUSTOM_SKILLS,
@@ -1,6 +1,16 @@
1
+ type OpenCodeVersionInvocation = {
2
+ command: string[];
3
+ options: {
4
+ stdout: 'pipe';
5
+ stderr: 'pipe';
6
+ shell?: boolean;
7
+ };
8
+ };
9
+ export declare function getOpenCodeVersionInvocation(opencodePath: string, platform?: typeof process.platform): OpenCodeVersionInvocation;
1
10
  export declare function resolveOpenCodePath(): string;
2
11
  export declare function isOpenCodeInstalled(): Promise<boolean>;
3
12
  export declare function isTmuxInstalled(): Promise<boolean>;
4
13
  export declare function getOpenCodeVersion(): Promise<string | null>;
5
14
  export declare function getOpenCodePath(): string | null;
6
15
  export declare function fetchLatestVersion(packageName: string): Promise<string | null>;
16
+ export {};
@@ -25,7 +25,7 @@ import {
25
25
  listOperationHarnesses,
26
26
  parseRoleTomlModel,
27
27
  parseSubagentModel
28
- } from "../../chunk-WH3F3GWE.js";
28
+ } from "../../chunk-FRZZ25ND.js";
29
29
  import {
30
30
  ALL_AGENT_NAMES,
31
31
  DEFAULT_MODELS,
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  renderOpenCodeAgentConfigs,
4
4
  spawn,
5
5
  spawnSync
6
- } from "./chunk-4WYCZ5Z7.js";
6
+ } from "./chunk-3SQ4ZQ57.js";
7
7
  import {
8
8
  DEFAULT_THOTH_COMMAND,
9
9
  POLL_INTERVAL_BACKGROUND_MS,
@@ -4,6 +4,7 @@ type SpawnOptions = {
4
4
  stdin?: 'pipe' | 'ignore';
5
5
  stdout?: 'pipe' | 'ignore';
6
6
  stderr?: 'pipe' | 'ignore';
7
+ shell?: boolean | string;
7
8
  };
8
9
  export type ManagedSubprocess = {
9
10
  stdin: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thoth-agents",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Delegate-first OpenCode plugin with seven agents, thoth-mem persistence, and bundled SDD skills.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",