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.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +10 -15
- package/dist/{chunk-NUSODNWE.js → chunk-UQOCEMU3.js} +4 -4
- package/dist/cli/codex-plugin-install.d.ts +51 -0
- package/dist/cli/index.js +258 -11
- package/dist/cli/tui/index.js +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
|
@@ -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.
|
|
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
|
-
|
|
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
|
|
83
|
-
|
|
84
|
-
`~/.codex/
|
|
85
|
-
|
|
86
|
-
|
|
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 |
|
|
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
|
|
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
|
|
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
|
|
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
|
-
"
|
|
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-
|
|
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/
|
|
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
|
|
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
|
|
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
|
|
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
|
|
118
|
-
const result =
|
|
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
|
|
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 ??
|
|
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
|
|
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
|
}
|
package/dist/cli/tui/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thoth-agents",
|
|
3
|
-
"version": "0.3.
|
|
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.
|
|
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"
|