@jossuealcala/madre 1.0.1 → 1.0.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 (189) hide show
  1. package/ADDITIONAL-TERMS.md +93 -0
  2. package/CHANGELOG.en.md +2013 -0
  3. package/CHANGELOG.md +102 -1
  4. package/CONTRIBUTING.md +1 -1
  5. package/LICENSE +661 -202
  6. package/NOTICE +26 -14
  7. package/README.en.md +241 -0
  8. package/README.md +21 -12
  9. package/TRADEMARKS.en.md +50 -0
  10. package/TRADEMARKS.md +33 -16
  11. package/bin/madre.cjs +40 -0
  12. package/bin/madre.mjs +7 -0
  13. package/docs/INTERNALS.md +6 -0
  14. package/docs/REFERENCE.md +40 -5
  15. package/docs/SDK.md +4 -2
  16. package/docs/en/INTERNALS.md +103 -0
  17. package/docs/en/REFERENCE.md +365 -0
  18. package/docs/en/SDK.md +308 -0
  19. package/docs/en/training/README.md +59 -0
  20. package/docs/training/README.md +48 -9
  21. package/docs/training/train.sh +7 -2
  22. package/package.json +13 -5
  23. package/public/abduction.js +2 -0
  24. package/public/app.js +3154 -539
  25. package/public/attribution.js +114 -0
  26. package/public/brands.js +23 -6
  27. package/public/code-tools.js +143 -0
  28. package/public/editor.js +22 -4
  29. package/public/es.js +1004 -416
  30. package/public/hardware.js +50 -0
  31. package/public/i18n.js +25 -1
  32. package/public/index.html +18 -11
  33. package/public/inquiry.js +2 -0
  34. package/public/loader.js +2 -0
  35. package/public/macroverso.js +189 -96
  36. package/public/market-art.js +161 -0
  37. package/public/market-view.js +529 -0
  38. package/public/market.js +189 -0
  39. package/public/neural.js +110 -0
  40. package/public/nostromo-engine.js +414 -47
  41. package/public/power.js +100 -0
  42. package/public/resay.js +11 -0
  43. package/public/review-ask.js +2 -0
  44. package/public/routing.js +23 -1
  45. package/public/salas-mac.css +119 -18
  46. package/public/salas-mac.html +14 -2
  47. package/public/salas-mac.js +358 -56
  48. package/public/salas.css +2 -0
  49. package/public/salas.html +1 -0
  50. package/public/salas.js +4 -2
  51. package/public/styles.css +1793 -77
  52. package/public/syntax.js +2 -0
  53. package/public/touch.js +2 -0
  54. package/public/tour-chapters.js +2 -0
  55. package/public/tour.js +84 -5
  56. package/public/troubleshooting.js +24 -17
  57. package/public/wallpaper.js +275 -0
  58. package/src/adapters/claude.mjs +2 -0
  59. package/src/adapters/codex.mjs +2 -0
  60. package/src/adapters/cursor.mjs +96 -0
  61. package/src/adapters/gemini.mjs +13 -4
  62. package/src/adapters/madre.mjs +5 -2
  63. package/src/adapters/opencode.mjs +7 -3
  64. package/src/adapters/process.mjs +2 -0
  65. package/src/asking.mjs +2 -0
  66. package/src/auth-probe.mjs +145 -12
  67. package/src/bridge/devices.mjs +2 -0
  68. package/src/bridge/handoff.mjs +2 -0
  69. package/src/bridge/host.mjs +2 -0
  70. package/src/bridge/network.mjs +2 -0
  71. package/src/bridge/policy.mjs +3 -1
  72. package/src/bridge/qr.mjs +2 -0
  73. package/src/bridge/server.mjs +2 -0
  74. package/src/capabilities.mjs +11 -0
  75. package/src/chats.mjs +2 -0
  76. package/src/checkpoint.mjs +18 -1
  77. package/src/choices.mjs +2 -0
  78. package/src/cli-args.mjs +2 -0
  79. package/src/cold.mjs +2 -0
  80. package/src/commands.mjs +2 -0
  81. package/src/config.mjs +2 -0
  82. package/src/conversation-context.mjs +15 -1
  83. package/src/credentials.mjs +35 -3
  84. package/src/dataset.mjs +78 -4
  85. package/src/directives.mjs +2 -0
  86. package/src/distiller.mjs +2 -0
  87. package/src/embeddings.mjs +2 -0
  88. package/src/enlaces.mjs +214 -6
  89. package/src/event-store.mjs +2 -0
  90. package/src/exam.mjs +6 -4
  91. package/src/extensions.mjs +13 -3
  92. package/src/eyecat-watch.mjs +2 -0
  93. package/src/eyecat.mjs +2 -0
  94. package/src/file-ops.mjs +2 -0
  95. package/src/files.mjs +32 -0
  96. package/src/github.mjs +2 -0
  97. package/src/heartbeat.mjs +2 -0
  98. package/src/i18n.mjs +31 -1
  99. package/src/image-studio.mjs +2 -0
  100. package/src/json-file.mjs +2 -0
  101. package/src/launch.mjs +2 -0
  102. package/src/lease.mjs +5 -1
  103. package/src/lobby-work.mjs +2 -0
  104. package/src/local-ai.mjs +2 -0
  105. package/src/looks.mjs +127 -2
  106. package/src/market-key.mjs +8 -0
  107. package/src/market-remote.mjs +239 -0
  108. package/src/maturity.mjs +3 -1
  109. package/src/mcp/connect.mjs +345 -0
  110. package/src/mcp/github-server.mjs +2 -0
  111. package/src/mcp/image-server.mjs +2 -0
  112. package/src/mcp/memory-server.mjs +2 -0
  113. package/src/mcp/proxy.mjs +153 -0
  114. package/src/mcp/smtp-server.mjs +2 -0
  115. package/src/memory-dashboard.mjs +2 -0
  116. package/src/memory-tools.mjs +2 -0
  117. package/src/memory.mjs +2 -0
  118. package/src/models.mjs +49 -3
  119. package/src/module-scope.mjs +68 -0
  120. package/src/modules/ahp.mjs +104 -7
  121. package/src/modules/ash-policy.mjs +2 -0
  122. package/src/modules/ash.mjs +3 -1
  123. package/src/modules/bishop-exam.mjs +122 -0
  124. package/src/modules/bishop-plan.mjs +5 -3
  125. package/src/modules/bishop.mjs +84 -23
  126. package/src/modules/choices.mjs +2 -0
  127. package/src/modules/correo.mjs +2 -0
  128. package/src/modules/enlaces.mjs +89 -6
  129. package/src/modules/git-pulse.mjs +2 -0
  130. package/src/modules/github.mjs +2 -0
  131. package/src/modules/helpers.mjs +2 -0
  132. package/src/modules/image-studio.mjs +13 -2
  133. package/src/modules/index.mjs +4 -1
  134. package/src/modules/intents-calibration.mjs +2 -0
  135. package/src/modules/intents-desk.mjs +4 -2
  136. package/src/modules/intents-observe.mjs +2 -0
  137. package/src/modules/intents-policy.mjs +4 -1
  138. package/src/modules/intents-try.mjs +2 -0
  139. package/src/modules/intents.mjs +11 -7
  140. package/src/modules/local-models.mjs +124 -0
  141. package/src/modules/mcp-connect.mjs +293 -0
  142. package/src/modules/ollama.mjs +15 -4
  143. package/src/modules/playwright.mjs +88 -15
  144. package/src/modules/ripley.mjs +2 -0
  145. package/src/modules/runs.mjs +5 -3
  146. package/src/modules/sdk.mjs +63 -9
  147. package/src/modules/updates.mjs +2 -0
  148. package/src/mother.mjs +2 -0
  149. package/src/npm-launch.mjs +18 -0
  150. package/src/ollama.mjs +8 -5
  151. package/src/outbound.mjs +16 -6
  152. package/src/override.mjs +2 -0
  153. package/src/ports.mjs +6 -2
  154. package/src/prices.mjs +2 -0
  155. package/src/privacy.mjs +2 -0
  156. package/src/quota-monitor.mjs +2 -0
  157. package/src/quota-sources.mjs +2 -0
  158. package/src/request-guard.mjs +2 -0
  159. package/src/review-ask.mjs +2 -0
  160. package/src/room/archivist.mjs +2 -0
  161. package/src/room/attachments.mjs +2 -0
  162. package/src/room/budget.mjs +2 -0
  163. package/src/room/context.mjs +2 -0
  164. package/src/room/control.mjs +7 -1
  165. package/src/room/copilot.mjs +76 -0
  166. package/src/room/economy.mjs +2 -0
  167. package/src/room/escalation.mjs +2 -0
  168. package/src/room/ghost.mjs +2 -0
  169. package/src/room/guard.mjs +2 -0
  170. package/src/room/prompt.mjs +25 -5
  171. package/src/room/returns.mjs +82 -0
  172. package/src/room/runs.mjs +4 -0
  173. package/src/room/vectors.mjs +2 -0
  174. package/src/room.mjs +223 -35
  175. package/src/router.mjs +3 -1
  176. package/src/runs.mjs +6 -1
  177. package/src/runtime-detection.mjs +11 -0
  178. package/src/salas.mjs +28 -0
  179. package/src/sentinel-errors.mjs +2 -0
  180. package/src/server-sentinel.mjs +2 -0
  181. package/src/server.mjs +757 -81
  182. package/src/setup.mjs +3 -1
  183. package/src/smtp.mjs +2 -0
  184. package/src/tour.mjs +2 -0
  185. package/src/updates.mjs +2 -0
  186. package/src/usage-sentinel.mjs +2 -0
  187. package/src/vault.mjs +2 -0
  188. package/src/verdict.mjs +3 -1
  189. package/src/whats-new.mjs +2 -0
