@nevermorelove/ompp 0.1.0 → 0.2.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 +23 -11
- package/ompp.js +177 -106
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -8,32 +8,44 @@ ompp gives each kind of work a name and a folder. Launch a session in a mode and
|
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
|
+
```sh
|
|
12
|
+
npm install -g @nevermorelove/ompp
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Node 18 or newer, that is the whole requirement. bun works too. The binary is
|
|
16
|
+
named `ompp` even though the package is scoped. You can also install from
|
|
17
|
+
source:
|
|
18
|
+
|
|
11
19
|
```sh
|
|
12
20
|
git clone git@github.com:ForeverInLaw/ompp.git
|
|
13
21
|
cd ompp
|
|
14
22
|
npm install -g .
|
|
15
23
|
```
|
|
16
24
|
|
|
17
|
-
Node 18 or newer, that is the whole requirement. bun works too. After install, `ompp` is on your PATH. To update, `git pull` and install again.
|
|
18
|
-
|
|
19
|
-
## Usage
|
|
20
|
-
|
|
21
25
|
```sh
|
|
22
26
|
ompp arrow-key picker, then launches omp
|
|
23
27
|
ompp pentest launch in a mode
|
|
24
28
|
ompp writing -p "..." mode plus any omp flags
|
|
29
|
+
ompp create pentest make a new mode with placeholder files,
|
|
30
|
+
then open its folder in your file manager
|
|
25
31
|
ompp list print mode names
|
|
26
32
|
ompp pentest --dry-run show the omp command line instead of running it
|
|
27
33
|
```
|
|
28
34
|
|
|
29
35
|
Before launch it prints one line to stderr, `[ompp] mode: pentest`, so you always know where you are.
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
Modes are read from up to three places, and same-named modes from earlier
|
|
38
|
+
places win:
|
|
32
39
|
|
|
33
|
-
|
|
40
|
+
1. `OMPP_MODES_DIR`, if you set it
|
|
41
|
+
2. `modes/` shipped next to the script (the repo checkout or the npm package)
|
|
42
|
+
3. `~/.omp/ompp/modes/`, the user-level home for your own modes
|
|
43
|
+
|
|
44
|
+
`ompp create` always writes to `~/.omp/ompp/modes/`, so you never edit files
|
|
45
|
+
inside an installed package. The first `ompp create` makes the folder for you.
|
|
34
46
|
|
|
35
47
|
```
|
|
36
|
-
modes/pentest/
|
|
48
|
+
~/.omp/ompp/modes/pentest/
|
|
37
49
|
config.yml settings overlay
|
|
38
50
|
system.md full system prompt replacement
|
|
39
51
|
append.md prompt addendum, used when system.md is absent
|
|
@@ -49,7 +61,9 @@ modes/pentest/
|
|
|
49
61
|
| `append.md` | `--append-system-prompt` | Rides on top of your normal prompt. This is what most modes want. |
|
|
50
62
|
| the folder itself | `--plugin-dir` | omp treats the mode folder as a plugin root, so `skills/` and `.mcp.json` inside it load too. |
|
|
51
63
|
|
|
52
|
-
A new mode is `
|
|
64
|
+
A new mode is `ompp create <name>` (or plain `mkdir` plus files). No manifest,
|
|
65
|
+
no code. The wrapper reads the folder, so it never needs to change when you
|
|
66
|
+
add modes. `modes/general` in the repo is a working example.
|
|
53
67
|
|
|
54
68
|
## Precedence
|
|
55
69
|
|
|
@@ -65,9 +79,7 @@ MCP servers can be added by a mode but never removed. omp has no launch-time MCP
|
|
|
65
79
|
|
|
66
80
|
Mode-local `skills/` are additive as well. To have fewer skills, set `skills.includeSkills` in the mode's `config.yml`. The allowlist filters every discovered skill, global ones included.
|
|
67
81
|
|
|
68
|
-
The picker needs a TTY. Piped or otherwise headless stdin gets a numbered prompt instead.
|
|
69
|
-
|
|
70
82
|
## Environment
|
|
71
83
|
|
|
72
|
-
- `OMPP_MODES_DIR`,
|
|
84
|
+
- `OMPP_MODES_DIR`, an extra modes directory that wins over the bundled one.
|
|
73
85
|
- `OMPP_OMP_BIN`, which omp to launch. Default is omp from PATH.
|
package/ompp.js
CHANGED
|
@@ -20,7 +20,20 @@ const fs = require("fs");
|
|
|
20
20
|
const path = require("path");
|
|
21
21
|
const { spawn } = require("child_process");
|
|
22
22
|
|
|
23
|
-
const
|
|
23
|
+
const os = require("os");
|
|
24
|
+
|
|
25
|
+
// Modes come from up to three places, in priority order:
|
|
26
|
+
// 1. OMPP_MODES_DIR (explicit override)
|
|
27
|
+
// 2. modes/ next to this script (repo checkout or npm package)
|
|
28
|
+
// 3. ~/.omp/ompp/modes (user-level default where `ompp create` writes)
|
|
29
|
+
// Same-named modes from a higher-priority source win.
|
|
30
|
+
const DEFAULT_MODES_DIR = path.join(os.homedir(), ".omp", "ompp", "modes");
|
|
31
|
+
const BUNDLED_MODES_DIR = path.join(__dirname, "modes");
|
|
32
|
+
const SOURCES = [];
|
|
33
|
+
if (process.env.OMPP_MODES_DIR) SOURCES.push(process.env.OMPP_MODES_DIR);
|
|
34
|
+
SOURCES.push(BUNDLED_MODES_DIR);
|
|
35
|
+
SOURCES.push(DEFAULT_MODES_DIR);
|
|
36
|
+
const RESERVED_NAMES = ["create", "list", "help", "version"];
|
|
24
37
|
const CONFIG_NAMES = ["config.yml", "config.yaml"];
|
|
25
38
|
const PLUGIN_ARTIFACTS = [
|
|
26
39
|
"skills",
|
|
@@ -32,6 +45,10 @@ const PLUGIN_ARTIFACTS = [
|
|
|
32
45
|
"tools",
|
|
33
46
|
];
|
|
34
47
|
|
|
48
|
+
function modeDirOf(name, source) {
|
|
49
|
+
return path.join(source, name);
|
|
50
|
+
}
|
|
51
|
+
|
|
35
52
|
function firstExisting(dir, names) {
|
|
36
53
|
for (const n of names) {
|
|
37
54
|
const p = path.join(dir, n);
|
|
@@ -40,27 +57,43 @@ function firstExisting(dir, names) {
|
|
|
40
57
|
return null;
|
|
41
58
|
}
|
|
42
59
|
|
|
43
|
-
function
|
|
44
|
-
|
|
45
|
-
const skipped = [];
|
|
46
|
-
if (!fs.existsSync(MODES_DIR)) return { modes, skipped };
|
|
60
|
+
function scanSource(source, modes, skipped, seen) {
|
|
61
|
+
if (!fs.existsSync(source)) return;
|
|
47
62
|
const entries = fs
|
|
48
|
-
.readdirSync(
|
|
63
|
+
.readdirSync(source, { withFileTypes: true })
|
|
49
64
|
.filter((e) => e.isDirectory())
|
|
50
65
|
.map((e) => e.name)
|
|
51
66
|
.sort();
|
|
52
67
|
for (const name of entries) {
|
|
53
68
|
if (name.startsWith(".") || name.startsWith("_")) continue;
|
|
54
|
-
const dir =
|
|
69
|
+
const dir = modeDirOf(name, source);
|
|
55
70
|
const hasSomething = firstExisting(dir, [
|
|
56
71
|
...CONFIG_NAMES,
|
|
57
72
|
"system.md",
|
|
58
73
|
"append.md",
|
|
59
74
|
...PLUGIN_ARTIFACTS,
|
|
60
75
|
]);
|
|
61
|
-
if (hasSomething)
|
|
62
|
-
|
|
76
|
+
if (!hasSomething) {
|
|
77
|
+
skipped.push(name);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (seen.has(name)) {
|
|
81
|
+
// A same-named mode from a higher-priority source already won.
|
|
82
|
+
console.error(
|
|
83
|
+
`[ompp] mode "${name}" exists in several mode folders; using the one in ${modeDirOf(name, SOURCES[0])}`,
|
|
84
|
+
);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
seen.add(name);
|
|
88
|
+
modes.push({ name, source });
|
|
63
89
|
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function discoverModes() {
|
|
93
|
+
const modes = [];
|
|
94
|
+
const skipped = [];
|
|
95
|
+
const seen = new Set();
|
|
96
|
+
for (const source of SOURCES) scanSource(source, modes, skipped, seen);
|
|
64
97
|
return { modes, skipped };
|
|
65
98
|
}
|
|
66
99
|
|
|
@@ -130,9 +163,13 @@ Usage:
|
|
|
130
163
|
ompp pick a mode interactively, then launch omp
|
|
131
164
|
ompp <mode> [args...] launch omp in a mode; everything after <mode>
|
|
132
165
|
is passed to omp unchanged and wins over the mode
|
|
166
|
+
ompp create <name> create a new mode with placeholder files
|
|
167
|
+
and open its folder
|
|
133
168
|
ompp list list available modes
|
|
134
169
|
|
|
135
|
-
|
|
170
|
+
Modes live in ~/.omp/ompp/modes/ (created for you by "ompp create") and,
|
|
171
|
+
if OMPP_MODES_DIR is set, in that folder too. Same-named modes from
|
|
172
|
+
OMPP_MODES_DIR win. All files are optional:
|
|
136
173
|
config.yml settings overlay: model, thinking level,
|
|
137
174
|
skills.includeSkills allowlist, approval mode, ...
|
|
138
175
|
system.md replaces the system prompt entirely
|
|
@@ -147,124 +184,154 @@ Flags:
|
|
|
147
184
|
-v, --version version
|
|
148
185
|
|
|
149
186
|
Environment:
|
|
150
|
-
OMPP_MODES_DIR modes directory (
|
|
187
|
+
OMPP_MODES_DIR extra modes directory (repo checkout or custom)
|
|
151
188
|
OMPP_OMP_BIN omp executable to launch (default: omp from PATH)`);
|
|
152
189
|
}
|
|
153
190
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (seq.startsWith("\u001b[A") || seq.startsWith("\u001b[B") ||
|
|
189
|
-
seq.startsWith("\u001b[C") || seq.startsWith("\u001b[D")) {
|
|
190
|
-
if (seq.startsWith("\u001b[A")) {
|
|
191
|
-
idx = (idx - 1 + modes.length) % modes.length;
|
|
192
|
-
render(false);
|
|
193
|
-
} else if (seq.startsWith("\u001b[B")) {
|
|
194
|
-
idx = (idx + 1) % modes.length;
|
|
195
|
-
render(false);
|
|
196
|
-
} // C/D: left/right, ignore
|
|
197
|
-
i += 3;
|
|
198
|
-
continue;
|
|
199
|
-
}
|
|
200
|
-
if (seq.length === 1) {
|
|
201
|
-
// Bare escape with nothing after it in this chunk: cancel.
|
|
202
|
-
finish(null);
|
|
203
|
-
process.exit(0);
|
|
204
|
-
}
|
|
205
|
-
i++; // unknown or split sequence, skip the escape byte
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
if (ch === "\r" || ch === "\n") return finish(modes[idx]);
|
|
209
|
-
if (ch === "\u0003") {
|
|
210
|
-
// Ctrl+C: restore the terminal and bail like a shell would.
|
|
211
|
-
finish(null);
|
|
212
|
-
process.exit(130);
|
|
213
|
-
}
|
|
214
|
-
if (ch === "q") {
|
|
215
|
-
finish(null);
|
|
216
|
-
process.exit(0);
|
|
217
|
-
}
|
|
218
|
-
if (ch === "j") {
|
|
219
|
-
idx = (idx + 1) % modes.length;
|
|
220
|
-
render(false);
|
|
221
|
-
}
|
|
222
|
-
if (ch === "k") {
|
|
223
|
-
idx = (idx - 1 + modes.length) % modes.length;
|
|
224
|
-
render(false);
|
|
225
|
-
}
|
|
226
|
-
i++;
|
|
227
|
-
}
|
|
191
|
+
const CONFIG_TEMPLATE = `# Settings overlay for this mode. Every line is optional:
|
|
192
|
+
# uncomment what you need. See "omp config list" for all keys.
|
|
193
|
+
|
|
194
|
+
# modelRoles:
|
|
195
|
+
# default: anthropic/claude-sonnet-4-5
|
|
196
|
+
# defaultThinkingLevel: high
|
|
197
|
+
# tools:
|
|
198
|
+
# approvalMode: write
|
|
199
|
+
|
|
200
|
+
# Allowlist of skills this mode can see. Globs are allowed.
|
|
201
|
+
# Empty (or absent) means every discovered skill loads.
|
|
202
|
+
# skills:
|
|
203
|
+
# includeSkills:
|
|
204
|
+
# - tdd
|
|
205
|
+
# - diagnosing-bugs
|
|
206
|
+
`;
|
|
207
|
+
|
|
208
|
+
const APPEND_TEMPLATE = `# Extra instructions added on top of your normal system prompt.
|
|
209
|
+
# This file is plain text: delete these lines and write your own.
|
|
210
|
+
|
|
211
|
+
Answer directly and briefly. No preamble, no restating the question.
|
|
212
|
+
`;
|
|
213
|
+
|
|
214
|
+
const SYSTEM_TEMPLATE = `# Rename this file to system.md to REPLACE the whole system prompt
|
|
215
|
+
# instead of appending. Replacing drops omp's default instructions and
|
|
216
|
+
# your global ~/.omp/agent/SYSTEM.md, including tool policy: write
|
|
217
|
+
# what you need into the file itself.
|
|
218
|
+
`;
|
|
219
|
+
|
|
220
|
+
const MCP_TEMPLATE = `{
|
|
221
|
+
"mcpServers": {
|
|
222
|
+
"example": {
|
|
223
|
+
"type": "http",
|
|
224
|
+
"url": "https://mcp.example.com/mcp"
|
|
228
225
|
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
`;
|
|
229
|
+
|
|
230
|
+
function revealInFileManager(dir) {
|
|
231
|
+
const cmd =
|
|
232
|
+
process.platform === "win32"
|
|
233
|
+
? { bin: "explorer", args: [dir] }
|
|
234
|
+
: process.platform === "darwin"
|
|
235
|
+
? { bin: "open", args: [dir] }
|
|
236
|
+
: { bin: "xdg-open", args: [dir] };
|
|
237
|
+
const child = spawn(cmd.bin, cmd.args, { stdio: "ignore", detached: true });
|
|
238
|
+
child.on("error", (err) => {
|
|
239
|
+
console.error(`[ompp] could not open a file manager: ${err.message}`);
|
|
240
|
+
});
|
|
241
|
+
child.unref();
|
|
242
|
+
}
|
|
229
243
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
244
|
+
function createMode(name) {
|
|
245
|
+
if (!name) {
|
|
246
|
+
console.error(`[ompp] usage: ompp create <name>`);
|
|
247
|
+
return 1;
|
|
248
|
+
}
|
|
249
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(name)) {
|
|
250
|
+
console.error(
|
|
251
|
+
`[ompp] "${name}" is not a valid mode name. Use lowercase letters, digits, and dashes.`,
|
|
252
|
+
);
|
|
253
|
+
return 1;
|
|
254
|
+
}
|
|
255
|
+
if (RESERVED_NAMES.includes(name)) {
|
|
256
|
+
console.error(`[ompp] "${name}" is reserved for ompp commands.`);
|
|
257
|
+
return 1;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Always create in the user-level default, regardless of OMPP_MODES_DIR.
|
|
261
|
+
const dir = modeDirOf(name, DEFAULT_MODES_DIR);
|
|
262
|
+
if (fs.existsSync(dir)) {
|
|
263
|
+
console.error(`[ompp] mode "${name}" already exists, opening its folder.`);
|
|
264
|
+
revealInFileManager(dir);
|
|
265
|
+
return 0;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
fs.mkdirSync(path.join(dir, "skills"), { recursive: true });
|
|
269
|
+
fs.writeFileSync(path.join(dir, "config.yml"), CONFIG_TEMPLATE);
|
|
270
|
+
fs.writeFileSync(path.join(dir, "append.md"), APPEND_TEMPLATE);
|
|
271
|
+
fs.writeFileSync(path.join(dir, "system.md.example"), SYSTEM_TEMPLATE);
|
|
272
|
+
fs.writeFileSync(path.join(dir, ".mcp.json.example"), MCP_TEMPLATE);
|
|
273
|
+
fs.writeFileSync(path.join(dir, "skills", ".gitkeep"), "");
|
|
274
|
+
|
|
275
|
+
console.error(`[ompp] created mode "${name}" in ${dir}`);
|
|
276
|
+
revealInFileManager(dir);
|
|
277
|
+
console.error(`[ompp] edit the placeholders, then launch it: ompp ${name}`);
|
|
278
|
+
return 0;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async function pickMode(modeNames) {
|
|
282
|
+
const { select, isCancel, cancel } = require("@clack/prompts");
|
|
283
|
+
const chosen = await select({
|
|
284
|
+
message: "Pick a mode",
|
|
285
|
+
options: modeNames.map((name) => ({ value: name, label: name })),
|
|
234
286
|
});
|
|
287
|
+
if (isCancel(chosen)) {
|
|
288
|
+
cancel("Cancelled");
|
|
289
|
+
process.exit(130);
|
|
290
|
+
}
|
|
291
|
+
return chosen;
|
|
235
292
|
}
|
|
236
293
|
|
|
237
|
-
|
|
294
|
+
// Non-TTY stdin: clack needs an interactive terminal, so numbered input.
|
|
295
|
+
function pickModePiped(modeNames) {
|
|
238
296
|
return new Promise((resolve, reject) => {
|
|
239
297
|
const readline = require("readline");
|
|
240
298
|
const rl = readline.createInterface({ input: process.stdin });
|
|
241
299
|
process.stdout.write("Select a mode:\n");
|
|
242
|
-
|
|
243
|
-
process.stdout.write(`Choice [1-${
|
|
300
|
+
modeNames.forEach((m, i) => process.stdout.write(` ${i + 1}. ${m}\n`));
|
|
301
|
+
process.stdout.write(`Choice [1-${modeNames.length}]: `);
|
|
302
|
+
let done = false;
|
|
244
303
|
rl.once("line", (line) => {
|
|
304
|
+
done = true;
|
|
245
305
|
rl.close();
|
|
246
306
|
const n = parseInt(line.trim(), 10);
|
|
247
|
-
if (n >= 1 && n <=
|
|
307
|
+
if (n >= 1 && n <= modeNames.length) resolve(modeNames[n - 1]);
|
|
248
308
|
else reject(new Error(`"${line.trim()}" is not a valid choice`));
|
|
249
309
|
});
|
|
250
310
|
rl.once("close", () => {
|
|
251
|
-
reject(new Error("no mode selected"));
|
|
311
|
+
if (!done) reject(new Error("no mode selected"));
|
|
252
312
|
});
|
|
253
313
|
});
|
|
254
314
|
}
|
|
255
315
|
|
|
316
|
+
|
|
317
|
+
|
|
256
318
|
async function main() {
|
|
257
319
|
const argv = process.argv.slice(2);
|
|
258
320
|
|
|
321
|
+
if (argv[0] === "create") {
|
|
322
|
+
return createMode(argv[1]);
|
|
323
|
+
}
|
|
324
|
+
|
|
259
325
|
if (argv[0] === "list") {
|
|
260
326
|
const { modes, skipped } = discoverModes();
|
|
261
327
|
if (!modes.length) {
|
|
262
328
|
console.error(
|
|
263
|
-
`[ompp] no modes found
|
|
329
|
+
`[ompp] no modes found. Run "ompp create <name>" to make one.`,
|
|
264
330
|
);
|
|
331
|
+
for (const s of SOURCES) console.error(`[ompp] looked in: ${s}`);
|
|
265
332
|
return 1;
|
|
266
333
|
}
|
|
267
|
-
for (const m of modes) console.log(m);
|
|
334
|
+
for (const m of modes) console.log(m.name);
|
|
268
335
|
if (skipped.length) {
|
|
269
336
|
console.error(
|
|
270
337
|
`[ompp] skipped folders without recognized files: ${skipped.join(", ")}`,
|
|
@@ -293,46 +360,50 @@ async function main() {
|
|
|
293
360
|
}
|
|
294
361
|
if (!modes.length) {
|
|
295
362
|
console.error(
|
|
296
|
-
`[ompp] no modes found
|
|
363
|
+
`[ompp] no modes found. Run "ompp create <name>" to make one.`,
|
|
297
364
|
);
|
|
365
|
+
for (const s of SOURCES) console.error(`[ompp] looked in: ${s}`);
|
|
298
366
|
return 1;
|
|
299
367
|
}
|
|
300
368
|
|
|
369
|
+
const modeNames = modes.map((m) => m.name);
|
|
301
370
|
let mode = null;
|
|
302
371
|
let userArgs = rest;
|
|
303
372
|
if (rest.length && !rest[0].startsWith("-")) {
|
|
304
373
|
const candidate = rest[0];
|
|
305
|
-
|
|
306
|
-
|
|
374
|
+
const found = modes.find((m) => m.name === candidate);
|
|
375
|
+
if (found) {
|
|
376
|
+
mode = found;
|
|
307
377
|
userArgs = rest.slice(1);
|
|
308
378
|
} else {
|
|
309
379
|
console.error(`[ompp] unknown mode "${candidate}"`);
|
|
310
|
-
console.error(`[ompp] available: ${
|
|
380
|
+
console.error(`[ompp] available: ${modeNames.join(", ")}`);
|
|
311
381
|
return 1;
|
|
312
382
|
}
|
|
313
383
|
} else {
|
|
314
384
|
try {
|
|
315
|
-
|
|
316
|
-
? await
|
|
317
|
-
: await
|
|
385
|
+
const name = process.stdin.isTTY
|
|
386
|
+
? await pickMode(modeNames)
|
|
387
|
+
: await pickModePiped(modeNames);
|
|
388
|
+
mode = modes.find((m) => m.name === name);
|
|
318
389
|
} catch (err) {
|
|
319
390
|
console.error(`[ompp] ${err.message}`);
|
|
320
391
|
return 1;
|
|
321
392
|
}
|
|
322
393
|
}
|
|
323
394
|
|
|
324
|
-
const modeDir =
|
|
395
|
+
const modeDir = modeDirOf(mode.name, mode.source);
|
|
325
396
|
const args = buildArgv(modeDir, userArgs);
|
|
326
397
|
const { bin, shell } = resolveBin();
|
|
327
398
|
|
|
328
399
|
if (dryRun) {
|
|
329
|
-
console.error(`[ompp] mode: ${mode}`);
|
|
400
|
+
console.error(`[ompp] mode: ${mode.name}`);
|
|
330
401
|
console.error(`[ompp] omp: ${bin}${shell ? " (shell)" : ""}`);
|
|
331
402
|
console.error(`[ompp] argv: ${JSON.stringify(args)}`);
|
|
332
403
|
return 0;
|
|
333
404
|
}
|
|
334
405
|
|
|
335
|
-
console.error(`[ompp] mode: ${mode}`);
|
|
406
|
+
console.error(`[ompp] mode: ${mode.name}`);
|
|
336
407
|
const child = shell
|
|
337
408
|
? spawn([winQuote(bin), ...args.map(winQuote)].join(" "), {
|
|
338
409
|
stdio: "inherit",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nevermorelove/ompp",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Mode presets for the omp coding agent: one folder per mode, zero config code.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -24,5 +24,8 @@
|
|
|
24
24
|
"cli"
|
|
25
25
|
],
|
|
26
26
|
"author": "ForeverInLaw",
|
|
27
|
-
"license": "MIT"
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@clack/prompts": "^1.8.1"
|
|
30
|
+
}
|
|
28
31
|
}
|