omkx 0.1.0 → 0.1.1
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 +41 -15
- package/bin/cli.mjs +286 -140
- package/install.sh +8 -1
- package/package.json +26 -6
package/README.md
CHANGED
|
@@ -35,33 +35,56 @@ omkx provides a three-tier agent system where main agents orchestrate work and s
|
|
|
35
35
|
## Quick Start
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
npx omkx@latest
|
|
38
|
+
npx omkx@latest
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
Or for global install (available in all projects):
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx omkx@latest --global
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This copies all agents, prompts, hooks, skills, steering files, and MCP configuration into `.kiro/` — either `./.kiro/` (local) or `~/.kiro/` (global). Then open your project in Kiro and the agents are available — `ctrl+p` for Prometheus (planner), `ctrl+a` for Atlas (plan executor), `ctrl+e` for Sisyphus (direct tasks).
|
|
42
48
|
|
|
43
49
|
---
|
|
44
50
|
|
|
45
51
|
## Installation
|
|
46
52
|
|
|
47
|
-
|
|
53
|
+
Two ways:
|
|
54
|
+
|
|
55
|
+
**Option 1 — npx (no clone needed):**
|
|
48
56
|
|
|
49
57
|
```bash
|
|
50
|
-
npx omkx@latest
|
|
58
|
+
npx omkx@latest
|
|
51
59
|
```
|
|
52
60
|
|
|
53
|
-
|
|
61
|
+
Or for global install (available in all projects):
|
|
54
62
|
|
|
55
63
|
```bash
|
|
56
|
-
|
|
64
|
+
npx omkx@latest --global
|
|
57
65
|
```
|
|
58
66
|
|
|
59
|
-
|
|
67
|
+
**Option 2 — from the repo:**
|
|
60
68
|
|
|
61
69
|
```bash
|
|
62
70
|
git clone https://github.com/seyisulu/omkx.git
|
|
63
71
|
cd omkx
|
|
64
|
-
|
|
72
|
+
./install.sh # local install (current project only)
|
|
73
|
+
./install.sh --global # global install (all projects)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Both methods copy the `.kiro/` directory (agents, prompts, hooks, skills, steering files, MCP config) into either `./.kiro/` (local) or `~/.kiro/` (global). Then just open your project in Kiro and the agents are available — `ctrl+p` for Prometheus (planner), `ctrl+a` for Atlas (plan executor), `ctrl+e` for Sisyphus (direct tasks).
|
|
77
|
+
|
|
78
|
+
### Updating later
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npx omkx@latest --update
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Uninstalling
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npx omkx@latest --uninstall
|
|
65
88
|
```
|
|
66
89
|
|
|
67
90
|
---
|
|
@@ -287,13 +310,16 @@ Update files in `.kiro/steering/omkx/` to change project conventions, plan forma
|
|
|
287
310
|
## Commands
|
|
288
311
|
|
|
289
312
|
```bash
|
|
290
|
-
omkx
|
|
291
|
-
omkx
|
|
313
|
+
omkx # Install (local, current project only)
|
|
314
|
+
omkx --global # Install globally (all projects)
|
|
315
|
+
omkx --update # Update to the latest version
|
|
316
|
+
omkx --uninstall # Remove omkx
|
|
317
|
+
omkx install --force # Force reinstall
|
|
292
318
|
omkx install --dir <path> # Install to specific directory
|
|
293
|
-
omkx status
|
|
294
|
-
omkx list
|
|
295
|
-
omkx plans
|
|
296
|
-
omkx help
|
|
319
|
+
omkx status # Show installation status
|
|
320
|
+
omkx list # List all installed agents
|
|
321
|
+
omkx plans # List execution plans
|
|
322
|
+
omkx help # Show help
|
|
297
323
|
```
|
|
298
324
|
|
|
299
325
|
---
|
|
@@ -302,7 +328,7 @@ omkx help # Show help
|
|
|
302
328
|
|
|
303
329
|
omkx is based on:
|
|
304
330
|
|
|
305
|
-
- **[oh-my-openagent](https://github.com/code-yeongyu/oh-my-openagent)** — The original TypeScript multi-agent system developed by
|
|
331
|
+
- **[oh-my-openagent](https://github.com/code-yeongyu/oh-my-openagent)** — The original TypeScript multi-agent system developed by code-yeongyu. Agent personalities, workflows, and delegation patterns are adapted from this project.
|
|
306
332
|
- **[oh-my-kiro](https://github.com/NachoFLizaur/oh-my-kiro)** — The Kiro IDE agent format and conventions that omkx follows.
|
|
307
333
|
|
|
308
334
|
### Agent Name Origins
|
package/bin/cli.mjs
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import {
|
|
4
|
+
readFileSync,
|
|
5
|
+
existsSync,
|
|
6
|
+
cpSync,
|
|
7
|
+
mkdirSync,
|
|
8
|
+
writeFileSync,
|
|
9
|
+
rmSync,
|
|
10
|
+
rmdirSync,
|
|
11
|
+
} from "fs";
|
|
12
|
+
import { resolve, dirname } from "path";
|
|
13
|
+
import { fileURLToPath } from "url";
|
|
14
|
+
import { execSync } from "child_process";
|
|
15
|
+
import { homedir } from "os";
|
|
7
16
|
|
|
8
17
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
const PKG_ROOT = resolve(__dirname,
|
|
18
|
+
const PKG_ROOT = resolve(__dirname, "..");
|
|
10
19
|
|
|
11
20
|
// ─── Help ────────────────────────────────────────────────────────────────
|
|
12
21
|
|
|
@@ -17,22 +26,27 @@ function showHelp() {
|
|
|
17
26
|
║ Multi-Agent Orchestration for Kiro ║
|
|
18
27
|
╚══════════════════════════════════════════════════════════╝
|
|
19
28
|
|
|
20
|
-
Usage: omkx
|
|
29
|
+
Usage: omkx [command] [options]
|
|
21
30
|
|
|
22
31
|
Commands:
|
|
23
|
-
|
|
32
|
+
(default) Install omkx agents and configuration
|
|
24
33
|
status Show installation status
|
|
25
34
|
list List installed agents
|
|
26
35
|
plans List execution plans
|
|
27
36
|
help Show this help
|
|
28
37
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
omkx
|
|
38
|
+
Flags:
|
|
39
|
+
--global Install/uninstall globally (~/.kiro) instead of locally (./.kiro)
|
|
40
|
+
--update Update to the latest version (force reinstall)
|
|
41
|
+
--uninstall Remove omkx from the target directory
|
|
42
|
+
--force Force reinstall
|
|
43
|
+
--dir <path> Target directory (default: current directory)
|
|
33
44
|
|
|
34
45
|
Examples:
|
|
35
|
-
omkx
|
|
46
|
+
npx omkx@latest Install in current project
|
|
47
|
+
npx omkx@latest --global Install globally (all projects)
|
|
48
|
+
npx omkx@latest --update Update to the latest version
|
|
49
|
+
npx omkx@latest --uninstall Remove omkx
|
|
36
50
|
omkx status Check what's installed
|
|
37
51
|
omkx list List all agents
|
|
38
52
|
omkx plans List plans from .kiro/plans/
|
|
@@ -51,10 +65,12 @@ Repository: https://github.com/seyisulu/omkx
|
|
|
51
65
|
|
|
52
66
|
function getVersion() {
|
|
53
67
|
try {
|
|
54
|
-
const pkg = JSON.parse(
|
|
68
|
+
const pkg = JSON.parse(
|
|
69
|
+
readFileSync(resolve(PKG_ROOT, "package.json"), "utf8"),
|
|
70
|
+
);
|
|
55
71
|
return pkg.version;
|
|
56
72
|
} catch {
|
|
57
|
-
return
|
|
73
|
+
return "0.1.0";
|
|
58
74
|
}
|
|
59
75
|
}
|
|
60
76
|
|
|
@@ -62,153 +78,171 @@ function getVersion() {
|
|
|
62
78
|
|
|
63
79
|
const MANIFEST = {
|
|
64
80
|
agents: [
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
81
|
+
"prometheus.json",
|
|
82
|
+
"atlas.json",
|
|
83
|
+
"sisyphus.json",
|
|
84
|
+
"ghost-explorer.json",
|
|
85
|
+
"ghost-metis.json",
|
|
86
|
+
"ghost-momus.json",
|
|
87
|
+
"ghost-oracle.json",
|
|
88
|
+
"ghost-librarian.json",
|
|
89
|
+
"ghost-junior.json",
|
|
90
|
+
"ghost-looker.json",
|
|
75
91
|
],
|
|
76
92
|
prompts: [
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
93
|
+
"prometheus.md",
|
|
94
|
+
"atlas.md",
|
|
95
|
+
"sisyphus.md",
|
|
96
|
+
"ghost-explorer.md",
|
|
97
|
+
"ghost-metis.md",
|
|
98
|
+
"ghost-momus.md",
|
|
99
|
+
"ghost-oracle.md",
|
|
100
|
+
"ghost-librarian.md",
|
|
101
|
+
"ghost-junior.md",
|
|
102
|
+
"ghost-looker.md",
|
|
87
103
|
],
|
|
88
104
|
hooks: [
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
105
|
+
"agent-spawn.sh",
|
|
106
|
+
"pre-tool-use.sh",
|
|
107
|
+
"prometheus-read-guard.sh",
|
|
108
|
+
"prometheus-write-guard.sh",
|
|
93
109
|
],
|
|
94
110
|
steering: [
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
111
|
+
"product.md",
|
|
112
|
+
"conventions.md",
|
|
113
|
+
"plan-format.md",
|
|
114
|
+
"architecture.md",
|
|
99
115
|
],
|
|
100
116
|
skills: [
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
],
|
|
107
|
-
settings: [
|
|
108
|
-
'mcp.json',
|
|
117
|
+
"git-operations",
|
|
118
|
+
"code-review",
|
|
119
|
+
"frontend-ux",
|
|
120
|
+
"debugging",
|
|
121
|
+
"programming",
|
|
109
122
|
],
|
|
123
|
+
settings: ["mcp.json"],
|
|
110
124
|
};
|
|
111
125
|
|
|
112
126
|
function install(targetDir, force = false) {
|
|
113
|
-
const kiroDir = resolve(targetDir,
|
|
127
|
+
const kiroDir = resolve(targetDir, ".kiro");
|
|
128
|
+
const isGlobal = resolve(targetDir) === homedir();
|
|
129
|
+
const scope = isGlobal ? "globally" : "locally";
|
|
114
130
|
|
|
115
131
|
// Check if already installed
|
|
116
|
-
const manifestMarker = resolve(kiroDir,
|
|
132
|
+
const manifestMarker = resolve(kiroDir, "agents", "prometheus.json");
|
|
117
133
|
if (existsSync(manifestMarker) && !force) {
|
|
118
|
-
console.log(
|
|
119
|
-
console.log(
|
|
134
|
+
console.log(`✅ omkx is already installed ${scope} (${kiroDir}).`);
|
|
135
|
+
console.log(" Use --force or --update to reinstall.");
|
|
120
136
|
return;
|
|
121
137
|
}
|
|
122
138
|
|
|
123
|
-
console.log(`📦 Installing omkx to ${
|
|
139
|
+
console.log(`📦 Installing omkx ${scope} to ${kiroDir}...\n`);
|
|
124
140
|
|
|
125
141
|
// Copy .kiro directory
|
|
126
|
-
copyDir(resolve(PKG_ROOT,
|
|
142
|
+
copyDir(resolve(PKG_ROOT, ".kiro"), kiroDir);
|
|
127
143
|
|
|
128
144
|
// Make hooks executable
|
|
129
|
-
const hooksDir = resolve(kiroDir,
|
|
145
|
+
const hooksDir = resolve(kiroDir, "hooks");
|
|
130
146
|
try {
|
|
131
|
-
execSync(`chmod +x ${hooksDir}/*.sh`, { stdio:
|
|
147
|
+
execSync(`chmod +x ${hooksDir}/*.sh`, { stdio: "pipe" });
|
|
132
148
|
} catch {
|
|
133
149
|
// Ignore if no hooks dir
|
|
134
150
|
}
|
|
135
151
|
|
|
136
152
|
// Create empty dirs with gitkeep
|
|
137
|
-
ensureDir(resolve(kiroDir,
|
|
138
|
-
ensureDir(resolve(kiroDir,
|
|
139
|
-
touchIfMissing(resolve(kiroDir,
|
|
140
|
-
touchIfMissing(resolve(kiroDir,
|
|
141
|
-
|
|
142
|
-
console.log(
|
|
143
|
-
console.log(
|
|
144
|
-
console.log(
|
|
145
|
-
console.log(
|
|
153
|
+
ensureDir(resolve(kiroDir, "plans"));
|
|
154
|
+
ensureDir(resolve(kiroDir, "notepads"));
|
|
155
|
+
touchIfMissing(resolve(kiroDir, "plans", ".gitkeep"));
|
|
156
|
+
touchIfMissing(resolve(kiroDir, "notepads", ".gitkeep"));
|
|
157
|
+
|
|
158
|
+
console.log("");
|
|
159
|
+
console.log("✅ omkx installed successfully!");
|
|
160
|
+
console.log("");
|
|
161
|
+
console.log("📂 Installed structure:");
|
|
146
162
|
console.log(` .kiro/agents/ → ${MANIFEST.agents.length} agents`);
|
|
147
163
|
console.log(` .kiro/prompts/ → ${MANIFEST.prompts.length} prompts`);
|
|
148
164
|
console.log(` .kiro/hooks/ → ${MANIFEST.hooks.length} hooks`);
|
|
149
165
|
console.log(` .kiro/skills/ → ${MANIFEST.skills.length} skills`);
|
|
150
|
-
console.log(
|
|
166
|
+
console.log(
|
|
167
|
+
` .kiro/steering/omkx/ → ${MANIFEST.steering.length} steering files`,
|
|
168
|
+
);
|
|
151
169
|
console.log(` .kiro/settings/ → ${MANIFEST.settings.length} settings`);
|
|
152
170
|
console.log(` .kiro/plans/ → Execution plans`);
|
|
153
171
|
console.log(` .kiro/notepads/ → Agent notepads`);
|
|
154
|
-
console.log(
|
|
155
|
-
console.log(
|
|
156
|
-
console.log(
|
|
157
|
-
console.log(
|
|
158
|
-
console.log(
|
|
159
|
-
console.log(
|
|
160
|
-
console.log(
|
|
172
|
+
console.log("");
|
|
173
|
+
console.log("⌨️ Keyboard Shortcuts in Kiro:");
|
|
174
|
+
console.log(" ctrl+p → Prometheus (Planner)");
|
|
175
|
+
console.log(" ctrl+a → Atlas (Plan Executor)");
|
|
176
|
+
console.log(" ctrl+e → Sisyphus (Direct Executor)");
|
|
177
|
+
console.log("");
|
|
178
|
+
console.log("📖 Read .kiro/steering/omkx/product.md for full documentation.");
|
|
161
179
|
}
|
|
162
180
|
|
|
163
181
|
// ─── Status ───────────────────────────────────────────────────────────────
|
|
164
182
|
|
|
165
183
|
function status(targetDir) {
|
|
166
|
-
const kiroDir = resolve(targetDir,
|
|
167
|
-
const manifestMarker = resolve(kiroDir,
|
|
184
|
+
const kiroDir = resolve(targetDir, ".kiro");
|
|
185
|
+
const manifestMarker = resolve(kiroDir, "agents", "prometheus.json");
|
|
168
186
|
|
|
169
|
-
console.log(
|
|
187
|
+
console.log("🔍 omkx Status\n");
|
|
170
188
|
|
|
171
189
|
if (!existsSync(manifestMarker)) {
|
|
172
|
-
console.log(
|
|
173
|
-
console.log(
|
|
190
|
+
console.log("❌ omkx is NOT installed.");
|
|
191
|
+
console.log(" Run: npx omkx install");
|
|
174
192
|
return;
|
|
175
193
|
}
|
|
176
194
|
|
|
177
|
-
console.log(
|
|
195
|
+
console.log("✅ omkx is installed.\n");
|
|
178
196
|
|
|
179
197
|
// Count agents
|
|
180
|
-
const agentsDir = resolve(kiroDir,
|
|
198
|
+
const agentsDir = resolve(kiroDir, "agents");
|
|
181
199
|
let agentCount = 0;
|
|
182
200
|
if (existsSync(agentsDir)) {
|
|
183
|
-
agentCount = MANIFEST.agents.filter(a =>
|
|
201
|
+
agentCount = MANIFEST.agents.filter((a) =>
|
|
202
|
+
existsSync(resolve(agentsDir, a)),
|
|
203
|
+
).length;
|
|
184
204
|
}
|
|
185
205
|
console.log(` Agents: ${agentCount}/${MANIFEST.agents.length}`);
|
|
186
206
|
|
|
187
207
|
// Count prompts
|
|
188
|
-
const promptsDir = resolve(kiroDir,
|
|
208
|
+
const promptsDir = resolve(kiroDir, "prompts");
|
|
189
209
|
let promptCount = 0;
|
|
190
210
|
if (existsSync(promptsDir)) {
|
|
191
|
-
promptCount = MANIFEST.prompts.filter(p =>
|
|
211
|
+
promptCount = MANIFEST.prompts.filter((p) =>
|
|
212
|
+
existsSync(resolve(promptsDir, p)),
|
|
213
|
+
).length;
|
|
192
214
|
}
|
|
193
215
|
console.log(` Prompts: ${promptCount}/${MANIFEST.prompts.length}`);
|
|
194
216
|
|
|
195
217
|
// Count plans
|
|
196
|
-
const plansDir = resolve(kiroDir,
|
|
218
|
+
const plansDir = resolve(kiroDir, "plans");
|
|
197
219
|
let planCount = 0;
|
|
198
220
|
if (existsSync(plansDir)) {
|
|
199
221
|
try {
|
|
200
|
-
planCount = execSync(`ls -1 ${plansDir}/*.md 2>/dev/null | wc -l`, {
|
|
201
|
-
|
|
222
|
+
planCount = execSync(`ls -1 ${plansDir}/*.md 2>/dev/null | wc -l`, {
|
|
223
|
+
stdio: "pipe",
|
|
224
|
+
})
|
|
225
|
+
.toString()
|
|
226
|
+
.trim();
|
|
227
|
+
} catch {
|
|
228
|
+
planCount = 0;
|
|
229
|
+
}
|
|
202
230
|
}
|
|
203
231
|
console.log(` Plans: ${planCount}`);
|
|
204
232
|
|
|
205
233
|
// Count notepads
|
|
206
|
-
const notepadsDir = resolve(kiroDir,
|
|
234
|
+
const notepadsDir = resolve(kiroDir, "notepads");
|
|
207
235
|
let notepadCount = 0;
|
|
208
236
|
if (existsSync(notepadsDir)) {
|
|
209
237
|
try {
|
|
210
|
-
notepadCount = execSync(`ls -1d ${notepadsDir}/*/ 2>/dev/null | wc -l`, {
|
|
211
|
-
|
|
238
|
+
notepadCount = execSync(`ls -1d ${notepadsDir}/*/ 2>/dev/null | wc -l`, {
|
|
239
|
+
stdio: "pipe",
|
|
240
|
+
})
|
|
241
|
+
.toString()
|
|
242
|
+
.trim();
|
|
243
|
+
} catch {
|
|
244
|
+
notepadCount = 0;
|
|
245
|
+
}
|
|
212
246
|
}
|
|
213
247
|
console.log(` Notepads: ${notepadCount}`);
|
|
214
248
|
}
|
|
@@ -216,45 +250,51 @@ function status(targetDir) {
|
|
|
216
250
|
// ─── List ──────────────────────────────────────────────────────────────────
|
|
217
251
|
|
|
218
252
|
function list(targetDir) {
|
|
219
|
-
const kiroDir = resolve(targetDir,
|
|
220
|
-
const agentsDir = resolve(kiroDir,
|
|
253
|
+
const kiroDir = resolve(targetDir, ".kiro");
|
|
254
|
+
const agentsDir = resolve(kiroDir, "agents");
|
|
221
255
|
|
|
222
|
-
console.log(
|
|
256
|
+
console.log("🤖 omkx Agents\n");
|
|
223
257
|
|
|
224
258
|
if (!existsSync(agentsDir)) {
|
|
225
|
-
console.log(
|
|
259
|
+
console.log("❌ No agents found. Run: npx omkx install");
|
|
226
260
|
return;
|
|
227
261
|
}
|
|
228
262
|
|
|
229
|
-
console.log(
|
|
230
|
-
const mainAgents = [
|
|
231
|
-
const shortcuts = {
|
|
263
|
+
console.log("Main Agents:");
|
|
264
|
+
const mainAgents = ["prometheus", "atlas", "sisyphus"];
|
|
265
|
+
const shortcuts = {
|
|
266
|
+
prometheus: "ctrl+p",
|
|
267
|
+
atlas: "ctrl+a",
|
|
268
|
+
sisyphus: "ctrl+e",
|
|
269
|
+
};
|
|
232
270
|
const descriptions = {
|
|
233
|
-
prometheus:
|
|
234
|
-
atlas:
|
|
235
|
-
sisyphus:
|
|
271
|
+
prometheus: "Planner — creates execution plans",
|
|
272
|
+
atlas: "Plan Executor — orchestrates plan execution",
|
|
273
|
+
sisyphus: "Direct Executor — handles ad-hoc tasks",
|
|
236
274
|
};
|
|
237
275
|
|
|
238
276
|
for (const name of mainAgents) {
|
|
239
277
|
const file = resolve(agentsDir, `${name}.json`);
|
|
240
|
-
const installed = existsSync(file) ?
|
|
241
|
-
console.log(
|
|
278
|
+
const installed = existsSync(file) ? "✅" : "❌";
|
|
279
|
+
console.log(
|
|
280
|
+
` ${installed} ${name.padEnd(16)} ${shortcuts[name].padEnd(8)} ${descriptions[name]}`,
|
|
281
|
+
);
|
|
242
282
|
}
|
|
243
283
|
|
|
244
|
-
console.log(
|
|
284
|
+
console.log("\nSubagents:");
|
|
245
285
|
const subAgents = [
|
|
246
|
-
{ name:
|
|
247
|
-
{ name:
|
|
248
|
-
{ name:
|
|
249
|
-
{ name:
|
|
250
|
-
{ name:
|
|
251
|
-
{ name:
|
|
252
|
-
{ name:
|
|
286
|
+
{ name: "ghost-oracle", desc: "Strategic technical advisor" },
|
|
287
|
+
{ name: "ghost-metis", desc: "Pre-planning analyst" },
|
|
288
|
+
{ name: "ghost-momus", desc: "Plan validator" },
|
|
289
|
+
{ name: "ghost-librarian", desc: "Research specialist" },
|
|
290
|
+
{ name: "ghost-explorer", desc: "Codebase explorer" },
|
|
291
|
+
{ name: "ghost-junior", desc: "Implementation specialist" },
|
|
292
|
+
{ name: "ghost-looker", desc: "Media analyst" },
|
|
253
293
|
];
|
|
254
294
|
|
|
255
295
|
for (const agent of subAgents) {
|
|
256
296
|
const file = resolve(agentsDir, `${agent.name}.json`);
|
|
257
|
-
const installed = existsSync(file) ?
|
|
297
|
+
const installed = existsSync(file) ? "✅" : "❌";
|
|
258
298
|
console.log(` ${installed} ${agent.name.padEnd(20)} ${agent.desc}`);
|
|
259
299
|
}
|
|
260
300
|
}
|
|
@@ -262,43 +302,111 @@ function list(targetDir) {
|
|
|
262
302
|
// ─── Plans ─────────────────────────────────────────────────────────────────
|
|
263
303
|
|
|
264
304
|
function plans(targetDir) {
|
|
265
|
-
const plansDir = resolve(targetDir,
|
|
305
|
+
const plansDir = resolve(targetDir, ".kiro", "plans");
|
|
266
306
|
|
|
267
|
-
console.log(
|
|
307
|
+
console.log("📐 Execution Plans\n");
|
|
268
308
|
|
|
269
309
|
if (!existsSync(plansDir)) {
|
|
270
|
-
console.log(
|
|
310
|
+
console.log(
|
|
311
|
+
"No plans directory found. Create plans with Prometheus (ctrl+p).",
|
|
312
|
+
);
|
|
271
313
|
return;
|
|
272
314
|
}
|
|
273
315
|
|
|
274
316
|
try {
|
|
275
|
-
const output = execSync(`ls -1t ${plansDir}/*.md 2>/dev/null`, {
|
|
317
|
+
const output = execSync(`ls -1t ${plansDir}/*.md 2>/dev/null`, {
|
|
318
|
+
stdio: "pipe",
|
|
319
|
+
})
|
|
320
|
+
.toString()
|
|
321
|
+
.trim();
|
|
276
322
|
if (!output) {
|
|
277
|
-
console.log(
|
|
323
|
+
console.log("No plans found. Create plans with Prometheus (ctrl+p).");
|
|
278
324
|
return;
|
|
279
325
|
}
|
|
280
|
-
const planFiles = output.split(
|
|
326
|
+
const planFiles = output.split("\n");
|
|
281
327
|
for (const plan of planFiles) {
|
|
282
|
-
const name = plan.split(
|
|
328
|
+
const name = plan.split("/").pop();
|
|
283
329
|
// Try to extract title from first line
|
|
284
330
|
try {
|
|
285
|
-
const firstLine = execSync(`head -1 "${plan}"`, { stdio:
|
|
286
|
-
|
|
331
|
+
const firstLine = execSync(`head -1 "${plan}"`, { stdio: "pipe" })
|
|
332
|
+
.toString()
|
|
333
|
+
.trim();
|
|
334
|
+
const title = firstLine.replace(/^#\s*(Plan:\s*)?/, "");
|
|
287
335
|
console.log(` 📄 ${name}`);
|
|
288
336
|
console.log(` ${title}`);
|
|
289
337
|
} catch {
|
|
290
338
|
console.log(` 📄 ${name}`);
|
|
291
339
|
}
|
|
292
|
-
console.log(
|
|
340
|
+
console.log("");
|
|
293
341
|
}
|
|
294
342
|
} catch {
|
|
295
|
-
console.log(
|
|
343
|
+
console.log("No plans found.");
|
|
296
344
|
}
|
|
297
345
|
}
|
|
298
346
|
|
|
299
|
-
// ───
|
|
347
|
+
// ─── Uninstall ────────────────────────────────────────────────────────────
|
|
348
|
+
|
|
349
|
+
function uninstall(targetDir) {
|
|
350
|
+
const kiroDir = resolve(targetDir, ".kiro");
|
|
351
|
+
const isGlobal = resolve(targetDir) === homedir();
|
|
352
|
+
const scope = isGlobal ? "global" : "local";
|
|
353
|
+
const manifestMarker = resolve(kiroDir, "agents", "prometheus.json");
|
|
354
|
+
|
|
355
|
+
console.log("🗑️ Uninstalling omkx...\n");
|
|
356
|
+
|
|
357
|
+
if (!existsSync(manifestMarker)) {
|
|
358
|
+
console.log(`❌ omkx is not installed ${scope} (${kiroDir}).`);
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Remove all omkx-managed directories and files
|
|
363
|
+
const targets = [
|
|
364
|
+
"agents",
|
|
365
|
+
"prompts",
|
|
366
|
+
"hooks",
|
|
367
|
+
"skills",
|
|
368
|
+
"settings/mcp.json",
|
|
369
|
+
"steering/omkx",
|
|
370
|
+
];
|
|
371
|
+
|
|
372
|
+
const removed = [];
|
|
373
|
+
for (const t of targets) {
|
|
374
|
+
const path = resolve(kiroDir, t);
|
|
375
|
+
if (existsSync(path)) {
|
|
376
|
+
rmSync(path, { recursive: true, force: true });
|
|
377
|
+
removed.push(t);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Clean up now-empty parent dirs (steering/, settings/)
|
|
382
|
+
for (const dir of ["steering", "settings"]) {
|
|
383
|
+
const path = resolve(kiroDir, dir);
|
|
384
|
+
try {
|
|
385
|
+
rmdirSync(path);
|
|
386
|
+
removed.push(`${dir}/`);
|
|
387
|
+
} catch {
|
|
388
|
+
// Not empty or doesn't exist — leave it alone
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Try to remove .kiro itself if entirely empty.
|
|
393
|
+
// If plans/ or notepads/ still has user content, .kiro is kept.
|
|
394
|
+
let kiroRemoved = false;
|
|
395
|
+
try {
|
|
396
|
+
rmdirSync(kiroDir);
|
|
397
|
+
kiroRemoved = true;
|
|
398
|
+
} catch {
|
|
399
|
+
// User still has plans/notepads — preserve them
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
console.log(`✅ omkx removed ${scope} from ${kiroDir}`);
|
|
403
|
+
console.log(` Removed: ${removed.join(", ")}`);
|
|
404
|
+
if (!kiroRemoved) {
|
|
405
|
+
console.log(` Kept: ${kiroDir}/plans/, ${kiroDir}/notepads/ (your data)`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
300
408
|
|
|
301
|
-
|
|
409
|
+
// ─── Utilities ─────────────────────────────────────────────────────────────
|
|
302
410
|
|
|
303
411
|
function copyDir(src, dest) {
|
|
304
412
|
cpSync(src, dest, { recursive: true });
|
|
@@ -310,7 +418,7 @@ function ensureDir(dir) {
|
|
|
310
418
|
|
|
311
419
|
function touchIfMissing(file) {
|
|
312
420
|
if (!existsSync(file)) {
|
|
313
|
-
writeFileSync(file,
|
|
421
|
+
writeFileSync(file, "");
|
|
314
422
|
}
|
|
315
423
|
}
|
|
316
424
|
|
|
@@ -318,36 +426,74 @@ function touchIfMissing(file) {
|
|
|
318
426
|
|
|
319
427
|
function main() {
|
|
320
428
|
const args = process.argv.slice(2);
|
|
321
|
-
const command = args[0] || 'help';
|
|
322
429
|
|
|
323
430
|
let targetDir = process.cwd();
|
|
324
431
|
let force = false;
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
432
|
+
let global = false;
|
|
433
|
+
let doUpdate = false;
|
|
434
|
+
let doUninstall = false;
|
|
435
|
+
let command = null;
|
|
436
|
+
|
|
437
|
+
// Parse all args — flags can appear anywhere.
|
|
438
|
+
for (let i = 0; i < args.length; i++) {
|
|
439
|
+
const arg = args[i];
|
|
440
|
+
if (arg === "--global" || arg === "-g") {
|
|
441
|
+
global = true;
|
|
442
|
+
} else if (arg === "--force" || arg === "-f") {
|
|
331
443
|
force = true;
|
|
444
|
+
} else if (arg === "--update") {
|
|
445
|
+
doUpdate = true;
|
|
446
|
+
} else if (arg === "--uninstall") {
|
|
447
|
+
doUninstall = true;
|
|
448
|
+
} else if (arg === "--dir" && args[i + 1]) {
|
|
449
|
+
targetDir = resolve(args[++i]);
|
|
450
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
451
|
+
showHelp();
|
|
452
|
+
return;
|
|
453
|
+
} else if (!arg.startsWith("-")) {
|
|
454
|
+
// First non-flag arg is the command (install/status/list/plans/help)
|
|
455
|
+
if (!command) command = arg;
|
|
456
|
+
} else {
|
|
457
|
+
console.log(`Unknown option: ${arg}`);
|
|
458
|
+
console.log('Run "omkx help" for usage information.');
|
|
459
|
+
process.exit(1);
|
|
332
460
|
}
|
|
333
461
|
}
|
|
334
462
|
|
|
463
|
+
// --global targets the user's home directory (~/.kiro)
|
|
464
|
+
if (global) {
|
|
465
|
+
targetDir = homedir();
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// --uninstall removes omkx from the target directory
|
|
469
|
+
if (doUninstall) {
|
|
470
|
+
uninstall(targetDir);
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// --update reinstalls with force (useful with npx to pull latest)
|
|
475
|
+
if (doUpdate) {
|
|
476
|
+
install(targetDir, true);
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Default command is install (so bare `npx omkx@latest` installs)
|
|
481
|
+
command = command || "install";
|
|
482
|
+
|
|
335
483
|
switch (command) {
|
|
336
|
-
case
|
|
484
|
+
case "install":
|
|
337
485
|
install(targetDir, force);
|
|
338
486
|
break;
|
|
339
|
-
case
|
|
487
|
+
case "status":
|
|
340
488
|
status(targetDir);
|
|
341
489
|
break;
|
|
342
|
-
case
|
|
490
|
+
case "list":
|
|
343
491
|
list(targetDir);
|
|
344
492
|
break;
|
|
345
|
-
case
|
|
493
|
+
case "plans":
|
|
346
494
|
plans(targetDir);
|
|
347
495
|
break;
|
|
348
|
-
case
|
|
349
|
-
case '--help':
|
|
350
|
-
case '-h':
|
|
496
|
+
case "help":
|
|
351
497
|
showHelp();
|
|
352
498
|
break;
|
|
353
499
|
default:
|
package/install.sh
CHANGED
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# omkx — Install Script
|
|
3
3
|
# Installs omkx multi-agent orchestration into the current Kiro project
|
|
4
|
-
# Usage: bash install.sh [--force] [--dir <path>]
|
|
4
|
+
# Usage: bash install.sh [--force] [--global] [--dir <path>]
|
|
5
5
|
|
|
6
6
|
set -e
|
|
7
7
|
|
|
8
8
|
FORCE=false
|
|
9
|
+
GLOBAL=false
|
|
9
10
|
TARGET_DIR="$(pwd)"
|
|
10
11
|
|
|
11
12
|
while [[ $# -gt 0 ]]; do
|
|
12
13
|
case "$1" in
|
|
13
14
|
--force) FORCE=true; shift ;;
|
|
15
|
+
--global) GLOBAL=true; shift ;;
|
|
14
16
|
--dir) TARGET_DIR="$2"; shift 2 ;;
|
|
15
17
|
*) echo "Unknown option: $1"; exit 1 ;;
|
|
16
18
|
esac
|
|
17
19
|
done
|
|
18
20
|
|
|
21
|
+
# --global installs to ~/.kiro so agents are available in all projects
|
|
22
|
+
if [ "$GLOBAL" = true ]; then
|
|
23
|
+
TARGET_DIR="$HOME"
|
|
24
|
+
fi
|
|
25
|
+
|
|
19
26
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
20
27
|
KIRO_DIR="$TARGET_DIR/.kiro"
|
|
21
28
|
|
package/package.json
CHANGED
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omkx",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Multi-agent orchestration for Kiro — agents from oh-my-openagent adapted for the Kiro IDE",
|
|
5
|
-
"bin": {
|
|
6
|
-
|
|
5
|
+
"bin": {
|
|
6
|
+
"omkx": "bin/cli.mjs"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/",
|
|
10
|
+
".kiro/",
|
|
11
|
+
"install.sh"
|
|
12
|
+
],
|
|
7
13
|
"type": "module",
|
|
8
|
-
"keywords": [
|
|
14
|
+
"keywords": [
|
|
15
|
+
"kiro",
|
|
16
|
+
"kiro-cli",
|
|
17
|
+
"kiro-agents",
|
|
18
|
+
"ai",
|
|
19
|
+
"agents",
|
|
20
|
+
"multi-agent",
|
|
21
|
+
"orchestration",
|
|
22
|
+
"oh-my-openagent"
|
|
23
|
+
],
|
|
9
24
|
"author": "seyisulu",
|
|
10
25
|
"license": "MIT",
|
|
11
|
-
"repository": {
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/seyisulu/omkx.git"
|
|
29
|
+
},
|
|
12
30
|
"homepage": "https://github.com/seyisulu/omkx#readme",
|
|
13
|
-
"engines": {
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18.0.0"
|
|
33
|
+
}
|
|
14
34
|
}
|