@mizyoel/mercury-mesh 1.0.0 → 1.1.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/README.md +72 -0
- package/bin/mercury-mesh.cjs +224 -150
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,6 +40,78 @@
|
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
+
## Experimental Status
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
47
|
+
│ CANDIDATE DISCLOSURE │
|
|
48
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
49
|
+
│ STATUS :: EXPERIMENTAL ONLY │
|
|
50
|
+
│ CLEARANCE :: NON-PRODUCTION │
|
|
51
|
+
│ LIVE-FIRE USE :: DENIED │
|
|
52
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Before you take the chair, the bridge issues one non-negotiable disclosure:
|
|
56
|
+
|
|
57
|
+
Mercury Mesh is **experimental software operating outside a production-certified flight envelope**.
|
|
58
|
+
|
|
59
|
+
This vessel is for proving grounds, not live-fire theaters. Do not hand Mercury Mesh authority over production deployments, destructive automation, regulated systems, or any mission path where one bad vector becomes a real operational, legal, or compliance event.
|
|
60
|
+
|
|
61
|
+
Expect turbulence. Runtime structure, prompt geometry, workflow contracts, CLI behavior, and nervous-system subsystems may reform between releases without notice.
|
|
62
|
+
|
|
63
|
+
Approved theaters for this phase:
|
|
64
|
+
|
|
65
|
+
- R&D labs and internal proving grounds
|
|
66
|
+
- sandbox repositories and prototype sorties
|
|
67
|
+
- AI workflow experiments and Copilot operating-model design
|
|
68
|
+
- reversible internal tooling where failure stays inside the hull
|
|
69
|
+
|
|
70
|
+
## Commander Hiring Session
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
74
|
+
│ COMMANDER HIRING SESSION │
|
|
75
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
76
|
+
│ OPEN CHAIR :: 01 │
|
|
77
|
+
│ ROLE :: COMMANDER, MERCURY MESH │
|
|
78
|
+
│ MISSION :: DEFINE TRAJECTORY. GOVERN DRIFT. AUTHORIZE THRUST. │
|
|
79
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The bridge is not hiring for prompt operators. It is hiring for Commanders.
|
|
83
|
+
|
|
84
|
+
If you are looking to shape how AI-assisted engineering behaves inside a repository, proceed. If you only want code generation on demand, the chair will reject you.
|
|
85
|
+
|
|
86
|
+
### Minimum Flight Qualifications
|
|
87
|
+
|
|
88
|
+
You are a strong candidate if you can answer yes to most of the following:
|
|
89
|
+
|
|
90
|
+
- You want to define Wing roles, routing rules, authority boundaries, and escalation gates.
|
|
91
|
+
- You care about telemetry, memory, review rituals, and course correction, not just raw output.
|
|
92
|
+
- You are running parallel workstreams where shared context and worktree isolation create leverage.
|
|
93
|
+
- You are designing a reusable Copilot operating doctrine for yourself, your team, or a fleet of repos.
|
|
94
|
+
- You want a bridge that governs how AI participates in triage, migration, review, and execution loops.
|
|
95
|
+
|
|
96
|
+
### Immediate Disqualifiers
|
|
97
|
+
|
|
98
|
+
You are not the right hire for this chair if your mission is any of the following:
|
|
99
|
+
|
|
100
|
+
- Ship a small app fast with minimal setup and minimal ceremony.
|
|
101
|
+
- Install a lightweight prompt pack without orchestration or authority controls.
|
|
102
|
+
- Depend on strict backward compatibility and production-grade workflow guarantees today.
|
|
103
|
+
- Hand automation a live production path where uptime, security, or compliance failures are unacceptable.
|
|
104
|
+
|
|
105
|
+
### Interview Question
|
|
106
|
+
|
|
107
|
+
Ask yourself one question before boarding:
|
|
108
|
+
|
|
109
|
+
**Do I need a bridge, or do I only need a tool?**
|
|
110
|
+
|
|
111
|
+
If you need a bridge, Mercury Mesh is worth the hiring cycle. If you only need a tool, do not put a Commander in the chair just to write a small app.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
43
115
|
## Installation
|
|
44
116
|
|
|
45
117
|
```text
|
package/bin/mercury-mesh.cjs
CHANGED
|
@@ -8,6 +8,68 @@ const { execFileSync, spawn } = require("node:child_process");
|
|
|
8
8
|
const PACKAGE_ROOT = path.resolve(__dirname, "..");
|
|
9
9
|
const VERSION = require(path.join(PACKAGE_ROOT, "package.json")).version;
|
|
10
10
|
|
|
11
|
+
// ─── Terminal styling ──────────────────────────────────────────────────
|
|
12
|
+
// Zero-dependency ANSI color system. Degrades to plain text in pipes / NO_COLOR.
|
|
13
|
+
|
|
14
|
+
const isTTY = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
15
|
+
const esc = (code, s) => isTTY ? `\x1b[${code}m${s}\x1b[0m` : s;
|
|
16
|
+
|
|
17
|
+
const style = {
|
|
18
|
+
bold: (s) => esc("1", s),
|
|
19
|
+
dim: (s) => esc("2", s),
|
|
20
|
+
cyan: (s) => esc("36", s),
|
|
21
|
+
green: (s) => esc("32", s),
|
|
22
|
+
red: (s) => esc("31", s),
|
|
23
|
+
yellow: (s) => esc("33", s),
|
|
24
|
+
magenta: (s) => esc("35", s),
|
|
25
|
+
|
|
26
|
+
// composites
|
|
27
|
+
boldCyan: (s) => esc("1;36", s),
|
|
28
|
+
boldGreen: (s) => esc("1;32", s),
|
|
29
|
+
boldRed: (s) => esc("1;31", s),
|
|
30
|
+
boldYellow: (s) => esc("1;33", s),
|
|
31
|
+
dimCyan: (s) => esc("2;36", s),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Gradient across a string using 256-color ANSI (blue→cyan: 33→51)
|
|
35
|
+
function gradient(text, from = 33, to = 51) {
|
|
36
|
+
if (!isTTY) return text;
|
|
37
|
+
return [...text].map((ch, i) => {
|
|
38
|
+
if (ch === " ") return ch;
|
|
39
|
+
const code = Math.round(from + (to - from) * (i / Math.max(text.length - 1, 1)));
|
|
40
|
+
return `\x1b[38;5;${code}m${ch}`;
|
|
41
|
+
}).join("") + "\x1b[0m";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Strip ANSI escape codes for width calculation
|
|
45
|
+
function stripAnsi(s) {
|
|
46
|
+
return s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Spinner for async-feeling operations (call stop() when done)
|
|
50
|
+
function createSpinner(msg) {
|
|
51
|
+
if (!isTTY) {
|
|
52
|
+
// Pipe mode: just print the message, return a no-op stop
|
|
53
|
+
return {
|
|
54
|
+
stop(symbol, color) {
|
|
55
|
+
const prefix = symbol === "✓" ? "✓" : symbol === "✗" ? "✗" : symbol || "→";
|
|
56
|
+
console.log(` ${prefix} ${msg}`);
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const frames = ["◜", "◠", "◝", "◞", "◡", "◟"];
|
|
61
|
+
let i = 0;
|
|
62
|
+
const id = setInterval(() => {
|
|
63
|
+
process.stdout.write(`\r ${style.cyan(frames[i++ % frames.length])} ${msg} `);
|
|
64
|
+
}, 80);
|
|
65
|
+
return {
|
|
66
|
+
stop(symbol = "✓", colorFn = style.green) {
|
|
67
|
+
clearInterval(id);
|
|
68
|
+
process.stdout.write(`\r ${colorFn(symbol)} ${msg} \n`);
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
11
73
|
// ─── Asset manifest ────────────────────────────────────────────────────
|
|
12
74
|
// Each entry: { src (relative to package root), dest (relative to target project root), type }
|
|
13
75
|
// type: "file" = single file, "dir" = recursive directory copy
|
|
@@ -87,9 +149,11 @@ function log(msg) {
|
|
|
87
149
|
}
|
|
88
150
|
|
|
89
151
|
function heading(msg) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
console.log(
|
|
152
|
+
const cols = Math.min(process.stdout.columns || 60, 80);
|
|
153
|
+
const rule = style.dimCyan("─".repeat(cols));
|
|
154
|
+
console.log(`\n${rule}`);
|
|
155
|
+
console.log(` ${gradient(msg)}`);
|
|
156
|
+
console.log(`${rule}`);
|
|
93
157
|
}
|
|
94
158
|
|
|
95
159
|
function ensureDir(dirPath) {
|
|
@@ -100,12 +164,12 @@ function ensureDir(dirPath) {
|
|
|
100
164
|
|
|
101
165
|
function copyFileIfMissing(src, dest, { force = false } = {}) {
|
|
102
166
|
if (fs.existsSync(dest) && !force) {
|
|
103
|
-
log(
|
|
167
|
+
log(`${style.dim("skip")} ${style.dim(dest)} ${style.dim("(already exists)")}`);
|
|
104
168
|
return false;
|
|
105
169
|
}
|
|
106
170
|
ensureDir(path.dirname(dest));
|
|
107
171
|
fs.copyFileSync(src, dest);
|
|
108
|
-
log(
|
|
172
|
+
log(`${style.green("write")} ${style.dim(dest)}`);
|
|
109
173
|
return true;
|
|
110
174
|
}
|
|
111
175
|
|
|
@@ -136,19 +200,19 @@ function patchGitignore(targetRoot) {
|
|
|
136
200
|
);
|
|
137
201
|
|
|
138
202
|
if (missing.length === 0) {
|
|
139
|
-
log("skip .gitignore (entries already present)");
|
|
203
|
+
log(`${style.dim("skip")} ${style.dim(".gitignore")} ${style.dim("(entries already present)")}`);
|
|
140
204
|
return;
|
|
141
205
|
}
|
|
142
206
|
|
|
143
207
|
const block = "\n" + GITIGNORE_LINES.join("\n") + "\n";
|
|
144
208
|
fs.writeFileSync(gitignorePath, content.trimEnd() + "\n" + block, "utf-8");
|
|
145
|
-
log("patch .gitignore (added mesh runtime ignores)");
|
|
209
|
+
log(`${style.green("patch")} ${style.dim(".gitignore")} ${style.dim("(added mesh runtime ignores)")}`);
|
|
146
210
|
}
|
|
147
211
|
|
|
148
212
|
function writeDefaultConfig(targetRoot) {
|
|
149
213
|
const configPath = path.join(targetRoot, ".mesh", "config.json");
|
|
150
214
|
if (fs.existsSync(configPath)) {
|
|
151
|
-
log("skip .mesh/config.json (already exists)");
|
|
215
|
+
log(`${style.dim("skip")} ${style.dim(".mesh/config.json")} ${style.dim("(already exists)")}`);
|
|
152
216
|
return;
|
|
153
217
|
}
|
|
154
218
|
ensureDir(path.dirname(configPath));
|
|
@@ -173,7 +237,7 @@ function writeDefaultConfig(targetRoot) {
|
|
|
173
237
|
},
|
|
174
238
|
};
|
|
175
239
|
fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2) + "\n", "utf-8");
|
|
176
|
-
log("write .mesh/config.json (default — nervous system off)");
|
|
240
|
+
log(`${style.green("write")} ${style.dim(".mesh/config.json")} ${style.dim("(default — nervous system off)")}`);
|
|
177
241
|
}
|
|
178
242
|
|
|
179
243
|
function stampVersion(targetRoot) {
|
|
@@ -191,7 +255,7 @@ function stampVersion(targetRoot) {
|
|
|
191
255
|
);
|
|
192
256
|
if (stamped !== content) {
|
|
193
257
|
fs.writeFileSync(agentFile, stamped, "utf-8");
|
|
194
|
-
log(
|
|
258
|
+
log(`${style.cyan("stamp")} ${style.dim(".github/agents/mercury-mesh.agent.md")} ${style.cyan("→")} ${style.bold(`v${VERSION}`)}`);
|
|
195
259
|
}
|
|
196
260
|
}
|
|
197
261
|
|
|
@@ -208,7 +272,7 @@ function runInit(targetRoot, flags) {
|
|
|
208
272
|
const dest = path.join(targetRoot, entry.dest);
|
|
209
273
|
|
|
210
274
|
if (!fs.existsSync(src)) {
|
|
211
|
-
log(
|
|
275
|
+
log(`${style.yellow("warn")} ${style.dim(entry.src)} ${style.yellow("(source missing in package — skipping)")}`);
|
|
212
276
|
continue;
|
|
213
277
|
}
|
|
214
278
|
|
|
@@ -224,13 +288,13 @@ function runInit(targetRoot, flags) {
|
|
|
224
288
|
stampVersion(targetRoot);
|
|
225
289
|
|
|
226
290
|
heading("Init complete");
|
|
227
|
-
log(`${filesWritten} file(s) written.`);
|
|
228
|
-
log("Existing files were preserved (use --force to overwrite)
|
|
229
|
-
log("Next steps:");
|
|
230
|
-
log("
|
|
231
|
-
log("
|
|
232
|
-
log(
|
|
233
|
-
log("
|
|
291
|
+
log(`${style.boldGreen(String(filesWritten))} file(s) written.`);
|
|
292
|
+
log(`${style.dim("Existing files were preserved (use --force to overwrite).")}\n`);
|
|
293
|
+
log(style.bold("Next steps:"));
|
|
294
|
+
log(` ${style.cyan("1.")} Open VS Code in this project`);
|
|
295
|
+
log(` ${style.cyan("2.")} Add your OpenRouter key to .mesh/local.json if you want semantic routing`);
|
|
296
|
+
log(` ${style.cyan("3.")} Chat with @mercury-mesh — say ${style.bold('"declare the mission"')}`);
|
|
297
|
+
log(` ${style.cyan("4.")} The bridge will cast your crew and scaffold team.md\n`);
|
|
234
298
|
}
|
|
235
299
|
|
|
236
300
|
function runUpdate(targetRoot) {
|
|
@@ -257,7 +321,7 @@ function runUpdate(targetRoot) {
|
|
|
257
321
|
} else {
|
|
258
322
|
ensureDir(path.dirname(dest));
|
|
259
323
|
fs.copyFileSync(src, dest);
|
|
260
|
-
log(
|
|
324
|
+
log(`${style.green("write")} ${style.dim(dest)}`);
|
|
261
325
|
filesWritten++;
|
|
262
326
|
}
|
|
263
327
|
}
|
|
@@ -265,7 +329,7 @@ function runUpdate(targetRoot) {
|
|
|
265
329
|
stampVersion(targetRoot);
|
|
266
330
|
|
|
267
331
|
heading("Update complete");
|
|
268
|
-
log(`${filesWritten} file(s) updated (agent prompt + skills + instructions).\n`);
|
|
332
|
+
log(`${style.boldGreen(String(filesWritten))} file(s) updated (agent prompt + skills + instructions).\n`);
|
|
269
333
|
}
|
|
270
334
|
|
|
271
335
|
function resolveGitHubCliToken() {
|
|
@@ -339,19 +403,19 @@ function runDoctor(targetRoot) {
|
|
|
339
403
|
|
|
340
404
|
function pass(msg) {
|
|
341
405
|
results.pass++;
|
|
342
|
-
log(` ✓ ${msg}`);
|
|
406
|
+
log(` ${style.green("✓")} ${msg}`);
|
|
343
407
|
}
|
|
344
408
|
function warn(msg) {
|
|
345
409
|
results.warn++;
|
|
346
|
-
log(` ⚠ ${msg}`);
|
|
410
|
+
log(` ${style.yellow("⚠")} ${style.yellow(msg)}`);
|
|
347
411
|
}
|
|
348
412
|
function fail(msg) {
|
|
349
413
|
results.fail++;
|
|
350
|
-
log(` ✗ ${msg}`);
|
|
414
|
+
log(` ${style.red("✗")} ${style.red(msg)}`);
|
|
351
415
|
}
|
|
352
416
|
|
|
353
417
|
// ── 1. Structure ──────────────────────────────────────────────────
|
|
354
|
-
log("Structure\n");
|
|
418
|
+
log(style.bold("Structure") + "\n");
|
|
355
419
|
|
|
356
420
|
for (const [rel, label, required] of DOCTOR_CHECKS.structure) {
|
|
357
421
|
const full = path.join(targetRoot, rel);
|
|
@@ -365,7 +429,7 @@ function runDoctor(targetRoot) {
|
|
|
365
429
|
}
|
|
366
430
|
|
|
367
431
|
// ── 2. Config schema ──────────────────────────────────────────────
|
|
368
|
-
log("\
|
|
432
|
+
log("\n" + style.bold("Config") + "\n");
|
|
369
433
|
|
|
370
434
|
const configPath = path.join(targetRoot, ".mesh", "config.json");
|
|
371
435
|
let config = null;
|
|
@@ -414,7 +478,7 @@ function runDoctor(targetRoot) {
|
|
|
414
478
|
}
|
|
415
479
|
|
|
416
480
|
// ── 3. Agent prompt version stamp ─────────────────────────────────
|
|
417
|
-
log("\
|
|
481
|
+
log("\n" + style.bold("Agent Prompt") + "\n");
|
|
418
482
|
|
|
419
483
|
const agentPath = path.join(
|
|
420
484
|
targetRoot,
|
|
@@ -439,7 +503,7 @@ function runDoctor(targetRoot) {
|
|
|
439
503
|
}
|
|
440
504
|
|
|
441
505
|
// ── 4. Skills sync check ──────────────────────────────────────────
|
|
442
|
-
log("\
|
|
506
|
+
log("\n" + style.bold("Skills") + "\n");
|
|
443
507
|
|
|
444
508
|
const liveSkillsDir = path.join(targetRoot, ".copilot", "skills");
|
|
445
509
|
const templateSkillsDir = path.join(PACKAGE_ROOT, ".mesh", "templates", "skills");
|
|
@@ -475,7 +539,7 @@ function runDoctor(targetRoot) {
|
|
|
475
539
|
}
|
|
476
540
|
|
|
477
541
|
// ── 5. Nervous system ─────────────────────────────────────────────
|
|
478
|
-
log("\
|
|
542
|
+
log("\n" + style.bold("Nervous System") + "\n");
|
|
479
543
|
|
|
480
544
|
if (config && config.nervousSystem) {
|
|
481
545
|
const ns = config.nervousSystem;
|
|
@@ -536,7 +600,7 @@ function runDoctor(targetRoot) {
|
|
|
536
600
|
}
|
|
537
601
|
|
|
538
602
|
// ── 6. Gitignore ──────────────────────────────────────────────────
|
|
539
|
-
log("\
|
|
603
|
+
log("\n" + style.bold("Gitignore") + "\n");
|
|
540
604
|
|
|
541
605
|
const gitignorePath = path.join(targetRoot, ".gitignore");
|
|
542
606
|
if (fs.existsSync(gitignorePath)) {
|
|
@@ -560,16 +624,16 @@ function runDoctor(targetRoot) {
|
|
|
560
624
|
heading("Diagnosis");
|
|
561
625
|
|
|
562
626
|
const total = results.pass + results.warn + results.fail;
|
|
563
|
-
log(`${results.pass}/${total} passed · ${results.warn} warning(s) · ${results.fail} failure(s)\n`);
|
|
627
|
+
log(`${style.green(String(results.pass))}/${total} passed · ${style.yellow(String(results.warn))} warning(s) · ${style.red(String(results.fail))} failure(s)\n`);
|
|
564
628
|
|
|
565
629
|
if (results.fail > 0) {
|
|
566
|
-
log("HULL BREACH — resolve failures above before flight
|
|
630
|
+
log(style.boldRed("HULL BREACH — resolve failures above before flight.") + "\n");
|
|
567
631
|
return 1;
|
|
568
632
|
} else if (results.warn > 0) {
|
|
569
|
-
log("HULL INTACT — minor drift detected. Review warnings
|
|
633
|
+
log(style.boldYellow("HULL INTACT — minor drift detected. Review warnings.") + "\n");
|
|
570
634
|
return 0;
|
|
571
635
|
} else {
|
|
572
|
-
log("ALL SYSTEMS NOMINAL — ready for sortie
|
|
636
|
+
log(style.boldGreen("ALL SYSTEMS NOMINAL — ready for sortie.") + "\n");
|
|
573
637
|
return 0;
|
|
574
638
|
}
|
|
575
639
|
}
|
|
@@ -741,74 +805,83 @@ function runStatus(targetRoot) {
|
|
|
741
805
|
}
|
|
742
806
|
|
|
743
807
|
// Render
|
|
808
|
+
const cols = Math.min(process.stdout.columns || 79, 79);
|
|
809
|
+
const bdr = (ch) => style.dimCyan(ch);
|
|
810
|
+
const lbl = (s) => style.bold(s);
|
|
811
|
+
const topBorder = bdr("┌") + bdr("─".repeat(77)) + bdr("┐");
|
|
812
|
+
const midBorder = bdr("├") + bdr("─".repeat(77)) + bdr("┤");
|
|
813
|
+
const bottomBorder = bdr("└") + bdr("─".repeat(77)) + bdr("┘");
|
|
814
|
+
const row = (content) => `${bdr("│")} ${content}${" ".repeat(Math.max(0, 75 - stripAnsi(content).length))}${bdr("│")}`;
|
|
815
|
+
const blank = row("");
|
|
816
|
+
|
|
744
817
|
console.log(`
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
const halted = config.halted ? "YES ■ ALL STOP" : "NO";
|
|
752
|
-
const orgMode = config.orgMode ? "ENABLED" : "DISABLED";
|
|
818
|
+
${topBorder}`);
|
|
819
|
+
console.log(row(gradient(`MERCURY MESH v${VERSION}`) + " — " + style.bold("BRIDGE TELEMETRY")));
|
|
820
|
+
console.log(midBorder);
|
|
821
|
+
console.log(blank);
|
|
822
|
+
console.log(row(lbl("SYSTEM STATE")));;
|
|
823
|
+
|
|
824
|
+
const halted = config.halted ? style.boldRed("YES ■ ALL STOP") : style.green("NO");
|
|
825
|
+
const orgMode = config.orgMode ? style.green("ENABLED") : style.dim("DISABLED");
|
|
753
826
|
const haltBar = config.halted
|
|
754
|
-
? "
|
|
755
|
-
: "
|
|
827
|
+
? style.red("░".repeat(20)) + " " + style.boldRed("HALTED")
|
|
828
|
+
: style.green("█".repeat(20)) + " " + style.boldGreen("ONLINE");
|
|
756
829
|
|
|
757
|
-
console.log(
|
|
758
|
-
console.log(
|
|
759
|
-
console.log(
|
|
760
|
-
console.log(
|
|
761
|
-
console.log(
|
|
830
|
+
console.log(row(` ${style.dim("Halted")} ${halted}`));
|
|
831
|
+
console.log(row(` ${style.dim("Org Mode")} ${orgMode}`));
|
|
832
|
+
console.log(row(` ${style.dim("Bridge Status")} ${haltBar}`));
|
|
833
|
+
console.log(row(` ${style.dim("Agent Prompt")} ${agentVersion ? `v${agentVersion}${agentVersion !== VERSION ? style.yellow(` (package: v${VERSION})`) : style.green(" ✓")}` : style.red("not found")}`));
|
|
834
|
+
console.log(row(` ${style.dim("Default Model")} ${(config.modelRouting && config.modelRouting.default) || "—"}`));
|
|
762
835
|
|
|
763
|
-
console.log(
|
|
764
|
-
console.log(
|
|
836
|
+
console.log(blank);
|
|
837
|
+
console.log(row(lbl("CREW")));
|
|
765
838
|
|
|
766
839
|
if (members && members.length > 0) {
|
|
767
|
-
console.log(
|
|
768
|
-
console.log(
|
|
769
|
-
console.log(
|
|
770
|
-
console.log(
|
|
840
|
+
console.log(row(` ${style.dim("Roster")} ${members.length} Wing(s)`));
|
|
841
|
+
console.log(row(` ${style.dim("Active")} ${style.green(String(statusCounts.active))}`));
|
|
842
|
+
console.log(row(` ${style.dim("Probation")} ${style.yellow(String(statusCounts.probation))}`));
|
|
843
|
+
console.log(row(` ${style.dim("Shadow")} ${style.dim(String(statusCounts.shadow))}`));
|
|
771
844
|
} else {
|
|
772
|
-
console.log(
|
|
845
|
+
console.log(row(` ${style.dim("Roster")} ${style.yellow("EMPTY — bridge unclaimed")}`));
|
|
773
846
|
}
|
|
774
847
|
|
|
775
|
-
console.log(
|
|
776
|
-
console.log(
|
|
777
|
-
console.log(
|
|
778
|
-
console.log(
|
|
779
|
-
console.log(
|
|
848
|
+
console.log(blank);
|
|
849
|
+
console.log(row(lbl("ORGANIZATION")));
|
|
850
|
+
console.log(row(` ${style.dim("Departments")} ${String(activeDepts.length)}`));
|
|
851
|
+
console.log(row(` ${style.dim("Ghost Wings")} ${String(ghostDepts.length)}${ns.ghostWings && ns.ghostWings.autoMaterialize ? style.green(" (auto-materialize)") : style.dim(" (manual approval)")}`));
|
|
852
|
+
console.log(row(` ${style.dim("Decisions")} ${inboxCount > 0 ? style.yellow(`${inboxCount} pending in inbox`) : style.dim("inbox clear")}`));
|
|
780
853
|
|
|
781
|
-
console.log(
|
|
782
|
-
console.log(
|
|
854
|
+
console.log(blank);
|
|
855
|
+
console.log(row(lbl("NERVOUS SYSTEM")));
|
|
783
856
|
|
|
784
857
|
if (ns.enabled) {
|
|
785
858
|
const provider = ns.embeddingProvider || "tfidf";
|
|
786
859
|
const hasKey = !!(ns.embeddingApiKey || process.env.OPENROUTER_API_KEY || process.env.OPENAI_API_KEY);
|
|
787
|
-
const keyStatus = provider === "tfidf" ? "—" : hasKey ? "configured" : "MISSING";
|
|
860
|
+
const keyStatus = provider === "tfidf" ? "—" : hasKey ? style.green("configured") : style.boldRed("MISSING");
|
|
788
861
|
|
|
789
|
-
console.log(
|
|
790
|
-
console.log(
|
|
791
|
-
console.log(
|
|
792
|
-
console.log(
|
|
862
|
+
console.log(row(` ${style.dim("Status")} ${style.boldGreen("ONLINE")}`));
|
|
863
|
+
console.log(row(` ${style.dim("Phase I")} ${style.cyan("Gravimetry")} :: ${provider}${provider !== "tfidf" ? ` (key: ${keyStatus})` : ""}`));
|
|
864
|
+
console.log(row(` ${style.dim("Phase II")} ${style.cyan("Autonomic Core")} :: pulse ${(ns.autonomic && ns.autonomic.pulseMs) || 30000}ms`));
|
|
865
|
+
console.log(row(` ${style.dim("Phase III")} ${style.cyan("Ghost Wings")} :: ${ns.ghostWings && ns.ghostWings.enabled ? style.green("armed") : style.dim("disabled")}`));
|
|
793
866
|
const constellationLabel = entryCount === "lancedb"
|
|
794
|
-
?
|
|
795
|
-
:
|
|
796
|
-
console.log(
|
|
867
|
+
? `${style.cyan("Constellation")} :: lancedb (indexed)`
|
|
868
|
+
: `${style.cyan("Constellation")} :: ${entryCount} embedding(s)${manifest && manifest.dimensions ? ` (${manifest.dimensions}D)` : ""}${constellationProvider !== "json" ? ` [${constellationProvider}]` : ""}`;
|
|
869
|
+
console.log(row(` ${style.dim("Phase IV")} ${constellationLabel}`));
|
|
797
870
|
} else {
|
|
798
|
-
console.log(
|
|
871
|
+
console.log(row(` ${style.dim("Status")} ${style.dim("OFFLINE")}`));
|
|
799
872
|
}
|
|
800
873
|
|
|
801
|
-
console.log(
|
|
802
|
-
console.log(
|
|
803
|
-
console.log(
|
|
874
|
+
console.log(blank);
|
|
875
|
+
console.log(row(lbl("SESSIONS")));
|
|
876
|
+
console.log(row(` ${style.dim("Total")} ${String(sessionCount)}`));
|
|
804
877
|
|
|
805
878
|
if (lastSession) {
|
|
806
|
-
console.log(
|
|
807
|
-
console.log(
|
|
879
|
+
console.log(row(` ${style.dim("Last Active")} ${lastSession.lastActiveAt || lastSession.createdAt || "—"}`));
|
|
880
|
+
console.log(row(` ${style.dim("Messages")} ${String(lastSession.messageCount)}`));
|
|
808
881
|
}
|
|
809
882
|
|
|
810
|
-
console.log(
|
|
811
|
-
console.log(
|
|
883
|
+
console.log(blank);
|
|
884
|
+
console.log(bottomBorder);
|
|
812
885
|
console.log();
|
|
813
886
|
|
|
814
887
|
return 0;
|
|
@@ -951,7 +1024,7 @@ function runResume(targetRoot, args) {
|
|
|
951
1024
|
}
|
|
952
1025
|
|
|
953
1026
|
// ── 3. Last conversation context ──────────────────────────────────
|
|
954
|
-
log("\
|
|
1027
|
+
log("\n" + style.bold("LAST ACTIVITY") + "\n");
|
|
955
1028
|
|
|
956
1029
|
const summary = summarizeMessages(session.messages, 4);
|
|
957
1030
|
if (summary.length > 0) {
|
|
@@ -963,7 +1036,7 @@ function runResume(targetRoot, args) {
|
|
|
963
1036
|
}
|
|
964
1037
|
|
|
965
1038
|
// ── 4. Pending work ───────────────────────────────────────────────
|
|
966
|
-
log("\
|
|
1039
|
+
log("\n" + style.bold("PENDING WORK") + "\n");
|
|
967
1040
|
|
|
968
1041
|
const inboxCount = countDirEntries(path.join(meshDir, "decisions", "inbox"));
|
|
969
1042
|
log(` Decision inbox ${inboxCount > 0 ? `${inboxCount} pending` : "clear"}`);
|
|
@@ -991,7 +1064,7 @@ function runResume(targetRoot, args) {
|
|
|
991
1064
|
}
|
|
992
1065
|
|
|
993
1066
|
// ── 5. Git state ──────────────────────────────────────────────────
|
|
994
|
-
log("\
|
|
1067
|
+
log("\n" + style.bold("GIT STATE") + "\n");
|
|
995
1068
|
|
|
996
1069
|
const git = detectGitState(targetRoot);
|
|
997
1070
|
if (git) {
|
|
@@ -1010,7 +1083,7 @@ function runResume(targetRoot, args) {
|
|
|
1010
1083
|
// ── 6. Recovery prompt ────────────────────────────────────────────
|
|
1011
1084
|
const hasWork = inboxCount > 0 || activeClaims > 0 || (git && git.changedFiles > 0);
|
|
1012
1085
|
|
|
1013
|
-
log("\
|
|
1086
|
+
log("\n" + style.bold("RECOVERY BRIEFING") + "\n");
|
|
1014
1087
|
|
|
1015
1088
|
if (hasWork) {
|
|
1016
1089
|
log(" Unfinished work detected. Paste this into your next Copilot session:\n");
|
|
@@ -1097,12 +1170,12 @@ function runWorktree(targetRoot, wtArgs) {
|
|
|
1097
1170
|
if (worktrees.length === 0) {
|
|
1098
1171
|
log(" (no worktrees found)");
|
|
1099
1172
|
} else {
|
|
1100
|
-
log("
|
|
1101
|
-
log(" " + "\u2500".repeat(70));
|
|
1173
|
+
log(` ${style.dim("BRANCH")} ${style.dim("PATH")}`);
|
|
1174
|
+
log(" " + style.dimCyan("\u2500".repeat(70)));
|
|
1102
1175
|
for (const wt of worktrees) {
|
|
1103
1176
|
const branch = wt.branch || "(detached)";
|
|
1104
|
-
const isMesh = branch.startsWith("mesh/") ? " [mesh]" : "";
|
|
1105
|
-
log(` ${pad(branch + isMesh
|
|
1177
|
+
const isMesh = branch.startsWith("mesh/") ? style.cyan(" [mesh]") : "";
|
|
1178
|
+
log(` ${pad(branch, 38)}${isMesh ? style.bold(branch) + isMesh : branch} ${style.dim(wt.path)}`);
|
|
1106
1179
|
}
|
|
1107
1180
|
}
|
|
1108
1181
|
|
|
@@ -1118,7 +1191,7 @@ function runWorktree(targetRoot, wtArgs) {
|
|
|
1118
1191
|
|
|
1119
1192
|
const { orphanedWorktrees, staleGhosts, healthy } = wm.reconcileWorktrees(repoRoot, meshDir);
|
|
1120
1193
|
|
|
1121
|
-
log("WORKTREE HEALTH\n");
|
|
1194
|
+
log(style.bold("WORKTREE HEALTH") + "\n");
|
|
1122
1195
|
log(` Healthy ${healthy.length}`);
|
|
1123
1196
|
log(` Orphaned worktrees ${orphanedWorktrees.length}`);
|
|
1124
1197
|
log(` Stale ghosts ${staleGhosts.length}`);
|
|
@@ -1215,7 +1288,7 @@ function runCoalescence(targetRoot, cArgs) {
|
|
|
1215
1288
|
if (sub === "scan") {
|
|
1216
1289
|
const report = gc.reconcile(meshDir, { apply: false });
|
|
1217
1290
|
|
|
1218
|
-
log(`GHOST WING OVERLAP SCAN\n
|
|
1291
|
+
log(style.bold(`GHOST WING OVERLAP SCAN`) + "\n");
|
|
1219
1292
|
log(` Active ghosts ${report.ghostCount}`);
|
|
1220
1293
|
log(` Overlaps found ${report.overlapCount}`);
|
|
1221
1294
|
log(` Auto-coalescible ${report.autoCoalesce}`);
|
|
@@ -1225,9 +1298,9 @@ function runCoalescence(targetRoot, cArgs) {
|
|
|
1225
1298
|
log("\n OVERLAPPING PAIRS:");
|
|
1226
1299
|
log(" " + "\u2500".repeat(70));
|
|
1227
1300
|
for (const o of report.overlaps) {
|
|
1228
|
-
const risk = o.score >= gc.COALESCENCE_AUTO_THRESHOLD ? "HIGH" : "MODERATE";
|
|
1229
|
-
log(` [${risk}] ${pad(o.wingAName || o.wingA, 20)} \u2194 ${pad(o.wingBName || o.wingB, 20)} score: ${o.score}`);
|
|
1230
|
-
log(` domain: ${o.signals.domain} keywords: ${o.signals.keywords} files: ${o.signals.files} attractors: ${o.signals.attractors}`);
|
|
1301
|
+
const risk = o.score >= gc.COALESCENCE_AUTO_THRESHOLD ? style.boldRed("HIGH") : style.yellow("MODERATE");
|
|
1302
|
+
log(` [${risk}] ${pad(o.wingAName || o.wingA, 20)} \u2194 ${pad(o.wingBName || o.wingB, 20)} score: ${style.bold(String(o.score))}`);
|
|
1303
|
+
log(` ${style.dim(`domain: ${o.signals.domain} keywords: ${o.signals.keywords} files: ${o.signals.files} attractors: ${o.signals.attractors}`)}`);
|
|
1231
1304
|
}
|
|
1232
1305
|
}
|
|
1233
1306
|
|
|
@@ -1244,7 +1317,7 @@ function runCoalescence(targetRoot, cArgs) {
|
|
|
1244
1317
|
if (sub === "apply") {
|
|
1245
1318
|
const report = gc.reconcile(meshDir, { apply: true });
|
|
1246
1319
|
|
|
1247
|
-
log(`COALESCENCE APPLIED\n
|
|
1320
|
+
log(style.bold(`COALESCENCE APPLIED`) + "\n");
|
|
1248
1321
|
log(` Coalesced pairs ${report.coalesced.length}`);
|
|
1249
1322
|
|
|
1250
1323
|
if (report.coalesced.length > 0) {
|
|
@@ -1298,7 +1371,7 @@ function runPeers(targetRoot, pArgs) {
|
|
|
1298
1371
|
if (sub === "list") {
|
|
1299
1372
|
const { peers, healthy, stale, halted, localId } = mp.classifyPeers(meshDir);
|
|
1300
1373
|
|
|
1301
|
-
log(
|
|
1374
|
+
log(style.bold("PEER REGISTRY") + "\n");
|
|
1302
1375
|
log(` Total peers ${peers.length}`);
|
|
1303
1376
|
log(` Healthy ${healthy.length}`);
|
|
1304
1377
|
log(` Stale ${stale.length}`);
|
|
@@ -1306,14 +1379,14 @@ function runPeers(targetRoot, pArgs) {
|
|
|
1306
1379
|
log(` Local node ${localId}`);
|
|
1307
1380
|
|
|
1308
1381
|
if (peers.length > 0) {
|
|
1309
|
-
log(
|
|
1310
|
-
log(" " + "\u2500".repeat(70));
|
|
1382
|
+
log(`\n ${style.dim("NODE ID")} ${style.dim("ALIAS")} ${style.dim("STATUS")} ${style.dim("LAST HEARTBEAT")}`);
|
|
1383
|
+
log(" " + style.dimCyan("\u2500".repeat(70)));
|
|
1311
1384
|
for (const p of peers) {
|
|
1312
1385
|
const status = p.halted
|
|
1313
|
-
? "HALTED"
|
|
1386
|
+
? style.red("HALTED")
|
|
1314
1387
|
: p._staleMinutes
|
|
1315
|
-
? `STALE (${p._staleMinutes}m)`
|
|
1316
|
-
: "HEALTHY";
|
|
1388
|
+
? style.yellow(`STALE (${p._staleMinutes}m)`)
|
|
1389
|
+
: style.green("HEALTHY");
|
|
1317
1390
|
const local = p._isLocal ? " (local)" : "";
|
|
1318
1391
|
log(` ${pad(p.nodeId, 14)}${pad(p.alias + local, 21)}${pad(status, 17)}${p.lastHeartbeat}`);
|
|
1319
1392
|
}
|
|
@@ -1331,7 +1404,7 @@ function runPeers(targetRoot, pArgs) {
|
|
|
1331
1404
|
|
|
1332
1405
|
const manifest = mp.registerSelf(meshDir, { alias });
|
|
1333
1406
|
|
|
1334
|
-
log(
|
|
1407
|
+
log(style.bold("REGISTERED") + "\n");
|
|
1335
1408
|
log(` Node ID ${manifest.nodeId}`);
|
|
1336
1409
|
log(` Alias ${manifest.alias}`);
|
|
1337
1410
|
log(` Hostname ${manifest.hostname}`);
|
|
@@ -1347,7 +1420,7 @@ function runPeers(targetRoot, pArgs) {
|
|
|
1347
1420
|
if (sub === "sync") {
|
|
1348
1421
|
const report = mp.syncWithPeers(meshDir);
|
|
1349
1422
|
|
|
1350
|
-
log(
|
|
1423
|
+
log(style.bold("SYNC COMPLETE") + "\n");
|
|
1351
1424
|
log(` Local node ${report.localNodeId}`);
|
|
1352
1425
|
log(` Peers scanned ${report.peersScanned}`);
|
|
1353
1426
|
log(` Delta exported ${report.localDeltaExported} entries`);
|
|
@@ -1368,7 +1441,7 @@ function runPeers(targetRoot, pArgs) {
|
|
|
1368
1441
|
if (sub === "health") {
|
|
1369
1442
|
const { peers, healthy, stale, halted, localId } = mp.classifyPeers(meshDir);
|
|
1370
1443
|
|
|
1371
|
-
log(
|
|
1444
|
+
log(style.bold("FLEET HEALTH") + "\n");
|
|
1372
1445
|
log(` Total nodes ${peers.length}`);
|
|
1373
1446
|
log(` Healthy ${healthy.length}`);
|
|
1374
1447
|
log(` Stale ${stale.length}`);
|
|
@@ -1378,7 +1451,8 @@ function runPeers(targetRoot, pArgs) {
|
|
|
1378
1451
|
? Math.round((healthy.length / peers.length) * 100)
|
|
1379
1452
|
: 100;
|
|
1380
1453
|
|
|
1381
|
-
|
|
1454
|
+
const healthColor = fleetHealth >= 80 ? style.boldGreen : fleetHealth >= 50 ? style.boldYellow : style.boldRed;
|
|
1455
|
+
log(`\n ${style.dim("Fleet health")} ${healthColor(fleetHealth + "%")}`);
|
|
1382
1456
|
|
|
1383
1457
|
if (stale.length > 0) {
|
|
1384
1458
|
log("\n STALE NODES (no heartbeat within TTL):");
|
|
@@ -1405,7 +1479,7 @@ function runPeers(targetRoot, pArgs) {
|
|
|
1405
1479
|
if (sub === "prune") {
|
|
1406
1480
|
const { pruned, removed } = mp.pruneStalePeers(meshDir);
|
|
1407
1481
|
|
|
1408
|
-
log(
|
|
1482
|
+
log(style.bold("PRUNE COMPLETE") + "\n");
|
|
1409
1483
|
log(` Removed ${pruned} stale peer(s)`);
|
|
1410
1484
|
|
|
1411
1485
|
if (removed.length > 0) {
|
|
@@ -1466,7 +1540,7 @@ function runEject(targetRoot) {
|
|
|
1466
1540
|
} else {
|
|
1467
1541
|
fs.unlinkSync(filePath);
|
|
1468
1542
|
}
|
|
1469
|
-
log(
|
|
1543
|
+
log(`${style.red("remove")} ${style.dim(label)}`);
|
|
1470
1544
|
removedCount++;
|
|
1471
1545
|
}
|
|
1472
1546
|
}
|
|
@@ -1486,7 +1560,7 @@ function runEject(targetRoot) {
|
|
|
1486
1560
|
const remaining = fs.readdirSync(agentsDir);
|
|
1487
1561
|
if (remaining.length === 0) {
|
|
1488
1562
|
fs.rmdirSync(agentsDir);
|
|
1489
|
-
log("remove .github/agents/ (empty)");
|
|
1563
|
+
log(`${style.green("remove")} ${style.dim(".github/agents/")} ${style.dim("(empty)")}`);
|
|
1490
1564
|
}
|
|
1491
1565
|
}
|
|
1492
1566
|
|
|
@@ -1497,7 +1571,7 @@ function runEject(targetRoot) {
|
|
|
1497
1571
|
// Keep .copilot/mcp-config.json if it exists (user may have customized)
|
|
1498
1572
|
const mcpConfig = path.join(targetRoot, ".copilot", "mcp-config.json");
|
|
1499
1573
|
if (fs.existsSync(mcpConfig)) {
|
|
1500
|
-
log("keep .copilot/mcp-config.json (may contain user config)");
|
|
1574
|
+
log(`${style.dim("keep")} ${style.dim(".copilot/mcp-config.json")} ${style.dim("(may contain user config)")}`);
|
|
1501
1575
|
skippedCount++;
|
|
1502
1576
|
}
|
|
1503
1577
|
|
|
@@ -1507,7 +1581,7 @@ function runEject(targetRoot) {
|
|
|
1507
1581
|
const remaining = fs.readdirSync(copilotDir);
|
|
1508
1582
|
if (remaining.length === 0) {
|
|
1509
1583
|
fs.rmdirSync(copilotDir);
|
|
1510
|
-
log("remove .copilot/ (empty)");
|
|
1584
|
+
log(`${style.green("remove")} ${style.dim(".copilot/")} ${style.dim("(empty)")}`);
|
|
1511
1585
|
}
|
|
1512
1586
|
}
|
|
1513
1587
|
|
|
@@ -1523,7 +1597,7 @@ function runEject(targetRoot) {
|
|
|
1523
1597
|
const remaining = fs.readdirSync(workflowsDir);
|
|
1524
1598
|
if (remaining.length === 0) {
|
|
1525
1599
|
fs.rmdirSync(workflowsDir);
|
|
1526
|
-
log("remove .github/workflows/ (empty)");
|
|
1600
|
+
log(`${style.green("remove")} ${style.dim(".github/workflows/")} ${style.dim("(empty)")}`);
|
|
1527
1601
|
}
|
|
1528
1602
|
} else {
|
|
1529
1603
|
log("(no workflows directory)");
|
|
@@ -1545,9 +1619,9 @@ function runEject(targetRoot) {
|
|
|
1545
1619
|
|
|
1546
1620
|
if (cleaned.length < lines.length) {
|
|
1547
1621
|
fs.writeFileSync(gitignorePath, cleaned.join("\n"));
|
|
1548
|
-
log(
|
|
1622
|
+
log(`${style.green("patch")} ${style.dim(".gitignore")} ${style.dim(`(removed ${lines.length - cleaned.length} mesh lines)`)}`);
|
|
1549
1623
|
} else {
|
|
1550
|
-
log("skip .gitignore (no mesh entries found)");
|
|
1624
|
+
log(`${style.dim("skip")} ${style.dim(".gitignore")} ${style.dim("(no mesh entries found)")}`);
|
|
1551
1625
|
}
|
|
1552
1626
|
} else {
|
|
1553
1627
|
log("(no .gitignore)");
|
|
@@ -1555,8 +1629,8 @@ function runEject(targetRoot) {
|
|
|
1555
1629
|
|
|
1556
1630
|
// ── Summary ───────────────────────────────────────────────────────
|
|
1557
1631
|
log("");
|
|
1558
|
-
log(`Ejected. ${removedCount} item(s) removed, ${skippedCount} preserved.`);
|
|
1559
|
-
log("Mercury Mesh has been cleanly removed from this project
|
|
1632
|
+
log(`Ejected. ${style.boldGreen(String(removedCount))} item(s) removed, ${style.dim(String(skippedCount))} preserved.`);
|
|
1633
|
+
log(`${style.dim("Mercury Mesh has been cleanly removed from this project.")}\n`);
|
|
1560
1634
|
|
|
1561
1635
|
return 0;
|
|
1562
1636
|
}
|
|
@@ -1638,70 +1712,70 @@ function runCreateSkill(targetRoot, args) {
|
|
|
1638
1712
|
// Write to live skills
|
|
1639
1713
|
ensureDir(liveDir);
|
|
1640
1714
|
fs.writeFileSync(path.join(liveDir, "SKILL.md"), content, "utf-8");
|
|
1641
|
-
log(
|
|
1715
|
+
log(`${style.green("write")} ${style.dim(`.copilot/skills/${slug}/SKILL.md`)}`);
|
|
1642
1716
|
|
|
1643
1717
|
// Mirror to template seeds (keep in sync)
|
|
1644
1718
|
if (fs.existsSync(path.join(targetRoot, ".mesh", "templates", "skills"))) {
|
|
1645
1719
|
ensureDir(templateDir);
|
|
1646
1720
|
fs.writeFileSync(path.join(templateDir, "SKILL.md"), content, "utf-8");
|
|
1647
|
-
log(
|
|
1648
|
-
log("Live and template skills are in sync.");
|
|
1721
|
+
log(`${style.green("write")} ${style.dim(`.mesh/templates/skills/${slug}/SKILL.md`)}`);
|
|
1722
|
+
log(style.dim("Live and template skills are in sync."));
|
|
1649
1723
|
} else {
|
|
1650
|
-
log("skip .mesh/templates/skills/ (directory not found — template sync skipped)");
|
|
1724
|
+
log(`${style.dim("skip")} ${style.dim(".mesh/templates/skills/ (directory not found — template sync skipped)")}`);
|
|
1651
1725
|
}
|
|
1652
1726
|
|
|
1653
|
-
log(`\nSkill "${slug}" created. Edit .copilot/skills/${slug}/SKILL.md to fill in patterns.\n`);
|
|
1727
|
+
log(`\nSkill ${style.bold(`"${slug}"`)} created. Edit ${style.cyan(`.copilot/skills/${slug}/SKILL.md`)} to fill in patterns.\n`);
|
|
1654
1728
|
return 0;
|
|
1655
1729
|
}
|
|
1656
1730
|
|
|
1657
1731
|
function printUsage() {
|
|
1658
1732
|
console.log(`
|
|
1659
|
-
Mercury Mesh v${VERSION} — CLI
|
|
1660
|
-
|
|
1661
|
-
Usage:
|
|
1662
|
-
npx @mizyoel/mercury-mesh init [--force] [--target <path>]
|
|
1663
|
-
npx @mizyoel/mercury-mesh update [--target <path>]
|
|
1664
|
-
npx @mizyoel/mercury-mesh doctor [--target <path>]
|
|
1665
|
-
npx @mizyoel/mercury-mesh status [--target <path>]
|
|
1666
|
-
npx @mizyoel/mercury-mesh create-skill <name> [--description <desc>] [--domain <domain>]
|
|
1667
|
-
npx @mizyoel/mercury-mesh resume [--session <id>] [--target <path>]
|
|
1668
|
-
npx @mizyoel/mercury-mesh eject [--target <path>]
|
|
1669
|
-
npx @mizyoel/mercury-mesh worktree [list|status|prune] [--target <path>]
|
|
1670
|
-
npx @mizyoel/mercury-mesh coalescence [scan|apply] [--target <path>]
|
|
1671
|
-
npx @mizyoel/mercury-mesh peers [list|register|sync|health|prune] [--target <path>]
|
|
1672
|
-
npx @mizyoel/mercury-mesh github-mcp
|
|
1673
|
-
npx @mizyoel/mercury-mesh version
|
|
1674
|
-
|
|
1675
|
-
Commands:
|
|
1676
|
-
init Scaffold Copilot agent, skills, workflows, and .mesh/ runtime
|
|
1733
|
+
${gradient(`Mercury Mesh v${VERSION}`)} ${style.dim("— CLI")}
|
|
1734
|
+
|
|
1735
|
+
${style.bold("Usage:")}
|
|
1736
|
+
${style.cyan("npx @mizyoel/mercury-mesh")} ${style.bold("init")} ${style.dim("[--force] [--target <path>]")}
|
|
1737
|
+
${style.cyan("npx @mizyoel/mercury-mesh")} ${style.bold("update")} ${style.dim("[--target <path>]")}
|
|
1738
|
+
${style.cyan("npx @mizyoel/mercury-mesh")} ${style.bold("doctor")} ${style.dim("[--target <path>]")}
|
|
1739
|
+
${style.cyan("npx @mizyoel/mercury-mesh")} ${style.bold("status")} ${style.dim("[--target <path>]")}
|
|
1740
|
+
${style.cyan("npx @mizyoel/mercury-mesh")} ${style.bold("create-skill")} ${style.dim("<name> [--description <desc>] [--domain <domain>]")}
|
|
1741
|
+
${style.cyan("npx @mizyoel/mercury-mesh")} ${style.bold("resume")} ${style.dim("[--session <id>] [--target <path>]")}
|
|
1742
|
+
${style.cyan("npx @mizyoel/mercury-mesh")} ${style.bold("eject")} ${style.dim("[--target <path>]")}
|
|
1743
|
+
${style.cyan("npx @mizyoel/mercury-mesh")} ${style.bold("worktree")} ${style.dim("[list|status|prune] [--target <path>]")}
|
|
1744
|
+
${style.cyan("npx @mizyoel/mercury-mesh")} ${style.bold("coalescence")} ${style.dim("[scan|apply] [--target <path>]")}
|
|
1745
|
+
${style.cyan("npx @mizyoel/mercury-mesh")} ${style.bold("peers")} ${style.dim("[list|register|sync|health|prune] [--target <path>]")}
|
|
1746
|
+
${style.cyan("npx @mizyoel/mercury-mesh")} ${style.bold("github-mcp")}
|
|
1747
|
+
${style.cyan("npx @mizyoel/mercury-mesh")} ${style.bold("version")}
|
|
1748
|
+
|
|
1749
|
+
${style.bold("Commands:")}
|
|
1750
|
+
${style.cyan("init")} Scaffold Copilot agent, skills, workflows, and .mesh/ runtime
|
|
1677
1751
|
into the target project. Existing files are preserved unless --force.
|
|
1678
|
-
update Overwrite agent prompt, skills, and copilot-instructions with the
|
|
1752
|
+
${style.cyan("update")} Overwrite agent prompt, skills, and copilot-instructions with the
|
|
1679
1753
|
latest from this package version. Config and team files are untouched.
|
|
1680
|
-
doctor Run hull diagnostics: validate config, structure, skills, nervous
|
|
1754
|
+
${style.cyan("doctor")} Run hull diagnostics: validate config, structure, skills, nervous
|
|
1681
1755
|
system, secrets, and version alignment. Paste output for bug reports.
|
|
1682
|
-
status Bridge telemetry: crew roster, org health, nervous system, sessions,
|
|
1756
|
+
${style.cyan("status")} Bridge telemetry: crew roster, org health, nervous system, sessions,
|
|
1683
1757
|
and pending decisions at a glance.
|
|
1684
|
-
create-skill
|
|
1758
|
+
${style.cyan("create-skill")}
|
|
1685
1759
|
Scaffold a new skill in .copilot/skills/ and .mesh/templates/skills/.
|
|
1686
1760
|
Creates SKILL.md with frontmatter and section stubs.
|
|
1687
|
-
resume Recover from an interrupted sortie: show last session context,
|
|
1761
|
+
${style.cyan("resume")} Recover from an interrupted sortie: show last session context,
|
|
1688
1762
|
pending decisions, uncommitted work, and a recovery briefing.
|
|
1689
|
-
eject Remove Mercury Mesh from the project. Strips .mesh/, agent prompt,
|
|
1763
|
+
${style.cyan("eject")} Remove Mercury Mesh from the project. Strips .mesh/, agent prompt,
|
|
1690
1764
|
skills, workflows, and .gitignore entries. Keeps mcp-config.json.
|
|
1691
|
-
worktree List, inspect, and prune git worktrees for parallel Wing execution.
|
|
1765
|
+
${style.cyan("worktree")} List, inspect, and prune git worktrees for parallel Wing execution.
|
|
1692
1766
|
Subcommands: list (all worktrees), status (health), prune (cleanup).
|
|
1693
|
-
coalescence
|
|
1767
|
+
${style.cyan("coalescence")}
|
|
1694
1768
|
Detect overlapping Ghost Wings and auto-merge compatible pairs.
|
|
1695
1769
|
Subcommands: scan (report only), apply (merge high-confidence overlaps).
|
|
1696
|
-
peers Multi-machine coordination: register nodes, sync constellation,
|
|
1770
|
+
${style.cyan("peers")} Multi-machine coordination: register nodes, sync constellation,
|
|
1697
1771
|
and monitor fleet health. Subcommands: list, register, sync, health, prune.
|
|
1698
|
-
github-mcp Start the GitHub MCP server using gh auth token for local auth.
|
|
1699
|
-
version Print package version.
|
|
1772
|
+
${style.cyan("github-mcp")} Start the GitHub MCP server using gh auth token for local auth.
|
|
1773
|
+
${style.cyan("version")} Print package version.
|
|
1700
1774
|
|
|
1701
|
-
Options:
|
|
1702
|
-
--force Overwrite existing files during init
|
|
1703
|
-
--target <path> Target project root (default: current working directory)
|
|
1704
|
-
--session <id> Target a specific session for resume (default: most recent)
|
|
1775
|
+
${style.bold("Options:")}
|
|
1776
|
+
${style.yellow("--force")} Overwrite existing files during init
|
|
1777
|
+
${style.yellow("--target")} ${style.dim("<path>")} Target project root (default: current working directory)
|
|
1778
|
+
${style.yellow("--session")} ${style.dim("<id>")} Target a specific session for resume (default: most recent)
|
|
1705
1779
|
`);
|
|
1706
1780
|
}
|
|
1707
1781
|
|