@jossuealcala/madre 1.0.0 → 1.0.2

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 (174) hide show
  1. package/ADDITIONAL-TERMS.md +93 -0
  2. package/CHANGELOG.en.md +1945 -0
  3. package/CHANGELOG.md +78 -1
  4. package/CONTRIBUTING.md +5 -1
  5. package/LICENSE +661 -202
  6. package/NOTICE +34 -3
  7. package/README.en.md +245 -0
  8. package/README.md +23 -13
  9. package/TRADEMARKS.en.md +50 -0
  10. package/TRADEMARKS.md +82 -0
  11. package/bin/madre.mjs +2 -0
  12. package/docs/INTERNALS.md +8 -2
  13. package/docs/REFERENCE.md +17 -7
  14. package/docs/en/INTERNALS.md +103 -0
  15. package/docs/en/REFERENCE.md +339 -0
  16. package/docs/en/SDK.md +306 -0
  17. package/docs/en/training/README.md +59 -0
  18. package/docs/madre-banner.png +0 -0
  19. package/docs/training/README.md +20 -8
  20. package/docs/training/train.sh +2 -1
  21. package/package.json +14 -5
  22. package/public/abduction.js +2 -0
  23. package/public/app.js +2066 -488
  24. package/public/attribution.js +71 -0
  25. package/public/brands.js +3 -1
  26. package/public/editor.js +2 -0
  27. package/public/es.js +1706 -1226
  28. package/public/i18n.js +25 -1
  29. package/public/index.html +13 -10
  30. package/public/inquiry.js +2 -0
  31. package/public/loader.js +2 -0
  32. package/public/macroverso.js +24 -2
  33. package/public/nostromo-engine.js +2 -0
  34. package/public/resay.js +6 -0
  35. package/public/review-ask.js +2 -0
  36. package/public/routing.js +23 -1
  37. package/public/salas-mac.css +539 -28
  38. package/public/salas-mac.html +30 -22
  39. package/public/salas-mac.js +1498 -144
  40. package/public/salas.css +2 -0
  41. package/public/salas.html +1 -0
  42. package/public/salas.js +4 -2
  43. package/public/styles.css +1123 -20
  44. package/public/syntax.js +2 -0
  45. package/public/touch.js +2 -0
  46. package/public/tour-chapters.js +164 -52
  47. package/public/tour.js +85 -12
  48. package/public/troubleshooting.js +20 -18
  49. package/src/adapters/claude.mjs +2 -0
  50. package/src/adapters/codex.mjs +2 -0
  51. package/src/adapters/gemini.mjs +3 -1
  52. package/src/adapters/madre.mjs +3 -1
  53. package/src/adapters/opencode.mjs +7 -3
  54. package/src/adapters/process.mjs +2 -0
  55. package/src/asking.mjs +2 -0
  56. package/src/auth-probe.mjs +32 -7
  57. package/src/bridge/devices.mjs +2 -0
  58. package/src/bridge/handoff.mjs +2 -0
  59. package/src/bridge/host.mjs +2 -0
  60. package/src/bridge/network.mjs +2 -0
  61. package/src/bridge/policy.mjs +3 -1
  62. package/src/bridge/qr.mjs +2 -0
  63. package/src/bridge/server.mjs +2 -0
  64. package/src/capabilities.mjs +2 -0
  65. package/src/chats.mjs +2 -0
  66. package/src/checkpoint.mjs +2 -0
  67. package/src/choices.mjs +2 -0
  68. package/src/cli-args.mjs +2 -0
  69. package/src/cold.mjs +2 -0
  70. package/src/commands.mjs +2 -0
  71. package/src/config.mjs +2 -0
  72. package/src/conversation-context.mjs +15 -1
  73. package/src/credentials.mjs +112 -3
  74. package/src/dataset.mjs +2 -0
  75. package/src/directives.mjs +8 -6
  76. package/src/distiller.mjs +2 -0
  77. package/src/embeddings.mjs +2 -0
  78. package/src/enlaces.mjs +6 -4
  79. package/src/event-store.mjs +2 -0
  80. package/src/exam.mjs +6 -4
  81. package/src/extensions.mjs +33 -10
  82. package/src/eyecat-watch.mjs +2 -0
  83. package/src/eyecat.mjs +2 -0
  84. package/src/file-ops.mjs +2 -0
  85. package/src/files.mjs +32 -0
  86. package/src/github.mjs +2 -0
  87. package/src/heartbeat.mjs +57 -0
  88. package/src/i18n.mjs +15 -1
  89. package/src/image-studio.mjs +2 -0
  90. package/src/json-file.mjs +2 -0
  91. package/src/launch.mjs +2 -0
  92. package/src/lease.mjs +5 -1
  93. package/src/lobby-work.mjs +2 -0
  94. package/src/local-ai.mjs +50 -0
  95. package/src/looks.mjs +40 -5
  96. package/src/maturity.mjs +3 -1
  97. package/src/mcp/connect.mjs +345 -0
  98. package/src/mcp/github-server.mjs +2 -0
  99. package/src/mcp/image-server.mjs +2 -0
  100. package/src/mcp/memory-server.mjs +2 -0
  101. package/src/mcp/proxy.mjs +153 -0
  102. package/src/mcp/smtp-server.mjs +2 -0
  103. package/src/memory-dashboard.mjs +2 -0
  104. package/src/memory-tools.mjs +2 -0
  105. package/src/memory.mjs +2 -0
  106. package/src/models.mjs +83 -3
  107. package/src/modules/ahp.mjs +2 -0
  108. package/src/modules/ash-policy.mjs +2 -0
  109. package/src/modules/ash.mjs +3 -1
  110. package/src/modules/bishop-plan.mjs +5 -3
  111. package/src/modules/bishop.mjs +13 -11
  112. package/src/modules/choices.mjs +2 -0
  113. package/src/modules/correo.mjs +2 -0
  114. package/src/modules/enlaces.mjs +2 -0
  115. package/src/modules/git-pulse.mjs +2 -0
  116. package/src/modules/github.mjs +2 -0
  117. package/src/modules/helpers.mjs +2 -0
  118. package/src/modules/image-studio.mjs +3 -1
  119. package/src/modules/index.mjs +4 -1
  120. package/src/modules/intents-calibration.mjs +2 -0
  121. package/src/modules/intents-desk.mjs +4 -2
  122. package/src/modules/intents-observe.mjs +2 -0
  123. package/src/modules/intents-policy.mjs +4 -1
  124. package/src/modules/intents-try.mjs +2 -0
  125. package/src/modules/intents.mjs +8 -6
  126. package/src/modules/mcp-connect.mjs +293 -0
  127. package/src/modules/ollama.mjs +17 -3
  128. package/src/modules/playwright.mjs +25 -10
  129. package/src/modules/ripley.mjs +2 -0
  130. package/src/modules/runs.mjs +5 -3
  131. package/src/modules/sdk.mjs +2 -0
  132. package/src/modules/updates.mjs +2 -0
  133. package/src/mother.mjs +2 -0
  134. package/src/ollama.mjs +2 -0
  135. package/src/outbound.mjs +24 -5
  136. package/src/override.mjs +2 -0
  137. package/src/ports.mjs +2 -0
  138. package/src/prices.mjs +2 -0
  139. package/src/privacy.mjs +2 -0
  140. package/src/quota-monitor.mjs +2 -0
  141. package/src/quota-sources.mjs +2 -0
  142. package/src/request-guard.mjs +2 -0
  143. package/src/review-ask.mjs +2 -0
  144. package/src/room/archivist.mjs +2 -0
  145. package/src/room/attachments.mjs +2 -0
  146. package/src/room/budget.mjs +2 -0
  147. package/src/room/context.mjs +2 -0
  148. package/src/room/control.mjs +7 -1
  149. package/src/room/copilot.mjs +76 -0
  150. package/src/room/economy.mjs +2 -0
  151. package/src/room/escalation.mjs +3 -0
  152. package/src/room/ghost.mjs +2 -0
  153. package/src/room/guard.mjs +2 -0
  154. package/src/room/prompt.mjs +13 -4
  155. package/src/room/returns.mjs +82 -0
  156. package/src/room/runs.mjs +4 -0
  157. package/src/room/vectors.mjs +2 -0
  158. package/src/room.mjs +264 -45
  159. package/src/router.mjs +2 -0
  160. package/src/runs.mjs +2 -0
  161. package/src/runtime-detection.mjs +2 -0
  162. package/src/salas.mjs +2 -0
  163. package/src/sentinel-errors.mjs +2 -0
  164. package/src/server-sentinel.mjs +2 -0
  165. package/src/server.mjs +485 -55
  166. package/src/setup.mjs +2 -0
  167. package/src/smtp.mjs +2 -0
  168. package/src/tour.mjs +26 -9
  169. package/src/updates.mjs +2 -0
  170. package/src/usage-sentinel.mjs +2 -0
  171. package/src/vault.mjs +2 -0
  172. package/src/verdict.mjs +3 -1
  173. package/src/whats-new.mjs +12 -10
  174. package/docs/madre-banner.svg +0 -25
