wyrm-mcp 7.3.2 → 7.3.3

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.
Files changed (184) hide show
  1. package/README.md +8 -14
  2. package/dist/activation.js +59 -1
  3. package/dist/agent-daemon.js +281 -4
  4. package/dist/agent-loop.js +332 -7
  5. package/dist/analytics.js +236 -13
  6. package/dist/attribution.js +49 -1
  7. package/dist/audit.js +457 -2
  8. package/dist/auto-capture.js +138 -3
  9. package/dist/auto-orchestrator.js +325 -1
  10. package/dist/autoconfig.d.ts +50 -0
  11. package/dist/autoconfig.d.ts.map +1 -1
  12. package/dist/autoconfig.js +1115 -39
  13. package/dist/autoconfig.js.map +1 -1
  14. package/dist/buddy-runner.js +109 -1
  15. package/dist/buddy.js +564 -14
  16. package/dist/build-flags.js +15 -1
  17. package/dist/capabilities.js +183 -3
  18. package/dist/capture.js +56 -1
  19. package/dist/causality.js +148 -8
  20. package/dist/cli.js +281 -20
  21. package/dist/cloud/cli.js +541 -5
  22. package/dist/cloud/client.js +221 -1
  23. package/dist/cloud/crypto.js +85 -1
  24. package/dist/cloud/machine-id.js +113 -2
  25. package/dist/cloud/recovery.js +60 -1
  26. package/dist/cloud/sync-engine.js +543 -7
  27. package/dist/cloud-backup.js +579 -5
  28. package/dist/cloud-profile.js +138 -1
  29. package/dist/cloud-sync-entrypoint.js +47 -1
  30. package/dist/cloud-sync.js +309 -2
  31. package/dist/connectors/bridge-source.d.ts +46 -0
  32. package/dist/connectors/bridge-source.d.ts.map +1 -0
  33. package/dist/connectors/bridge-source.js +77 -0
  34. package/dist/connectors/bridge-source.js.map +1 -0
  35. package/dist/connectors/index.d.ts +24 -0
  36. package/dist/connectors/index.d.ts.map +1 -0
  37. package/dist/connectors/index.js +69 -0
  38. package/dist/connectors/index.js.map +1 -0
  39. package/dist/connectors/ingest.d.ts +16 -0
  40. package/dist/connectors/ingest.d.ts.map +1 -0
  41. package/dist/connectors/ingest.js +116 -0
  42. package/dist/connectors/ingest.js.map +1 -0
  43. package/dist/connectors/types.d.ts +99 -0
  44. package/dist/connectors/types.d.ts.map +1 -0
  45. package/dist/connectors/types.js +17 -0
  46. package/dist/connectors/types.js.map +1 -0
  47. package/dist/constellation.js +168 -12
  48. package/dist/content-signature.js +45 -1
  49. package/dist/context-build-budgeted.js +144 -4
  50. package/dist/context-ranking.js +69 -1
  51. package/dist/crypto.js +179 -1
  52. package/dist/daemon-write-endpoint.js +290 -1
  53. package/dist/daemon-writer.js +406 -2
  54. package/dist/database.js +1278 -53
  55. package/dist/deprecations.js +162 -2
  56. package/dist/design.js +141 -13
  57. package/dist/event-replication.js +112 -1
  58. package/dist/events-sse.js +43 -7
  59. package/dist/events.js +238 -6
  60. package/dist/failure-patterns.d.ts +107 -0
  61. package/dist/failure-patterns.d.ts.map +1 -1
  62. package/dist/failure-patterns.js +924 -43
  63. package/dist/failure-patterns.js.map +1 -1
  64. package/dist/federation.js +236 -12
  65. package/dist/goals.js +101 -13
  66. package/dist/golden.js +355 -3
  67. package/dist/handlers/agent.js +165 -4
  68. package/dist/handlers/alias-adapters.js +129 -1
  69. package/dist/handlers/aliases.js +171 -1
  70. package/dist/handlers/audit.js +87 -1
  71. package/dist/handlers/boundary.js +221 -1
  72. package/dist/handlers/capture.js +1114 -73
  73. package/dist/handlers/causality.js +119 -9
  74. package/dist/handlers/cloud.js +382 -85
  75. package/dist/handlers/companion.js +459 -28
  76. package/dist/handlers/datalake.js +187 -7
  77. package/dist/handlers/dispatch-context.js +22 -0
  78. package/dist/handlers/entity.js +256 -25
  79. package/dist/handlers/events.js +335 -16
  80. package/dist/handlers/failure.d.ts.map +1 -1
  81. package/dist/handlers/failure.js +408 -13
  82. package/dist/handlers/failure.js.map +1 -1
  83. package/dist/handlers/goals.js +296 -4
  84. package/dist/handlers/intelligence.js +681 -126
  85. package/dist/handlers/invoicing.js +70 -1
  86. package/dist/handlers/mcpclient.js +137 -6
  87. package/dist/handlers/orchestration.js +125 -40
  88. package/dist/handlers/output-schemas.js +24 -1
  89. package/dist/handlers/presence.js +99 -3
  90. package/dist/handlers/project.js +182 -28
  91. package/dist/handlers/prompts.js +157 -6
  92. package/dist/handlers/quest.js +224 -4
  93. package/dist/handlers/recall.js +237 -13
  94. package/dist/handlers/registry.js +167 -1
  95. package/dist/handlers/resources.js +288 -1
  96. package/dist/handlers/review.js +74 -11
  97. package/dist/handlers/run.js +498 -16
  98. package/dist/handlers/search.js +338 -15
  99. package/dist/handlers/session.js +643 -31
  100. package/dist/handlers/share.js +184 -8
  101. package/dist/handlers/shims.js +464 -1
  102. package/dist/handlers/skill.js +449 -67
  103. package/dist/handlers/survivors.js +120 -1
  104. package/dist/handlers/symbols.js +109 -8
  105. package/dist/handlers/syncops.js +302 -4
  106. package/dist/handlers/types.js +27 -1
  107. package/dist/harvest.js +191 -5
  108. package/dist/hours.js +156 -7
  109. package/dist/http-auth.js +321 -3
  110. package/dist/http-fast.js +1302 -22
  111. package/dist/icons.js +47 -1
  112. package/dist/importers.js +268 -1
  113. package/dist/index.js +840 -2
  114. package/dist/indexer.js +145 -4
  115. package/dist/intelligence.js +261 -31
  116. package/dist/internal-dispatch.js +212 -3
  117. package/dist/keyset.js +110 -1
  118. package/dist/knowledge-graph.js +176 -12
  119. package/dist/license.js +441 -2
  120. package/dist/logger.js +199 -2
  121. package/dist/maintenance.js +148 -2
  122. package/dist/mcp-client.js +262 -6
  123. package/dist/memory-artifacts.js +596 -32
  124. package/dist/migrate-prompt.js +124 -2
  125. package/dist/migrations.d.ts.map +1 -1
  126. package/dist/migrations.js +799 -42
  127. package/dist/migrations.js.map +1 -1
  128. package/dist/performance.js +228 -1
  129. package/dist/presence.js +140 -11
  130. package/dist/priority-embed.js +164 -5
  131. package/dist/providers/embedding-provider.js +196 -1
  132. package/dist/readonly-gate.js +29 -1
  133. package/dist/receipt.js +43 -1
  134. package/dist/rehydration.js +157 -9
  135. package/dist/reindex.js +88 -1
  136. package/dist/render-target.js +544 -21
  137. package/dist/render.js +280 -4
  138. package/dist/repl-guard.js +173 -1
  139. package/dist/replication-daemon-entrypoint.js +31 -1
  140. package/dist/replication-daemon.js +262 -2
  141. package/dist/rerank.js +142 -1
  142. package/dist/resilience.js +591 -1
  143. package/dist/reverse-bridge.js +360 -5
  144. package/dist/security.js +244 -1
  145. package/dist/session-seen.js +51 -3
  146. package/dist/setup.js +260 -1
  147. package/dist/skill-author.js +168 -5
  148. package/dist/spec-kit.js +191 -1
  149. package/dist/sqlite-busy.js +154 -1
  150. package/dist/statusline.js +315 -11
  151. package/dist/sub-agent.js +262 -13
  152. package/dist/summarizer.js +139 -13
  153. package/dist/symbols.js +283 -7
  154. package/dist/sync.js +359 -5
  155. package/dist/tasks-dispatch.js +84 -1
  156. package/dist/tasks.js +282 -1
  157. package/dist/token-budget.js +143 -1
  158. package/dist/tool-analytics.js +129 -7
  159. package/dist/tool-annotations.js +365 -1
  160. package/dist/tool-manifest-v2.json +1 -1
  161. package/dist/tool-manifest.json +1 -1
  162. package/dist/tool-profiles.js +75 -1
  163. package/dist/trace-harvest.js +244 -6
  164. package/dist/types.js +30 -1
  165. package/dist/ui-dashboard.js +50 -41
  166. package/dist/ulid.js +81 -1
  167. package/dist/usage-tracker.js +66 -1
  168. package/dist/validate.js +129 -1
  169. package/dist/vault.js +534 -1
  170. package/dist/vector-init.js +67 -1
  171. package/dist/vectors.js +184 -3
  172. package/dist/version-check.js +136 -4
  173. package/dist/visibility.js +155 -19
  174. package/dist/wyrm-cli.js +2845 -101
  175. package/dist/wyrm-cli.js.map +1 -1
  176. package/dist/wyrm-guard.d.ts.map +1 -1
  177. package/dist/wyrm-guard.js +475 -14
  178. package/dist/wyrm-guard.js.map +1 -1
  179. package/dist/wyrm-loop.js +150 -3
  180. package/dist/wyrm-manifest.json +1 -1
  181. package/dist/wyrm-statusline-daemon.js +11 -1
  182. package/dist/wyrm-statusline.js +56 -4
  183. package/dist/wyrm-ui.js +77 -9
  184. package/package.json +1 -1
