oh-my-githubcopilot 1.8.1-alpha.1f91ed9 → 1.8.1-alpha.4ccdcc7
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/plugin.json +9 -2
- package/AGENTS.md +23 -24
- package/README.md +1 -1
- package/agents/code-reviewer.agent.md +5 -0
- package/agents/{simplifier.agent.md → code-simplifier.agent.md} +2 -2
- package/agents/debugger.agent.md +1 -1
- package/agents/document-specialist.agent.md +6 -1
- package/agents/{explorer.agent.md → explore.agent.md} +2 -2
- package/agents/security-reviewer.agent.md +1 -1
- package/agents/test-engineer.agent.md +3 -1
- package/bin/omp-statusline.mjs +5 -4
- package/bin/omp-statusline.mjs.map +2 -2
- package/bin/omp.mjs +589 -35
- package/bin/omp.mjs.map +4 -4
- package/dist/hooks/delegation-enforcer.mjs +56 -13
- package/dist/hooks/delegation-enforcer.mjs.map +4 -4
- package/dist/hooks/hud-emitter.mjs +64 -21
- package/dist/hooks/hud-emitter.mjs.map +4 -4
- package/dist/hooks/keyword-detector.mjs +71 -11
- package/dist/hooks/keyword-detector.mjs.map +4 -4
- package/dist/hooks/model-router.mjs +55 -12
- package/dist/hooks/model-router.mjs.map +4 -4
- package/dist/hooks/stop-continuation.mjs +57 -14
- package/dist/hooks/stop-continuation.mjs.map +4 -4
- package/dist/hooks/token-tracker.mjs +72 -19
- package/dist/hooks/token-tracker.mjs.map +4 -4
- package/dist/mcp/server.mjs +17 -16
- package/dist/mcp/server.mjs.map +2 -2
- package/extension/extension.mjs +594 -0
- package/hooks/hooks.json +6 -6
- package/package.json +3 -2
- package/plugin.json +9 -2
- package/skills/cancel/SKILL.md +33 -0
- package/skills/code-review/SKILL.md +33 -0
- package/skills/help/SKILL.md +33 -0
- package/skills/omp-doctor/SKILL.md +23 -1
- package/skills/omp-reference/SKILL.md +20 -24
- package/skills/research/SKILL.md +1 -1
- package/skills/security-review/SKILL.md +33 -0
- package/skills/ultragoal/SKILL.md +33 -0
- package/skills/ultraqa/SKILL.md +33 -0
- package/skills/verify/SKILL.md +33 -0
- package/agents/orchestrator.agent.md +0 -26
- package/agents/researcher.agent.md +0 -18
- package/agents/reviewer.agent.md +0 -23
- package/agents/tester.agent.md +0 -20
package/bin/omp.mjs
CHANGED
|
@@ -44,7 +44,7 @@ function renderAnsi(state) {
|
|
|
44
44
|
const modeStr = mode === "-" ? "-" : `\x1B[36m${mode}${reset()}`;
|
|
45
45
|
const reqWarning = state.warningActive ? " !!" : "";
|
|
46
46
|
const reqStr = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarning}`;
|
|
47
|
-
return `[OMP v${state.version}] ${modeStr} | ${model} | ${ctxStr} | ${tokenStr} | ${reqStr} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ??
|
|
47
|
+
return `[OMP v${state.version}] ${modeStr} | ${model} | ${ctxStr} | ${tokenStr} | ${reqStr} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 19} | ${icon} ${state.status}`;
|
|
48
48
|
}
|
|
49
49
|
function renderPlain(state) {
|
|
50
50
|
const age = formatAge(state.startedAt);
|
|
@@ -54,7 +54,7 @@ function renderPlain(state) {
|
|
|
54
54
|
const model = state.activeModel || "sonnet";
|
|
55
55
|
const reqWarningPlain = state.warningActive ? " !!" : "";
|
|
56
56
|
const reqStrPlain = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarningPlain}`;
|
|
57
|
-
return `[OMP v${state.version}] ${mode} | ${model} | ctx:${ctx}% | tok:~${tokens}/${state.tokensTotal} | ${reqStrPlain} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ??
|
|
57
|
+
return `[OMP v${state.version}] ${mode} | ${model} | ctx:${ctx}% | tok:~${tokens}/${state.tokensTotal} | ${reqStrPlain} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 19} | ${state.status}`;
|
|
58
58
|
}
|
|
59
59
|
var STATUS_ICONS;
|
|
60
60
|
var init_renderer = __esm({
|
|
@@ -135,7 +135,7 @@ function deserializeHudState(raw) {
|
|
|
135
135
|
skillsUsed,
|
|
136
136
|
toolsTotal: typeof value.toolsTotal === "number" ? value.toolsTotal : 13,
|
|
137
137
|
skillsTotal: typeof value.skillsTotal === "number" ? value.skillsTotal : 25,
|
|
138
|
-
agentsTotal: typeof value.agentsTotal === "number" ? value.agentsTotal :
|
|
138
|
+
agentsTotal: typeof value.agentsTotal === "number" ? value.agentsTotal : 19,
|
|
139
139
|
premiumRequests: typeof value.premiumRequests === "number" ? value.premiumRequests : 0,
|
|
140
140
|
premiumRequestsTotal: typeof value.premiumRequestsTotal === "number" ? value.premiumRequestsTotal : DEFAULT_PREMIUM_REQUESTS_TOTAL,
|
|
141
141
|
warningActive: typeof value.warningActive === "boolean" ? value.warningActive : false
|
|
@@ -168,7 +168,7 @@ function buildHudState(snapshot, now = Date.now()) {
|
|
|
168
168
|
skillsUsed,
|
|
169
169
|
toolsTotal: 13,
|
|
170
170
|
skillsTotal: 25,
|
|
171
|
-
agentsTotal:
|
|
171
|
+
agentsTotal: 19,
|
|
172
172
|
premiumRequests: snapshot.premium_requests ?? 0,
|
|
173
173
|
premiumRequestsTotal: snapshot.premium_requests_total ?? DEFAULT_PREMIUM_REQUESTS_TOTAL,
|
|
174
174
|
warningActive: snapshot.warning_active ?? false
|
|
@@ -216,7 +216,7 @@ var init_statusline = __esm({
|
|
|
216
216
|
DEFAULT_STATUSLINE = "OMP | hud: no active session";
|
|
217
217
|
DEFAULT_TOKEN_BUDGET = 2e5;
|
|
218
218
|
DEFAULT_PREMIUM_REQUESTS_TOTAL = 1500;
|
|
219
|
-
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
219
|
+
if (process.argv[1] === fileURLToPath(import.meta.url) && (process.argv[1].endsWith("omp-statusline.mjs") || process.argv[1].endsWith("statusline.mts"))) {
|
|
220
220
|
console.log(readStatusline());
|
|
221
221
|
}
|
|
222
222
|
}
|
|
@@ -250,7 +250,7 @@ function tick(paths = getStatuslinePaths()) {
|
|
|
250
250
|
function runHudWatch() {
|
|
251
251
|
const intervalMs = Math.max(
|
|
252
252
|
500,
|
|
253
|
-
parseInt(process.env["OMP_HUD_INTERVAL"] ?? "", 10) || DEFAULT_INTERVAL_MS
|
|
253
|
+
parseInt(process.env["OMP_HUD_POLL_MS"] ?? "", 10) || parseInt(process.env["OMP_HUD_INTERVAL"] ?? "", 10) || DEFAULT_INTERVAL_MS
|
|
254
254
|
);
|
|
255
255
|
const paths = getStatuslinePaths();
|
|
256
256
|
process.stdout.write("\x1B[?25l");
|
|
@@ -278,7 +278,7 @@ var init_watch = __esm({
|
|
|
278
278
|
"use strict";
|
|
279
279
|
init_statusline();
|
|
280
280
|
init_renderer();
|
|
281
|
-
DEFAULT_INTERVAL_MS =
|
|
281
|
+
DEFAULT_INTERVAL_MS = 1e3;
|
|
282
282
|
STATE_PATH = join3(homedir3(), ".omp", "state", "session.json");
|
|
283
283
|
}
|
|
284
284
|
});
|
|
@@ -339,6 +339,182 @@ var init_install = __esm({
|
|
|
339
339
|
}
|
|
340
340
|
});
|
|
341
341
|
|
|
342
|
+
// src/cli/doctor.mts
|
|
343
|
+
var doctor_exports = {};
|
|
344
|
+
__export(doctor_exports, {
|
|
345
|
+
AGENT_MIGRATIONS: () => AGENT_MIGRATIONS,
|
|
346
|
+
runDoctor: () => runDoctor,
|
|
347
|
+
scanProjectForStaleAgents: () => scanProjectForStaleAgents,
|
|
348
|
+
scanTextForStaleAgents: () => scanTextForStaleAgents
|
|
349
|
+
});
|
|
350
|
+
import { existsSync, readFileSync as readFileSync3, readdirSync, statSync } from "fs";
|
|
351
|
+
import { join as join5, relative } from "path";
|
|
352
|
+
function scanTextForStaleAgents(text, file) {
|
|
353
|
+
const warnings = [];
|
|
354
|
+
const lines = text.split("\n");
|
|
355
|
+
for (let i = 0; i < lines.length; i++) {
|
|
356
|
+
const line = lines[i];
|
|
357
|
+
for (const match of line.matchAll(STALE_AGENT_PATTERN)) {
|
|
358
|
+
const staleId = match[1];
|
|
359
|
+
warnings.push({
|
|
360
|
+
file,
|
|
361
|
+
line: i + 1,
|
|
362
|
+
staleId: `@${staleId}`,
|
|
363
|
+
replacement: AGENT_MIGRATIONS[staleId],
|
|
364
|
+
text: line.trim()
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return warnings;
|
|
369
|
+
}
|
|
370
|
+
function collectDirFiles(dir, depth) {
|
|
371
|
+
if (depth > MAX_SCAN_DEPTH) return [];
|
|
372
|
+
const files = [];
|
|
373
|
+
let entries;
|
|
374
|
+
try {
|
|
375
|
+
entries = readdirSync(dir);
|
|
376
|
+
} catch {
|
|
377
|
+
return [];
|
|
378
|
+
}
|
|
379
|
+
for (const entry of entries) {
|
|
380
|
+
const fullPath = join5(dir, entry);
|
|
381
|
+
try {
|
|
382
|
+
const stats = statSync(fullPath);
|
|
383
|
+
if (stats.isDirectory()) {
|
|
384
|
+
files.push(...collectDirFiles(fullPath, depth + 1));
|
|
385
|
+
} else if (SCANNABLE_EXTENSIONS.some((ext) => entry.endsWith(ext))) {
|
|
386
|
+
files.push(fullPath);
|
|
387
|
+
}
|
|
388
|
+
} catch {
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return files;
|
|
392
|
+
}
|
|
393
|
+
function scanProjectForStaleAgents(cwd) {
|
|
394
|
+
const targets = [];
|
|
395
|
+
for (const file of SCAN_FILES) {
|
|
396
|
+
const fullPath = join5(cwd, file);
|
|
397
|
+
if (existsSync(fullPath)) targets.push(fullPath);
|
|
398
|
+
}
|
|
399
|
+
for (const dir of SCAN_DIRS) {
|
|
400
|
+
const fullPath = join5(cwd, dir);
|
|
401
|
+
if (existsSync(fullPath)) targets.push(...collectDirFiles(fullPath, 0));
|
|
402
|
+
}
|
|
403
|
+
const warnings = [];
|
|
404
|
+
for (const target of targets) {
|
|
405
|
+
try {
|
|
406
|
+
const text = readFileSync3(target, "utf-8");
|
|
407
|
+
warnings.push(...scanTextForStaleAgents(text, relative(cwd, target)));
|
|
408
|
+
} catch {
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return warnings;
|
|
412
|
+
}
|
|
413
|
+
function runDoctor(cwd = process.cwd()) {
|
|
414
|
+
console.log("OMP Doctor \u2014 agent migration check (2.0)");
|
|
415
|
+
console.log("");
|
|
416
|
+
const warnings = scanProjectForStaleAgents(cwd);
|
|
417
|
+
if (warnings.length === 0) {
|
|
418
|
+
console.log("OK: no stale agent references found.");
|
|
419
|
+
return 0;
|
|
420
|
+
}
|
|
421
|
+
console.log(`WARN: found ${warnings.length} stale agent reference(s):`);
|
|
422
|
+
console.log("");
|
|
423
|
+
for (const warning of warnings) {
|
|
424
|
+
console.log(` ${warning.file}:${warning.line} \u2014 ${warning.staleId} \u2192 ${warning.replacement}`);
|
|
425
|
+
console.log(` ${warning.text}`);
|
|
426
|
+
}
|
|
427
|
+
console.log("");
|
|
428
|
+
console.log("Suggested replacements (OMP 2.0 agent parity):");
|
|
429
|
+
for (const [staleId, replacement] of Object.entries(AGENT_MIGRATIONS)) {
|
|
430
|
+
console.log(` @${staleId} \u2192 ${replacement}`);
|
|
431
|
+
}
|
|
432
|
+
return warnings.length;
|
|
433
|
+
}
|
|
434
|
+
var AGENT_MIGRATIONS, STALE_AGENT_PATTERN, SCAN_FILES, SCAN_DIRS, SCANNABLE_EXTENSIONS, MAX_SCAN_DEPTH;
|
|
435
|
+
var init_doctor = __esm({
|
|
436
|
+
"src/cli/doctor.mts"() {
|
|
437
|
+
"use strict";
|
|
438
|
+
AGENT_MIGRATIONS = {
|
|
439
|
+
explorer: "explore",
|
|
440
|
+
simplifier: "code-simplifier",
|
|
441
|
+
researcher: "document-specialist",
|
|
442
|
+
reviewer: "code-reviewer",
|
|
443
|
+
tester: "test-engineer",
|
|
444
|
+
orchestrator: "top-level orchestration role (no longer a delegatable agent)"
|
|
445
|
+
};
|
|
446
|
+
STALE_AGENT_PATTERN = /(?<![\w-])@(explorer|simplifier|researcher|reviewer|tester|orchestrator)(?![\w-])/g;
|
|
447
|
+
SCAN_FILES = [
|
|
448
|
+
".github/copilot-instructions.md",
|
|
449
|
+
".copilot/copilot-instructions.md",
|
|
450
|
+
"AGENTS.md"
|
|
451
|
+
];
|
|
452
|
+
SCAN_DIRS = [".omg", ".omp"];
|
|
453
|
+
SCANNABLE_EXTENSIONS = [".md", ".json", ".yml", ".yaml", ".txt"];
|
|
454
|
+
MAX_SCAN_DEPTH = 3;
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
// src/hooks/runner.mts
|
|
459
|
+
var runner_exports = {};
|
|
460
|
+
__export(runner_exports, {
|
|
461
|
+
readStdin: () => readStdin,
|
|
462
|
+
runHookMain: () => runHookMain
|
|
463
|
+
});
|
|
464
|
+
import { appendFileSync, mkdirSync as mkdirSync2 } from "fs";
|
|
465
|
+
import { homedir as homedir5 } from "os";
|
|
466
|
+
import { join as join6 } from "path";
|
|
467
|
+
async function readStdin() {
|
|
468
|
+
const chunks = [];
|
|
469
|
+
for await (const chunk of process.stdin) {
|
|
470
|
+
chunks.push(String(chunk));
|
|
471
|
+
}
|
|
472
|
+
return chunks.join("");
|
|
473
|
+
}
|
|
474
|
+
function logHookFailure(hook, reason) {
|
|
475
|
+
try {
|
|
476
|
+
process.stderr.write(`[omp hook fail-open] ${hook}: ${reason}
|
|
477
|
+
`);
|
|
478
|
+
} catch {
|
|
479
|
+
}
|
|
480
|
+
try {
|
|
481
|
+
const logsDir = join6(homedir5(), ".omp", "logs");
|
|
482
|
+
mkdirSync2(logsDir, { recursive: true });
|
|
483
|
+
const record = JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), hook, reason });
|
|
484
|
+
appendFileSync(join6(logsDir, "hook-failures.jsonl"), record + "\n", "utf-8");
|
|
485
|
+
} catch {
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
async function runHookMain(processHook2, options = {}) {
|
|
489
|
+
let outputJson;
|
|
490
|
+
try {
|
|
491
|
+
const input = JSON.parse(await readStdin());
|
|
492
|
+
const serialized = JSON.stringify(processHook2(input));
|
|
493
|
+
if (typeof serialized !== "string") {
|
|
494
|
+
throw new Error("hook produced no serializable output");
|
|
495
|
+
}
|
|
496
|
+
outputJson = serialized;
|
|
497
|
+
} catch (err) {
|
|
498
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
499
|
+
logHookFailure(options.hookName ?? "unknown", reason);
|
|
500
|
+
const failOpen = {
|
|
501
|
+
...options.failOpenDecision ? { decision: "allow" } : {},
|
|
502
|
+
status: "error",
|
|
503
|
+
latencyMs: 0,
|
|
504
|
+
mutations: [],
|
|
505
|
+
log: [`fail-open: ${reason}`]
|
|
506
|
+
};
|
|
507
|
+
outputJson = JSON.stringify(failOpen);
|
|
508
|
+
}
|
|
509
|
+
console.log(outputJson);
|
|
510
|
+
process.exitCode = 0;
|
|
511
|
+
}
|
|
512
|
+
var init_runner = __esm({
|
|
513
|
+
"src/hooks/runner.mts"() {
|
|
514
|
+
"use strict";
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
|
|
342
518
|
// src/hooks/keyword-detector.mts
|
|
343
519
|
var keyword_detector_exports = {};
|
|
344
520
|
__export(keyword_detector_exports, {
|
|
@@ -430,17 +606,11 @@ function processHook(input) {
|
|
|
430
606
|
};
|
|
431
607
|
}
|
|
432
608
|
}
|
|
433
|
-
async function readStdin() {
|
|
434
|
-
const chunks = [];
|
|
435
|
-
for await (const chunk of process.stdin) {
|
|
436
|
-
chunks.push(chunk);
|
|
437
|
-
}
|
|
438
|
-
return chunks.join("");
|
|
439
|
-
}
|
|
440
609
|
var KEYWORD_MAP, KEYWORD_ENTRIES, CANONICAL_COMMAND_MAP;
|
|
441
610
|
var init_keyword_detector = __esm({
|
|
442
611
|
async "src/hooks/keyword-detector.mts"() {
|
|
443
612
|
"use strict";
|
|
613
|
+
init_runner();
|
|
444
614
|
KEYWORD_MAP = {
|
|
445
615
|
"autopilot:": "autopilot",
|
|
446
616
|
"/autopilot": "autopilot",
|
|
@@ -541,7 +711,26 @@ var init_keyword_detector = __esm({
|
|
|
541
711
|
"/omp:notifications": "notifications",
|
|
542
712
|
"session:": "session",
|
|
543
713
|
"/session": "session",
|
|
544
|
-
"/omp:session": "session"
|
|
714
|
+
"/omp:session": "session",
|
|
715
|
+
"verify:": "verify",
|
|
716
|
+
"/verify": "verify",
|
|
717
|
+
"/omp:verify": "verify",
|
|
718
|
+
"cancel:": "cancel",
|
|
719
|
+
"/omp:cancel": "cancel",
|
|
720
|
+
"help:": "help",
|
|
721
|
+
"/omp:help": "help",
|
|
722
|
+
"code-review:": "code-review",
|
|
723
|
+
"/code-review": "code-review",
|
|
724
|
+
"/omp:code-review": "code-review",
|
|
725
|
+
"security-review:": "security-review",
|
|
726
|
+
"/security-review": "security-review",
|
|
727
|
+
"/omp:security-review": "security-review",
|
|
728
|
+
"ultraqa:": "ultraqa",
|
|
729
|
+
"/ultraqa": "ultraqa",
|
|
730
|
+
"/omp:ultraqa": "ultraqa",
|
|
731
|
+
"ultragoal:": "ultragoal",
|
|
732
|
+
"/ultragoal": "ultragoal",
|
|
733
|
+
"/omp:ultragoal": "ultragoal"
|
|
545
734
|
};
|
|
546
735
|
KEYWORD_ENTRIES = Object.entries(KEYWORD_MAP).sort(([a], [b]) => b.length - a.length);
|
|
547
736
|
CANONICAL_COMMAND_MAP = {
|
|
@@ -550,13 +739,285 @@ var init_keyword_detector = __esm({
|
|
|
550
739
|
"mcp-setup": "/mcp"
|
|
551
740
|
};
|
|
552
741
|
if (process.argv[1]?.endsWith("keyword-detector.mjs") || process.argv[1]?.endsWith("keyword-detector.mts")) {
|
|
553
|
-
|
|
554
|
-
const output = processHook(input);
|
|
555
|
-
console.log(JSON.stringify(output));
|
|
742
|
+
await runHookMain(processHook, { failOpenDecision: true, hookName: "keyword-detector" });
|
|
556
743
|
}
|
|
557
744
|
}
|
|
558
745
|
});
|
|
559
746
|
|
|
747
|
+
// src/extension/commands.mts
|
|
748
|
+
function buildActivationInstruction(skillId, args) {
|
|
749
|
+
const trimmed = args.trim();
|
|
750
|
+
return `Activate the OMP skill "${skillId}" with args: ${trimmed.length > 0 ? trimmed : "(none)"}`;
|
|
751
|
+
}
|
|
752
|
+
function buildCommands(registry) {
|
|
753
|
+
const commands = [];
|
|
754
|
+
for (const entry of registry) {
|
|
755
|
+
commands.push({
|
|
756
|
+
name: entry.id,
|
|
757
|
+
description: entry.description,
|
|
758
|
+
handler: (args) => buildActivationInstruction(entry.id, args)
|
|
759
|
+
});
|
|
760
|
+
for (const alias of entry.aliases ?? []) {
|
|
761
|
+
commands.push({
|
|
762
|
+
name: alias,
|
|
763
|
+
description: `Alias for /${entry.id} \u2014 ${entry.description}`,
|
|
764
|
+
handler: (args) => buildActivationInstruction(entry.id, args)
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
return commands;
|
|
769
|
+
}
|
|
770
|
+
var init_commands = __esm({
|
|
771
|
+
"src/extension/commands.mts"() {
|
|
772
|
+
"use strict";
|
|
773
|
+
}
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
// src/extension/registry.mts
|
|
777
|
+
var registry_exports = {};
|
|
778
|
+
__export(registry_exports, {
|
|
779
|
+
SKILL_REGISTRY: () => SKILL_REGISTRY,
|
|
780
|
+
getCommandDefinitions: () => getCommandDefinitions
|
|
781
|
+
});
|
|
782
|
+
function getCommandDefinitions() {
|
|
783
|
+
return buildCommands(SKILL_REGISTRY);
|
|
784
|
+
}
|
|
785
|
+
var SKILL_REGISTRY;
|
|
786
|
+
var init_registry = __esm({
|
|
787
|
+
"src/extension/registry.mts"() {
|
|
788
|
+
"use strict";
|
|
789
|
+
init_commands();
|
|
790
|
+
SKILL_REGISTRY = [
|
|
791
|
+
{
|
|
792
|
+
id: "autopilot",
|
|
793
|
+
description: "Autonomous end-to-end execution from idea to working code",
|
|
794
|
+
keywords: ["autopilot:"]
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
id: "ralph",
|
|
798
|
+
description: "Persistence loop with architect verification gate",
|
|
799
|
+
keywords: ["ralph:"]
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
id: "ultrawork",
|
|
803
|
+
description: "Parallel multi-agent high-throughput implementation",
|
|
804
|
+
aliases: ["ulw"],
|
|
805
|
+
keywords: ["ulw:", "ultrawork:"]
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
id: "team",
|
|
809
|
+
description: "Coordinated N-agent team with staged pipeline",
|
|
810
|
+
keywords: ["team:"]
|
|
811
|
+
},
|
|
812
|
+
{
|
|
813
|
+
id: "ecomode",
|
|
814
|
+
description: "Cost-optimized execution with low-cost model tier",
|
|
815
|
+
aliases: ["eco"],
|
|
816
|
+
keywords: ["eco:", "ecomode:"]
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
id: "swarm",
|
|
820
|
+
description: "Parallel agent swarm for independent subtasks",
|
|
821
|
+
keywords: ["swarm:"]
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
id: "pipeline",
|
|
825
|
+
description: "Sequential stage-based execution pipeline",
|
|
826
|
+
keywords: ["pipeline:"]
|
|
827
|
+
},
|
|
828
|
+
{
|
|
829
|
+
id: "deep-interview",
|
|
830
|
+
description: "Socratic deep requirements interview with ambiguity gating",
|
|
831
|
+
aliases: ["di"],
|
|
832
|
+
keywords: ["deep interview:"]
|
|
833
|
+
},
|
|
834
|
+
{
|
|
835
|
+
id: "omp-plan",
|
|
836
|
+
description: "Strategic planning with interview, direct, consensus, and review modes",
|
|
837
|
+
aliases: ["plan"],
|
|
838
|
+
keywords: ["plan:"]
|
|
839
|
+
},
|
|
840
|
+
{
|
|
841
|
+
id: "omp-setup",
|
|
842
|
+
description: "OMP onboarding and configuration wizard",
|
|
843
|
+
keywords: ["setup:"]
|
|
844
|
+
},
|
|
845
|
+
{
|
|
846
|
+
id: "hud",
|
|
847
|
+
description: "Display current HUD session state",
|
|
848
|
+
keywords: ["hud:"]
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
id: "wiki",
|
|
852
|
+
description: "Project wiki operations and management",
|
|
853
|
+
keywords: ["wiki:"]
|
|
854
|
+
},
|
|
855
|
+
{
|
|
856
|
+
id: "learner",
|
|
857
|
+
description: "Structured learning and knowledge sessions",
|
|
858
|
+
keywords: ["learner:"]
|
|
859
|
+
},
|
|
860
|
+
{
|
|
861
|
+
id: "note",
|
|
862
|
+
description: "Session notes and context management",
|
|
863
|
+
keywords: ["note:"]
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
id: "trace",
|
|
867
|
+
description: "Execution tracing and debugging",
|
|
868
|
+
keywords: ["trace:"]
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
id: "release",
|
|
872
|
+
description: "Guided release workflow and automation",
|
|
873
|
+
keywords: ["release:"]
|
|
874
|
+
},
|
|
875
|
+
{
|
|
876
|
+
id: "configure-notifications",
|
|
877
|
+
description: "Configure session notification settings",
|
|
878
|
+
keywords: ["configure-notifications:"]
|
|
879
|
+
},
|
|
880
|
+
{
|
|
881
|
+
id: "psm",
|
|
882
|
+
description: "Plugin State Manager operations",
|
|
883
|
+
keywords: ["psm:"]
|
|
884
|
+
},
|
|
885
|
+
{
|
|
886
|
+
id: "swe-bench",
|
|
887
|
+
description: "SWE-bench evaluation harness runner",
|
|
888
|
+
keywords: ["swe-bench:"]
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
id: "mcp-setup",
|
|
892
|
+
description: "MCP server configuration wizard",
|
|
893
|
+
keywords: ["mcp:", "mcp-setup:"]
|
|
894
|
+
},
|
|
895
|
+
{
|
|
896
|
+
id: "setup",
|
|
897
|
+
description: "OMP setup and onboarding wizard"
|
|
898
|
+
},
|
|
899
|
+
{
|
|
900
|
+
id: "graphify",
|
|
901
|
+
description: "Convert any input to a knowledge graph",
|
|
902
|
+
keywords: ["graphify:"]
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
id: "graphwiki",
|
|
906
|
+
description: "GraphWiki CLI operations: query, lint, build",
|
|
907
|
+
keywords: ["graphwiki:"]
|
|
908
|
+
},
|
|
909
|
+
{
|
|
910
|
+
id: "graph-provider",
|
|
911
|
+
description: "Manage and configure the active graph provider",
|
|
912
|
+
keywords: ["graph:"]
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
id: "spending",
|
|
916
|
+
description: "Track and reset premium request usage",
|
|
917
|
+
keywords: ["spending:"]
|
|
918
|
+
},
|
|
919
|
+
{
|
|
920
|
+
id: "ralplan",
|
|
921
|
+
description: "Consensus planning gate for vague ralph/autopilot/team requests"
|
|
922
|
+
},
|
|
923
|
+
{
|
|
924
|
+
id: "research",
|
|
925
|
+
description: "Research and investigation workflows (investigate, deep dive)",
|
|
926
|
+
keywords: ["autoresearch:"]
|
|
927
|
+
},
|
|
928
|
+
{
|
|
929
|
+
id: "omp-doctor",
|
|
930
|
+
description: "Diagnose and fix oh-my-githubcopilot installation issues"
|
|
931
|
+
},
|
|
932
|
+
{
|
|
933
|
+
id: "omp-reference",
|
|
934
|
+
description: "OMP agent catalog, tools, routing, commit protocol, and skills registry"
|
|
935
|
+
},
|
|
936
|
+
{
|
|
937
|
+
id: "ai-slop-cleaner",
|
|
938
|
+
description: "Clean AI-generated code slop with a regression-safe, deletion-first workflow",
|
|
939
|
+
keywords: ["deslop", "anti-slop"]
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
id: "tdd",
|
|
943
|
+
description: "Test-Driven Development with Red-Green-Refactor cycle",
|
|
944
|
+
keywords: ["tdd:"]
|
|
945
|
+
},
|
|
946
|
+
{
|
|
947
|
+
id: "improve-codebase-architecture",
|
|
948
|
+
description: "Deep exploration and architectural improvement via friction detection"
|
|
949
|
+
},
|
|
950
|
+
{
|
|
951
|
+
id: "skillify",
|
|
952
|
+
description: "Turn a repeatable session workflow into a reusable OMP skill draft"
|
|
953
|
+
},
|
|
954
|
+
{
|
|
955
|
+
id: "interview",
|
|
956
|
+
description: "Socratic interview and ambiguity scoring",
|
|
957
|
+
keywords: ["interview:"]
|
|
958
|
+
},
|
|
959
|
+
{
|
|
960
|
+
id: "graph-context",
|
|
961
|
+
description: "Load codebase context from the knowledge graph instead of raw files"
|
|
962
|
+
},
|
|
963
|
+
{
|
|
964
|
+
id: "interactive-menu",
|
|
965
|
+
description: "Numbered-choice selection pattern for OMP's conversational TUI"
|
|
966
|
+
},
|
|
967
|
+
{
|
|
968
|
+
id: "notifications",
|
|
969
|
+
description: "Send and manage runtime notifications (Telegram, Discord, Slack, Email)",
|
|
970
|
+
keywords: ["notifications:"]
|
|
971
|
+
},
|
|
972
|
+
{
|
|
973
|
+
id: "doctor",
|
|
974
|
+
description: "Diagnose and fix common issues",
|
|
975
|
+
keywords: ["doctor:"]
|
|
976
|
+
},
|
|
977
|
+
{
|
|
978
|
+
id: "session",
|
|
979
|
+
description: "Worktree and tmux session management",
|
|
980
|
+
keywords: ["session:"]
|
|
981
|
+
},
|
|
982
|
+
{
|
|
983
|
+
id: "verify",
|
|
984
|
+
description: "Evidence-based completion check via verifier agent",
|
|
985
|
+
keywords: ["verify:"]
|
|
986
|
+
},
|
|
987
|
+
{
|
|
988
|
+
id: "cancel",
|
|
989
|
+
description: "Ends active execution modes and clears .omp/state/",
|
|
990
|
+
keywords: ["cancel:"]
|
|
991
|
+
},
|
|
992
|
+
{
|
|
993
|
+
id: "help",
|
|
994
|
+
description: "Command and skill discovery; prints the full skill catalog",
|
|
995
|
+
keywords: ["help:"]
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
id: "code-review",
|
|
999
|
+
description: "Trigger the code-reviewer agent lane for structured code review",
|
|
1000
|
+
keywords: ["code-review:"]
|
|
1001
|
+
},
|
|
1002
|
+
{
|
|
1003
|
+
id: "security-review",
|
|
1004
|
+
description: "Trigger the security-reviewer agent lane for security analysis",
|
|
1005
|
+
keywords: ["security-review:"]
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
id: "ultraqa",
|
|
1009
|
+
description: "QA cycle loop with qa-tester agent; runs until all checks pass",
|
|
1010
|
+
keywords: ["ultraqa:"]
|
|
1011
|
+
},
|
|
1012
|
+
{
|
|
1013
|
+
id: "ultragoal",
|
|
1014
|
+
description: "Durable goal ledger in .omp/ultragoal/ with fail-closed checkpoints",
|
|
1015
|
+
keywords: ["ultragoal:"]
|
|
1016
|
+
}
|
|
1017
|
+
];
|
|
1018
|
+
}
|
|
1019
|
+
});
|
|
1020
|
+
|
|
560
1021
|
// src/index.mts
|
|
561
1022
|
import { parseArgs } from "util";
|
|
562
1023
|
import { createRequire } from "module";
|
|
@@ -759,6 +1220,33 @@ async function main() {
|
|
|
759
1220
|
await runInstall2();
|
|
760
1221
|
break;
|
|
761
1222
|
}
|
|
1223
|
+
case "doctor": {
|
|
1224
|
+
const { runDoctor: runDoctor2 } = await Promise.resolve().then(() => (init_doctor(), doctor_exports));
|
|
1225
|
+
const warnings = runDoctor2(process.cwd());
|
|
1226
|
+
process.exitCode = warnings > 0 ? 1 : 0;
|
|
1227
|
+
break;
|
|
1228
|
+
}
|
|
1229
|
+
case "verify":
|
|
1230
|
+
console.log("OMP verify: use /verify or /oh-my-githubcopilot:verify in GitHub Copilot CLI to trigger @verifier evidence-based completion check.");
|
|
1231
|
+
break;
|
|
1232
|
+
case "cancel":
|
|
1233
|
+
await runCancel();
|
|
1234
|
+
break;
|
|
1235
|
+
case "help":
|
|
1236
|
+
await runHelp();
|
|
1237
|
+
break;
|
|
1238
|
+
case "code-review":
|
|
1239
|
+
console.log("OMP code-review: use /code-review or /oh-my-githubcopilot:code-review in GitHub Copilot CLI to trigger @code-reviewer agent.");
|
|
1240
|
+
break;
|
|
1241
|
+
case "security-review":
|
|
1242
|
+
console.log("OMP security-review: use /security-review or /oh-my-githubcopilot:security-review in GitHub Copilot CLI to trigger @security-reviewer agent.");
|
|
1243
|
+
break;
|
|
1244
|
+
case "ultraqa":
|
|
1245
|
+
console.log("OMP ultraqa: use /ultraqa or /oh-my-githubcopilot:ultraqa in GitHub Copilot CLI to start a QA cycle with @qa-tester agent.");
|
|
1246
|
+
break;
|
|
1247
|
+
case "ultragoal":
|
|
1248
|
+
await runUltragoal(positionals.slice(1));
|
|
1249
|
+
break;
|
|
762
1250
|
default:
|
|
763
1251
|
console.error(`Unknown subcommand: ${resolvedSubcommand}`);
|
|
764
1252
|
printUsage(true);
|
|
@@ -767,15 +1255,15 @@ async function main() {
|
|
|
767
1255
|
}
|
|
768
1256
|
function printUsage(stderr = false) {
|
|
769
1257
|
const output = stderr ? console.error : console.log;
|
|
770
|
-
output("Usage: omp [hud|install|version|psm|bench|hook] [--watch]");
|
|
1258
|
+
output("Usage: omp [hud|install|doctor|version|psm|bench|hook|verify|cancel|help|code-review|security-review|ultraqa|ultragoal] [--watch]");
|
|
771
1259
|
}
|
|
772
1260
|
async function printHud() {
|
|
773
1261
|
try {
|
|
774
|
-
const { readFileSync:
|
|
775
|
-
const { join:
|
|
776
|
-
const { homedir:
|
|
777
|
-
const hudPath =
|
|
778
|
-
const line =
|
|
1262
|
+
const { readFileSync: readFileSync4 } = await import("fs");
|
|
1263
|
+
const { join: join7 } = await import("path");
|
|
1264
|
+
const { homedir: homedir6 } = await import("os");
|
|
1265
|
+
const hudPath = join7(homedir6(), ".omp", "hud.line");
|
|
1266
|
+
const line = readFileSync4(hudPath, "utf-8").trim();
|
|
779
1267
|
console.log(line);
|
|
780
1268
|
} catch {
|
|
781
1269
|
console.log(`OMP v${PKG_VERSION} | hud: no active session`);
|
|
@@ -795,22 +1283,88 @@ async function runHook(args) {
|
|
|
795
1283
|
process.exit(1);
|
|
796
1284
|
}
|
|
797
1285
|
const { processHook: processHook2 } = await init_keyword_detector().then(() => keyword_detector_exports);
|
|
798
|
-
const
|
|
799
|
-
|
|
800
|
-
const output = processHook2(input);
|
|
801
|
-
console.log(JSON.stringify(output));
|
|
802
|
-
}
|
|
803
|
-
async function readStdin2() {
|
|
804
|
-
const chunks = [];
|
|
805
|
-
for await (const chunk of process.stdin) {
|
|
806
|
-
chunks.push(String(chunk));
|
|
807
|
-
}
|
|
808
|
-
return chunks.join("");
|
|
1286
|
+
const { runHookMain: runHookMain2 } = await Promise.resolve().then(() => (init_runner(), runner_exports));
|
|
1287
|
+
await runHookMain2(processHook2, { failOpenDecision: true, hookName: "keyword-detector" });
|
|
809
1288
|
}
|
|
810
1289
|
async function runBench(_args) {
|
|
811
1290
|
console.log("SWE-bench requires Node.js subprocess with Python evaluation harness.");
|
|
812
1291
|
console.log("Usage: /omp:swe-bench --suite lite --compare baseline");
|
|
813
1292
|
}
|
|
1293
|
+
async function runCancel() {
|
|
1294
|
+
try {
|
|
1295
|
+
const { rmSync, existsSync: existsSync2 } = await import("fs");
|
|
1296
|
+
const { join: join7 } = await import("path");
|
|
1297
|
+
const statePath = join7(process.cwd(), ".omp", "state");
|
|
1298
|
+
if (existsSync2(statePath)) {
|
|
1299
|
+
rmSync(statePath, { recursive: true, force: true });
|
|
1300
|
+
console.log("OMP: active session cancelled. .omp/state/ cleared.");
|
|
1301
|
+
} else {
|
|
1302
|
+
console.log("OMP: no active session state found. Nothing to cancel.");
|
|
1303
|
+
}
|
|
1304
|
+
} catch (err) {
|
|
1305
|
+
console.error("OMP cancel failed:", err);
|
|
1306
|
+
process.exitCode = 1;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
async function runHelp() {
|
|
1310
|
+
try {
|
|
1311
|
+
const { SKILL_REGISTRY: SKILL_REGISTRY2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
|
|
1312
|
+
console.log("OMP Skills Catalog\n");
|
|
1313
|
+
console.log(" ID Description");
|
|
1314
|
+
console.log(" " + "-".repeat(70));
|
|
1315
|
+
for (const skill of SKILL_REGISTRY2) {
|
|
1316
|
+
const id = skill.id.padEnd(30);
|
|
1317
|
+
console.log(` ${id} ${skill.description}`);
|
|
1318
|
+
}
|
|
1319
|
+
console.log(`
|
|
1320
|
+
Total: ${SKILL_REGISTRY2.length} skills`);
|
|
1321
|
+
console.log("\nUsage: /omp:<skill-id> [args]");
|
|
1322
|
+
} catch (err) {
|
|
1323
|
+
console.error("OMP help failed:", err);
|
|
1324
|
+
process.exitCode = 1;
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
async function runUltragoal(args) {
|
|
1328
|
+
try {
|
|
1329
|
+
const { mkdirSync: mkdirSync3, readFileSync: readFileSync4, writeFileSync: writeFileSync2, existsSync: existsSync2 } = await import("fs");
|
|
1330
|
+
const { join: join7 } = await import("path");
|
|
1331
|
+
const goalDir = join7(process.cwd(), ".omp", "ultragoal");
|
|
1332
|
+
const goalsPath = join7(goalDir, "goals.json");
|
|
1333
|
+
mkdirSync3(goalDir, { recursive: true });
|
|
1334
|
+
let goals = [];
|
|
1335
|
+
if (existsSync2(goalsPath)) {
|
|
1336
|
+
const parsed = JSON.parse(readFileSync4(goalsPath, "utf-8"));
|
|
1337
|
+
if (Array.isArray(parsed)) {
|
|
1338
|
+
goals = parsed;
|
|
1339
|
+
} else {
|
|
1340
|
+
console.error("OMP UltraGoal: goals.json is corrupted (not an array). Resetting to empty.");
|
|
1341
|
+
goals = [];
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
if (args.length > 0) {
|
|
1345
|
+
const nextId = goals.length === 0 ? 1 : Math.max(...goals.map((g) => g.id)) + 1;
|
|
1346
|
+
const newGoal = { id: nextId, goal: args.join(" "), status: "active", createdAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
1347
|
+
goals.push(newGoal);
|
|
1348
|
+
const tmpPath = goalsPath + ".tmp";
|
|
1349
|
+
writeFileSync2(tmpPath, JSON.stringify(goals, null, 2));
|
|
1350
|
+
const { renameSync: renameSync2 } = await import("fs");
|
|
1351
|
+
renameSync2(tmpPath, goalsPath);
|
|
1352
|
+
console.log(`OMP UltraGoal: added goal #${newGoal.id}: "${newGoal.goal}"`);
|
|
1353
|
+
} else {
|
|
1354
|
+
if (goals.length === 0) {
|
|
1355
|
+
console.log("OMP UltraGoal: no goals set. Use: omp ultragoal <goal description>");
|
|
1356
|
+
} else {
|
|
1357
|
+
console.log("OMP UltraGoal \u2014 Current Goals:\n");
|
|
1358
|
+
for (const g of goals) {
|
|
1359
|
+
console.log(` #${g.id} [${g.status}] ${g.goal}`);
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
} catch (err) {
|
|
1364
|
+
console.error("OMP ultragoal failed:", err);
|
|
1365
|
+
process.exitCode = 1;
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
814
1368
|
main().catch((err) => {
|
|
815
1369
|
console.error(err);
|
|
816
1370
|
process.exit(1);
|