package/src/setup.mjs 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
  import { spawn } from 'node:child_process';
2
4
  import { createInterface } from 'node:readline/promises';
3
5
  import { stdin, stdout } from 'node:process';
package/src/smtp.mjs 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
  // SMTP, enough of it to send one message over TLS. No dependencies, by the same rule as the rest
2
4
  // of MADRE: a library that handles the human's mail password is a library somebody has to read.
3
5
  //
package/src/tour.mjs 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 welcome of MADRE 1.0 (2026-10-11): one bonjour per person and per major version, then the
2
4
  // chapters that tell everything new, at the person's own pace (docs: the «Recorrido de MADRE 1.0»
3
5
  // decision, option B with two pieces of C — the one-line hints and the sheet of gestures).
@@ -20,14 +22,24 @@ import { createInterface } from 'node:readline';
20
22
  import { oneAtATime, writeWhole } from './json-file.mjs';
21
23
  import { PROJECT_HOMES, associateProject, projectRoomId, salasRoomId } from './salas.mjs';
22
24
 
23
- export const TOUR_VERSION = '1.0';
24
- // The chapters, in their order; «moved» is only for whoever comes from 0.7.2.
25
- export const CHAPTERS = ['moved', 'home', 'project', 'talk', 'modes', 'coordinator', 'links', 'maps', 'settings', 'modules', 'phone', 'gestures'];
26
- // The places that confuse most, each told once in one line (from option C).
27
- export const HINTS = ['switch', 'links', 'key4'];
28
- const PATHS = ['new', 'back'];
25
+ // 1.1 (2026-10-14): the same welcome, a third way through it. Whoever read the tour of 1.0 is told
26
+ // what changed since (path «since»): the clearer names, Home as a board, its widgets and the local
27
+ // AI chosen project by project. A tour.json of 1.0 is that person; it is started again for 1.1 and
28
+ // remembers where it came from (`before`).
29
+ export const TOUR_VERSION = '1.1';
30
+ // The chapters, in their order; «moved» is only for whoever comes from 0.7.2, «renamed» only for
31
+ // whoever comes from 1.0.
32
+ export const CHAPTERS = ['moved', 'home', 'renamed', 'board', 'widgets', 'project', 'talk', 'modes', 'coordinator', 'links', 'maps', 'settings', 'modules', 'local', 'phone', 'gestures'];
33
+ // The places that confuse most, each told once in one line (from option C); then, from 1.1, what
34
+ // each key of Home's bar opens, the first time it opens, and what each widget of Home shows. (A
35
+ // project's bar says it with its own first-touch cards, public/app.js, FIRST_TOUCH.)
36
+ export const HINTS = ['switch', 'links', 'key4',
37
+ 'home-links', 'home-map', 'home-settings', 'home-add',
38
+ 'w-system', 'w-servers', 'w-memory', 'w-coordinator', 'w-models', 'w-usage'];
39
+ const PATHS = ['new', 'back', 'since'];
40
+ const BEFORE = ['1.0'];
29
41
 