package/dist/wyrm-loop.js CHANGED
@@ -1,6 +1,62 @@
1
1
  #!/usr/bin/env node
2
- import{WyrmDB as m}from"./database.js";import{Goals as f}from"./goals.js";import{AgentLoop as d}from"./agent-loop.js";import{OutboundMcpClient as h}from"./mcp-client.js";function g(e){const t={interval:600,once:!1,maxSteps:3,verbose:process.env.WYRM_LOOP_LOG==="1"};for(let s=0;s<e.length;s++){const o=e[s];o==="--interval"?t.interval=Math.max(10,parseInt(e[++s],10)||600):o==="--once"?t.once=!0:o==="--goal"?t.goalId=parseInt(e[++s],10):o==="--max-steps"?t.maxSteps=Math.max(1,Math.min(20,parseInt(e[++s],10)||3)):o==="--project"?t.projectPath=e[++s]:o==="--verbose"||o==="-v"?t.verbose=!0:(o==="--help"||o==="-h")&&(console.log(w),process.exit(0))}return t}const w=`
3
- wyrm-loop \u2014 autonomous OODA scheduler
2
+ /**
3
+ * wyrm-loop the autonomous scheduler.
4
+ *
5
+ * Long-lived daemon. Wakes up every N seconds, picks the highest-priority
6
+ * active goal that hasn't hit its iteration cap, runs ONE OODA iteration
7
+ * via AgentLoop, logs to agent_actions + goal_iterations, and goes back
8
+ * to sleep. Stops a goal once it completes / blocks / errors.
9
+ *
10
+ * Usage:
11
+ * wyrm-loop # default 10-minute interval, loop forever
12
+ * wyrm-loop --interval 60 # 60-second interval
13
+ * wyrm-loop --once # one iteration, then exit (cron-friendly)
14
+ * wyrm-loop --goal 42 # only this goal
15
+ * wyrm-loop --max-steps 3 # max iterations per goal per tick
16
+ * wyrm-loop --project /path # scope to project
17
+ *
18
+ * Environment:
19
+ * WYRM_DB_PATH path to wyrm.db (default ~/.wyrm/wyrm.db)
20
+ * WYRM_OLLAMA_URL default http://localhost:11434
21
+ * OPENAI_API_KEY optional fallback
22
+ * WYRM_LOOP_LOG '1' to log every tick to stderr
23
+ *
24
+ * @copyright 2026 Ghost Protocol (Pvt) Ltd.
25
+ */
26
+ import { WyrmDB } from './database.js';
27
+ import { Goals } from './goals.js';
28
+ import { AgentLoop } from './agent-loop.js';
29
+ import { OutboundMcpClient } from './mcp-client.js';
30
+ function parseArgs(argv) {
31
+ const out = {
32
+ interval: 600,
33
+ once: false,
34
+ maxSteps: 3,
35
+ verbose: process.env.WYRM_LOOP_LOG === '1',
36
+ };
37
+ for (let i = 0; i < argv.length; i++) {
38
+ const a = argv[i];
39
+ if (a === '--interval')
40
+ out.interval = Math.max(10, parseInt(argv[++i], 10) || 600);
41
+ else if (a === '--once')
42
+ out.once = true;
43
+ else if (a === '--goal')
44
+ out.goalId = parseInt(argv[++i], 10);
45
+ else if (a === '--max-steps')
46
+ out.maxSteps = Math.max(1, Math.min(20, parseInt(argv[++i], 10) || 3));
47
+ else if (a === '--project')
48
+ out.projectPath = argv[++i];
49
+ else if (a === '--verbose' || a === '-v')
50
+ out.verbose = true;
51
+ else if (a === '--help' || a === '-h') {
52
+ console.log(USAGE);
53
+ process.exit(0);
54
+ }
55
+ }
56
+ return out;
57
+ }
58
+ const USAGE = `
59
+ wyrm-loop — autonomous OODA scheduler
4
60
 
