@pcircle/memesh 4.8.3 → 4.9.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.
Files changed (254) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +2 -1
  3. package/.codex-plugin/mcp.json +6 -4
  4. package/.codex-plugin/plugin.json +1 -1
  5. package/AGENTS.md +68 -17
  6. package/README.de.md +83 -555
  7. package/README.md +83 -581
  8. package/README.zh-TW.md +84 -572
  9. package/dashboard/dist/index.html +10 -10
  10. package/dist/cli/view-live.d.ts.map +1 -1
  11. package/dist/cli/view-live.js +154 -384
  12. package/dist/cli/view-live.js.map +1 -1
  13. package/dist/core/agent-message-inbox.d.ts +2 -1
  14. package/dist/core/agent-message-inbox.d.ts.map +1 -1
  15. package/dist/core/agent-message-inbox.js +23 -4
  16. package/dist/core/agent-message-inbox.js.map +1 -1
  17. package/dist/core/agent-messaging.d.ts.map +1 -1
  18. package/dist/core/agent-messaging.js +23 -15
  19. package/dist/core/agent-messaging.js.map +1 -1
  20. package/dist/core/agent-router.d.ts +11 -10
  21. package/dist/core/agent-router.d.ts.map +1 -1
  22. package/dist/core/agent-router.js +29 -14
  23. package/dist/core/agent-router.js.map +1 -1
  24. package/dist/core/agent-scope-id.d.ts +11 -0
  25. package/dist/core/agent-scope-id.d.ts.map +1 -0
  26. package/dist/core/agent-scope-id.js +40 -0
  27. package/dist/core/agent-scope-id.js.map +1 -0
  28. package/dist/core/analytics.d.ts.map +1 -1
  29. package/dist/core/analytics.js.map +1 -1
  30. package/dist/core/briefing.d.ts.map +1 -1
  31. package/dist/core/briefing.js +8 -2
  32. package/dist/core/briefing.js.map +1 -1
  33. package/dist/core/config.d.ts +4 -40
  34. package/dist/core/config.d.ts.map +1 -1
  35. package/dist/core/config.js +75 -141
  36. package/dist/core/config.js.map +1 -1
  37. package/dist/core/demo.d.ts.map +1 -1
  38. package/dist/core/demo.js +6 -6
  39. package/dist/core/demo.js.map +1 -1
  40. package/dist/core/doctor.d.ts +2 -6
  41. package/dist/core/doctor.d.ts.map +1 -1
  42. package/dist/core/doctor.js +120 -154
  43. package/dist/core/doctor.js.map +1 -1
  44. package/dist/core/dreamer.d.ts +32 -47
  45. package/dist/core/dreamer.d.ts.map +1 -1
  46. package/dist/core/dreamer.js +214 -704
  47. package/dist/core/dreamer.js.map +1 -1
  48. package/dist/core/install-channel.d.ts.map +1 -1
  49. package/dist/core/install-channel.js +4 -47
  50. package/dist/core/install-channel.js.map +1 -1
  51. package/dist/core/install-id.d.ts.map +1 -1
  52. package/dist/core/install-id.js.map +1 -1
  53. package/dist/core/kg-backfill.d.ts.map +1 -1
  54. package/dist/core/kg-backfill.js.map +1 -1
  55. package/dist/core/lesson-engine.d.ts +0 -5
  56. package/dist/core/lesson-engine.d.ts.map +1 -1
  57. package/dist/core/lesson-engine.js +0 -25
  58. package/dist/core/lesson-engine.js.map +1 -1
  59. package/dist/core/lifecycle.d.ts.map +1 -1
  60. package/dist/core/lifecycle.js +58 -49
  61. package/dist/core/lifecycle.js.map +1 -1
  62. package/dist/core/memory-tool.d.ts.map +1 -1
  63. package/dist/core/memory-tool.js +20 -18
  64. package/dist/core/memory-tool.js.map +1 -1
  65. package/dist/core/operations.d.ts +3 -27
  66. package/dist/core/operations.d.ts.map +1 -1
  67. package/dist/core/operations.js +10 -245
  68. package/dist/core/operations.js.map +1 -1
  69. package/dist/core/paths.d.ts +4 -1
  70. package/dist/core/paths.d.ts.map +1 -1
  71. package/dist/core/paths.js +88 -14
  72. package/dist/core/paths.js.map +1 -1
  73. package/dist/core/product-improvements.js +2 -2
  74. package/dist/core/product-improvements.js.map +1 -1
  75. package/dist/core/project-tags.d.ts +2 -0
  76. package/dist/core/project-tags.d.ts.map +1 -1
  77. package/dist/core/project-tags.js +29 -1
  78. package/dist/core/project-tags.js.map +1 -1
  79. package/dist/core/schema-export.d.ts.map +1 -1
  80. package/dist/core/schema-export.js +13 -3
  81. package/dist/core/schema-export.js.map +1 -1
  82. package/dist/core/semver.d.ts +7 -0
  83. package/dist/core/semver.d.ts.map +1 -0
  84. package/dist/core/semver.js +49 -0
  85. package/dist/core/semver.js.map +1 -0
  86. package/dist/core/serializer.d.ts.map +1 -1
  87. package/dist/core/serializer.js +69 -57
  88. package/dist/core/serializer.js.map +1 -1
  89. package/dist/core/signal-scorer.d.ts.map +1 -1
  90. package/dist/core/signal-scorer.js.map +1 -1
  91. package/dist/core/transcript-extractor.d.ts +1 -85
  92. package/dist/core/transcript-extractor.d.ts.map +1 -1
  93. package/dist/core/transcript-extractor.js +5 -364
  94. package/dist/core/transcript-extractor.js.map +1 -1
  95. package/dist/core/transcript-source.d.ts +22 -6
  96. package/dist/core/transcript-source.d.ts.map +1 -1
  97. package/dist/core/transcript-source.js +108 -69
  98. package/dist/core/transcript-source.js.map +1 -1
  99. package/dist/core/types.d.ts +1 -17
  100. package/dist/core/types.d.ts.map +1 -1
  101. package/dist/core/version-check.d.ts +1 -0
  102. package/dist/core/version-check.d.ts.map +1 -1
  103. package/dist/core/version-check.js +46 -1
  104. package/dist/core/version-check.js.map +1 -1
  105. package/dist/db.d.ts +0 -34
  106. package/dist/db.d.ts.map +1 -1
  107. package/dist/db.js +6 -287
  108. package/dist/db.js.map +1 -1
  109. package/dist/host-runtime/acp.d.ts.map +1 -1
  110. package/dist/host-runtime/acp.js +4 -3
  111. package/dist/host-runtime/acp.js.map +1 -1
  112. package/dist/host-runtime/claude.d.ts.map +1 -1
  113. package/dist/host-runtime/claude.js +11 -11
  114. package/dist/host-runtime/claude.js.map +1 -1
  115. package/dist/host-runtime/codex-session.d.ts +9 -1
  116. package/dist/host-runtime/codex-session.d.ts.map +1 -1
  117. package/dist/host-runtime/codex-session.js +474 -29
  118. package/dist/host-runtime/codex-session.js.map +1 -1
  119. package/dist/host-runtime/codex.d.ts.map +1 -1
  120. package/dist/host-runtime/codex.js +4 -3
  121. package/dist/host-runtime/codex.js.map +1 -1
  122. package/dist/host-runtime/config.d.ts +1 -0
  123. package/dist/host-runtime/config.d.ts.map +1 -1
  124. package/dist/host-runtime/config.js +4 -0
  125. package/dist/host-runtime/config.js.map +1 -1
  126. package/dist/host-runtime/entry.d.ts +5 -0
  127. package/dist/host-runtime/entry.d.ts.map +1 -0
  128. package/dist/host-runtime/entry.js +11 -0
  129. package/dist/host-runtime/entry.js.map +1 -0
  130. package/dist/host-runtime/router-client.d.ts.map +1 -1
  131. package/dist/host-runtime/router-client.js +62 -15
  132. package/dist/host-runtime/router-client.js.map +1 -1
  133. package/dist/host-runtime/router.js +2 -2
  134. package/dist/host-runtime/router.js.map +1 -1
  135. package/dist/knowledge-graph.d.ts +0 -1
  136. package/dist/knowledge-graph.d.ts.map +1 -1
  137. package/dist/knowledge-graph.js +77 -60
  138. package/dist/knowledge-graph.js.map +1 -1
  139. package/dist/mcp/THIRD_PARTY_NOTICES.txt +217 -0
  140. package/dist/mcp/server.js +30685 -38
  141. package/dist/mcp/server.js.map +6 -1
  142. package/dist/skills-manifest.json +39 -34
  143. package/dist/storage/entity-index.d.ts +3 -0
  144. package/dist/storage/entity-index.d.ts.map +1 -0
  145. package/dist/storage/entity-index.js +8 -0
  146. package/dist/storage/entity-index.js.map +1 -0
  147. package/dist/storage/fts-index.d.ts.map +1 -1
  148. package/dist/storage/fts-index.js +11 -7
  149. package/dist/storage/fts-index.js.map +1 -1
  150. package/dist/storage/graph-repairs.d.ts +7 -2
  151. package/dist/storage/graph-repairs.d.ts.map +1 -1
  152. package/dist/storage/graph-repairs.js +89 -13
  153. package/dist/storage/graph-repairs.js.map +1 -1
  154. package/dist/storage/schema.d.ts +1 -1
  155. package/dist/storage/schema.d.ts.map +1 -1
  156. package/dist/storage/schema.js +1 -2
  157. package/dist/storage/schema.js.map +1 -1
  158. package/dist/storage/sqlite.d.ts +0 -1
  159. package/dist/storage/sqlite.d.ts.map +1 -1
  160. package/dist/storage/sqlite.js.map +1 -1
  161. package/dist/transports/agent-messaging.d.ts.map +1 -1
  162. package/dist/transports/agent-messaging.js +5 -7
  163. package/dist/transports/agent-messaging.js.map +1 -1
  164. package/dist/transports/cli/cli.d.ts.map +1 -1
  165. package/dist/transports/cli/cli.js +75 -686
  166. package/dist/transports/cli/cli.js.map +1 -1
  167. package/dist/transports/http/retired-routes.js +1 -1
  168. package/dist/transports/http/retired-routes.js.map +1 -1
  169. package/dist/transports/http/server.d.ts.map +1 -1
  170. package/dist/transports/http/server.js +13 -232
  171. package/dist/transports/http/server.js.map +1 -1
  172. package/dist/transports/mcp/handlers.d.ts +130 -4
  173. package/dist/transports/mcp/handlers.d.ts.map +1 -1
  174. package/dist/transports/mcp/handlers.js +56 -7
  175. package/dist/transports/mcp/handlers.js.map +1 -1
  176. package/dist/transports/schemas.d.ts +71 -19
  177. package/dist/transports/schemas.d.ts.map +1 -1
  178. package/dist/transports/schemas.js +57 -11
  179. package/dist/transports/schemas.js.map +1 -1
  180. package/docs/platforms/README.md +6 -5
  181. package/docs/platforms/agent-messaging.md +241 -20
  182. package/hooks/hooks.json +23 -2
  183. package/llms-install.md +62 -30
  184. package/package.json +12 -9
  185. package/scripts/hooks/_generated/agent-message-inbox.js +23 -4
  186. package/scripts/hooks/_generated/core-paths.js +88 -14
  187. package/scripts/hooks/_generated/fts-index.js +11 -7
  188. package/scripts/hooks/_generated/schema.js +1 -2
  189. package/scripts/hooks/_shared.js +65 -23
  190. package/scripts/hooks/decision-nudge.js +152 -0
  191. package/scripts/hooks/post-commit.js +11 -0
  192. package/scripts/hooks/pre-compact.js +12 -4
  193. package/scripts/hooks/session-start.js +32 -9
  194. package/scripts/hooks/session-summary.js +19 -374
  195. package/scripts/upgrade-plugin.sh +71 -2
  196. package/skills/memesh/SKILL.md +24 -15
  197. package/skills/memesh-review/SKILL.md +7 -6
  198. package/dist/core/auto-tagger.d.ts +0 -10
  199. package/dist/core/auto-tagger.d.ts.map +0 -1
  200. package/dist/core/auto-tagger.js +0 -63
  201. package/dist/core/auto-tagger.js.map +0 -1
  202. package/dist/core/conflict-candidates.d.ts +0 -20
  203. package/dist/core/conflict-candidates.d.ts.map +0 -1
  204. package/dist/core/conflict-candidates.js +0 -71
  205. package/dist/core/conflict-candidates.js.map +0 -1
  206. package/dist/core/conflict-judge.d.ts +0 -58
  207. package/dist/core/conflict-judge.d.ts.map +0 -1
  208. package/dist/core/conflict-judge.js +0 -189
  209. package/dist/core/conflict-judge.js.map +0 -1
  210. package/dist/core/digest-validator.d.ts +0 -18
  211. package/dist/core/digest-validator.d.ts.map +0 -1
  212. package/dist/core/digest-validator.js +0 -85
  213. package/dist/core/digest-validator.js.map +0 -1
  214. package/dist/core/embedder.d.ts +0 -20
  215. package/dist/core/embedder.d.ts.map +0 -1
  216. package/dist/core/embedder.js +0 -242
  217. package/dist/core/embedder.js.map +0 -1
  218. package/dist/core/failure-analyzer.d.ts +0 -19
  219. package/dist/core/failure-analyzer.d.ts.map +0 -1
  220. package/dist/core/failure-analyzer.js +0 -83
  221. package/dist/core/failure-analyzer.js.map +0 -1
  222. package/dist/core/json-utils.d.ts +0 -3
  223. package/dist/core/json-utils.d.ts.map +0 -1
  224. package/dist/core/json-utils.js +0 -46
  225. package/dist/core/json-utils.js.map +0 -1
  226. package/dist/core/llm-client.d.ts +0 -22
  227. package/dist/core/llm-client.d.ts.map +0 -1
  228. package/dist/core/llm-client.js +0 -203
  229. package/dist/core/llm-client.js.map +0 -1
  230. package/dist/core/llm-telemetry.d.ts +0 -47
  231. package/dist/core/llm-telemetry.d.ts.map +0 -1
  232. package/dist/core/llm-telemetry.js +0 -117
  233. package/dist/core/llm-telemetry.js.map +0 -1
  234. package/dist/core/llm-validator.d.ts +0 -20
  235. package/dist/core/llm-validator.d.ts.map +0 -1
  236. package/dist/core/llm-validator.js +0 -231
  237. package/dist/core/llm-validator.js.map +0 -1
  238. package/dist/core/ollama-host.d.ts +0 -6
  239. package/dist/core/ollama-host.d.ts.map +0 -1
  240. package/dist/core/ollama-host.js +0 -30
  241. package/dist/core/ollama-host.js.map +0 -1
  242. package/dist/core/output-language.d.ts +0 -6
  243. package/dist/core/output-language.d.ts.map +0 -1
  244. package/dist/core/output-language.js +0 -25
  245. package/dist/core/output-language.js.map +0 -1
  246. package/dist/core/prompt-safety.d.ts +0 -4
  247. package/dist/core/prompt-safety.d.ts.map +0 -1
  248. package/dist/core/prompt-safety.js +0 -20
  249. package/dist/core/prompt-safety.js.map +0 -1
  250. package/dist/storage/vector-index.d.ts +0 -3
  251. package/dist/storage/vector-index.d.ts.map +0 -1
  252. package/dist/storage/vector-index.js +0 -13
  253. package/dist/storage/vector-index.js.map +0 -1
  254. /package/{.mcp.json → .claude-plugin/mcp.json} +0 -0
