thoth-agents 0.1.5 → 0.1.7
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 +35 -8
- package/dist/chunk-DYGVRAMS.js +182 -0
- package/dist/chunk-OES76C67.js +1898 -0
- package/dist/chunk-OJCEGZSA.js +3735 -0
- package/dist/cli/codex-install.d.ts +15 -0
- package/dist/cli/commands.d.ts +9 -0
- package/dist/cli/index.d.ts +3 -2
- package/dist/cli/index.js +543 -4154
- package/dist/cli/operations/codex.d.ts +22 -0
- package/dist/cli/operations/index.d.ts +8 -0
- package/dist/cli/operations/opencode.d.ts +14 -0
- package/dist/cli/operations/types.d.ts +126 -0
- package/dist/cli/parser.d.ts +6 -0
- package/dist/cli/runtime.d.ts +21 -0
- package/dist/cli/skills.d.ts +17 -0
- package/dist/cli/tui/App.d.ts +7 -0
- package/dist/cli/tui/components/Header.d.ts +6 -0
- package/dist/cli/tui/components/Menu.d.ts +12 -0
- package/dist/cli/tui/components/ModelChoiceScreen.d.ts +9 -0
- package/dist/cli/tui/components/ModelScreen.d.ts +14 -0
- package/dist/cli/tui/components/PathLine.d.ts +8 -0
- package/dist/cli/tui/components/PlanPreview.d.ts +8 -0
- package/dist/cli/tui/components/StatusView.d.ts +7 -0
- package/dist/cli/tui/index.d.ts +3 -0
- package/dist/cli/tui/index.js +1285 -0
- package/dist/cli/tui/model-catalog.d.ts +20 -0
- package/dist/cli/tui/operations.d.ts +18 -0
- package/dist/cli/tui/theme.d.ts +9 -0
- package/dist/cli/types.d.ts +19 -0
- package/dist/harness/core/sdd.d.ts +20 -0
- package/dist/harness/core/skills.d.ts +2 -2
- package/dist/index.js +156 -1693
- package/package.json +5 -1
- package/src/skills/sdd-design/SKILL.md +12 -2
package/README.md
CHANGED
|
@@ -43,16 +43,39 @@ provide the same hard runtime controls.
|
|
|
43
43
|
|
|
44
44
|
| Harness | Status | Setup path | Notes |
|
|
45
45
|
| --- | --- | --- | --- |
|
|
46
|
-
| OpenCode | Stable default | `
|
|
47
|
-
| Codex | Supported explicit path | `
|
|
46
|
+
| OpenCode | Stable default | `npx thoth-agents@latest install` or `npx thoth-agents@latest install --agent=opencode` | Native plugin config, native `task` delegation, optional tmux panes, OpenCode provider auth. |
|
|
47
|
+
| Codex | Supported explicit path | `npx thoth-agents@latest install --agent=codex` | Installs ambient/root guidance, six role subagents, and a Personal plugin source. Requires `/plugins` and `/hooks` trust review. Some governance remains instruction-level. |
|
|
48
|
+
|
|
49
|
+
OpenCode can load the plugin with:
|
|
50
|
+
|
|
51
|
+
```jsonc
|
|
52
|
+
{
|
|
53
|
+
"plugin": ["thoth-agents@latest"]
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
That plugin entry is not a shell command. To run the installer or TUI, use the
|
|
58
|
+
npm binary through a global install, `npx thoth-agents@latest`, or
|
|
59
|
+
`pnpm dlx thoth-agents@latest`.
|
|
48
60
|
|
|
49
61
|
## Quick Start
|
|
50
62
|
|
|
63
|
+
Run the binary with no arguments in an interactive terminal to open the
|
|
64
|
+
multi-harness TUI:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npx thoth-agents@latest
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The same no-argument binary invocation falls back to the OpenCode install path
|
|
71
|
+
in CI, redirected, or `TERM=dumb` terminals. Use explicit commands when you
|
|
72
|
+
need deterministic automation.
|
|
73
|
+
|
|
51
74
|
### OpenCode
|
|
52
75
|
|
|
53
76
|
```bash
|
|
54
|
-
|
|
55
|
-
|
|
77
|
+
npx thoth-agents@latest install
|
|
78
|
+
npx thoth-agents@latest install --agent=opencode
|
|
56
79
|
opencode auth login
|
|
57
80
|
opencode
|
|
58
81
|
```
|
|
@@ -66,16 +89,20 @@ ping all agents
|
|
|
66
89
|
For non-interactive setup:
|
|
67
90
|
|
|
68
91
|
```bash
|
|
69
|
-
|
|
92
|
+
npx thoth-agents@latest install --no-tui --tmux=no --skills=yes
|
|
70
93
|
```
|
|
71
94
|
|
|
95
|
+
Interactive status, list, update, sync, and model previews are available from
|
|
96
|
+
the no-argument TUI. Command help also documents the explicit command names for
|
|
97
|
+
terminal workflows.
|
|
98
|
+
|
|
72
99
|
### Codex
|
|
73
100
|
|
|
74
101
|
Review the plan first, then install explicitly:
|
|
75
102
|
|
|
76
103
|
```bash
|
|
77
|
-
|
|
78
|
-
|
|
104
|
+
npx thoth-agents@latest install --agent=codex --dry-run
|
|
105
|
+
npx thoth-agents@latest install --agent=codex
|
|
79
106
|
```
|
|
80
107
|
|
|
81
108
|
Restart Codex and review plugin/hook trust:
|
|
@@ -92,7 +119,7 @@ runtime guarantees unless Codex exposes those controls.
|
|
|
92
119
|
### Reset Generated Config
|
|
93
120
|
|
|
94
121
|
```bash
|
|
95
|
-
|
|
122
|
+
npx thoth-agents@latest install --reset
|
|
96
123
|
```
|
|
97
124
|
|
|
98
125
|
## Seven-Agent Roster
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
// src/utils/subprocess.ts
|
|
2
|
+
import {
|
|
3
|
+
spawn as nodeSpawn,
|
|
4
|
+
spawnSync as nodeSpawnSync
|
|
5
|
+
} from "child_process";
|
|
6
|
+
import { Readable } from "stream";
|
|
7
|
+
function emptyReadableStream() {
|
|
8
|
+
return new ReadableStream({
|
|
9
|
+
start(controller) {
|
|
10
|
+
controller.close();
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function toWebReadable(stream) {
|
|
15
|
+
if (!stream) {
|
|
16
|
+
return emptyReadableStream();
|
|
17
|
+
}
|
|
18
|
+
return Readable.toWeb(
|
|
19
|
+
stream
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
function fallbackStdin() {
|
|
23
|
+
return {
|
|
24
|
+
write: () => void 0,
|
|
25
|
+
end: () => void 0
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function spawn(command, options = {}) {
|
|
29
|
+
const child = nodeSpawn(command[0], command.slice(1), {
|
|
30
|
+
cwd: options.cwd,
|
|
31
|
+
env: options.env,
|
|
32
|
+
stdio: [
|
|
33
|
+
options.stdin ?? "pipe",
|
|
34
|
+
options.stdout ?? "pipe",
|
|
35
|
+
options.stderr ?? "pipe"
|
|
36
|
+
]
|
|
37
|
+
});
|
|
38
|
+
const managed = {
|
|
39
|
+
stdin: child.stdin ?? fallbackStdin(),
|
|
40
|
+
stdout: toWebReadable(child.stdout),
|
|
41
|
+
stderr: toWebReadable(child.stderr),
|
|
42
|
+
exited: new Promise((resolve) => {
|
|
43
|
+
child.on("exit", (code) => {
|
|
44
|
+
managed.exitCode = code;
|
|
45
|
+
resolve(code ?? 1);
|
|
46
|
+
});
|
|
47
|
+
child.on("error", () => {
|
|
48
|
+
managed.exitCode = 1;
|
|
49
|
+
resolve(1);
|
|
50
|
+
});
|
|
51
|
+
}),
|
|
52
|
+
exitCode: child.exitCode,
|
|
53
|
+
kill: () => {
|
|
54
|
+
child.kill();
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
return managed;
|
|
58
|
+
}
|
|
59
|
+
function spawnSync(command, options = {}) {
|
|
60
|
+
const result = nodeSpawnSync(command[0], command.slice(1), {
|
|
61
|
+
cwd: options.cwd,
|
|
62
|
+
env: options.env,
|
|
63
|
+
stdio: [
|
|
64
|
+
options.stdin ?? "ignore",
|
|
65
|
+
options.stdout ?? "pipe",
|
|
66
|
+
options.stderr ?? "pipe"
|
|
67
|
+
]
|
|
68
|
+
});
|
|
69
|
+
return { exitCode: result.status };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/cli/system.ts
|
|
73
|
+
import { statSync } from "fs";
|
|
74
|
+
var cachedOpenCodePath = null;
|
|
75
|
+
function getOpenCodePaths() {
|
|
76
|
+
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
77
|
+
return [
|
|
78
|
+
// PATH (try this first)
|
|
79
|
+
"opencode",
|
|
80
|
+
// User local installations (Linux & macOS)
|
|
81
|
+
`${home}/.local/bin/opencode`,
|
|
82
|
+
`${home}/.opencode/bin/opencode`,
|
|
83
|
+
`${home}/bin/opencode`,
|
|
84
|
+
// System-wide installations
|
|
85
|
+
"/usr/local/bin/opencode",
|
|
86
|
+
"/opt/opencode/bin/opencode",
|
|
87
|
+
"/usr/bin/opencode",
|
|
88
|
+
"/bin/opencode",
|
|
89
|
+
// macOS specific
|
|
90
|
+
"/Applications/OpenCode.app/Contents/MacOS/opencode",
|
|
91
|
+
`${home}/Applications/OpenCode.app/Contents/MacOS/opencode`,
|
|
92
|
+
// Homebrew (macOS & Linux)
|
|
93
|
+
"/opt/homebrew/bin/opencode",
|
|
94
|
+
"/home/linuxbrew/.linuxbrew/bin/opencode",
|
|
95
|
+
`${home}/homebrew/bin/opencode`,
|
|
96
|
+
// macOS user Library
|
|
97
|
+
`${home}/Library/Application Support/opencode/bin/opencode`,
|
|
98
|
+
// Snap (Linux)
|
|
99
|
+
"/snap/bin/opencode",
|
|
100
|
+
"/var/snap/opencode/current/bin/opencode",
|
|
101
|
+
// Flatpak (Linux)
|
|
102
|
+
"/var/lib/flatpak/exports/bin/ai.opencode.OpenCode",
|
|
103
|
+
`${home}/.local/share/flatpak/exports/bin/ai.opencode.OpenCode`,
|
|
104
|
+
// Nix (Linux/macOS)
|
|
105
|
+
"/nix/store/opencode/bin/opencode",
|
|
106
|
+
`${home}/.nix-profile/bin/opencode`,
|
|
107
|
+
"/run/current-system/sw/bin/opencode",
|
|
108
|
+
// Cargo (Rust toolchain)
|
|
109
|
+
`${home}/.cargo/bin/opencode`,
|
|
110
|
+
// npm/npx global
|
|
111
|
+
`${home}/.npm-global/bin/opencode`,
|
|
112
|
+
"/usr/local/lib/node_modules/opencode/bin/opencode",
|
|
113
|
+
// Yarn global
|
|
114
|
+
`${home}/.yarn/bin/opencode`,
|
|
115
|
+
// PNPM
|
|
116
|
+
`${home}/.pnpm-global/bin/opencode`
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
function resolveOpenCodePath() {
|
|
120
|
+
if (cachedOpenCodePath) {
|
|
121
|
+
return cachedOpenCodePath;
|
|
122
|
+
}
|
|
123
|
+
const paths = getOpenCodePaths();
|
|
124
|
+
for (const opencodePath of paths) {
|
|
125
|
+
if (opencodePath === "opencode") continue;
|
|
126
|
+
try {
|
|
127
|
+
const stat = statSync(opencodePath);
|
|
128
|
+
if (stat.isFile()) {
|
|
129
|
+
cachedOpenCodePath = opencodePath;
|
|
130
|
+
return opencodePath;
|
|
131
|
+
}
|
|
132
|
+
} catch {
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return "opencode";
|
|
136
|
+
}
|
|
137
|
+
async function isOpenCodeInstalled() {
|
|
138
|
+
const paths = getOpenCodePaths();
|
|
139
|
+
for (const opencodePath of paths) {
|
|
140
|
+
try {
|
|
141
|
+
const proc = spawn([opencodePath, "--version"], {
|
|
142
|
+
stdout: "pipe",
|
|
143
|
+
stderr: "pipe"
|
|
144
|
+
});
|
|
145
|
+
await proc.exited;
|
|
146
|
+
if (proc.exitCode === 0) {
|
|
147
|
+
cachedOpenCodePath = opencodePath;
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
} catch {
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
async function getOpenCodeVersion() {
|
|
156
|
+
const opencodePath = resolveOpenCodePath();
|
|
157
|
+
try {
|
|
158
|
+
const proc = spawn([opencodePath, "--version"], {
|
|
159
|
+
stdout: "pipe",
|
|
160
|
+
stderr: "pipe"
|
|
161
|
+
});
|
|
162
|
+
const output = await new Response(proc.stdout).text();
|
|
163
|
+
await proc.exited;
|
|
164
|
+
if (proc.exitCode === 0) {
|
|
165
|
+
return output.trim();
|
|
166
|
+
}
|
|
167
|
+
} catch {
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
function getOpenCodePath() {
|
|
172
|
+
const path = resolveOpenCodePath();
|
|
173
|
+
return path === "opencode" ? null : path;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export {
|
|
177
|
+
spawn,
|
|
178
|
+
spawnSync,
|
|
179
|
+
isOpenCodeInstalled,
|
|
180
|
+
getOpenCodeVersion,
|
|
181
|
+
getOpenCodePath
|
|
182
|
+
};
|