5
61
  wyrm-loop [options]
6
62
 
@@ -12,4 +68,95 @@ Options
12
68
  --project PATH Scope to a project root
13
69
  --verbose, -v Log every tick to stderr
14
70
  --help, -h Show this help
15
- `;function i(e,t){e.verbose&&console.error(`[wyrm-loop ${new Date().toISOString()}] ${t}`)}async function v(e,t,s,o){let r=e.goalId;if(!r){let l;if(e.projectPath){const u=t.getProject(e.projectPath);if(!u)return i(e,`project '${e.projectPath}' not registered \u2014 idle`),!1;l=u.id}const p=s.nextToPursue(l);if(!p)return i(e,"no active goals \u2014 idle"),!1;r=p.id}const c=s.get(r);if(!c||c.status!=="active")return i(e,`goal #${r} not active \u2014 skipping`),!1;i(e,`pursuing goal #${r}: ${c.title.slice(0,80)}`);const n=await o.pursue(r,{max_steps:e.maxSteps});if(n.length===0)return i(e,`goal #${r} returned no iterations`),!1;const a=n[n.length-1];return i(e,`goal #${r} ran ${n.length} iteration(s); last outcome=${a.outcome} (${a.latency_ms}ms, model=${a.model}${a.degraded?" DEGRADED":""})`),!0}async function x(){const e=g(process.argv.slice(2)),t=new m(process.env.WYRM_DB_PATH),s=new f(t.getDatabase()),o=new h(t.getDatabase()),r=async()=>({ok:!1,error:"wyrm-loop does not enable internal tool dispatch in this build \u2014 use the wyrm-mcp server for full agent runs"}),c=new d(t.getDatabase(),o,r);let n=!1;const a=()=>{n||(n=!0,i(e,"shutting down\u2026"),o.shutdown().finally(()=>{try{t.close()}catch{}process.exit(0)}))};for(process.on("SIGINT",a),process.on("SIGTERM",a),e.verbose&&console.error(`wyrm-loop starting \xB7 interval=${e.interval}s \xB7 once=${e.once} \xB7 max-steps=${e.maxSteps}`);!n;){try{await v(e,t,s,c)}catch(l){console.error(`wyrm-loop tick error: ${l.message}`)}if(e.once){a();return}await new Promise(l=>{setTimeout(l,e.interval*1e3)})}}x().catch(e=>{console.error(`wyrm-loop fatal: ${e.message}`),process.exit(1)});
71
+ `;
72
+ function log(args, msg) {
73
+ if (args.verbose)
74
+ console.error(`[wyrm-loop ${new Date().toISOString()}] ${msg}`);
75
+ }
76
+ /** Run a single tick. Returns true if work was done, false on idle. */
77
+ async function tick(args, db, goals, agent) {
78
+ let goalId = args.goalId;
79
+ if (!goalId) {
80
+ let projectId;
81
+ if (args.projectPath) {
82
+ const p = db.getProject(args.projectPath);
83
+ if (!p) {
84
+ log(args, `project '${args.projectPath}' not registered — idle`);
85
+ return false;
86
+ }
87
+ projectId = p.id;
88
+ }
89
+ const next = goals.nextToPursue(projectId);
90
+ if (!next) {
91
+ log(args, 'no active goals — idle');
92
+ return false;
93
+ }
94
+ goalId = next.id;
95
+ }
96
+ const goal = goals.get(goalId);
97
+ if (!goal || goal.status !== 'active') {
98
+ log(args, `goal #${goalId} not active — skipping`);
99
+ return false;
100
+ }
101
+ log(args, `pursuing goal #${goalId}: ${goal.title.slice(0, 80)}`);
102
+ const results = await agent.pursue(goalId, { max_steps: args.maxSteps });
103
+ if (results.length === 0) {
104
+ log(args, `goal #${goalId} returned no iterations`);
105
+ return false;
106
+ }
107
+ const last = results[results.length - 1];
108
+ log(args, `goal #${goalId} ran ${results.length} iteration(s); last outcome=${last.outcome} (${last.latency_ms}ms, model=${last.model}${last.degraded ? ' DEGRADED' : ''})`);
109
+ return true;
110
+ }
111
+ async function main() {
112
+ const args = parseArgs(process.argv.slice(2));
113
+ const db = new WyrmDB(process.env.WYRM_DB_PATH);
114
+ const goals = new Goals(db.getDatabase());
115
+ const mcp = new OutboundMcpClient(db.getDatabase());
116
+ // Minimal dispatcher for wyrm-loop — reads only, since this is the
117
+ // autonomous path and we want safe defaults. Goals can still call
118
+ // write tools via the standard MCP path (wyrm-mcp server), but loop
119
+ // ticks stick to a conservative subset.
120
+ const dispatcher = async () => {
121
+ return { ok: false, error: 'wyrm-loop does not enable internal tool dispatch in this build — use the wyrm-mcp server for full agent runs' };
122
+ };
123
+ const agent = new AgentLoop(db.getDatabase(), mcp, dispatcher);
124
+ let stopped = false;
125
+ const stop = () => {
126
+ if (stopped)
127
+ return;
128
+ stopped = true;
129
+ log(args, 'shutting down…');
130
+ mcp.shutdown().finally(() => {
131
+ try {
132
+ db.close();
133
+ }
134
+ catch { /* best-effort */ }
135
+ process.exit(0);
136
+ });
137
+ };
138
+ process.on('SIGINT', stop);
139
+ process.on('SIGTERM', stop);
140
+ if (args.verbose) {
141
+ console.error(`wyrm-loop starting · interval=${args.interval}s · once=${args.once} · max-steps=${args.maxSteps}`);
142
+ }
143
+ // Loop
144
+ while (!stopped) {
145
+ try {
146
+ await tick(args, db, goals, agent);
147
+ }
148
+ catch (err) {
149
+ console.error(`wyrm-loop tick error: ${err.message}`);
150
+ }
151
+ if (args.once) {
152
+ stop();
153
+ return;
154
+ }
155
+ await new Promise(r => { setTimeout(r, args.interval * 1000); });
156
+ }
157
+ }
158
+ main().catch(err => {
159
+ console.error(`wyrm-loop fatal: ${err.message}`);
160
+ process.exit(1);
161
+ });
162
+ //# sourceMappingURL=wyrm-loop.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "contract": "wyrm-cloud-memory-v1",
3
- "version": "7.3.2",
3
+ "version": "7.3.3",
4
4
  "generatedBy": "scripts/gen-tool-manifest.mjs (from the dist/ registry modules — never hand-edited)",