@@ -0,0 +1,50 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // MADRE · © 2026 Jossue Alcalá · GNU AGPL v3 with additional terms (Section 7): ADDITIONAL-TERMS.md
3
+ // «Your computer» (2026-10-16), the same block in a project (Modules and Settings › Local AI) and in
4
+ // Home (Settings › Local AI). Each page hands in its own row builders, so it reads like the rest.
5
+ import { t } from './i18n.js';
6
+
7
+ // What this computer can do with a local AI, measured on it (src/modules/local-models.mjs): which
8
+ // sizes run and train here, the one to use every day, and which features are worth turning on.
9
+ const LOCAL_FEATURE_NAMES = { search: 'Search by meaning', archivist: 'Archivist', agent: '@madre in the project', coordinator: 'The Coordinator with local AI', train: 'Train your own AI' };
10
+ export function hardwareLine(hw) {
11
+ if (!hw) return t('Not measured.');
12
+ if (hw.accelerator === 'apple') return t('{chip} · {gb} GB of shared memory', { chip: hw.chip ?? t('Apple chip'), gb: hw.memoryGb });
13
+ if (hw.accelerator === 'nvidia') return t('{gpu} · {vram} GB of video memory · {gb} GB of memory', { gpu: hw.gpus.map((gpu) => gpu.name).join(' + '), vram: hw.acceleratorGb, gb: hw.memoryGb });
14
+ return t('No compatible graphics card found · {gb} GB of memory', { gb: hw.memoryGb });
15
+ }
16
+ export function drawHardware(host, fit, { el, sxBlock, sxRow, sxChip }) {
17
+ const block = sxBlock(host, t('Your computer'), t('What it can do with a local AI, measured on it. Each model has a minimum to run it and another to train it.'));
18
+ sxRow(block, t('Hardware'), hardwareLine(fit?.hardware));
19
+ if (!fit?.models) return block;
20
+ const daily = fit.recommended?.run;
21
+ sxRow(block, t('Model for every day'), daily ? t('{model} · Ollama downloads it as {tag}', { model: daily.label, tag: daily.ollama }) : t('None runs well here: the project keeps using its providers.'));
22
+ for (const feature of fit.features ?? []) {
23
+ const tier = fit.models.find((model) => model.id === feature.needs);
24
+ const hint = feature.ok
25
+ ? (feature.slow ? t('Yes, slowly: it runs on the processor.') : null)
26
+ : feature.id === 'train'
27
+ ? (fit.accelerated ? t('Training starts at {gb} GB.', { gb: tier.trainGb }) : t('Training needs an Apple chip or an NVIDIA card.'))
28
+ : t('Needs at least {model}, from {gb} GB.', { model: tier.label, gb: tier.runGb });
29
+ sxRow(block, t(LOCAL_FEATURE_NAMES[feature.id]), hint, sxChip(feature.ok ? (feature.slow ? t('Slow') : t('Yes')) : t('No'), feature.ok ? (feature.slow ? 'warn' : 'on') : ''));
30
+ }
31
+ const more = el('details', 'sx-more');
32
+ more.append(el('summary', null, t('Every size, to run and to train')));
33
+ const wrap = el('div', 'sx-table');
34
+ const table = el('table', 'sx-models');
35
+ const head = el('tr');
36
+ for (const text of [t('Model'), t('To run'), t('To train'), t('Here')]) head.append(el('th', null, text));
37
+ table.append(head);
38
+ const verdict = (value) => (value === 'yes' ? t('runs') : value === 'slow' ? t('runs slowly') : null);
39
+ for (const model of fit.models) {
40
+ const row = el('tr', model.id === daily?.id ? 'pick' : null);
41
+ const here = [verdict(model.run), model.train === 'yes' ? t('trains') : null].filter(Boolean).join(' · ') || t('does not fit');
42
+ row.append(el('td', null, model.label), el('td', null, t('{gb} GB', { gb: model.runGb })), el('td', null, t('{gb} GB', { gb: model.trainGb })), el('td', model.run === 'no' ? 'no' : null, here));
43
+ table.append(row);
44
+ }
45
+ wrap.append(table);
46
+ more.append(wrap, el('p', 'sx-hint', t('Minimums for the whole computer, with the system and the browser open: a 4-bit model in Ollama to run it, a LoRA with mlx-lm to train it. On a Mac with an Apple chip the memory is shared; with an NVIDIA card what counts is the card\'s own.')));
47
+ block.append(more);
48
+ return block;
49
+ }
50
+
package/public/i18n.js CHANGED
@@ -1,3 +1,5 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // MADRE · © 2026 Jossue Alcalá · GNU AGPL v3 with additional terms (Section 7): ADDITIONAL-TERMS.md
1
3
  // The room's language.