30
- const fresh = () => ({ version: TOUR_VERSION, path: null, bonjourAt: null, done: [], at: null, closed: false, finished: null, hints: {}, held: null });
42
+ const fresh = (before = null) => ({ version: TOUR_VERSION, path: null, bonjourAt: null, done: [], at: null, closed: false, finished: null, hints: {}, held: null, before });
31
43
  // A tab that shows the bonjour or the chapters says so every few seconds; another tab that finds it
32
44
  // said within this long tells the person it is open there, instead of a second bonjour.
33
45
  export const HELD_MS = 45 * 1000;
@@ -38,7 +50,10 @@ const tourFile = (stateRoot) => join(stateRoot, 'tour.json');
38
50
  // what it says correctly and nothing else. A file for another version starts the tour again.
39
51
  export async function readTour(stateRoot) {
40
52
  const raw = await readFile(tourFile(stateRoot), 'utf8').then((text) => JSON.parse(text)).catch(() => null);
41
- if (!raw || typeof raw !== 'object' || raw.version !== TOUR_VERSION) return fresh();
53
+ if (!raw || typeof raw !== 'object') return fresh();
54
+ // The tour of 1.0, read or not: this person had 1.0, and 1.1 starts again for them.
55
+ if (raw.version === '1.0') return fresh('1.0');
56
+ if (raw.version !== TOUR_VERSION) return fresh();
42
57
  const iso = (value) => (typeof value === 'string' && !Number.isNaN(Date.parse(value)) ? value : null);
43
58
  return {
44
59
  version: TOUR_VERSION,
@@ -50,6 +65,7 @@ export async function readTour(stateRoot) {
50
65
  finished: iso(raw.finished),
51
66
  hints: Object.fromEntries(HINTS.filter((id) => iso(raw.hints?.[id])).map((id) => [id, raw.hints[id]])),
52
67
  held: raw.held && TAB.test(String(raw.held.by ?? '')) && iso(raw.held.at) ? { by: raw.held.by, at: raw.held.at } : null,
68
+ before: BEFORE.includes(raw.before) ? raw.before : null,
53
69
  };
54
70
  }
55
71
 
@@ -67,7 +83,8 @@ export function changeTour(stateRoot, change, now = new Date()) {
67
83
  }
68
84
  async function applyChange(stateRoot, change, now) {
69
85
  if (!change || typeof change !== 'object') return { error: 'change' };
70
- if (change.reset === true) return writeTour(stateRoot, fresh());
86
+ // Again from the start, as the same person: whoever came from 1.0 still did.
87
+ if (change.reset === true) return writeTour(stateRoot, fresh((await readTour(stateRoot)).before));
71
88
  const state = await readTour(stateRoot);
72
89
  const at = new Date(now).toISOString();
73
90
  if (change.path !== undefined) {
package/src/updates.mjs 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
  // Release channel: is there a newer MADRE on npm? One read of the public registry, at most
2
4
  // once a day, cached in ~/.pulse/updates.json. It sends the package name and nothing else,
3
5
  // the same request `npx` makes; PULSE_UPDATE_CHECK=0 or the switch in MU/TH/UR turns it off.
@@ -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
  import { t } from './i18n.mjs';
2
4
 
3
5
  const severity = { normal: 0, warning: 1, critical: 2, exhausted: 3 };
package/src/vault.mjs 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 vault: where a connector's secret lives.
2
4
  //
3
5
  // Until now MADRE held none. A key for Gemini or OpenCode is written where THAT CLI looks for it
package/src/verdict.mjs 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
  // One sentence about where a room stands, and one thing to do about it.
2
4
  //
3
5
  // Everything needed to say it was already being measured: six readings of what the archive is
@@ -28,7 +30,7 @@ export function verdictFor({ maturity = null, exams = {}, cold = null, asks = 0
28
30
  return {
29
31
  headline: stage?.label ?? null,
30
32
  says: consistency.says,
31
- next: { text: t('Settle the {n} contradictions EYECAT is holding. Until they are settled, everything built on this archive inherits them.', { n: consistency.open }), where: where('nostromo') },
33
+ next: { text: (consistency.open === 1 ? t('Settle the contradiction the memory reviewer found. Until it is settled, everything built on this memory inherits it.') : t('Settle the {n} contradictions the memory reviewer found. Until they are settled, everything built on this memory inherits them.', { n: consistency.open })), where: where('nostromo') },
32
34
  };
33
35
  }
34
36
 
package/src/whats-new.mjs 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
  // What a version brings, said to the person who just got it.
2
4
  //
3
5
  // After an update the room opens once on a sheet of what is new: a few things, each said plainly,
@@ -51,9 +53,9 @@ export const NOTES = {
51
53
  id: 'mother',
52
54
  icon: 'check',
53
55
  image: '/assets/news/1.0/mother.webp',
54
- title: { es: 'Diagnóstico te da el remedio', en: 'Diagnostics gives you the remedy' },
56
+ title: { es: 'Diagnóstico te da la solución', en: 'Diagnostics gives you the remedy' },
55
57
  body: {
56
- es: 'Escribe lo que pasa con tus palabras y ves qué hacer, con la tecla que lo resuelve sin salir del proyecto. Lo que falló en este proyecto aparece primero y marcado, para que no tengas que adivinar.',
58
+ es: 'Describe con tus palabras lo que pasa y te dice qué hacer, con la tecla que lo resuelve sin salir del proyecto. Lo que falló en este proyecto aparece primero y marcado, para que no tengas que adivinar.',
57
59
  en: 'Describe what is happening in your own words and you see what to do, with the key that fixes it without leaving the project. What failed in this project shows first and marked, so you do not have to guess.',
58
60
  },
59
61
  where: { es: 'El botón DIAGNÓSTICO de la barra', en: 'The DIAGNOSTICS button in the bar' },
@@ -65,7 +67,7 @@ export const NOTES = {
65
67
  image: '/assets/news/1.0/intents.webp',
66
68
  title: { es: 'Intenciones aprende de tu uso', en: 'Intenciones learns from how you work' },
67
69
  body: {
68
- es: 'Mientras escribes, sugiere cuánto debe pensar cada agente para lo que pides, a partir de tus propios turnos y sin gastar tokens. Puede proponerte un nivel más bajo para un solo mensaje, y si se quedó corto vuelve a subir.',
70
+ es: 'Mientras escribes, sugiere cuánto debe pensar cada agente para lo que pides, según cómo has trabajado y sin gastar tokens. Puede proponerte un nivel más bajo para un solo mensaje y, si se quedó corto, vuelve a subir.',
69
71
  en: 'As you write, it suggests how hard each agent should think for what you ask, learned from your own turns at no token cost. It can offer a lower level for a single message, and if that fell short it goes back up.',
70
72
  },
71
73
  where: { es: 'Bajo la caja de texto · Módulos › Intenciones', en: 'Under the message box · Modules › Intenciones' },
@@ -77,7 +79,7 @@ export const NOTES = {
77
79
  image: '/assets/news/1.0/permissions.webp',
78
80
  title: { es: 'Permisos a tu manera', en: 'Permissions your way' },
79
81
  body: {
80
- es: 'Elige qué abre #3 y #4: el nombre del proyecto, una frase tuya o, en #3, solo confirmar. Una llave aceptada puede valer unos minutos, y el modo máximo de cada agente cabe en una sola tabla.',
82
+ es: 'Elige cómo confirmas #3 y #4: con el nombre del proyecto, con una frase tuya o, en #3, solo confirmando. Una confirmación puede valer unos minutos, y el permiso máximo de cada agente cabe en una sola tabla.',
81
83
  en: 'Choose what unlocks #3 and #4: the project name, a phrase of your own or, for #3, just a confirmation. An accepted key can hold for a few minutes, and every agent’s highest mode fits in one table.',
82
84
  },
83
85
  where: { es: 'Ajustes › Permisos', en: 'Settings › Permissions' },
@@ -89,7 +91,7 @@ export const NOTES = {
89
91
  image: '/assets/news/1.0/github.webp',
90
92
  title: { es: 'GitHub en el proyecto', en: 'GitHub in the project' },
91
93
  body: {
92
- es: 'Revisa pull requests, CI e issues con /gh, usando la sesión de gh que ya tienes. Antes de publicar algo te enseña qué saldría y te pregunta, y los agentes solo publican en #4.',
94
+ es: 'Revisa pull requests, pruebas automáticas (CI) e issues con /gh, usando la sesión de gh que ya tienes. Antes de publicar algo te muestra qué saldría y te pregunta; los agentes solo publican en #4.',
93
95
  en: 'Check pull requests, CI and issues with /gh, using the gh session you already have. Before anything is posted it shows you what would go out and asks, and agents only post in #4.',
94
96
  },
95
97
  where: { es: 'Módulos › GitHub · luego /gh en la caja', en: 'Modules › GitHub · then /gh in the box' },
@@ -125,7 +127,7 @@ export const NOTES = {
125
127
  image: '/assets/news/1.0/nostromo.webp',
126
128
  title: { es: 'El Mapa de memoria a un clic', en: 'The Memory map one click away' },
127
129
  body: {
128
- es: 'El cerebro de la memoria tiene su propio botón en la barra. Las conexiones entre memorias se ven aunque Ollama esté apagado.',
130
+ es: 'El Mapa de memoria tiene su propio botón en la barra. Los vínculos entre memorias se ven aunque Ollama esté apagado.',
129
131
  en: 'The memory brain has its own button in the bar. The links between memories show even with Ollama off.',
130
132
  },
131
133
  where: { es: 'El botón Mapa de memoria de la barra', en: 'The Memory map button in the bar' },
@@ -137,17 +139,17 @@ export const NOTES = {
137
139
  image: '/assets/news/1.0/room.webp',
138
140
  title: { es: 'El proyecto, acomodado a tu gusto', en: 'The project, arranged your way' },
139
141
  body: {
140
- es: 'Cada panel se abre al lado o en una ventana que mueves. Varias conversaciones trabajan a la vez, los servidores de tu proyecto viven dentro del proyecto y el visor edita código.',
142
+ es: 'Cada panel se abre al lado o en una ventana que mueves. Varias conversaciones trabajan a la vez, los servidores de tu proyecto corren dentro del proyecto y el visor también edita código.',
141
143
  en: 'Every panel opens beside you or in a window you move. Several conversations work at once, your project’s servers live inside the project, and the viewer edits code.',
142
144
  },
143
- where: { es: 'El encabezado de cada panel · Ajustes › Proyecto y turnos', en: 'The header of every panel · Settings › Project and turns' },
145
+ where: { es: 'El encabezado de cada panel · Ajustes › Proyecto y respuestas', en: 'The header of every panel · Settings › Project and turns' },
144
146
  action: 'room',
145
147
  },
146
148
  {
147
149
  id: 'looks',
148
150
  icon: 'star',
149
151
  image: '/assets/news/1.0/looks.webp',
150
- title: { es: '17 acentos y 12 fondos', en: '17 accents and 12 wallpapers' },
152
+ title: { es: '17 colores de acento y 12 fondos', en: '17 accents and 12 wallpapers' },
151
153
  body: {
152
154
  es: 'Cada uno pensado para tema claro y oscuro. Las respuestas se leen sobre vidrio esmerilado encima de tu fondo, y las tarjetas tienen un relieve suave.',
153
155
  en: 'Each one made for light and dark themes. Replies read on frosted glass over your wallpaper, and cards stand out in soft relief.',
@@ -161,7 +163,7 @@ export const NOTES = {
161
163
  image: '/assets/news/1.0/alerts.webp',
162
164
  title: { es: 'Alertas más claras', en: 'Clearer alerts' },
163
165
  body: {
164
- es: 'Las confirmaciones y las llaves de #3 y #4 llegan en una sola hoja clara, con lo que vas a aprobar a la vista. El menú «revisarlo con» ya no se corta.',
166
+ es: 'Las confirmaciones de #3 y #4 llegan en una sola hoja clara, con lo que vas a aprobar a la vista. El menú «revisarlo con» ya no se corta.',
165
167
  en: 'Confirmations and the keys for #3 and #4 arrive as one clear sheet, with what you are approving in view. The “review it with” menu is no longer cut off.',
166
168
  },
167
169
  where: { es: 'Aparecen solas cuando el proyecto necesita tu palabra', en: 'They appear on their own when the project needs your word' },
@@ -1,25 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="300" viewBox="0 0 1200 300" role="img" aria-label="MADRE · MU/TH/UR 6000 · INTERFACE 2037">
2
- <defs>
3
- <linearGradient id="bg" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#050605"/><stop offset="1" stop-color="#0b0d0b"/></linearGradient>
4
- <pattern id="scan" width="4" height="4" patternUnits="userSpaceOnUse"><rect width="4" height="1" fill="#9bff66" fill-opacity="0.06"/></pattern>
5
- <filter id="glow" x="-20%" y="-50%" width="140%" height="200%"><feGaussianBlur stdDeviation="4" result="b"/><feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge></filter>
6
- <filter id="glowSoft" x="-20%" y="-50%" width="140%" height="200%"><feGaussianBlur stdDeviation="10"/></filter>
7
- </defs>
8
- <rect width="1200" height="300" fill="url(#bg)"/>
9
- <rect width="1200" height="300" fill="url(#scan)"/>
10
- <rect x="0.5" y="0.5" width="1199" height="299" fill="none" stroke="#9bff66" stroke-opacity="0.18"/>
11
- <g transform="translate(90 150)" stroke="#9bff66" fill="none" stroke-width="5" stroke-linecap="round" stroke-linejoin="round">
12
- <path d="M0 0 H140 L176 0 L208 -70 L248 70 L284 0 L312 0 L330 -36 L348 0 H460" stroke-opacity="0.25" filter="url(#glowSoft)" stroke-width="14"/>
13
- <path d="M0 0 H140 L176 0 L208 -70 L248 70 L284 0 L312 0 L330 -36 L348 0 H460" filter="url(#glow)"/>
14
- <circle cx="520" cy="0" r="12" fill="#9bff66" stroke="none" filter="url(#glow)"/>
15
- </g>
16
- <g font-family="SF Mono, Menlo, Consolas, monospace" fill="#9bff66">
17
- <text x="690" y="150" font-size="84" font-weight="700" letter-spacing="14" filter="url(#glow)">MADRE</text>
18
- <text x="692" y="194" font-size="15" letter-spacing="6" fill-opacity="0.75">MU/TH/UR 6000 · INTERFACE 2037</text>
19
- <text x="692" y="224" font-size="13" letter-spacing="3" fill-opacity="0.55">ONE ROOM · FOUR AGENTS · ONE MEMORY</text>
20
- </g>
21
- <g font-family="SF Mono, Menlo, Consolas, monospace" font-size="11" letter-spacing="4" fill="#9bff66" fill-opacity="0.45">
22
- <text x="90" y="262">CODEX · CLAUDE CODE · GEMINI CLI · OPENCODE</text>
23
- <text x="1110" y="262" text-anchor="end">PULSE CHANNEL · LOCAL FIRST</text>
24
- </g>
25
- </svg>