5
5
  "tiers": {
6
6
  "core": [
@@ -1,2 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import{runDaemon as m}from"./statusline.js";m();
2
+ /**
3
+ * wyrm-statusline-daemon — long-lived process serving statusline queries.
4
+ *
5
+ * Auto-spawned by the wyrm-statusline binary on first call. Listens on
6
+ * ~/.wyrm/statusline.sock. Idle-times-out after 5 minutes of no requests.
7
+ *
8
+ * @copyright 2026 Ghost Protocol (Pvt) Ltd.
9
+ */
10
+ import { runDaemon } from './statusline.js';
11
+ runDaemon();
12
+ //# sourceMappingURL=wyrm-statusline-daemon.js.map
@@ -1,5 +1,57 @@
1
1
  #!/usr/bin/env node
2
- import{queryDaemon as i}from"./statusline.js";function c(s){let o=process.cwd(),n,e=!1;for(let t=2;t<s.length;t++){const r=s[t];r==="--cwd"?o=s[++t]:r==="--session"?n=Number(s[++t]):r==="--json"&&(e=!0)}return{cwd:o,sessionId:n,json:e}}async function p(){const{cwd:s,sessionId:o,json:n}=c(process.argv);try{const e=await i({cwd:s,sessionId:o,privateMode:process.env.WYRM_STATUSLINE_PRIVATE==="1",showSavings:process.env.WYRM_STATUSLINE_SHOW_SAVINGS==="1"});n?process.stdout.write(`${JSON.stringify(e.raw)}
3
- `):process.stdout.write(`${e.text}
4
- `)}catch{process.stdout.write(`\u{F115D} Wyrm
5
- `)}}p();
2
+ /**
3
+ * wyrm-statusline — print a single statusline string and exit.
4
+ *
5
+ * Designed to be invoked from a client's statusline hook every few seconds.
6
+ * Spawns the wyrm-statusline-daemon if not already running (detached, idle-
7
+ * times out after 5min). Per-call latency target: ≤ 50ms warm.
8
+ *
9
+ * Usage:
10
+ * wyrm-statusline # default, uses $PWD
11
+ * wyrm-statusline --cwd /path # explicit cwd
12
+ * wyrm-statusline --session 142 # explicit session id
13
+ * wyrm-statusline --json # emit raw JSON instead of formatted text
14
+ *
15
+ * @copyright 2026 Ghost Protocol (Pvt) Ltd.
16
+ */
17
+ import { queryDaemon } from './statusline.js';
18
+ function parseArgs(argv) {
19
+ let cwd = process.cwd();
20
+ let sessionId;
21
+ let json = false;
22
+ for (let i = 2; i < argv.length; i++) {
23
+ const a = argv[i];
24
+ if (a === '--cwd')
25
+ cwd = argv[++i];
26
+ else if (a === '--session')
27
+ sessionId = Number(argv[++i]);
28
+ else if (a === '--json')
29
+ json = true;
30
+ }
31
+ return { cwd, sessionId, json };
32
+ }
33
+ async function main() {
34
+ const { cwd, sessionId, json } = parseArgs(process.argv);
35
+ try {
36
+ // Forward the binary's per-call env so each invocation can toggle
37
+ // privacy / savings without daemon restart.
38
+ const resp = await queryDaemon({
39
+ cwd,
40
+ sessionId,
41
+ privateMode: process.env.WYRM_STATUSLINE_PRIVATE === '1',
42
+ showSavings: process.env.WYRM_STATUSLINE_SHOW_SAVINGS === '1',
43
+ });
44
+ if (json) {
45
+ process.stdout.write(`${JSON.stringify(resp.raw)}\n`);
46
+ }
47
+ else {
48
+ process.stdout.write(`${resp.text}\n`);
49
+ }
50
+ }
51
+ catch (e) {
52
+ // Statusline must never crash a client's status bar — always print SOMETHING.
53
+ process.stdout.write(`󱅝 Wyrm\n`);
54
+ }
55
+ }
56
+ main();
57
+ //# sourceMappingURL=wyrm-statusline.js.map
package/dist/wyrm-ui.js CHANGED
@@ -1,10 +1,78 @@
1
1
  #!/usr/bin/env node
2
- import{spawn as s}from"child_process";const n=parseInt(process.env.WYRM_HTTP_PORT??"3333",10)||3333,i="127.0.0.1",o=`http://${i}:${n}`;async function a(){try{return(await fetch(`${o}/health`,{signal:AbortSignal.timeout(1500)})).ok}catch{return!1}}function u(r){switch(process.platform){case"darwin":return["open",[r]];case"win32":return["cmd",["/c","start",'""',r]];default:return["xdg-open",[r]]}}function p(r){const[t,c]=u(r);try{s(t,c,{detached:!0,stdio:"ignore"}).unref(),process.stdout.write(`\u{F115D} Opened ${r}
3
- `)}catch(e){process.stderr.write(`[wyrm-ui] could not launch browser via ${t}: ${e.message}
4
- `),process.stdout.write(`Open this URL manually: ${r}
5
- `)}}async function d(){const r=`${o}/ui`;if(await a()){p(r);return}process.stderr.write(`[wyrm-ui] starting \`wyrm serve --ui\` detached on :${n}
6
- `);try{s("wyrm",["serve","--ui"],{detached:!0,stdio:"ignore"}).unref(),process.stdout.write(`\u{F115D} Launching the Wyrm dashboard at ${r}
7
- `)}catch(t){process.stderr.write(`[wyrm-ui] could not start the server: ${t.message}
8
- `),process.stdout.write(`Run it manually: wyrm serve --ui
9
- `),process.exit(1)}}d().catch(r=>{process.stderr.write(`[wyrm-ui] fatal: ${r.message}
10
- `),process.exit(1)});
2
+ /**
3
+ * 󱅝 wyrm-ui open the Wyrm web dashboard in the operator's default browser.
4
+ *
5
+ * 1. Probes localhost:WYRM_HTTP_PORT (default 3333) for /health.
6
+ * 2. If a server is already up, opens the browser at /ui.
7
+ * 3. If nothing is running, delegates to `wyrm serve --ui` the canonical
8
+ * http-fast dashboard (silver-dragon logo + /dragon-mark.svg + live data
9
+ * endpoints) with localhost dev-auth which starts the server AND opens the
10
+ * browser itself. (Before 6.8.1 this spawned `wyrm-http`, a *different*
11
+ * server whose static /ui never carried the brand mark — the two-dashboard
12
+ * split. Both bind :3333, so converging the launcher fixes the inconsistency.)
13
+ *
14
+ * Cross-OS shell-out: `xdg-open` (Linux/Termux), `open` (macOS), `start` (Win).
15
+ *
16
+ * @copyright 2026 Ghost Protocol (Pvt) Ltd.
17
+ * @license Proprietary — (c) 2026 Ghost Protocol (Pvt) Ltd. All rights reserved. See LICENSE.
18
+ */
19
+ import { spawn } from 'child_process';
20
+ const PORT = parseInt(process.env.WYRM_HTTP_PORT ?? '3333', 10) || 3333;
21
+ const HOST = '127.0.0.1';
22
+ const URL_BASE = `http://${HOST}:${PORT}`;
23
+ async function isHttpUp() {
24
+ try {
25
+ const r = await fetch(`${URL_BASE}/health`, { signal: AbortSignal.timeout(1500) });
26
+ return r.ok;
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ function platformOpenCmd(target) {
33
+ switch (process.platform) {
34
+ case 'darwin': return ['open', [target]];
35
+ case 'win32': return ['cmd', ['/c', 'start', '""', target]];
36
+ default: return ['xdg-open', [target]]; // linux / freebsd / termux
37
+ }
38
+ }
39
+ function openBrowser(target) {
40
+ const [cmd, argv] = platformOpenCmd(target);
41
+ try {
42
+ const proc = spawn(cmd, argv, { detached: true, stdio: 'ignore' });
43
+ proc.unref();
44
+ process.stdout.write(`󱅝 Opened ${target}\n`);
45
+ }
46
+ catch (e) {
47
+ process.stderr.write(`[wyrm-ui] could not launch browser via ${cmd}: ${e.message}\n`);
48
+ process.stdout.write(`Open this URL manually: ${target}\n`);
49
+ }
50
+ }
51
+ async function main() {
52
+ const target = `${URL_BASE}/ui`;
53
+ // Already running → just open the dashboard at /ui (exact path; http-fast's
54
+ // /ui route is an exact match, not a static-dir prefix).
55
+ if (await isHttpUp()) {
56
+ openBrowser(target);
57
+ return;
58
+ }
59
+ // Nothing up → `wyrm serve --ui` starts the http-fast dashboard (with the
60
+ // silver dragon), enables localhost dev-auth so the browser can load /ui,
61
+ // and opens the browser itself. Don't double-open here.
62
+ process.stderr.write(`[wyrm-ui] starting \`wyrm serve --ui\` detached on :${PORT}\n`);
63
+ try {
64
+ const proc = spawn('wyrm', ['serve', '--ui'], { detached: true, stdio: 'ignore' });
65
+ proc.unref();
66
+ process.stdout.write(`󱅝 Launching the Wyrm dashboard at ${target}\n`);
67
+ }
68
+ catch (e) {
69
+ process.stderr.write(`[wyrm-ui] could not start the server: ${e.message}\n`);
70
+ process.stdout.write(`Run it manually: wyrm serve --ui\n`);
71
+ process.exit(1);
72
+ }
73
+ }
74
+ main().catch((e) => {
75
+ process.stderr.write(`[wyrm-ui] fatal: ${e.message}\n`);
76
+ process.exit(1);
77
+ });
78
+ //# sourceMappingURL=wyrm-ui.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wyrm-mcp",
3
- "version": "7.3.2",
3
+ "version": "7.3.3",
4
4
  "description": "Local-first persistent memory for AI agents over MCP. Ground truths, negative learning (recorded failures block repeats), decision causality, hybrid recall, live memory streams, run-attributed fleet memory — a structured SQLite memory on your machine, no cloud or LLM required. Claude / Copilot / Cursor / Windsurf / Codex.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",