2
4
  //
3
5
  // MADRE is written in Spanish and answers in English when it is asked to. That is the way round
@@ -37,6 +39,13 @@ export function setLanguage(id) {
37
39
  return current;
38
40
  }
39
41
 
42
+ // The language of the person at this browser, for a MADRE nobody has set yet (2026-10-15): the
43
+ // browser's first language, Spanish in any of its variants, English for every other one.
44
+ export function browserLanguage(nav = globalThis.navigator) {
45
+ const first = String((Array.isArray(nav?.languages) && nav.languages[0]) || nav?.language || '').toLowerCase();
46
+ return first.startsWith('es') ? 'es' : 'en';
47
+ }
48
+
40
49
  // `{name}` is filled from `vars` after the sentence is chosen, so the Spanish can put the number
41
50
  // where Spanish puts it. A slot with nothing to fill it is left as it is rather than printed as
42
51
  // "undefined": a visible brace is a bug you can see.
@@ -45,15 +54,30 @@ export function fill(text, vars) {
45
54
  return String(text).replace(/\{(\w+)\}/g, (whole, name) => (Object.hasOwn(vars, name) ? String(vars[name]) : whole));
46
55
  }
47
56
 
57
+ // «Mac» only where MADRE runs on one (2026-10-15). It installs on Linux too, so a sentence about
58
+ // the machine it runs on («this Mac», «tu Mac», «la Mac») says «computer»/«computadora» anywhere
59
+ // else. The page is always opened on the machine that serves it (127.0.0.1), so the browser's own
60
+ // platform is that machine's. Hardware named on purpose — «a Mac with an M chip» — has no article
61
+ // in front and is left as it is.
62
+ let hostIsMac = /mac/i.test(String(globalThis.navigator?.userAgentData?.platform ?? globalThis.navigator?.platform ?? ''));
63
+ export const setHostIsMac = (value) => { hostIsMac = Boolean(value); return hostIsMac; };
64
+ export function hostWords(text) {
65
+ if (hostIsMac || typeof text !== 'string' || !text.includes('Mac')) return text;
66
+ return text
67
+ .replace(/\b(this|your|the|This|Your|The) Mac\b/g, '$1 computer')
68
+ .replace(/(^|[^\p{L}])(esta|tu|la|Esta|Tu|La) Mac\b/gu, '$1$2 computadora');
69
+ }
70
+
48
71
  export function t(text, vars = null) {
49
72
  const said = CATALOGUES[current]?.[text] ?? text;
50
- return fill(said, vars);
73
+ return fill(hostWords(said), vars);
51
74
  }