@@ -258,11 +258,6 @@ export function generateLiveDashboardHtml() {
258
258
  .form-group { margin-bottom: 14px; }
259
259
  .form-label { display: block; font-size: 13px; font-weight: 500; color: var(--text-primary); margin-bottom: 5px; }
260
260
  .form-hint { font-size: 12px; color: var(--text-muted); margin-top: 4px; }
261
- .provider-radio-group { display: flex; gap: 8px; flex-wrap: wrap; }
262
- .provider-radio { display: flex; align-items: center; gap: 6px; padding: 8px 14px; border: 1px solid var(--border); border-radius: var(--radius-sm); cursor: pointer; transition: border-color 0.15s; color: var(--text-secondary); font-size: 13px; }
263
- .provider-radio:hover { border-color: var(--accent); color: var(--text-primary); }
264
- .provider-radio.selected { border-color: var(--accent); background: var(--accent-glow); color: var(--accent-hover); }
265
- .provider-radio input[type=radio] { accent-color: var(--accent); }
266
261
  .cap-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; margin-bottom: 16px; }
267
262
  .cap-item { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; font-size: 12px; }
268
263
  .cap-item .cap-label { color: var(--text-muted); margin-bottom: 2px; }
@@ -277,10 +272,6 @@ export function generateLiveDashboardHtml() {
277
272
  .wizard-modal { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius); padding: 32px; max-width: 520px; width: 90%; box-shadow: var(--shadow-lg); }
