cto-agent-system 1.0.0 → 1.2.0
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/.zcode-plugin/plugin.json +1 -1
- package/LICENSE +21 -0
- package/README.md +26 -3
- package/install.js +229 -39
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
{
|
|
10
10
|
"name": "cto-agent-system",
|
|
11
11
|
"description": "An autonomous software company: CEO (you) + CTO/CPO/CMO leading 15 specialist agents. Run /cto and the CTO takes over — digests the project, fixes fires, improves the product, reports back with a roadmap.",
|
|
12
|
-
"version": "1.
|
|
12
|
+
"version": "1.2.0",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "xenitV1",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cto-agent-system",
|
|
3
3
|
"description": "An autonomous software company: CEO (you) + CTO/CPO/CMO leading 15 specialist agents. Run /cto and the CTO takes over — digests the project, fixes fires, improves the product, reports back with a roadmap.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.2.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "xenitV1",
|
|
7
7
|
"url": "https://github.com/xenitV1"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cto-agent-system",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "An autonomous software company: CEO (you) + CTO/CPO/CMO leading 15 specialist agents. Run /cto and the CTO takes over — digests the project, fixes fires, improves the product, reports back with a roadmap.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "xenitV1",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "cto-agent-system",
|
|
3
3
|
"displayName": "Software Company Agent System",
|
|
4
4
|
"description": "An autonomous software company: CEO (you) + CTO/CPO/CMO leading 15 specialist agents. Run /cto and the CTO takes over.",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.2.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "xenitV1",
|
|
8
8
|
"url": "https://github.com/xenitV1"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cto-agent-system",
|
|
3
3
|
"description": "An autonomous software company: CEO (you) + CTO/CPO/CMO leading 15 specialist agents. Run /cto and the CTO takes over — digests the project, fixes fires, improves the product, reports back with a roadmap.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.2.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "xenitV1",
|
|
7
7
|
"url": "https://github.com/xenitV1"
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 xenitV1
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Software Company Agent System
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/cto-agent-system)
|
|
4
|
+
[](https://www.npmjs.com/package/cto-agent-system)
|
|
5
|
+
[](https://github.com/xenitV1/cto-agent-system/releases)
|
|
6
|
+
[](https://github.com/xenitV1/cto-agent-system/blob/main/LICENSE)
|
|
7
|
+
[](https://github.com/xenitV1/cto-agent-system/actions/workflows/ci.yml)
|
|
8
|
+
|
|
3
9
|
**A software company you own, but don't run.**
|
|
4
10
|
|
|
5
11
|
Type `/cto` in the morning and say "good morning, start working". The CTO takes over: digests the project, decides what needs doing on its own, coordinates the team (CTO/CPO/CMO + specialists), improves code and product, and hands you a daily report + roadmap in the evening. You're the CEO (owner); they run the company.
|
|
@@ -8,6 +14,12 @@ This is **not a feature-request system**. It's an **autonomous software company*
|
|
|
8
14
|
|
|
9
15
|
Works in **Claude Code, Codex, and OpenCode** (Cursor / Copilot adapters planned). Zero runtime — just markdown + one install script.
|
|
10
16
|
|
|
17
|
+
> 📦 **npm:** [cto-agent-system](https://www.npmjs.com/package/cto-agent-system) ·
|
|
18
|
+
> 🐙 **GitHub:** [xenitV1/cto-agent-system](https://github.com/xenitV1/cto-agent-system) ·
|
|
19
|
+
> 🚀 **Releases:** [v1.0.0](https://github.com/xenitV1/cto-agent-system/releases) ·
|
|
20
|
+
> 📖 **Vision:** [VISION.md](VISION.md) ·
|
|
21
|
+
> 🛡️ **Security:** [SECURITY.md](SECURITY.md)
|
|
22
|
+
|
|
11
23
|
---
|
|
12
24
|
|
|
13
25
|
## Why
|
|
@@ -171,12 +183,23 @@ Borrowed the best ideas from proven systems (studied from their source):
|
|
|
171
183
|
|
|
172
184
|
## Status
|
|
173
185
|
|
|
174
|
-
**Phase 1 (MVP):** ✅ Core doctrine, 15 agents,
|
|
175
|
-
**Phase 2 (planned):** UX/accessibility lens skills, Cursor/Copilot adapters, evals.
|
|
186
|
+
**Phase 1 (MVP):** ✅ Core doctrine, 15 agents, 22 skills (incl. bootstrap + secure-branch + self-improvement), state system, 3 CLI adapters + Cursor plugin manifest, SessionStart hook, npx installer.
|
|
187
|
+
**Phase 2 (planned):** UX/accessibility lens skills, Cursor/Copilot adapters, evals, self-improvement feedback aggregators.
|
|
176
188
|
**Phase 3 (optional):** Kanban UI, cron autonomy (runs while you're away), multi-project.
|
|
177
189
|
|
|
178
190
|
---
|
|
179
191
|
|
|
192
|
+
## Contributing
|
|
193
|
+
|
|
194
|
+
Contributions welcome — see [`CONTRIBUTING.md`](CONTRIBUTING.md). Please read the [`VISION.md`](VISION.md) and the constitution ([`AGENTS.md`](AGENTS.md)) first; changes that affect agent behavior are high-stakes and should be discussed in an issue before a PR.
|
|
195
|
+
|
|
196
|
+
- 🐛 [Report a bug](https://github.com/xenitV1/cto-agent-system/issues/new?template=bug_report.md)
|
|
197
|
+
- 💡 [Request a feature](https://github.com/xenitV1/cto-agent-system/issues/new?template=feature_request.md)
|
|
198
|
+
- 🛡️ [Security policy](SECURITY.md)
|
|
199
|
+
- 📜 [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
180
203
|
## License
|
|
181
204
|
|
|
182
|
-
MIT — see `LICENSE
|
|
205
|
+
MIT © [xenitV1](https://github.com/xenitV1) — see [`LICENSE`](LICENSE).
|
package/install.js
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
import { dirname, join, resolve, isAbsolute } from "node:path";
|
|
23
23
|
import { fileURLToPath } from "node:url";
|
|
24
24
|
import { homedir, platform } from "node:os";
|
|
25
|
+
import { ReadStream } from "node:tty";
|
|
25
26
|
|
|
26
27
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
27
28
|
// install.js lives at the package root (next to AGENTS.md, src/, .claude/).
|
|
@@ -57,10 +58,26 @@ function hasCommand(cmd) {
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
const ADAPTERS = [
|
|
60
|
-
{
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
{
|
|
62
|
+
key: "claude", name: "Claude Code", dir: ".claude", cmds: ["claude"],
|
|
63
|
+
globalDir: () => join(homedir(), ".claude"),
|
|
64
|
+
pluginNote: "In Claude Code/ZCode, also install as a plugin for auto-updates:\n /plugin marketplace add xenitV1/cto-agent-system\n /plugin install cto-agent-system@cto-agent-marketplace",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
key: "codex", name: "OpenAI Codex", dir: ".codex", cmds: ["codex"],
|
|
68
|
+
globalDir: () => join(homedir(), ".codex"),
|
|
69
|
+
pluginNote: "Codex plugin (.codex-plugin/) installed via folder copy — Codex auto-detects it.",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
key: "opencode", name: "OpenCode", dir: ".opencode", cmds: ["opencode"],
|
|
73
|
+
globalDir: () => join(homedir(), ".config", "opencode"),
|
|
74
|
+
pluginNote: "OpenCode agents/rules installed (OpenCode plugins are JS hooks, separate concept).",
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
key: "cursor", name: "Cursor", dir: ".cursor", cmds: ["cursor"],
|
|
78
|
+
globalDir: () => join(homedir(), ".cursor"),
|
|
79
|
+
pluginNote: "Cursor plugin (.cursor-plugin/) installed via folder copy — Cursor auto-detects it.",
|
|
80
|
+
},
|
|
64
81
|
];
|
|
65
82
|
|
|
66
83
|
function detectInstalledClis() {
|
|
@@ -84,6 +101,174 @@ async function askYesNo(rl, question, defaultYes = true) {
|
|
|
84
101
|
return answer === "y" || answer === "yes";
|
|
85
102
|
}
|
|
86
103
|
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
// Interactive multi-select (arrow keys + space to toggle + enter to confirm)
|
|
106
|
+
// Zero-dependency: drives raw TTY mode directly. Falls back to a numbered
|
|
107
|
+
// prompt when stdin is not a TTY (piped/CI).
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
|
|
110
|
+
const ESC = "\x1b[";
|
|
111
|
+
|
|
112
|
+
function hideCursor() { stdout.write(`${ESC}?25l`); }
|
|
113
|
+
function showCursor() { stdout.write(`${ESC}?25h`); }
|
|
114
|
+
function clearMenu(lines) { stdout.write(`${ESC}${lines}A${ESC}J`); } // move up, clear down
|
|
115
|
+
function writeLine(s) { stdout.write(`${s}\r\n`); }
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Render a multi-select menu.
|
|
119
|
+
* @param {string} title Prompt header.
|
|
120
|
+
* @param {{label:string, hint?:string, checked:boolean}[]} items
|
|
121
|
+
* @param {boolean} allowToggle If false, behaves like a single-select.
|
|
122
|
+
* @returns {Promise<number[]>} Indices of checked items (on confirm).
|
|
123
|
+
*/
|
|
124
|
+
function checkboxMenu(title, items, { allowToggle = true } = {}) {
|
|
125
|
+
return new Promise((resolvePromise) => {
|
|
126
|
+
// Non-TTY fallback: numbered prompt.
|
|
127
|
+
const isTTY = stdin.isTTY && stdin instanceof ReadStream;
|
|
128
|
+
if (!isTTY) {
|
|
129
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
130
|
+
const fallback = async () => {
|
|
131
|
+
console.log(title);
|
|
132
|
+
items.forEach((it, i) => {
|
|
133
|
+
const mark = it.checked ? "[x]" : "[ ]";
|
|
134
|
+
console.log(` ${i + 1}. ${mark} ${it.label}${it.hint ? ` — ${it.hint}` : ""}`);
|
|
135
|
+
});
|
|
136
|
+
const ans = (await rl.question(
|
|
137
|
+
`Enter numbers comma-separated (e.g. 1,3) or 'all': `
|
|
138
|
+
)).trim().toLowerCase();
|
|
139
|
+
rl.close();
|
|
140
|
+
if (ans === "all" || ans === "") return items.map((_, i) => i);
|
|
141
|
+
const picked = ans.split(/[,\s]+/).map((n) => parseInt(n, 10) - 1)
|
|
142
|
+
.filter((n) => n >= 0 && n < items.length);
|
|
143
|
+
return picked;
|
|
144
|
+
};
|
|
145
|
+
fallback().then(resolvePromise);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let cursor = 0;
|
|
150
|
+
const state = items.map((it) => !!it.checked);
|
|
151
|
+
const headerLines = title.split("\n").length + 1; // title + blank
|
|
152
|
+
|
|
153
|
+
const render = () => {
|
|
154
|
+
writeLine(title);
|
|
155
|
+
writeLine(" (↑/↓ move, space toggle, a all, enter confirm)");
|
|
156
|
+
items.forEach((it, i) => {
|
|
157
|
+
const arrow = i === cursor ? "❯" : " ";
|
|
158
|
+
const box = state[i] ? "◉" : "◯";
|
|
159
|
+
const hint = it.hint ? ` ${it.hint}` : "";
|
|
160
|
+
writeLine(` ${arrow} ${box} ${it.label}${hint}`);
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// Render once, then capture how many lines we wrote so we can clear on re-render.
|
|
165
|
+
let lastLines = 0;
|
|
166
|
+
const paint = () => {
|
|
167
|
+
if (lastLines > 0) clearMenu(lastLines);
|
|
168
|
+
const before = stdout.rows; // unused; we count lines instead
|
|
169
|
+
const lineCount = headerLines + 1 + items.length; // title(=headerLines) + hint + items
|
|
170
|
+
render();
|
|
171
|
+
lastLines = lineCount;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
stdin.setRawMode(true);
|
|
175
|
+
stdin.resume();
|
|
176
|
+
stdin.setEncoding("utf8");
|
|
177
|
+
hideCursor();
|
|
178
|
+
paint();
|
|
179
|
+
|
|
180
|
+
const onData = (ch) => {
|
|
181
|
+
// Ctrl-C
|
|
182
|
+
if (ch === "\x03") { cleanup(); process.exit(0); }
|
|
183
|
+
// Enter
|
|
184
|
+
if (ch === "\r" || ch === "\n") {
|
|
185
|
+
cleanup();
|
|
186
|
+
const result = items.map((_, i) => i).filter((i) => state[i]);
|
|
187
|
+
resolvePromise(result);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// 'a' = toggle all
|
|
191
|
+
if (ch === "a" || ch === "A") {
|
|
192
|
+
const allOn = state.every(Boolean);
|
|
193
|
+
for (let i = 0; i < state.length; i++) state[i] = !allOn;
|
|
194
|
+
paint();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
// space = toggle current
|
|
198
|
+
if (ch === " ") {
|
|
199
|
+
if (allowToggle) { state[cursor] = !state[cursor]; paint(); }
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
// arrows
|
|
203
|
+
if (ch === `${ESC}A`) { cursor = (cursor - 1 + items.length) % items.length; paint(); return; } // up
|
|
204
|
+
if (ch === `${ESC}B`) { cursor = (cursor + 1) % items.length; paint(); return; } // down
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const cleanup = () => {
|
|
208
|
+
stdin.removeListener("data", onData);
|
|
209
|
+
stdin.setRawMode(false);
|
|
210
|
+
stdin.pause();
|
|
211
|
+
showCursor();
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
stdin.on("data", onData);
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Single-select menu (arrows + enter). Returns chosen index.
|
|
220
|
+
*/
|
|
221
|
+
function selectMenu(title, items) {
|
|
222
|
+
return new Promise((resolvePromise) => {
|
|
223
|
+
const isTTY = stdin.isTTY && stdin instanceof ReadStream;
|
|
224
|
+
if (!isTTY) {
|
|
225
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
226
|
+
const fallback = async () => {
|
|
227
|
+
console.log(title);
|
|
228
|
+
items.forEach((it, i) => console.log(` ${i + 1}. ${it.label}`));
|
|
229
|
+
const ans = parseInt((await rl.question("Choice (number): ")).trim(), 10);
|
|
230
|
+
rl.close();
|
|
231
|
+
return Number.isNaN(ans) ? 0 : Math.max(0, Math.min(items.length - 1, ans - 1));
|
|
232
|
+
};
|
|
233
|
+
fallback().then(resolvePromise);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
let cursor = 0;
|
|
238
|
+
let lastLines = 0;
|
|
239
|
+
const paint = () => {
|
|
240
|
+
if (lastLines > 0) clearMenu(lastLines);
|
|
241
|
+
writeLine(title);
|
|
242
|
+
writeLine(" (↑/↓ move, enter select)");
|
|
243
|
+
items.forEach((it, i) => {
|
|
244
|
+
const arrow = i === cursor ? "❯" : " ";
|
|
245
|
+
writeLine(` ${arrow} ${it.label}`);
|
|
246
|
+
});
|
|
247
|
+
lastLines = 1 + 1 + items.length;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
stdin.setRawMode(true);
|
|
251
|
+
stdin.resume();
|
|
252
|
+
stdin.setEncoding("utf8");
|
|
253
|
+
hideCursor();
|
|
254
|
+
paint();
|
|
255
|
+
|
|
256
|
+
const onData = (ch) => {
|
|
257
|
+
if (ch === "\x03") { cleanup(); process.exit(0); }
|
|
258
|
+
if (ch === "\r" || ch === "\n") { cleanup(); resolvePromise(cursor); return; }
|
|
259
|
+
if (ch === `${ESC}A`) { cursor = (cursor - 1 + items.length) % items.length; paint(); return; }
|
|
260
|
+
if (ch === `${ESC}B`) { cursor = (cursor + 1) % items.length; paint(); return; }
|
|
261
|
+
};
|
|
262
|
+
const cleanup = () => {
|
|
263
|
+
stdin.removeListener("data", onData);
|
|
264
|
+
stdin.setRawMode(false);
|
|
265
|
+
stdin.pause();
|
|
266
|
+
showCursor();
|
|
267
|
+
};
|
|
268
|
+
stdin.on("data", onData);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
87
272
|
// ---------------------------------------------------------------------------
|
|
88
273
|
// File helpers
|
|
89
274
|
// ---------------------------------------------------------------------------
|
|
@@ -220,20 +405,25 @@ Examples:
|
|
|
220
405
|
console.log("");
|
|
221
406
|
|
|
222
407
|
const interactive = !yes && stdin.isTTY;
|
|
223
|
-
const rl = interactive ? createInterface({ input: stdin, output: stdout }) : null;
|
|
224
408
|
|
|
225
|
-
// 2. Scope
|
|
409
|
+
// 2. Scope — arrow-key single select (interactive) or flags/default.
|
|
226
410
|
let scope;
|
|
227
411
|
if (goGlobal) scope = "global";
|
|
228
412
|
else if (goProject) scope = "project";
|
|
229
413
|
else if (interactive) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
414
|
+
const scopeItems = installed.length > 0
|
|
415
|
+
? [
|
|
416
|
+
{ label: "Global — install into the user config of detected CLIs (user-wide)" },
|
|
417
|
+
{ label: "Project — install into a specific project directory" },
|
|
418
|
+
]
|
|
419
|
+
: [
|
|
420
|
+
{ label: "Project — install into a specific project directory" },
|
|
421
|
+
{ label: "Global — install into the user config of detected CLIs" },
|
|
422
|
+
];
|
|
423
|
+
const idx = await selectMenu("Where do you want to install?", scopeItems);
|
|
424
|
+
scope = scopeItems[idx].label.startsWith("Global") ? "global" : "project";
|
|
234
425
|
} else {
|
|
235
|
-
//
|
|
236
|
-
scope = "project";
|
|
426
|
+
scope = "project"; // non-interactive default
|
|
237
427
|
}
|
|
238
428
|
|
|
239
429
|
// 3. Target
|
|
@@ -253,7 +443,7 @@ Examples:
|
|
|
253
443
|
log("→", `Target: ${target}`);
|
|
254
444
|
console.log("");
|
|
255
445
|
|
|
256
|
-
// 4. Which adapters
|
|
446
|
+
// 4. Which adapters — checkbox multi-select (interactive) or flags/default.
|
|
257
447
|
let chosen;
|
|
258
448
|
if (toolList) {
|
|
259
449
|
const want = toolList.split(",").map((s) => s.trim()).filter(Boolean);
|
|
@@ -261,22 +451,16 @@ Examples:
|
|
|
261
451
|
} else if (installAll) {
|
|
262
452
|
chosen = scope === "global" && installed.length ? installed : ADAPTERS;
|
|
263
453
|
} else if (interactive) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
chosen = [];
|
|
274
|
-
for (const a of ADAPTERS) {
|
|
275
|
-
if (await askYesNo(rl, ` Install ${a.name} adapter?`, false)) chosen.push(a);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
454
|
+
// Build checkbox items. Detected CLIs are pre-checked; others unchecked.
|
|
455
|
+
const detectedKeys = new Set(installed.map((a) => a.key));
|
|
456
|
+
const items = ADAPTERS.map((a) => ({
|
|
457
|
+
label: a.name,
|
|
458
|
+
hint: detectedKeys.has(a.key) ? "detected" : (existsSync(join(PKG_ROOT, a.dir)) ? "available" : "not shipped yet"),
|
|
459
|
+
checked: detectedKeys.has(a.key),
|
|
460
|
+
}));
|
|
461
|
+
const pickedIdx = await checkboxMenu("Select which CLI adapters to install:", items);
|
|
462
|
+
chosen = pickedIdx.map((i) => ADAPTERS[i]);
|
|
278
463
|
} else {
|
|
279
|
-
// Non-interactive default: all detected CLIs (global) or all adapters (project).
|
|
280
464
|
chosen = scope === "global" && installed.length ? installed : ADAPTERS;
|
|
281
465
|
}
|
|
282
466
|
|
|
@@ -285,12 +469,14 @@ Examples:
|
|
|
285
469
|
if (scope !== "project") {
|
|
286
470
|
initCto = false;
|
|
287
471
|
} else if (interactive) {
|
|
288
|
-
|
|
472
|
+
const idx = await selectMenu("Initialize .cto/ state files in the project?", [
|
|
473
|
+
{ label: "Yes — create .cto/ state files" },
|
|
474
|
+
{ label: "No — skip state init" },
|
|
475
|
+
]);
|
|
476
|
+
initCto = idx === 0;
|
|
289
477
|
} else {
|
|
290
|
-
initCto = true;
|
|
478
|
+
initCto = true;
|
|
291
479
|
}
|
|
292
|
-
|
|
293
|
-
if (rl) rl.close();
|
|
294
480
|
console.log("");
|
|
295
481
|
console.log(" ── Installing ──────────────────────────────────────────────");
|
|
296
482
|
|
|
@@ -302,19 +488,23 @@ Examples:
|
|
|
302
488
|
console.log("");
|
|
303
489
|
console.log(" ✅ Done.");
|
|
304
490
|
console.log("");
|
|
491
|
+
// Per-CLI next steps: each tool has a different plugin model.
|
|
492
|
+
console.log(" Next steps per installed CLI:");
|
|
493
|
+
for (const a of chosen) {
|
|
494
|
+
console.log(` ── ${a.name} ──`);
|
|
495
|
+
console.log(` ${a.pluginNote}`);
|
|
496
|
+
console.log("");
|
|
497
|
+
}
|
|
498
|
+
console.log(" Then start the CTO's daily loop:");
|
|
305
499
|
if (scope === "global") {
|
|
306
|
-
console.log(" Next steps:");
|
|
307
500
|
console.log(" • Open any project in your CLI.");
|
|
308
|
-
console.log(" • Run: /cto good morning, start working");
|
|
309
|
-
console.log(" • The CTO digests the project and runs the autonomous loop.");
|
|
310
501
|
} else {
|
|
311
|
-
console.log(" Next steps:");
|
|
312
502
|
console.log(` • cd ${target}`);
|
|
313
|
-
console.log(" • Open it in your CLI (claude / codex / opencode).");
|
|
314
|
-
console.log(" • Run: /cto good morning, start working");
|
|
315
503
|
}
|
|
504
|
+
console.log(" • Run: /cto good morning, start working");
|
|
505
|
+
console.log(" • The CTO runs Phase 0 (secure-branch) → Digest → Prioritize → ... → Report.");
|
|
316
506
|
console.log("");
|
|
317
|
-
console.log(" Docs: AGENTS.md (constitution),
|
|
507
|
+
console.log(" Docs: AGENTS.md (constitution), src/state/protocol.md (the loop).");
|
|
318
508
|
console.log("");
|
|
319
509
|
}
|
|
320
510
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cto-agent-system",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "An autonomous software company: CEO (you) + CTO/CPO/CMO leading 15 specialist agents. Run /cto and the CTO takes over — digests the project, fixes fires, improves the product, reports back with a roadmap.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|