52
75
 
53
76
  // A table that carries both languages: `{ en: …, es: … }` anywhere inside it. Whole objects,
54
77
  // whole arrays — the shape is the table's own and this only chooses the side.
55
78
  export function pick(value) {
56
79
  if (Array.isArray(value)) return value.map(pick);
80
+ if (typeof value === 'string') return hostWords(value);
57
81
  if (!value || typeof value !== 'object') return value;
58
82
  if (Object.hasOwn(value, 'en') && Object.hasOwn(value, current)) return pick(value[current] ?? value.en);
59
83
  const out = {};
package/public/index.html CHANGED
@@ -1,4 +1,5 @@
1
1
  <!doctype html>
2
+ <!-- SPDX-License-Identifier: AGPL-3.0-only · MADRE · © 2026 Jossue Alcalá · GNU AGPL v3 with additional terms (Section 7): ADDITIONAL-TERMS.md -->
2
3
  <html lang="en">
3
4
  <head>
4
5
  <meta charset="utf-8">
@@ -42,6 +43,9 @@
42
43
  <button id="stop-all" class="stop-all" type="button" title="STOP ALL · halt every plan and every agent turn" hidden>
43
44
  <svg class="bar-glyph" viewBox="0 0 20 20" aria-hidden="true"><rect class="ic-f" x="4" y="4" width="12" height="12" rx="3.4" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>STOP ALL
44
45
  </button>
46
+ <button id="code-button" class="mother-button code-button" type="button" title="Code · your files, the editor and the preview beside the conversation" aria-pressed="false">
47
+ <svg class="bar-glyph" viewBox="0 0 20 20" aria-hidden="true"><path d="M7.2 5.4 2.8 10l4.4 4.6M12.8 5.4l4.4 4.6-4.4 4.6" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><path class="code-slash" d="M11.3 5.6 8.7 14.4" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" pathLength="10"/></svg>CODE
48
+ </button>
45
49
  <button id="modules-button" class="mother-button" type="button" title="Modules · optional integrations for this project" aria-haspopup="dialog" aria-pressed="false">
46
50
  <span class="mother-glyph modules-glyph" aria-hidden="true"></span><svg class="bar-glyph" viewBox="0 0 20 20" aria-hidden="true"><path class="ic-f" d="M2.75 8.45a2.2 2.2 0 0 1 2.2-2.2h2a1.9 1.9 0 1 1 2.6 0h2a2.2 2.2 0 0 1 2.2 2.2v2a1.9 1.9 0 1 1 0 2.6v2a2.2 2.2 0 0 1-2.2 2.2h-2a1.9 1.9 0 1 0-2.6 0h-2a2.2 2.2 0 0 1-2.2-2.2z" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>MODULES<span id="modules-count" class="modules-count" hidden></span>
47
51
  </button>
@@ -94,6 +98,7 @@
94
98
  <aside id="tree" class="tree" aria-label="Project files" hidden>
95
99
  <header class="tree-head">
96
100
  <span class="tree-title">FILES <span id="tree-root" class="tree-root"></span></span>
101
+ <button id="tree-refresh" class="surface-gear tree-refresh" type="button" aria-label="Refresh files" title="Refresh files"><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M15.6 8.4A5.8 5.8 0 0 0 4.9 6.6M4.4 11.6a5.8 5.8 0 0 0 10.7 1.8" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="M15.9 3.9v4.6h-4.6M4.1 16.1v-4.6h4.6" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
97
102
  <button id="tree-settings" class="surface-gear" type="button" aria-label="Settings for files and servers" title="Settings for files and servers"><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M3.5 6h6M14 6h2.5M3.5 14h2.5M10.5 14h6" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><circle cx="11.8" cy="6" r="2.2" fill="none" stroke="currentColor" stroke-width="1.6"/><circle cx="8.2" cy="14" r="2.2" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></button>
98
103
  <button id="tree-close" class="tree-close" type="button" aria-label="Close files">×</button>
99
104
  </header>
@@ -109,8 +114,8 @@
109
114
  <span class="mother-title">What is sent</span>
110
115
  <span class="mother-sub">What this project says in your name</span>
111
116
  <span class="mother-actions">
112
- <button id="core-copy" class="mother-close" type="button" title="Copy the whole briefing as the agent receives it">Copy all</button>
113
- <button id="core-close" class="mother-close" type="button" aria-label="Close">Close</button>
117
+ <button id="core-copy" class="sx-btn core-copy-all" type="button" title="Copy the whole briefing as the agent receives it">Copy all</button>
118
+ <span class="surface-modes"><button id="core-close" class="surface-mode close x-close x-only" type="button" aria-label="Close"><span class="x-icon"><svg focusable="false" viewBox="0 0 20 20" aria-hidden="true"><path d="M5.5 5.5l9 9M14.5 5.5l-9 9" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg></span></button></span>
114
119
  </span>
115
120
  </header>
116
121
  <p id="core-boot" class="mother-boot"></p>
@@ -139,7 +144,7 @@
139
144
  </form>
140
145
  <div id="mother-os" class="sx-seg mother-os" role="radiogroup" aria-label="Operating system"></div>
141
146
  <span class="mother-tools">
142
- <button id="mother-settings-button" class="surface-gear" type="button" title="Diagnostics settings: what the sentinel keeps and whether it reports" aria-label="Diagnostics settings"><svg class="gear-glyph" viewBox="0 0 20 20" aria-hidden="true"><path fill-rule="evenodd" d="M8.65 3.85L8.92 1.97L11.08 1.97L11.35 3.85L13.40 4.69L14.91 3.56L16.44 5.09L15.31 6.60L16.15 8.65L18.03 8.92L18.03 11.08L16.15 11.35L15.31 13.40L16.44 14.91L14.91 16.44L13.40 15.31L11.35 16.15L11.08 18.03L8.92 18.03L8.65 16.15L6.60 15.31L5.09 16.44L3.56 14.91L4.69 13.40L3.85 11.35L1.97 11.08L1.97 8.92L3.85 8.65L4.69 6.60L3.56 5.09L5.09 3.56L6.60 4.69ZM12.6 10a2.6 2.6 0 1 1-5.2 0a2.6 2.6 0 1 1 5.2 0Z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/></svg></button>
147
+ <button id="mother-settings-button" class="surface-gear" type="button" title="Diagnostics settings: what the failure monitor keeps and whether it reports" aria-label="Diagnostics settings"><svg class="gear-glyph" viewBox="0 0 20 20" aria-hidden="true"><path fill-rule="evenodd" d="M8.65 3.85L8.92 1.97L11.08 1.97L11.35 3.85L13.40 4.69L14.91 3.56L16.44 5.09L15.31 6.60L16.15 8.65L18.03 8.92L18.03 11.08L16.15 11.35L15.31 13.40L16.44 14.91L14.91 16.44L13.40 15.31L11.35 16.15L11.08 18.03L8.92 18.03L8.65 16.15L6.60 15.31L5.09 16.44L3.56 14.91L4.69 13.40L3.85 11.35L1.97 11.08L1.97 8.92L3.85 8.65L4.69 6.60L3.56 5.09L5.09 3.56L6.60 4.69ZM12.6 10a2.6 2.6 0 1 1-5.2 0a2.6 2.6 0 1 1 5.2 0Z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/></svg></button>
143
148
  <button id="nostromo-button" class="surface-gear nostromo-button" type="button" title="Memory map · memory research · needs the project name" aria-label="Memory map"><svg viewBox="0 0 20 20" aria-hidden="true"><path class="ic-f" d="M9.2 4.6A2.5 2.5 0 0 0 4.9 5.9a2.6 2.6 0 0 0-1.4 4.2 2.7 2.7 0 0 0 1.6 4.1 2.5 2.5 0 0 0 4.1 1.6z" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/><path class="ic-f" d="M10.8 4.6a2.5 2.5 0 0 1 4.3 1.3 2.6 2.6 0 0 1 1.4 4.2 2.7 2.7 0 0 1-1.6 4.1 2.5 2.5 0 0 1-4.1 1.6z" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/><path d="M6.2 9.4c.9 0 1.6.6 1.8 1.4M13.8 9.4c-.9 0-1.6.6-1.8 1.4M7.2 6.6c.5.2.9.6 1 1.1M12.8 6.6c-.5.2-.9.6-1 1.1" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg></button>
144
149
  <button id="tour-button" class="surface-gear tour-button" type="button" title="The tour of MADRE" aria-label="Tour">?</button>
145
150
  </span>
@@ -147,7 +152,7 @@
147
152
  </header>
148
153
  <p id="mother-boot" class="mother-status" aria-live="polite"></p>
149
154
  <div id="mother-body" class="mother-body">
150
- <section id="mother-list" class="mother-list" aria-label="Conditions"></section>
155
+ <section id="mother-list" class="mother-list" aria-label="Problems"></section>
151
156
  <section id="mother-answer" class="mother-detail" aria-live="polite"></section>
152
157
  </div>
153
158
  </dialog>
@@ -192,7 +197,7 @@
192
197
  <textarea id="message" rows="1" placeholder="Type here, human. Ask the project…"></textarea>
193
198
  <div id="slash-menu" class="slash-menu" role="listbox" hidden></div>
194
199
  </div>
195
- <button id="create-toggle" type="button" class="create-toggle" aria-pressed="false" title="Creation lease: let the agent create files for this request, only inside .pulse/out/" hidden>
200
+ <button id="create-toggle" type="button" class="create-toggle" aria-pressed="false" title="Permission to create: let the agent create files for this request, only inside .pulse/out/" hidden>
196
201
  <svg class="lock closed" viewBox="0 0 20 20" aria-hidden="true"><path d="M6.8 8.6V6.7a3.2 3.2 0 0 1 6.4 0v1.9" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><rect x="4.4" y="8.6" width="11.2" height="8.2" rx="2.6" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><circle cx="10" cy="12.7" r="1.1" fill="currentColor"/></svg>
197
202
  <svg class="lock open" viewBox="0 0 20 20" aria-hidden="true"><path d="M13.2 8.6V6.5a3.2 3.2 0 0 0-6.2-1.15" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><rect x="4.4" y="8.6" width="11.2" height="8.2" rx="2.6" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><circle cx="10" cy="12.7" r="1.1" fill="currentColor"/></svg>
198
203
  <span class="create-word">CREATE</span>
@@ -236,7 +241,8 @@
236
241
  <form id="nostromo-gate-form" class="key-form" autocomplete="off">
237
242
  <label class="room-ask-field"><span class="k">Type the project name</span><input id="nostromo-gate-input" autocomplete="off" spellcheck="false"></label>
238
243
  <p class="key-reply" id="nostromo-gate-reply" aria-live="polite"></p>
239
- <div class="room-ask-actions"><button id="nostromo-gate-cancel" class="room-ask-choice" type="button">Cancel</button><button type="submit" class="room-ask-choice primary">Board</button></div>
244
+ <div class="room-ask-actions"><button id="nostromo-gate-cancel" class="room-ask-choice" type="button">Cancel</button><button type="submit" class="room-ask-choice primary">Enter</button></div>
245
+ <button id="nostromo-gate-skip" class="key-skip" type="button">Don't ask again…</button>
240
246
  </form>
241
247
  </div>
242
248
  </dialog>
@@ -246,13 +252,14 @@
246
252
  <span class="mother-title">MEMORY MAP</span>
247
253
  <span id="nostromo-sub" class="mother-sub">MEMORY RESEARCH · LOADING…</span>
248
254
  <span class="nostromo-legend" aria-label="Memory kinds">
249
- <span class="k decision" title="YELLOW DWARF · DECISION"><i>DECISION</i></span><span class="k fact" title="WHITE DWARF · FACT"><i>FACT</i></span><span class="k preference" title="GREEN DWARF · PREFERENCE"><i>PREFERENCE</i></span><span class="k question" title="BLUE DWARF · QUESTION"><i>QUESTION</i></span>
255
+ <span class="k decision" title="YELLOW STAR · DECISION"><i>DECISION</i></span><span class="k fact" title="WHITE STAR · FACT"><i>FACT</i></span><span class="k preference" title="GREEN STAR · PREFERENCE"><i>PREFERENCE</i></span><span class="k question" title="BLUE STAR · QUESTION"><i>QUESTION</i></span>
250
256
  </span>
251
257
  <span class="nostromo-actions">
252
258
  <button id="nostromo-cold" class="mother-close cold" type="button" hidden aria-pressed="false" title="The memories nothing has ever reached for, that share a subject with nothing, and that have had their chances">UNUSED · 0</button>
253
259
  <button id="nostromo-ask" class="mother-close ask" type="button" hidden aria-pressed="false" title="The questions this archive cannot answer yet, written from what it already holds">ASK · 0</button>
260
+ <button id="nostromo-neural" class="mother-close neural-key" type="button" aria-pressed="false">Neural</button>
254
261
  <button id="nostromo-recenter" class="mother-close" type="button" hidden>RECENTER</button>
255
- <button id="nostromo-close" class="mother-close" type="button">LEAVE ×</button>
262
+ <span class="surface-modes"><button id="nostromo-close" class="surface-mode close" type="button" aria-label="Leave the Memory map" title="Leave the Memory map">×</button></span>
256
263
  </span>
257
264
  </header>
258
265
  <canvas id="nostromo-canvas" class="nostromo-canvas" tabindex="-1" aria-label="Memories orbiting the core"></canvas>
@@ -285,7 +292,7 @@
285
292
  <dt>SOURCE</dt><dd id="nostromo-card-span" data-part="span"></dd>
286
293
  <dt>ARCHIVIST</dt><dd id="nostromo-card-agent" data-part="agent"></dd>
287
294
  <dt>DISTILLED</dt><dd id="nostromo-card-when" data-part="when"></dd>
288
- <dt>ZONE</dt><dd id="nostromo-card-zone" data-part="zone"></dd>
295
+ <dt>STATUS</dt><dd id="nostromo-card-zone" data-part="zone"></dd>
289
296
  </dl>
290
297
  <section class="wire">
291
298
  <h6>LINKS <span id="nostromo-card-degree" data-part="degree" class="n"></span></h6>
@@ -307,7 +314,7 @@
307
314
  <header class="viewer-head browser-head">
308
315
  <span class="viewer-nav" id="browser-nav">
309
316
  <button id="browser-back" class="nav" type="button" title="Back" aria-label="Back" disabled>‹</button>
310
- <button id="browser-reload" class="nav" type="button" title="Reload" aria-label="Reload">↻</button>
317
+ <button id="browser-reload" class="nav reload" type="button" title="Reload" aria-label="Reload"><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M16 10a6 6 0 1 1-1.76-4.24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/><path d="M16.1 3.6v3.6h-3.6" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
311
318
  <button id="browser-servers" class="nav ports" type="button" aria-expanded="false" aria-haspopup="menu" aria-label="This project's servers"><i class="ports-dot" aria-hidden="true"></i><span>YOUR SERVERS</span><i class="ports-caret" aria-hidden="true"></i></button>
312
319
  <button id="browser-point" class="nav point" type="button" aria-pressed="false" aria-label="Point and ask"><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M5.4 3.9v11.4c0 .5.6.75.95.4l2.5-2.4 1.95 4.1c.17.37.6.52.96.35l.9-.43c.36-.17.5-.6.33-.96l-1.95-4.1h3.45c.5 0 .74-.6.38-.94L6.36 3.5c-.36-.33-.96-.08-.96.4z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg><span>POINT</span></button>
313
320
  </span>
@@ -366,7 +373,7 @@
366
373
  </dialog>
367
374
  </div>
368
375
  <script type="module" src="/app.js"></script>
369
- <dialog id="intents-window" class="surface window custom-window intents-window" aria-label="Intenciones · quick test">
376
+ <dialog id="intents-window" class="surface window custom-window intents-window" aria-label="Suggested effort · quick test">
370
377
  <header class="custom-head">
371
378
  <span class="custom-title">INTENCIONES</span>
372
379
  <span class="custom-sub">QUICK TEST · YOU JUDGE, BLIND</span>
package/public/inquiry.js CHANGED
@@ -1,3 +1,5 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // MADRE · © 2026 Jossue Alcalá · GNU AGPL v3 with additional terms (Section 7): ADDITIONAL-TERMS.md
1
3
  // The console inside the core.
2
4
  //
3
5
  // MU/TH/UR 6000 answered by being asked. The core already holds everything an answer would need —
package/public/loader.js CHANGED
@@ -1,3 +1,5 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // MADRE · © 2026 Jossue Alcalá · GNU AGPL v3 with additional terms (Section 7): ADDITIONAL-TERMS.md
1
3
  // MADRE loading (2026-10-10): the pulse of the logo beating, a thin bar that fills and the share
2
4
  // done under it, as a Mac starts. One loader for every wait that takes time — a RELOAD, the room
3
5
  // or Home coming back after an update, a project waking, an agent installing — so a wait always