thoth-agents 0.3.2 → 0.3.3

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.
@@ -9,7 +9,7 @@
9
9
  {
10
10
  "name": "thoth-agents",
11
11
  "description": "Adaptive root orchestration, six specialist subagents, and a runtime-autonomous Spec Kit-compatible SDD bundle.",
12
- "version": "0.3.2",
12
+ "version": "0.3.3",
13
13
  "author": {
14
14
  "name": "thoth-agents maintainers"
15
15
  },
package/README.md CHANGED
@@ -65,25 +65,19 @@ from the CLI step. Existing project-owned files are preserved.
65
65
 
66
66
  ### Codex
67
67
 
68
- Register the repository marketplace from a terminal:
69
-
70
- ```bash
71
- codex plugin marketplace add EremesNG/thoth-agents
72
- ```
73
-
74
- Restart Codex, open `/plugins`, and install or enable `thoth-agents`. Then return
75
- to a terminal and apply the mandatory global layer:
68
+ Preview, then run the combined native-plugin and global-layer installer:
76
69
 
77
70
  ```bash
78
71
  npx thoth-agents@latest install --agent=codex --dry-run
79
72
  npx thoth-agents@latest install --agent=codex
80
73
  ```
81
74
 
82
- The CLI writes the orchestrator block to `~/.codex/AGENTS.md`, creates six
83
- custom-agent TOMLs under `~/.codex/agents/`, and merges the managed feature into
84
- `~/.codex/config.toml`. It also installs the external skills and invokes
85
- provider-owned thoth-mem setup. Restart Codex again, then initialize each target
86
- repository's SDD governance:
75
+ The CLI first uses Codex's native manager to register `EremesNG/thoth-agents`
76
+ and install or enable `thoth-agents@thoth-agents`. It then writes the
77
+ orchestrator block to `~/.codex/AGENTS.md`, creates six custom-agent TOMLs under
78
+ `~/.codex/agents/`, merges the managed feature into `~/.codex/config.toml`,
79
+ installs the external skills, and invokes provider-owned thoth-mem setup.
80
+ Restart Codex, then initialize each target repository's SDD governance:
87
81
 
88
82
  ```text
89
83
  $thoth-init
@@ -345,7 +339,7 @@ diagnostics, manual actions, and receipt paths remain visible for recovery.
345
339
  | Harness | Important limitation |
346
340
  | --- | --- |
347
341
  | OpenCode | Strongest integrated path. The CLI installs the npm plugin configuration, external skills, and provider-owned thoth-mem setup; `/thoth-init` materializes thoth-owned project skills/governance. Only the OpenAI built-in preset ships. |
348
- | Codex | Native plugin installation is incomplete without the CLI. The CLI manages global `AGENTS.md`, six agent TOMLs, config, external skills, and thoth-mem setup; `$thoth-init` only initializes per-repository SDD governance. Runtime role matching and some permissions remain instruction-level. |
342
+ | Codex | The CLI installs the native plugin and manages global `AGENTS.md`, six agent TOMLs, config, external skills, and thoth-mem setup; `$thoth-init` only initializes per-repository SDD governance. Runtime role matching and some permissions remain instruction-level. |
349
343
  | Claude Code | Run both native marketplace commands before the CLI installs external skills and requests thoth-mem setup. The native manager owns cache files; fine-grained path restrictions remain instruction-level. |
350
344
 
351
345
  Codex and Claude marketplace manifests are versioned in
@@ -385,7 +379,8 @@ npx thoth-agents@latest install --agent=claude
385
379
  npx thoth-agents@latest model --harness=codex --role=deep --model=gpt-5.6-sol
386
380
  ```
387
381
 
388
- It does not replace native marketplace trust or mutate manager-owned caches.
382
+ It does not bypass native marketplace trust or edit manager-owned caches
383
+ directly; Codex and Claude own their native manager mutations.
389
384
 
390
385
  ## Documentation
391
386
 
@@ -1411,11 +1411,11 @@ function buildCodexManagedConfigPatch(content, options) {
1411
1411
  ];
1412
1412
  if (options.pluginId) {
1413
1413
  diffSummary.push(
1414
- `plugin enablement for "${options.pluginId}" is not textually merged; use /plugins to enable it`
1414
+ `plugin enablement for "${options.pluginId}" is not textually merged; use the native Codex plugin manager`
1415
1415
  );
1416
1416
  } else {
1417
1417
  diffSummary.push(
1418
- "plugin enablement left to /plugins; no guessed plugin id written"
1418
+ "plugin installation and enablement owned by the native Codex plugin manager; no plugin table written"
1419
1419
  );
1420
1420
  }
1421
1421
  return {
@@ -1843,8 +1843,8 @@ function buildCodexSetupPlan(config) {
1843
1843
  configPath: targets.configPath,
1844
1844
  pluginId: config.pluginId,
1845
1845
  diagnostics: [
1846
- "Register the published marketplace with `codex plugin marketplace add EremesNG/thoth-agents`, restart Codex, then open /plugins to install and enable thoth-agents.",
1847
- "The CLI does not copy a plugin into ~/.codex/plugins or merge ~/.agents/plugins/marketplace.json; Codex owns marketplace snapshots and installed plugin cache state.",
1846
+ "The combined install flow runs `codex plugin marketplace add EremesNG/thoth-agents` and `codex plugin add thoth-agents@thoth-agents` through the native manager; restart Codex, then use /plugins to review its state.",
1847
+ "The CLI does not copy a plugin into ~/.codex/plugins or merge ~/.agents/plugins/marketplace.json directly; Codex owns marketplace snapshots and installed plugin cache state.",
1848
1848
  "The /hooks surface may show hooks from independently installed plugins; this thoth-agents setup plan does not install provider hooks.",
1849
1849
  "Codex Default mode user-input requests require features.default_mode_request_user_input = true and use the request_user_input tool; other modes may not expose it.",
1850
1850
  "Higher-precedence Codex config (project, profile, CLI, system, or admin) may override user config feature flags.",
@@ -0,0 +1,51 @@
1
+ export type CodexPluginSetupAction = 'register-marketplace' | 'install-plugin';
2
+ export interface CodexCommandResult {
3
+ exitCode: number;
4
+ stdout: string;
5
+ stderr: string;
6
+ }
7
+ export interface CodexCommandOptions {
8
+ cwd: string;
9
+ }
10
+ export interface CodexCommandInvocationOptions {
11
+ platform?: NodeJS.Platform;
12
+ commandShell?: string;
13
+ }
14
+ export interface CodexCommandInvocation {
15
+ command: string;
16
+ args: string[];
17
+ }
18
+ export type CodexCommandExecutor = (command: string, args: readonly string[], options: CodexCommandOptions) => CodexCommandResult;
19
+ export interface CodexPluginInstallConfig {
20
+ dryRun?: boolean;
21
+ projectRoot: string;
22
+ commandExecutor?: CodexCommandExecutor;
23
+ }
24
+ export interface CodexPluginSetupPlanItem {
25
+ action: CodexPluginSetupAction;
26
+ targetPath: string;
27
+ description: string;
28
+ command: {
29
+ executable: 'codex';
30
+ args: string[];
31
+ cwd: string;
32
+ };
33
+ }
34
+ export interface CodexPluginSetupPlan {
35
+ dryRun: boolean;
36
+ items: CodexPluginSetupPlanItem[];
37
+ diagnostics: string[];
38
+ ready: boolean;
39
+ projectRoot: string;
40
+ commandExecutor: CodexCommandExecutor;
41
+ }
42
+ export interface CodexPluginApplyResult {
43
+ success: boolean;
44
+ changed: string[];
45
+ diagnostics: string[];
46
+ error?: string;
47
+ }
48
+ export declare function getCodexCommand(args: readonly string[], options?: CodexCommandInvocationOptions): CodexCommandInvocation;
49
+ export declare function buildCodexPluginSetupPlan(config: CodexPluginInstallConfig): CodexPluginSetupPlan;
50
+ export declare function applyCodexPluginSetup(plan: CodexPluginSetupPlan): CodexPluginApplyResult;
51
+ export declare function formatCodexPluginSetupPlan(plan: CodexPluginSetupPlan): string;
package/dist/cli/index.js CHANGED
@@ -43,7 +43,7 @@ import {
43
43
  installRequiredSkill,
44
44
  listOperationHarnesses,
45
45
  normalizeEffortSelection
46
- } from "../chunk-NUSODNWE.js";
46
+ } from "../chunk-UQOCEMU3.js";
47
47
  import {
48
48
  ALL_AGENT_NAMES,
49
49
  detectCurrentConfig,
@@ -74,8 +74,243 @@ import { existsSync } from "fs";
74
74
  import { homedir } from "os";
75
75
  import { cwd } from "process";
76
76
 
77
- // src/cli/thoth-mem-install.ts
77
+ // src/cli/codex-plugin-install.ts
78
78
  import { spawnSync } from "child_process";
79
+ var MARKETPLACE_NAME = "thoth-agents";
80
+ var MARKETPLACE_SOURCE = "EremesNG/thoth-agents";
81
+ var PLUGIN_ID = "thoth-agents@thoth-agents";
82
+ var MARKETPLACE_TARGET = "codex://marketplaces/thoth-agents";
83
+ var PLUGIN_TARGET = "codex://plugins/thoth-agents@thoth-agents";
84
+ function getCodexCommand(args, options = {}) {
85
+ if ((options.platform ?? process.platform) !== "win32") {
86
+ return { command: "codex", args: [...args] };
87
+ }
88
+ return {
89
+ command: options.commandShell ?? process.env.ComSpec ?? "cmd.exe",
90
+ args: ["/d", "/s", "/c", "codex.cmd", ...args]
91
+ };
92
+ }
93
+ function defaultCommandExecutor(command, args, options) {
94
+ const invocation = command === "codex" ? getCodexCommand(args) : { command, args: [...args] };
95
+ const result = spawnSync(invocation.command, invocation.args, {
96
+ cwd: options.cwd,
97
+ encoding: "utf8",
98
+ shell: false,
99
+ windowsHide: true
100
+ });
101
+ return {
102
+ exitCode: result.status ?? (result.error ? 1 : 0),
103
+ stdout: result.stdout ?? "",
104
+ stderr: result.stderr ?? result.error?.message ?? ""
105
+ };
106
+ }
107
+ function isRecord(value) {
108
+ return typeof value === "object" && value !== null && !Array.isArray(value);
109
+ }
110
+ function parseRecordArray(value) {
111
+ return Array.isArray(value) && value.every(isRecord) ? value : null;
112
+ }
113
+ function parseManagerRecord(content) {
114
+ try {
115
+ const parsed = JSON.parse(content);
116
+ return isRecord(parsed) ? parsed : null;
117
+ } catch {
118
+ return null;
119
+ }
120
+ }
121
+ function normalizeMarketplaceSource(value) {
122
+ return value.trim().replace(/^git@github\.com:/i, "").replace(/^(?:https?|ssh):\/\/(?:git@)?github\.com\//i, "").replace(/^github\.com\//i, "").replace(/\/?\.git\/?$/i, "").replace(/\/$/, "").toLowerCase();
123
+ }
124
+ function marketplaceSources(entry) {
125
+ const sources = [entry.repo, entry.source];
126
+ if (isRecord(entry.marketplaceSource)) {
127
+ sources.push(entry.marketplaceSource.repo, entry.marketplaceSource.source);
128
+ }
129
+ return sources.filter(
130
+ (source) => typeof source === "string"
131
+ );
132
+ }
133
+ function isCanonicalMarketplace(entry) {
134
+ if (entry.name !== MARKETPLACE_NAME) return false;
135
+ const canonical = MARKETPLACE_SOURCE.toLowerCase();
136
+ return marketplaceSources(entry).some(
137
+ (source) => normalizeMarketplaceSource(source) === canonical
138
+ );
139
+ }
140
+ function inspectCodexManager(executor, cwd2) {
141
+ const marketplaceResult = executor(
142
+ "codex",
143
+ ["plugin", "marketplace", "list", "--json"],
144
+ { cwd: cwd2 }
145
+ );
146
+ const pluginResult = executor(
147
+ "codex",
148
+ ["plugin", "list", "--available", "--json"],
149
+ { cwd: cwd2 }
150
+ );
151
+ const diagnostics = [];
152
+ if (marketplaceResult.exitCode !== 0 || pluginResult.exitCode !== 0) {
153
+ diagnostics.push(
154
+ "Codex native plugin state could not be inspected; no manager mutation will be attempted."
155
+ );
156
+ return {
157
+ ready: false,
158
+ marketplace: "unknown",
159
+ plugin: "unknown",
160
+ diagnostics
161
+ };
162
+ }
163
+ const marketplaceRecord = parseManagerRecord(marketplaceResult.stdout);
164
+ const pluginRecord = parseManagerRecord(pluginResult.stdout);
165
+ const marketplaces = marketplaceRecord ? parseRecordArray(marketplaceRecord.marketplaces) : null;
166
+ const installedPlugins = pluginRecord ? parseRecordArray(pluginRecord.installed) : null;
167
+ if (!marketplaces || !installedPlugins) {
168
+ diagnostics.push(
169
+ "Codex returned unparseable plugin manager JSON; no manager mutation will be attempted."
170
+ );
171
+ return {
172
+ ready: false,
173
+ marketplace: "unknown",
174
+ plugin: "unknown",
175
+ diagnostics
176
+ };
177
+ }
178
+ const namedMarketplaces = marketplaces.filter(
179
+ (entry) => entry.name === MARKETPLACE_NAME
180
+ );
181
+ let marketplace = "absent";
182
+ if (namedMarketplaces.length > 0) {
183
+ marketplace = namedMarketplaces.every(isCanonicalMarketplace) ? "installed" : "conflict";
184
+ }
185
+ if (marketplace === "conflict") {
186
+ diagnostics.push(
187
+ "A Codex marketplace named thoth-agents is registered from a different source; resolve it through Codex before retrying."
188
+ );
189
+ }
190
+ const matchingPlugins = installedPlugins.filter(
191
+ (entry) => entry.pluginId === PLUGIN_ID
192
+ );
193
+ let plugin = "absent";
194
+ if (matchingPlugins.some((entry) => entry.enabled === true)) {
195
+ plugin = "installed";
196
+ } else if (matchingPlugins.length > 0) {
197
+ plugin = "disabled";
198
+ }
199
+ return {
200
+ ready: marketplace !== "conflict",
201
+ marketplace,
202
+ plugin,
203
+ diagnostics
204
+ };
205
+ }
206
+ function commandItem(action, projectRoot) {
207
+ if (action === "register-marketplace") {
208
+ return {
209
+ action,
210
+ targetPath: MARKETPLACE_TARGET,
211
+ description: "Register the package-owned thoth-agents Codex marketplace.",
212
+ command: {
213
+ executable: "codex",
214
+ args: ["plugin", "marketplace", "add", MARKETPLACE_SOURCE, "--json"],
215
+ cwd: projectRoot
216
+ }
217
+ };
218
+ }
219
+ return {
220
+ action,
221
+ targetPath: PLUGIN_TARGET,
222
+ description: "Install and enable the thoth-agents Codex plugin from its native marketplace.",
223
+ command: {
224
+ executable: "codex",
225
+ args: ["plugin", "add", PLUGIN_ID, "--json"],
226
+ cwd: projectRoot
227
+ }
228
+ };
229
+ }
230
+ function buildCodexPluginSetupPlan(config) {
231
+ const commandExecutor = config.commandExecutor ?? defaultCommandExecutor;
232
+ const inspection = inspectCodexManager(commandExecutor, config.projectRoot);
233
+ const items = [];
234
+ if (inspection.ready) {
235
+ if (inspection.marketplace === "absent") {
236
+ items.push(commandItem("register-marketplace", config.projectRoot));
237
+ }
238
+ if (inspection.plugin === "absent" || inspection.plugin === "disabled") {
239
+ items.push(commandItem("install-plugin", config.projectRoot));
240
+ }
241
+ }
242
+ return {
243
+ dryRun: config.dryRun === true,
244
+ items,
245
+ ready: inspection.ready,
246
+ projectRoot: config.projectRoot,
247
+ commandExecutor,
248
+ diagnostics: [
249
+ ...inspection.diagnostics,
250
+ "Codex installs thoth-agents from EremesNG/thoth-agents through its native plugin manager and owns the cached plugin files.",
251
+ "Restart Codex after installation; use /plugins to inspect marketplace and plugin state."
252
+ ]
253
+ };
254
+ }
255
+ function uniqueMessages(messages) {
256
+ return [...new Set(messages)];
257
+ }
258
+ function boundedCommandFailure(item, result) {
259
+ const detail = result.stderr.trim().replace(/\s+/g, " ").slice(0, 240);
260
+ return `${item.description} Codex exited with code ${result.exitCode}${detail ? `: ${detail}` : "."}`;
261
+ }
262
+ function applyCodexPluginSetup(plan) {
263
+ const changed = [];
264
+ const diagnostics = uniqueMessages(plan.diagnostics);
265
+ if (!plan.ready) {
266
+ return {
267
+ success: false,
268
+ changed,
269
+ diagnostics,
270
+ error: "Codex native plugin manager state is not safe to mutate."
271
+ };
272
+ }
273
+ if (plan.dryRun) return { success: true, changed, diagnostics };
274
+ for (const item of plan.items) {
275
+ const result = plan.commandExecutor(
276
+ item.command.executable,
277
+ item.command.args,
278
+ { cwd: item.command.cwd }
279
+ );
280
+ if (result.exitCode !== 0) {
281
+ return {
282
+ success: false,
283
+ changed,
284
+ diagnostics,
285
+ error: boundedCommandFailure(item, result)
286
+ };
287
+ }
288
+ changed.push(item.targetPath);
289
+ }
290
+ const inspection = inspectCodexManager(
291
+ plan.commandExecutor,
292
+ plan.projectRoot
293
+ );
294
+ diagnostics.push(...inspection.diagnostics);
295
+ if (inspection.marketplace !== "installed" || inspection.plugin !== "installed") {
296
+ return {
297
+ success: false,
298
+ changed,
299
+ diagnostics: uniqueMessages(diagnostics),
300
+ error: "Codex did not verify the expected marketplace and enabled plugin after mutation."
301
+ };
302
+ }
303
+ return { success: true, changed, diagnostics: uniqueMessages(diagnostics) };
304
+ }
305
+ function formatCodexPluginSetupPlan(plan) {
306
+ const lines = plan.items.map(
307
+ (item) => `- ${item.action}: ${item.command.executable} ${item.command.args.join(" ")}`
308
+ );
309
+ return ["Codex plugin setup plan:", ...lines].join("\n");
310
+ }
311
+
312
+ // src/cli/thoth-mem-install.ts
313
+ import { spawnSync as spawnSync2 } from "child_process";
79
314
  var THOTH_MEM_SETUP_TIMEOUT_MS = 12e4;
80
315
  var STATUS_EXIT_CODE = {
81
316
  complete: 0,
@@ -93,17 +328,17 @@ var STEP_OUTCOMES = /* @__PURE__ */ new Set([
93
328
  "failed",
94
329
  "unavailable"
95
330
  ]);
96
- function isRecord(value) {
331
+ function isRecord2(value) {
97
332
  return typeof value === "object" && value !== null && !Array.isArray(value);
98
333
  }
99
334
  function isStringArray(value) {
100
335
  return Array.isArray(value) && value.every((item) => typeof item === "string");
101
336
  }
102
337
  function isSetupStep(value) {
103
- return isRecord(value) && typeof value.name === "string" && value.name.length > 0 && typeof value.outcome === "string" && STEP_OUTCOMES.has(value.outcome);
338
+ return isRecord2(value) && typeof value.name === "string" && value.name.length > 0 && typeof value.outcome === "string" && STEP_OUTCOMES.has(value.outcome);
104
339
  }
105
340
  function isProviderSetupResult(value, expectedHarness) {
106
- return isRecord(value) && typeof value.status === "string" && SETUP_STATUSES.has(value.status) && typeof value.changed === "boolean" && value.harness === expectedHarness && value.scope === "global" && typeof value.target === "string" && value.target.length > 0 && Array.isArray(value.steps) && value.steps.every(isSetupStep) && isStringArray(value.diagnostics) && isStringArray(value.manual_actions) && (value.receipt === null || typeof value.receipt === "string");
341
+ return isRecord2(value) && typeof value.status === "string" && SETUP_STATUSES.has(value.status) && typeof value.changed === "boolean" && value.harness === expectedHarness && value.scope === "global" && typeof value.target === "string" && value.target.length > 0 && Array.isArray(value.steps) && value.steps.every(isSetupStep) && isStringArray(value.diagnostics) && isStringArray(value.manual_actions) && (value.receipt === null || typeof value.receipt === "string");
107
342
  }
108
343
  function parseProviderSetupResult(stdout, expectedHarness) {
109
344
  let value;
@@ -114,8 +349,8 @@ function parseProviderSetupResult(stdout, expectedHarness) {
114
349
  }
115
350
  return isProviderSetupResult(value, expectedHarness) ? value : void 0;
116
351
  }
117
- function defaultCommandExecutor(command, args, options) {
118
- const result = spawnSync(command, [...args], {
352
+ function defaultCommandExecutor2(command, args, options) {
353
+ const result = spawnSync2(command, [...args], {
119
354
  cwd: options.cwd,
120
355
  encoding: "utf8",
121
356
  stdio: ["ignore", "pipe", "pipe"],
@@ -132,7 +367,7 @@ function describeError(error) {
132
367
  return error instanceof Error ? error.message : String(error);
133
368
  }
134
369
  function isTimeoutError(error) {
135
- return isRecord(error) && error.code === "ETIMEDOUT";
370
+ return isRecord2(error) && error.code === "ETIMEDOUT";
136
371
  }
137
372
  function invalidResult(harness, command, args, exitCode, error) {
138
373
  return {
@@ -171,7 +406,7 @@ function runThothMemSetup(options) {
171
406
  options.harness,
172
407
  options.dryRun ?? false
173
408
  );
174
- const executor = options.commandExecutor ?? defaultCommandExecutor;
409
+ const executor = options.commandExecutor ?? defaultCommandExecutor2;
175
410
  let commandResult;
176
411
  try {
177
412
  commandResult = executor(command, args, {
@@ -466,11 +701,23 @@ function createInstallConfig(args) {
466
701
  async function install(args, dependencies = {}) {
467
702
  const config = createInstallConfig(args);
468
703
  if (config.agent === "codex") {
704
+ const projectRoot = cwd();
705
+ const pluginPlan = buildCodexPluginSetupPlan({
706
+ dryRun: config.dryRun,
707
+ projectRoot
708
+ });
709
+ console.log(formatCodexPluginSetupPlan(pluginPlan));
710
+ const pluginResult = applyCodexPluginSetup(pluginPlan);
711
+ for (const diagnostic of pluginResult.diagnostics) printInfo(diagnostic);
712
+ if (!pluginResult.success) {
713
+ printError(`Codex plugin install failed: ${pluginResult.error}`);
714
+ return 1;
715
+ }
469
716
  const plan = buildCodexSetupPlan({
470
717
  dryRun: config.dryRun,
471
718
  reset: config.reset,
472
719
  scope: "user",
473
- projectRoot: cwd(),
720
+ projectRoot,
474
721
  homeDir: homedir()
475
722
  });
476
723
  console.log(formatCodexSetupPlan(plan));
@@ -485,7 +732,7 @@ async function install(args, dependencies = {}) {
485
732
  return 1;
486
733
  }
487
734
  printSuccess(
488
- config.dryRun ? "Codex dry-run complete; no files written" : "Codex agent-pack setup complete"
735
+ config.dryRun ? "Codex dry-run complete; no files written" : "Codex plugin installed as thoth-agents@thoth-agents and agent-pack setup complete (restart Codex to activate)"
489
736
  );
490
737
  return 0;
491
738
  }
@@ -2,7 +2,7 @@ import {
2
2
  defaultTuiOperations,
3
3
  effortChoicesForModel,
4
4
  listOperationHarnesses
5
- } from "../../chunk-NUSODNWE.js";
5
+ } from "../../chunk-UQOCEMU3.js";
6
6
  import "../../chunk-XO74DXBZ.js";
7
7
 
8
8
  // src/cli/tui/index.tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thoth-agents",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Adaptive multi-harness orchestration with seven roles, runtime-autonomous Spec Kit-compatible SDD routes, and external provider boundaries.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thoth-agents",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Adaptive multi-harness agent pack with seven roles and a runtime-autonomous Spec Kit-compatible SDD bundle for Claude Code.",
5
5
  "author": {
6
6
  "name": "thoth-agents"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thoth-agents",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Bundled Spec Kit-compatible SDD skills and MCP configuration; the seven-role global Codex layer requires thoth-agents CLI setup.",
5
5
  "skills": "./skills/",
6
6
  "mcpServers": "./codex.mcp.json"