278
273
  .wizard-modal h2 { font-size: 22px; font-weight: 700; margin-bottom: 8px; color: var(--text-primary); letter-spacing: -0.02em; }
279
274
  .wizard-modal .subtitle { color: var(--text-secondary); font-size: 14px; margin-bottom: 24px; line-height: 1.6; }
280
- .wizard-steps { display: flex; gap: 6px; margin-bottom: 28px; }
281
- .wizard-step-dot { flex: 1; height: 3px; background: var(--border); border-radius: 2px; transition: background 0.2s; }
282
- .wizard-step-dot.active { background: var(--accent); }
283
- .wizard-step-dot.done { background: var(--success); }
284
275
  .wizard-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 24px; }
285
276
 
286
277
  /* Analytics */
@@ -391,8 +382,6 @@ export function generateLiveDashboardHtml() {
391
382
  'use strict';
392
383
 
393
384
  var _currentVersion = '';
394
- var _currentSearchLevel = '';
395
-
396
385
  // ---- API ----
397
386
  async function apiCall(method, path, body) {
398
387
  var controller = new AbortController();
@@ -411,6 +400,35 @@ export function generateLiveDashboardHtml() {
411
400
  }
412
401
  }
413
402
 
403
+ function successData(response, label) {
404
+ if (!response || response.success !== true) {
405
+ throw new Error((response && response.error) || ('Failed to load ' + label));
406
+ }
407
+ return response.data;
408
+ }
409
+
410
+ function entityList(value, label) {
411
+ if (!Array.isArray(value)) throw new Error('Invalid ' + label + ' response');
412
+ return value;
413
+ }
414
+
415
+ function graphData(value) {
416
+ if (!value || typeof value !== 'object'
417
+ || !Array.isArray(value.entities) || !Array.isArray(value.relations)) {
418
+ throw new Error('Invalid graph response');
419
+ }
420
+ return value;
421
+ }
422
+
423
+ function configData(response) {
424
+ var value = successData(response, 'config');
425
+ if (!value || typeof value !== 'object' || !value.config
426
+ || typeof value.config !== 'object' || Array.isArray(value.config)) {
427
+ throw new Error('Invalid config response');
428
+ }
429
+ return value.config;
430
+ }
431
+
414
432
  // ---- Theme (dark default, light class toggles light mode) ----
415
433
  (function initTheme() {
416
434
  var saved = localStorage.getItem('memesh-theme');
@@ -644,8 +662,10 @@ export function generateLiveDashboardHtml() {
644
662
  try {
645
663
  var data = await apiCall('POST', '/v1/recall', { query: q, limit: 20 });
646
664
  searchResults.textContent = '';
647
- if (!data.success) { showError(searchResults, data.error || 'Unknown error'); return; }
648
- var entities = Array.isArray(data.data) ? data.data : (data.data.entities || []);
665
+ var result = successData(data, 'search results');
666
+ var entities = Array.isArray(result)
667
+ ? result
668
+ : entityList(result && result.entities, 'search results');
649
669
  if (entities.length === 0) { showPlaceholder(searchResults, 'No results for "' + q + '"'); return; }
650
670
  searchResults.appendChild(buildEntityTable(entities, q));
651
671
  } catch (err) {
@@ -665,8 +685,7 @@ export function generateLiveDashboardHtml() {
665
685
  showSpinner(browseWrap);
666
686
  try {
667
687
  var data = await apiCall('GET', '/v1/entities?limit=200');
668
- if (!data.success) throw new Error(data.error || 'Failed to load entities');
669
- allEntities = data.data || [];
688
+ allEntities = entityList(successData(data, 'entities'), 'entities');
670
689
  renderBrowseTable(browseFilter.value);
671
690
  } catch (err) {
672
691
  showError(browseWrap, err.message);
@@ -696,8 +715,8 @@ export function generateLiveDashboardHtml() {
696
715
  showSpinner(wrap);
697
716
  try {
698
717
  var data = await apiCall('GET', '/v1/graph');
699
- if (!data.success) throw new Error(data.error || 'Failed to load graph');
700
- renderGraph(data.data.entities || [], data.data.relations || [], wrap);
718
+ var graph = graphData(successData(data, 'graph'));
719
+ renderGraph(graph.entities, graph.relations, wrap);
701
720
  } catch (err) {
702
721
  showError(wrap, err.message);
703
722
  graphLoaded = false;
@@ -1115,8 +1134,8 @@ export function generateLiveDashboardHtml() {
1115
1134
  showSpinner(container);
1116
1135
  try {
1117
1136
  var data = await apiCall('GET', '/v1/graph');
1118
- if (!data.success) throw new Error(data.error || 'Failed to load graph');
1119
- renderTimeline(data.data.entities || [], data.data.relations || [], container);
1137
+ var graph = graphData(successData(data, 'graph'));
1138
+ renderTimeline(graph.entities, graph.relations, container);
1120
1139
  } catch (err) {
1121
1140
  showError(container, err.message);
1122
1141
  timelineLoaded = false;
@@ -1238,8 +1257,7 @@ export function generateLiveDashboardHtml() {
1238
1257
  showSpinner(tableWrap);
1239
1258
  try {
1240
1259
  var data = await apiCall('GET', '/v1/entities?limit=500&status=all');
1241
- if (!data.success) throw new Error(data.error || 'Failed to load');
1242
- allManageEntities = data.data || [];
1260
+ allManageEntities = entityList(successData(data, 'entities'), 'entities');
1243
1261
  renderManageTable();
1244
1262
  } catch (err) {
1245
1263
  showError(tableWrap, err.message);
@@ -1496,7 +1514,7 @@ export function generateLiveDashboardHtml() {
1496
1514
  var title = encodeURIComponent('[' + fbType + '] ' + desc.slice(0, 50));
1497
1515
  var bodyText = '## Description\\n' + desc;
1498
1516
  if (includeSys) {
1499
- bodyText += '\\n\\n## System Info\\nVersion: ' + _currentVersion + '\\nSearch Level: ' + _currentSearchLevel;
1517
+ bodyText += '\\n\\n## System Info\\nVersion: ' + _currentVersion;
1500
1518
  }
1501
1519
  var body = encodeURIComponent(bodyText);
1502
1520
  window.open('https://github.com/PCIRCLE-AI/memesh/issues/new?title=' + title + '&body=' + body + '&labels=' + labels, '_blank');
@@ -1514,11 +1532,7 @@ export function generateLiveDashboardHtml() {
1514
1532
  })();
1515
1533
 
1516
1534
  // ---- Settings tab ----
1517
- var settingsLoaded = false;
1518
-
1519
1535
  async function loadSettings() {
1520
- if (settingsLoaded) return;
1521
- settingsLoaded = false; // allow re-render on each visit to reflect saved state
1522
1536
  var body = document.getElementById('settings-body');
1523
1537
  body.textContent = '';
1524
1538
 
@@ -1530,14 +1544,19 @@ export function generateLiveDashboardHtml() {
1530
1544
  return;
1531
1545
  }
1532
1546
 
1533
- var currentConfig = (configRes.success && configRes.data && configRes.data.config) || {};
1534
- var caps = (configRes.success && configRes.data && configRes.data.capabilities) || {};
1547
+ var currentConfig;
1548
+ try {
1549
+ currentConfig = configData(configRes);
1550
+ } catch (err) {
1551
+ showError(body, 'Failed to load config: ' + err.message);
1552
+ return;
1553
+ }
1535
1554
 
1536
- // --- Capabilities section ---
1555
+ // --- Status ---
1537
1556
  var capSection = document.createElement('div');
1538
1557
  capSection.className = 'settings-section';
1539
1558
  var capH3 = document.createElement('h3');
1540
- capH3.textContent = 'Current Capabilities';
1559
+ capH3.textContent = 'Status';
1541
1560
  capSection.appendChild(capH3);
1542
1561
 
1543
1562
  var capGrid = document.createElement('div');
@@ -1562,150 +1581,12 @@ export function generateLiveDashboardHtml() {
1562
1581
  capGrid.appendChild(item);
1563
1582
  }
1564
1583
 
1565
- var searchLevel = caps.searchLevel !== undefined ? caps.searchLevel : '?';
1566
- _currentSearchLevel = String(searchLevel);
1567
- addCap('Search Level', searchLevel === 1 ? 'Smart Mode' : 'Core FTS5', searchLevel === 1);
1568
- addCap('Embeddings', caps.embeddings, caps.embeddings !== 'tfidf');
1569
- var llmProvider = (caps.llm && caps.llm.provider) ? caps.llm.provider : 'None';
1570
- addCap('LLM Provider', llmProvider, !!caps.llm);
1571
- var llmModel = (caps.llm && caps.llm.model) ? caps.llm.model : '\u2014';
1572
- addCap('LLM Model', llmModel, !!caps.llm);
1584
+ addCap('Memory engine', 'Local FTS5', true);
1585
+ addCap('Initial setup', currentConfig.setupCompleted ? 'Complete' : 'Not complete', currentConfig.setupCompleted === true);
1573
1586
 
1574
1587
  capSection.appendChild(capGrid);
1575
1588
  body.appendChild(capSection);
1576
1589
 
1577
- // --- LLM Provider section ---
1578
- var llmSection = document.createElement('div');
1579
- llmSection.className = 'settings-section';
1580
- var llmH3 = document.createElement('h3');
1581
- llmH3.textContent = 'LLM Provider';
1582
- llmSection.appendChild(llmH3);
1583
-
1584
- var providerGroup = document.createElement('div');
1585
- providerGroup.className = 'form-group';
1586
- var providerLabel = document.createElement('label');
1587
- providerLabel.className = 'form-label';
1588
- providerLabel.textContent = 'Provider';
1589
- providerGroup.appendChild(providerLabel);
1590
-
1591
- var radioGroup = document.createElement('div');
1592
- radioGroup.className = 'provider-radio-group';
1593
- var currentProvider = (currentConfig.llm && currentConfig.llm.provider) || '';
1594
-
1595
- ['anthropic', 'openai', 'ollama'].forEach(function (p) {
1596
- var wrapper = document.createElement('label');
1597
- wrapper.className = 'provider-radio' + (currentProvider === p ? ' selected' : '');
1598
-
1599
- var radio = document.createElement('input');
1600
- radio.type = 'radio';
1601
- radio.name = 'llm-provider';
1602
- radio.value = p;
1603
- if (currentProvider === p) radio.checked = true;
1604
-
1605
- radio.addEventListener('change', function () {
1606
- document.querySelectorAll('.provider-radio').forEach(function (el) { el.classList.remove('selected'); });
1607
- wrapper.classList.add('selected');
1608
- apiKeyGroup.style.display = p === 'ollama' ? 'none' : 'block';
1609
- modelGroup.style.display = 'block';
1610
- });
1611
-
1612
- wrapper.appendChild(radio);
1613
- wrapper.appendChild(document.createTextNode(p.charAt(0).toUpperCase() + p.slice(1)));
1614
- radioGroup.appendChild(wrapper);
1615
- });
1616
-
1617
- providerGroup.appendChild(radioGroup);
1618
- llmSection.appendChild(providerGroup);
1619
-
1620
- // API Key input
1621
- var apiKeyGroup = document.createElement('div');
1622
- apiKeyGroup.className = 'form-group';
1623
- apiKeyGroup.style.display = currentProvider && currentProvider !== 'ollama' ? 'block' : (currentProvider === 'ollama' ? 'none' : 'none');
1624
-
1625
- var apiKeyLabel = document.createElement('label');
1626
- apiKeyLabel.className = 'form-label';
1627
- apiKeyLabel.textContent = 'API Key';
1628
- apiKeyGroup.appendChild(apiKeyLabel);
1629
-
1630
- var apiKeyInput = document.createElement('input');
1631
- apiKeyInput.type = 'password';
1632
- apiKeyInput.className = 'search-input';
1633
- apiKeyInput.placeholder = 'sk-ant-api03-\u2026 or sk-\u2026';
1634
- apiKeyInput.style.width = '100%';
1635
- apiKeyInput.autocomplete = 'off';
1636
- apiKeyGroup.appendChild(apiKeyInput);
1637
-
1638
- var apiKeyHint = document.createElement('div');
1639
- apiKeyHint.className = 'form-hint';
1640
- apiKeyHint.textContent = 'Leave blank to keep existing key. Key is stored in ~/.memesh/config.json (mode 600).';
1641
- apiKeyGroup.appendChild(apiKeyHint);
1642
- llmSection.appendChild(apiKeyGroup);
1643
-
1644
- // Model input
1645
- var modelGroup = document.createElement('div');
1646
- modelGroup.className = 'form-group';
1647
- modelGroup.style.display = currentProvider ? 'block' : 'none';
1648
-
1649
- var modelLabel = document.createElement('label');
1650
- modelLabel.className = 'form-label';
1651
- modelLabel.textContent = 'Model (optional)';
1652
- modelGroup.appendChild(modelLabel);
1653
-
1654
- var modelInput = document.createElement('input');
1655
- modelInput.type = 'text';
1656
- modelInput.className = 'search-input';
1657
- modelInput.placeholder = 'e.g. claude-haiku-4-5, gpt-4o-mini, llama3.2';
1658
- modelInput.style.width = '100%';
1659
- if (currentConfig.llm && currentConfig.llm.model) modelInput.value = currentConfig.llm.model;
1660
- modelGroup.appendChild(modelInput);
1661
- llmSection.appendChild(modelGroup);
1662
-
1663
- // Save button row
1664
- var saveRow = document.createElement('div');
1665
- saveRow.style.display = 'flex';
1666
- saveRow.style.gap = '10px';
1667
- saveRow.style.alignItems = 'center';
1668
- saveRow.style.marginTop = '4px';
1669
-
1670
- var saveBtn = document.createElement('button');
1671
- saveBtn.className = 'btn btn-primary btn-sm';
1672
- saveBtn.textContent = 'Save';
1673
-
1674
- var saveMsg = document.createElement('span');
1675
- saveMsg.style.fontSize = '13px';
1676
- saveMsg.style.color = 'var(--success)';
1677
-
1678
- saveBtn.addEventListener('click', async function () {
1679
- var selectedProvider = document.querySelector('input[name=llm-provider]:checked');
1680
- if (!selectedProvider) { saveMsg.style.color = 'var(--danger)'; saveMsg.textContent = 'Select a provider first.'; return; }
1681
- var prov = selectedProvider.value;
1682
- var llmUpdate = { provider: prov };
1683
- if (modelInput.value.trim()) llmUpdate.model = modelInput.value.trim();
1684
- if (apiKeyInput.value.trim()) llmUpdate.apiKey = apiKeyInput.value.trim();
1685
-
1686
- saveBtn.disabled = true;
1687
- saveBtn.textContent = 'Saving\u2026';
1688
- try {
1689
- var res = await apiCall('POST', '/v1/config', { llm: llmUpdate });
1690
- if (!res.success) throw new Error(res.error || 'Save failed');
1691
- saveMsg.style.color = 'var(--success)';
1692
- saveMsg.textContent = 'Saved! Restart the server to apply LLM changes.';
1693
- apiKeyInput.value = '';
1694
- settingsLoaded = false; // force re-render on next visit
1695
- } catch (err) {
1696
- saveMsg.style.color = 'var(--danger)';
1697
- saveMsg.textContent = 'Error: ' + err.message;
1698
- } finally {
1699
- saveBtn.disabled = false;
1700
- saveBtn.textContent = 'Save';
1701
- }
1702
- });
1703
-
1704
- saveRow.appendChild(saveBtn);
1705
- saveRow.appendChild(saveMsg);
1706
- llmSection.appendChild(saveRow);
1707
- body.appendChild(llmSection);
1708
-
1709
1590
  // --- General settings section ---
1710
1591
  var genSection = document.createElement('div');
1711
1592
  genSection.className = 'settings-section';
@@ -1731,7 +1612,7 @@ export function generateLiveDashboardHtml() {
1731
1612
  autoLabel.style.fontSize = '13px';
1732
1613
  autoLabel.style.fontWeight = '600';
1733
1614
  autoLabel.style.cursor = 'pointer';
1734
- autoLabel.textContent = 'Auto-capture (session-start hook)';
1615
+ autoLabel.textContent = 'Auto-capture';
1735
1616
 
1736
1617
  autoGroup.appendChild(autoCheck);
1737
1618
  autoGroup.appendChild(autoLabel);
@@ -1740,9 +1621,63 @@ export function generateLiveDashboardHtml() {
1740
1621
  var autoHint = document.createElement('div');
1741
1622
  autoHint.className = 'form-hint';
1742
1623
  autoHint.style.marginLeft = '28px';
1743
- autoHint.textContent = 'Automatically recall project memories at the start of each Claude Code session.';
1624
+ autoHint.textContent = 'Automatically load project memories when a supported agent session starts.';
1744
1625
  genSection.appendChild(autoHint);
1745
1626
 
1627
+ // Auto-update policy
1628
+ var updateGroup = document.createElement('div');
1629
+ updateGroup.className = 'form-group';
1630
+ var updateLabel = document.createElement('label');
1631
+ updateLabel.className = 'form-label';
1632
+ updateLabel.htmlFor = 'auto-update';
1633
+ updateLabel.textContent = 'Automatic updates';
1634
+ updateGroup.appendChild(updateLabel);
1635
+
1636
+ var autoUpdateSelect = document.createElement('select');
1637
+ autoUpdateSelect.id = 'auto-update';
1638
+ autoUpdateSelect.className = 'search-input';
1639
+ autoUpdateSelect.style.width = '100%';
1640
+ [
1641
+ ['off', 'Off'],
1642
+ ['patch', 'Patch releases'],
1643
+ ['minor', 'Minor releases'],
1644
+ ['major', 'All releases'],
1645
+ ].forEach(function (option) {
1646
+ var el = document.createElement('option');
1647
+ el.value = option[0];
1648
+ el.textContent = option[1];
1649
+ autoUpdateSelect.appendChild(el);
1650
+ });
1651
+ autoUpdateSelect.value = currentConfig.autoUpdate || 'off';
1652
+ updateGroup.appendChild(autoUpdateSelect);
1653
+ genSection.appendChild(updateGroup);
1654
+
1655
+ // Session memory limit
1656
+ var limitGroup = document.createElement('div');
1657
+ limitGroup.className = 'form-group';
1658
+ var limitLabel = document.createElement('label');
1659
+ limitLabel.className = 'form-label';
1660
+ limitLabel.htmlFor = 'session-limit';
1661
+ limitLabel.textContent = 'Session memory limit';
1662
+ limitGroup.appendChild(limitLabel);
1663
+
1664
+ var limitInput = document.createElement('input');
1665
+ limitInput.id = 'session-limit';
1666
+ limitInput.type = 'number';
1667
+ limitInput.min = '1';
1668
+ limitInput.max = '100';
1669
+ limitInput.step = '1';
1670
+ limitInput.className = 'search-input';
1671
+ limitInput.style.width = '100%';
1672
+ limitInput.value = String(currentConfig.sessionLimit || 10);
1673
+ limitGroup.appendChild(limitInput);
1674
+
1675
+ var limitHint = document.createElement('div');
1676
+ limitHint.className = 'form-hint';
1677
+ limitHint.textContent = 'Number of recent memories loaded for session context (1\u2013100).';
1678
+ limitGroup.appendChild(limitHint);
1679
+ genSection.appendChild(limitGroup);
1680
+
1746
1681
  var genSaveRow = document.createElement('div');
1747
1682
  genSaveRow.style.marginTop = '12px';
1748
1683
 
@@ -1751,21 +1686,39 @@ export function generateLiveDashboardHtml() {
1751
1686
  genSaveBtn.textContent = 'Save';
1752
1687
 
1753
1688
  var genMsg = document.createElement('span');
1689
+ genMsg.id = 'general-settings-message';
1754
1690
  genMsg.style.fontSize = '13px';
1755
1691
  genMsg.style.marginLeft = '10px';
1756
1692
  genMsg.style.color = 'var(--success)';
1693
+ genMsg.setAttribute('role', 'status');
1694
+ limitInput.setAttribute('aria-describedby', genMsg.id);
1757
1695
 
1758
1696
  genSaveBtn.addEventListener('click', async function () {
1697
+ var sessionLimit = Number(limitInput.value);
1698
+ if (!Number.isInteger(sessionLimit) || sessionLimit < 1 || sessionLimit > 100) {
1699
+ genMsg.style.color = 'var(--danger)';
1700
+ genMsg.setAttribute('role', 'alert');
1701
+ genMsg.textContent = 'Session memory limit must be a whole number from 1 to 100.';
1702
+ limitInput.setAttribute('aria-invalid', 'true');
1703
+ return;
1704
+ }
1705
+ limitInput.removeAttribute('aria-invalid');
1759
1706
  genSaveBtn.disabled = true;
1760
1707
  genSaveBtn.textContent = 'Saving\u2026';
1761
1708
  try {
1762
- var res = await apiCall('POST', '/v1/config', { autoCapture: autoCheck.checked });
1709
+ var res = await apiCall('POST', '/v1/config', {
1710
+ autoCapture: autoCheck.checked,
1711
+ autoUpdate: autoUpdateSelect.value,
1712
+ sessionLimit: sessionLimit,
1713
+ });
1763
1714
  if (!res.success) throw new Error(res.error || 'Save failed');
1764
1715
  genMsg.style.color = 'var(--success)';
1716
+ genMsg.setAttribute('role', 'status');
1765
1717
  genMsg.textContent = 'Saved!';
1766
1718
  setTimeout(function () { genMsg.textContent = ''; }, 3000);
1767
1719
  } catch (err) {
1768
1720
  genMsg.style.color = 'var(--danger)';
1721
+ genMsg.setAttribute('role', 'alert');
1769
1722
  genMsg.textContent = 'Error: ' + err.message;
1770
1723
  } finally {
1771
1724
  genSaveBtn.disabled = false;
@@ -1779,225 +1732,43 @@ export function generateLiveDashboardHtml() {
1779
1732
  body.appendChild(genSection);
1780
1733
  }
1781
1734
 
1782
- // ---- Welcome Wizard ----
1783
- var wizardStep = 0;
1784
- var wizardProvider = '';
1785
- var wizardApiKey = '';
1786
- var wizardModel = '';
1787
-
1788
- function updateWizardStepDots(totalSteps) {
1789
- var dotsEl = document.getElementById('wizard-steps');
1790
- dotsEl.textContent = '';
1791
- for (var i = 0; i < totalSteps; i++) {
1792
- var dot = document.createElement('div');
1793
- dot.className = 'wizard-step-dot' + (i < wizardStep ? ' done' : (i === wizardStep ? ' active' : ''));
1794
- dotsEl.appendChild(dot);
1795
- }
1796
- }
1797
-
1798
- function renderWizardStep() {
1735
+ // ---- Welcome ----
1736
+ function showWelcomeWizard() {
1799
1737
  var content = document.getElementById('wizard-content');
1800
1738
  var actions = document.getElementById('wizard-actions');
1801
1739
  content.textContent = '';
1802
1740
  actions.textContent = '';
1803
- updateWizardStepDots(3);
1804
-
1805
- if (wizardStep === 0) {
1806
- var title = document.createElement('h2');
1807
- title.textContent = 'Welcome to MeMesh';
1808
- content.appendChild(title);
1809
-
1810
- var sub = document.createElement('p');
1811
- sub.className = 'subtitle';
1812
- sub.textContent = 'MeMesh gives Claude a persistent knowledge graph. Set up an LLM provider to unlock Smart Mode \u2014 semantic search, conflict detection, and knowledge evolution.';
1813
- content.appendChild(sub);
1814
-
1815
- var capList = document.createElement('ul');
1816
- capList.style.listStyle = 'none';
1817
- capList.style.marginBottom = '8px';
1818
- [
1819
- ['Core FTS5 search \u2014 always available', true],
1820
- ['Smart Mode (LLM) \u2014 requires API key', false],
1821
- ['Auto-capture on session start', true],
1822
- ].forEach(function (item) {
1823
- var li = document.createElement('li');
1824
- li.style.cssText = 'display:flex;align-items:center;gap:8px;padding:6px 0;font-size:14px;';
1825
- var dot = document.createElement('span');
1826
- dot.className = 'status-dot ' + (item[1] ? 'ok' : 'warn');
1827
- li.appendChild(dot);
1828
- li.appendChild(document.createTextNode(String(item[0])));
1829
- capList.appendChild(li);
1830
- });
1831
- content.appendChild(capList);
1832
-
1833
- var skipBtn = document.createElement('button');
1834
- skipBtn.className = 'btn btn-secondary';
1835
- skipBtn.textContent = 'Skip for now';
1836
- skipBtn.addEventListener('click', closeWizard);
1837
-
1838
- var nextBtn = document.createElement('button');
1839
- nextBtn.className = 'btn btn-primary';
1840
- nextBtn.textContent = 'Set up Smart Mode \u2192';
1841
- nextBtn.addEventListener('click', function () { wizardStep = 1; renderWizardStep(); });
1842
-
1843
- actions.appendChild(skipBtn);
1844
- actions.appendChild(nextBtn);
1845
-
1846
- } else if (wizardStep === 1) {
1847
- var title2 = document.createElement('h2');
1848
- title2.textContent = 'Choose a Provider';
1849
- content.appendChild(title2);
1850
-
1851
- var sub2 = document.createElement('p');
1852
- sub2.className = 'subtitle';
1853
- sub2.textContent = 'Select your LLM provider and enter your API key. Keys are stored locally in ~/.memesh/config.json (mode 600).';
1854
- content.appendChild(sub2);
1855
-
1856
- // Provider radios
1857
- var radioGroupW = document.createElement('div');
1858
- radioGroupW.className = 'provider-radio-group';
1859
- radioGroupW.style.marginBottom = '16px';
1860
-
1861
- ['anthropic', 'openai', 'ollama'].forEach(function (p) {
1862
- var wrapper = document.createElement('label');
1863
- wrapper.className = 'provider-radio' + (wizardProvider === p ? ' selected' : '');
1864
-
1865
- var radio = document.createElement('input');
1866
- radio.type = 'radio';
1867
- radio.name = 'wizard-provider';
1868
- radio.value = p;
1869
- if (wizardProvider === p) radio.checked = true;
1870
-
1871
- radio.addEventListener('change', function () {
1872
- document.querySelectorAll('.provider-radio').forEach(function (el) { el.classList.remove('selected'); });
1873
- wrapper.classList.add('selected');
1874
- wizardProvider = p;
1875
- keyInput.style.display = p === 'ollama' ? 'none' : 'block';
1876
- keyLabel.style.display = p === 'ollama' ? 'none' : 'block';
1877
- });
1878
1741
 
1879
- wrapper.appendChild(radio);
1880
- wrapper.appendChild(document.createTextNode(p.charAt(0).toUpperCase() + p.slice(1)));
1881
- radioGroupW.appendChild(wrapper);
1882
- });
1883
- content.appendChild(radioGroupW);
1884
-
1885
- // API Key
1886
- var keyLabel = document.createElement('label');
1887
- keyLabel.className = 'form-label';
1888
- keyLabel.textContent = 'API Key';
1889
- keyLabel.style.display = wizardProvider && wizardProvider !== 'ollama' ? 'block' : 'none';
1890
- content.appendChild(keyLabel);
1891
-
1892
- var keyInput = document.createElement('input');
1893
- keyInput.type = 'password';
1894
- keyInput.className = 'search-input';
1895
- keyInput.placeholder = 'Paste your API key\u2026';
1896
- keyInput.style.width = '100%';
1897
- keyInput.style.marginBottom = '12px';
1898
- keyInput.style.display = wizardProvider && wizardProvider !== 'ollama' ? 'block' : 'none';
1899
- keyInput.value = wizardApiKey;
1900
- keyInput.addEventListener('input', function () { wizardApiKey = keyInput.value; });
1901
- content.appendChild(keyInput);
1902
-
1903
- // Error message
1904
- var errMsg = document.createElement('div');
1905
- errMsg.style.cssText = 'font-size:13px;color:var(--danger);min-height:18px;margin-bottom:8px;';
1906
- content.appendChild(errMsg);
1907
-
1908
- var backBtn = document.createElement('button');
1909
- backBtn.className = 'btn btn-secondary';
1910
- backBtn.textContent = '\u2190 Back';
1911
- backBtn.addEventListener('click', function () { wizardStep = 0; renderWizardStep(); });
1912
-
1913
- var testBtn = document.createElement('button');
1914
- testBtn.className = 'btn btn-secondary';
1915
- testBtn.textContent = 'Test Connection';
1916
- testBtn.addEventListener('click', async function () {
1917
- if (!wizardProvider) { errMsg.textContent = 'Select a provider.'; return; }
1918
- if (wizardProvider !== 'ollama' && !wizardApiKey.trim()) { errMsg.textContent = 'Enter an API key.'; return; }
1919
- testBtn.disabled = true;
1920
- testBtn.textContent = 'Testing\u2026';
1921
- errMsg.textContent = '';
1922
- try {
1923
- // Save to config and check capabilities
1924
- var payload = { llm: { provider: wizardProvider } };
1925
- if (wizardApiKey.trim()) payload.llm.apiKey = wizardApiKey.trim();
1926
- var res = await apiCall('POST', '/v1/config', payload);
1927
- if (!res.success) throw new Error(res.error || 'Config save failed');
1928
- errMsg.style.color = 'var(--success)';
1929
- errMsg.textContent = 'Connection config saved!';
1930
- } catch (err) {
1931
- errMsg.style.color = 'var(--danger)';
1932
- errMsg.textContent = 'Error: ' + err.message;
1933
- } finally {
1934
- testBtn.disabled = false;
1935
- testBtn.textContent = 'Test Connection';
1936
- }
1937
- });
1742
+ var title = document.createElement('h2');
1743
+ title.textContent = 'Welcome to MeMesh';
1744
+ content.appendChild(title);
1938
1745
 
1939
- var nextBtn2 = document.createElement('button');
1940
- nextBtn2.className = 'btn btn-primary';
1941
- nextBtn2.textContent = 'Next \u2192';
1942
- nextBtn2.addEventListener('click', async function () {
1943
- if (!wizardProvider) { errMsg.textContent = 'Select a provider.'; return; }
1944
- nextBtn2.disabled = true;
1945
- nextBtn2.textContent = 'Saving\u2026';
1946
- try {
1947
- var payload2 = { llm: { provider: wizardProvider }, setupCompleted: true };
1948
- if (wizardApiKey.trim()) payload2.llm.apiKey = wizardApiKey.trim();
1949
- var res2 = await apiCall('POST', '/v1/config', payload2);
1950
- if (!res2.success) throw new Error(res2.error || 'Save failed');
1951
- wizardStep = 2;
1952
- renderWizardStep();
1953
- } catch (err) {
1954
- errMsg.style.color = 'var(--danger)';
1955
- errMsg.textContent = 'Error: ' + err.message;
1956
- nextBtn2.disabled = false;
1957
- nextBtn2.textContent = 'Next \u2192';
1958
- }
1959
- });
1746
+ var sub = document.createElement('p');
1747
+ sub.className = 'subtitle';
1748
+ sub.textContent = 'MeMesh keeps shared agent memory on this machine with local FTS5 search and deterministic rules. No external service configuration is needed.';
1749
+ content.appendChild(sub);
1960
1750
 
1961
- actions.appendChild(backBtn);
1962
- actions.appendChild(testBtn);
1963
- actions.appendChild(nextBtn2);
1964
-
1965
- } else if (wizardStep === 2) {
1966
- var title3 = document.createElement('h2');
1967
- title3.textContent = "You're all set!";
1968
- content.appendChild(title3);
1969
-
1970
- var sub3 = document.createElement('p');
1971
- sub3.className = 'subtitle';
1972
- sub3.textContent = 'MeMesh Smart Mode is configured. Restart the server for LLM changes to take effect. Start using the Search and Browse tabs to explore your knowledge graph.';
1973
- content.appendChild(sub3);
1974
-
1975
- var tipBox = document.createElement('div');
1976
- tipBox.style.cssText = 'background:var(--accent-glow);border:1px solid rgba(59,130,246,0.2);border-radius:var(--radius-sm);padding:14px 16px;font-size:13px;line-height:1.6;color:var(--text-secondary);';
1977
- var tipLines = [
1978
- '\u2022 Use the Search tab to find anything across all your memories.',
1979
- '\u2022 Browse tab shows all entities with filter controls.',
1980
- '\u2022 Settings tab lets you change your provider anytime.',
1981
- ];
1982
- tipLines.forEach(function (line) {
1983
- var p = document.createElement('p');
1984
- p.textContent = line;
1985
- tipBox.appendChild(p);
1986
- });
1987
- content.appendChild(tipBox);
1751
+ var capList = document.createElement('ul');
1752
+ capList.style.margin = '0 0 8px 20px';
1753
+ [
1754
+ 'Remember and recall work across supported agent hosts.',
1755
+ 'Auto-capture can load project memories when a supported agent session starts.',
1756
+ 'Ask an already-running agent to use work_package when a digest or visible-transcript package would help. The Dashboard reviews staged proposals; it does not run or wake agents.',
1757
+ ].forEach(function (item) {
1758
+ var li = document.createElement('li');
1759
+ li.style.cssText = 'padding:6px 0;font-size:14px;color:var(--text-secondary);';
1760
+ li.textContent = item;
1761
+ capList.appendChild(li);
1762
+ });
1763
+ content.appendChild(capList);
1988
1764
 
1989
- var doneBtn = document.createElement('button');
1990
- doneBtn.className = 'btn btn-primary';
1991
- doneBtn.textContent = 'Go to Dashboard';
1992
- doneBtn.addEventListener('click', closeWizard);
1993
- actions.appendChild(doneBtn);
1994
- }
1995
- }
1765
+ var doneBtn = document.createElement('button');
1766
+ doneBtn.className = 'btn btn-primary';
1767
+ doneBtn.textContent = 'Open Dashboard';
1768
+ doneBtn.addEventListener('click', closeWizard);
1769
+ actions.appendChild(doneBtn);
1996
1770
 
1997
- function showWelcomeWizard() {
1998
- wizardStep = 0;
1999
1771
  document.getElementById('wizard-overlay').classList.remove('hidden');
2000
- renderWizardStep();
2001
1772
  }
2002
1773
 
2003
1774
  function closeWizard() {
@@ -2006,7 +1777,7 @@ export function generateLiveDashboardHtml() {
2006
1777
  apiCall('POST', '/v1/config', { setupCompleted: true });
2007
1778
  }
2008
1779
 
2009
- // Overlay click does NOT close wizard user must use Skip or complete setup
1780
+ // Overlay click does not close onboarding, preventing accidental dismissal.
2010
1781
  document.getElementById('wizard-overlay').addEventListener('click', function (e) {
2011
1782
  if (e.target === this) {
2012
1783
  // Intentionally do nothing — prevent accidental dismissal
@@ -2142,7 +1913,6 @@ ${bundledD3}
2142
1913
  <!-- Welcome Wizard Modal -->
2143
1914
  <div class="wizard-overlay hidden" id="wizard-overlay">
2144
1915
  <div class="wizard-modal">
2145
- <div class="wizard-steps" id="wizard-steps"></div>
2146
1916
  <div id="wizard-content"></div>
2147
1917
  <div class="wizard-actions" id="wizard-actions"></div>
2148
1918
  </div>