@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.
- package/ADDITIONAL-TERMS.md +93 -0
- package/CHANGELOG.en.md +1945 -0
- package/CHANGELOG.md +78 -1
- package/CONTRIBUTING.md +5 -1
- package/LICENSE +661 -202
- package/NOTICE +34 -3
- package/README.en.md +245 -0
- package/README.md +23 -13
- package/TRADEMARKS.en.md +50 -0
- package/TRADEMARKS.md +82 -0
- package/bin/madre.mjs +2 -0
- package/docs/INTERNALS.md +8 -2
- package/docs/REFERENCE.md +17 -7
- package/docs/en/INTERNALS.md +103 -0
- package/docs/en/REFERENCE.md +339 -0
- package/docs/en/SDK.md +306 -0
- package/docs/en/training/README.md +59 -0
- package/docs/madre-banner.png +0 -0
- package/docs/training/README.md +20 -8
- package/docs/training/train.sh +2 -1
- package/package.json +14 -5
- package/public/abduction.js +2 -0
- package/public/app.js +2066 -488
- package/public/attribution.js +71 -0
- package/public/brands.js +3 -1
- package/public/editor.js +2 -0
- package/public/es.js +1706 -1226
- package/public/i18n.js +25 -1
- package/public/index.html +13 -10
- package/public/inquiry.js +2 -0
- package/public/loader.js +2 -0
- package/public/macroverso.js +24 -2
- package/public/nostromo-engine.js +2 -0
- package/public/resay.js +6 -0
- package/public/review-ask.js +2 -0
- package/public/routing.js +23 -1
- package/public/salas-mac.css +539 -28
- package/public/salas-mac.html +30 -22
- package/public/salas-mac.js +1498 -144
- package/public/salas.css +2 -0
- package/public/salas.html +1 -0
- package/public/salas.js +4 -2
- package/public/styles.css +1123 -20
- package/public/syntax.js +2 -0
- package/public/touch.js +2 -0
- package/public/tour-chapters.js +164 -52
- package/public/tour.js +85 -12
- package/public/troubleshooting.js +20 -18
- package/src/adapters/claude.mjs +2 -0
- package/src/adapters/codex.mjs +2 -0
- package/src/adapters/gemini.mjs +3 -1
- package/src/adapters/madre.mjs +3 -1
- package/src/adapters/opencode.mjs +7 -3
- package/src/adapters/process.mjs +2 -0
- package/src/asking.mjs +2 -0
- package/src/auth-probe.mjs +32 -7
- package/src/bridge/devices.mjs +2 -0
- package/src/bridge/handoff.mjs +2 -0
- package/src/bridge/host.mjs +2 -0
- package/src/bridge/network.mjs +2 -0
- package/src/bridge/policy.mjs +3 -1
- package/src/bridge/qr.mjs +2 -0
- package/src/bridge/server.mjs +2 -0
- package/src/capabilities.mjs +2 -0
- package/src/chats.mjs +2 -0
- package/src/checkpoint.mjs +2 -0
- package/src/choices.mjs +2 -0
- package/src/cli-args.mjs +2 -0
- package/src/cold.mjs +2 -0
- package/src/commands.mjs +2 -0
- package/src/config.mjs +2 -0
- package/src/conversation-context.mjs +15 -1
- package/src/credentials.mjs +112 -3
- package/src/dataset.mjs +2 -0
- package/src/directives.mjs +8 -6
- package/src/distiller.mjs +2 -0
- package/src/embeddings.mjs +2 -0
- package/src/enlaces.mjs +6 -4
- package/src/event-store.mjs +2 -0
- package/src/exam.mjs +6 -4
- package/src/extensions.mjs +33 -10
- package/src/eyecat-watch.mjs +2 -0
- package/src/eyecat.mjs +2 -0
- package/src/file-ops.mjs +2 -0
- package/src/files.mjs +32 -0
- package/src/github.mjs +2 -0
- package/src/heartbeat.mjs +57 -0
- package/src/i18n.mjs +15 -1
- package/src/image-studio.mjs +2 -0
- package/src/json-file.mjs +2 -0
- package/src/launch.mjs +2 -0
- package/src/lease.mjs +5 -1
- package/src/lobby-work.mjs +2 -0
- package/src/local-ai.mjs +50 -0
- package/src/looks.mjs +40 -5
- package/src/maturity.mjs +3 -1
- package/src/mcp/connect.mjs +345 -0
- package/src/mcp/github-server.mjs +2 -0
- package/src/mcp/image-server.mjs +2 -0
- package/src/mcp/memory-server.mjs +2 -0
- package/src/mcp/proxy.mjs +153 -0
- package/src/mcp/smtp-server.mjs +2 -0
- package/src/memory-dashboard.mjs +2 -0
- package/src/memory-tools.mjs +2 -0
- package/src/memory.mjs +2 -0
- package/src/models.mjs +83 -3
- package/src/modules/ahp.mjs +2 -0
- package/src/modules/ash-policy.mjs +2 -0
- package/src/modules/ash.mjs +3 -1
- package/src/modules/bishop-plan.mjs +5 -3
- package/src/modules/bishop.mjs +13 -11
- package/src/modules/choices.mjs +2 -0
- package/src/modules/correo.mjs +2 -0
- package/src/modules/enlaces.mjs +2 -0
- package/src/modules/git-pulse.mjs +2 -0
- package/src/modules/github.mjs +2 -0
- package/src/modules/helpers.mjs +2 -0
- package/src/modules/image-studio.mjs +3 -1
- package/src/modules/index.mjs +4 -1
- package/src/modules/intents-calibration.mjs +2 -0
- package/src/modules/intents-desk.mjs +4 -2
- package/src/modules/intents-observe.mjs +2 -0
- package/src/modules/intents-policy.mjs +4 -1
- package/src/modules/intents-try.mjs +2 -0
- package/src/modules/intents.mjs +8 -6
- package/src/modules/mcp-connect.mjs +293 -0
- package/src/modules/ollama.mjs +17 -3
- package/src/modules/playwright.mjs +25 -10
- package/src/modules/ripley.mjs +2 -0
- package/src/modules/runs.mjs +5 -3
- package/src/modules/sdk.mjs +2 -0
- package/src/modules/updates.mjs +2 -0
- package/src/mother.mjs +2 -0
- package/src/ollama.mjs +2 -0
- package/src/outbound.mjs +24 -5
- package/src/override.mjs +2 -0
- package/src/ports.mjs +2 -0
- package/src/prices.mjs +2 -0
- package/src/privacy.mjs +2 -0
- package/src/quota-monitor.mjs +2 -0
- package/src/quota-sources.mjs +2 -0
- package/src/request-guard.mjs +2 -0
- package/src/review-ask.mjs +2 -0
- package/src/room/archivist.mjs +2 -0
- package/src/room/attachments.mjs +2 -0
- package/src/room/budget.mjs +2 -0
- package/src/room/context.mjs +2 -0
- package/src/room/control.mjs +7 -1
- package/src/room/copilot.mjs +76 -0
- package/src/room/economy.mjs +2 -0
- package/src/room/escalation.mjs +3 -0
- package/src/room/ghost.mjs +2 -0
- package/src/room/guard.mjs +2 -0
- package/src/room/prompt.mjs +13 -4
- package/src/room/returns.mjs +82 -0
- package/src/room/runs.mjs +4 -0
- package/src/room/vectors.mjs +2 -0
- package/src/room.mjs +264 -45
- package/src/router.mjs +2 -0
- package/src/runs.mjs +2 -0
- package/src/runtime-detection.mjs +2 -0
- package/src/salas.mjs +2 -0
- package/src/sentinel-errors.mjs +2 -0
- package/src/server-sentinel.mjs +2 -0
- package/src/server.mjs +485 -55
- package/src/setup.mjs +2 -0
- package/src/smtp.mjs +2 -0
- package/src/tour.mjs +26 -9
- package/src/updates.mjs +2 -0
- package/src/usage-sentinel.mjs +2 -0
- package/src/vault.mjs +2 -0
- package/src/verdict.mjs +3 -1
- package/src/whats-new.mjs +12 -10
- package/docs/madre-banner.svg +0 -25
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">
|
|
@@ -94,6 +95,7 @@
|
|
|
94
95
|
<aside id="tree" class="tree" aria-label="Project files" hidden>
|
|
95
96
|
<header class="tree-head">
|
|
96
97
|
<span class="tree-title">FILES <span id="tree-root" class="tree-root"></span></span>
|
|
98
|
+
<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
99
|
<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
100
|
<button id="tree-close" class="tree-close" type="button" aria-label="Close files">×</button>
|
|
99
101
|
</header>
|
|
@@ -109,8 +111,8 @@
|
|
|
109
111
|
<span class="mother-title">What is sent</span>
|
|
110
112
|
<span class="mother-sub">What this project says in your name</span>
|
|
111
113
|
<span class="mother-actions">
|
|
112
|
-
<button id="core-copy" class="
|
|
113
|
-
<button id="core-close" class="
|
|
114
|
+
<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>
|
|
115
|
+
<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
116
|
</span>
|
|
115
117
|
</header>
|
|
116
118
|
<p id="core-boot" class="mother-boot"></p>
|
|
@@ -139,7 +141,7 @@
|
|
|
139
141
|
</form>
|
|
140
142
|
<div id="mother-os" class="sx-seg mother-os" role="radiogroup" aria-label="Operating system"></div>
|
|
141
143
|
<span class="mother-tools">
|
|
142
|
-
<button id="mother-settings-button" class="surface-gear" type="button" title="Diagnostics settings: what the
|
|
144
|
+
<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
145
|
<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
146
|
<button id="tour-button" class="surface-gear tour-button" type="button" title="The tour of MADRE" aria-label="Tour">?</button>
|
|
145
147
|
</span>
|
|
@@ -147,7 +149,7 @@
|
|
|
147
149
|
</header>
|
|
148
150
|
<p id="mother-boot" class="mother-status" aria-live="polite"></p>
|
|
149
151
|
<div id="mother-body" class="mother-body">
|
|
150
|
-
<section id="mother-list" class="mother-list" aria-label="
|
|
152
|
+
<section id="mother-list" class="mother-list" aria-label="Problems"></section>
|
|
151
153
|
<section id="mother-answer" class="mother-detail" aria-live="polite"></section>
|
|
152
154
|
</div>
|
|
153
155
|
</dialog>
|
|
@@ -192,7 +194,7 @@
|
|
|
192
194
|
<textarea id="message" rows="1" placeholder="Type here, human. Ask the project…"></textarea>
|
|
193
195
|
<div id="slash-menu" class="slash-menu" role="listbox" hidden></div>
|
|
194
196
|
</div>
|
|
195
|
-
<button id="create-toggle" type="button" class="create-toggle" aria-pressed="false" title="
|
|
197
|
+
<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
198
|
<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
199
|
<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
200
|
<span class="create-word">CREATE</span>
|
|
@@ -236,7 +238,8 @@
|
|
|
236
238
|
<form id="nostromo-gate-form" class="key-form" autocomplete="off">
|
|
237
239
|
<label class="room-ask-field"><span class="k">Type the project name</span><input id="nostromo-gate-input" autocomplete="off" spellcheck="false"></label>
|
|
238
240
|
<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">
|
|
241
|
+
<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>
|
|
242
|
+
<button id="nostromo-gate-skip" class="key-skip" type="button">Don't ask again…</button>
|
|
240
243
|
</form>
|
|
241
244
|
</div>
|
|
242
245
|
</dialog>
|
|
@@ -246,7 +249,7 @@
|
|
|
246
249
|
<span class="mother-title">MEMORY MAP</span>
|
|
247
250
|
<span id="nostromo-sub" class="mother-sub">MEMORY RESEARCH · LOADING…</span>
|
|
248
251
|
<span class="nostromo-legend" aria-label="Memory kinds">
|
|
249
|
-
<span class="k decision" title="YELLOW
|
|
252
|
+
<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
253
|
</span>
|
|
251
254
|
<span class="nostromo-actions">
|
|
252
255
|
<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>
|
|
@@ -285,7 +288,7 @@
|
|
|
285
288
|
<dt>SOURCE</dt><dd id="nostromo-card-span" data-part="span"></dd>
|
|
286
289
|
<dt>ARCHIVIST</dt><dd id="nostromo-card-agent" data-part="agent"></dd>
|
|
287
290
|
<dt>DISTILLED</dt><dd id="nostromo-card-when" data-part="when"></dd>
|
|
288
|
-
<dt>
|
|
291
|
+
<dt>STATUS</dt><dd id="nostromo-card-zone" data-part="zone"></dd>
|
|
289
292
|
</dl>
|
|
290
293
|
<section class="wire">
|
|
291
294
|
<h6>LINKS <span id="nostromo-card-degree" data-part="degree" class="n"></span></h6>
|
|
@@ -307,7 +310,7 @@
|
|
|
307
310
|
<header class="viewer-head browser-head">
|
|
308
311
|
<span class="viewer-nav" id="browser-nav">
|
|
309
312
|
<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"
|
|
313
|
+
<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
314
|
<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
315
|
<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
316
|
</span>
|
|
@@ -366,7 +369,7 @@
|
|
|
366
369
|
</dialog>
|
|
367
370
|
</div>
|
|
368
371
|
<script type="module" src="/app.js"></script>
|
|
369
|
-
<dialog id="intents-window" class="surface window custom-window intents-window" aria-label="
|
|
372
|
+
<dialog id="intents-window" class="surface window custom-window intents-window" aria-label="Suggested effort · quick test">
|
|
370
373
|
<header class="custom-head">
|
|
371
374
|
<span class="custom-title">INTENCIONES</span>
|
|
372
375
|
<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
|
package/public/macroverso.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 MACROVERSE: every room on this Mac as a NOSTROMO in open space (docs/MACROVERSO.md, phase 3a).
|
|
2
4
|
// It is entered from SALAS and only on a large screen; on a phone SALAS is the list and nothing more.
|
|
3
5
|
//
|
|
@@ -573,6 +575,15 @@ export function openMacroverso({ host, rooms, here, enlaces = [], accent = '#9bf
|
|
|
573
575
|
now[key] = answer ?? { unreachable: true };
|
|
574
576
|
if (now.loading) delete now.loading[key];
|
|
575
577
|
if (!full) { now.dirty = true; redraw(); }
|
|
578
|
+
// A saturated machine can miss one read while the room is still alive. Do not keep
|
|
579
|
+
// that transient failure as the universe's permanent texture.
|
|
580
|
+
if (now[key].unreachable || now[key].outdated) setTimeout(() => {
|
|
581
|
+
const current = universes.find((item) => item.room.id === one.room.id);
|
|
582
|
+
if (!current || current.face !== one.face || (!current[key]?.unreachable && !current[key]?.outdated)) return;
|
|
583
|
+
current[key] = null;
|
|
584
|
+
if (full) { if (focus === current && !live) enterLive(current); }
|
|
585
|
+
else { current.dirty = true; redraw(); }
|
|
586
|
+
}, 5000);
|
|
576
587
|
return now[key];
|
|
577
588
|
});
|
|
578
589
|
one.loading = { ...(one.loading ?? {}), [key]: asked };
|
|
@@ -1345,8 +1356,16 @@ export function openMacroverso({ host, rooms, here, enlaces = [], accent = '#9bf
|
|
|
1345
1356
|
|
|
1346
1357
|
// Pointer: a drag on the space moves it; a drag on the chosen universe turns it; a click picks a
|
|
1347
1358
|
// universe, or a memory inside the chosen one; the wheel brings the space closer round the pointer.
|
|
1359
|
+
const covered = (event) => {
|
|
1360
|
+
const panels = [...windows.map((win) => win.el), card, ...document.querySelectorAll('dialog[open], .tree.window, .surface.window, .conv-window, .browser-dock.window')];
|
|
1361
|
+
return panels.some((panel) => {
|
|
1362
|
+
if (panel.hidden || panel.contains(canvas)) return false;
|
|
1363
|
+
const rect = panel.getBoundingClientRect();
|
|
1364
|
+
return event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom;
|
|
1365
|
+
});
|
|
1366
|
+
};
|
|
1348
1367
|
canvas.addEventListener('pointerdown', (event) => {
|
|
1349
|
-
if (event.button !== 0) return;
|
|
1368
|
+
if (event.button !== 0 || covered(event)) return;
|
|
1350
1369
|
drag.active = true;
|
|
1351
1370
|
drag.moved = false;
|
|
1352
1371
|
drag.turning = Boolean(liveAt(event)?.inside);
|
|
@@ -1357,6 +1376,7 @@ export function openMacroverso({ host, rooms, here, enlaces = [], accent = '#9bf
|
|
|
1357
1376
|
try { canvas.setPointerCapture(event.pointerId); } catch { /* the pointer already left */ }
|
|
1358
1377
|
});
|
|
1359
1378
|
canvas.addEventListener('pointermove', (event) => {
|
|
1379
|
+
if (covered(event)) return;
|
|
1360
1380
|
const box = canvas.getBoundingClientRect();
|
|
1361
1381
|
pointer = { x: event.clientX - box.left, y: event.clientY - box.top };
|
|
1362
1382
|
if (drag.active) {
|
|
@@ -1400,7 +1420,7 @@ export function openMacroverso({ host, rooms, here, enlaces = [], accent = '#9bf
|
|
|
1400
1420
|
});
|
|
1401
1421
|
const release = (event) => {
|
|
1402
1422
|
// Let go over another universe: the notes of the one carried would travel to it.
|
|
1403
|
-
if (linking?.over && event?.type === 'pointerup') actions.link?.(linking.from.room, linking.over.room);
|
|
1423
|
+
if (linking?.over && event?.type === 'pointerup' && !covered(event)) actions.link?.(linking.from.room, linking.over.room);
|
|
1404
1424
|
linking = null;
|
|
1405
1425
|
drag.active = false;
|
|
1406
1426
|
drag.turning = false;
|
|
@@ -1412,6 +1432,7 @@ export function openMacroverso({ host, rooms, here, enlaces = [], accent = '#9bf
|
|
|
1412
1432
|
canvas.addEventListener('pointercancel', release);
|
|
1413
1433
|
canvas.addEventListener('pointerleave', () => { hover = null; pointer = null; if (live) live.scene.hover = null; redraw(); });
|
|
1414
1434
|
canvas.addEventListener('click', (event) => {
|
|
1435
|
+
if (covered(event)) return;
|
|
1415
1436
|
if (drag.moved) { drag.moved = false; return; }
|
|
1416
1437
|
const over = liveAt(event);
|
|
1417
1438
|
if (over?.inside && live) {
|
|
@@ -1428,6 +1449,7 @@ export function openMacroverso({ host, rooms, here, enlaces = [], accent = '#9bf
|
|
|
1428
1449
|
choose(one && one !== focus ? one : focus && !one ? null : one);
|
|
1429
1450
|
});
|
|
1430
1451
|
canvas.addEventListener('wheel', (event) => {
|
|
1452
|
+
if (covered(event)) return;
|
|
1431
1453
|
event.preventDefault();
|
|
1432
1454
|
const rect = canvas.getBoundingClientRect();
|
|
1433
1455
|
const px = event.clientX - rect.left, py = event.clientY - rect.top;
|
|
@@ -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
|
// NOSTROMO's engine: the physics and the painters of the archive as a body in space, lifted out
|
|
2
4
|
// of the room's page so the Macroverso can draw every room the way its own NOSTROMO is drawn —
|
|
3
5
|
// with these very functions, not a copy of them (docs/MACROVERSO.md, phase 3a).
|
package/public/resay.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
|
// What MADRE said in another language, said again.
|
|
2
4
|
//
|
|
3
5
|
// A failure is recorded in the ledger with the sentence MADRE wrote at the time, and a room that
|
|
@@ -41,6 +43,7 @@ const SAID = [
|
|
|
41
43
|
'{n} agents are working at once. If this is not what you asked for, type STOPALL.',
|
|
42
44
|
'@{agent} is already answering another turn; answers may cross.',
|
|
43
45
|
' STOPALL halts everything.',
|
|
46
|
+
'The copilot ran commands by itself {n} times in a row; the next ones wait for you. Write to it to go on.',
|
|
44
47
|
'The plan by @{agent} has been running for {n} min.',
|
|
45
48
|
' STOPALL halts it.',
|
|
46
49
|
'@{holder} still holds EDIT; @{agent} answers read-only this turn.',
|
|
@@ -55,6 +58,9 @@ const SAID = [
|
|
|
55
58
|
'@{agent} is capped at #{n} {label}; raise its MAX MODE to #{wanted} in CONNECTIONS to arm {mode}.',
|
|
56
59
|
'@{agent} already holds {mode} of this project; one holder at a time. STOPALL revokes it.',
|
|
57
60
|
'@{agent} left the project: Ollama is not running. Start Ollama, or open Local AI in Modules.',
|
|
61
|
+
'@madre is in the project · {version}',
|
|
62
|
+
'{agent} is not installed on this computer.',
|
|
63
|
+
'@madre left the project: Ollama has no chat model running',
|
|
58
64
|
'@{agent} left the room: Ollama is not running. Start Ollama, or open Ollama in Modules.',
|
|
59
65
|
'Google reported the model as unavailable (HTTP 503) and the CLI kept retrying.',
|
|
60
66
|
'Try again shortly or choose another model.',
|
package/public/review-ask.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
|
// Asking for a star or a review (2026-10-10), in the room and in Home: the server keeps when to
|
|
2
4
|
// ask (src/review-ask.mjs); this page says once a minute that it is in view, and when a moment is
|
|
3
5
|
// due it asks — only when nothing is going on: no turn running, nothing half written, no other
|
package/public/routing.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
|
// Which questions the room can answer without paying for them.
|
|
2
4
|
//
|
|
3
5
|
// @madre runs on Ollama, on this computer. A turn it answers costs nothing: no input tokens, no
|
|
@@ -59,6 +61,13 @@ export function archiveQuestion(text = '') {
|
|
|
59
61
|
const NEEDS = /(necesit|requier|hace falta|no alcanza|insuficiente|permiso|conced|eleva|sub[ei]r|needs?|requires?|not enough|insufficient|permission|grant|raise|escalat)/i;
|
|
60
62
|
|
|
61
63
|
export function modeAsked(text = '', { ran = 1 } = {}) {
|
|
64
|
+
return modeAskedWithTime(text, { ran })?.mode ?? null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// The same reading, and the time it asked for beside the number, if it said one (2026-10-14:
|
|
68
|
+
// agents are taught to write «I need #3 for 15 min: why»). Minutes, or null when it said none.
|
|
69
|
+
const TIME = /(\d{1,4})\s*(min(?:uto)?s?\b|m\b|h(?:ora)?s?\b|hours?\b)/i;
|
|
70
|
+
export function modeAskedWithTime(text = '', { ran = 1 } = {}) {
|
|
62
71
|
const reply = String(text ?? '');
|
|
63
72
|
if (reply.length > 8000) return null;
|
|
64
73
|
let wanted = null;
|
|
@@ -68,7 +77,20 @@ export function modeAsked(text = '', { ran = 1 } = {}) {
|
|
|
68
77
|
// The word of need has to sit beside the number, not anywhere in a long answer.
|
|
69
78
|
const around = reply.slice(Math.max(0, match.index - 90), match.index + 90);
|
|
70
79
|
if (!NEEDS.test(around)) continue;
|
|
71
|
-
if (wanted === null || mode > wanted)
|
|
80
|
+
if (wanted === null || mode > wanted.mode) {
|
|
81
|
+
const after = reply.slice(match.index, match.index + 60).match(TIME);
|
|
82
|
+
const amount = after ? Number(after[1]) : null;
|
|
83
|
+
wanted = { mode, minutes: amount ? (/^h/i.test(after[2]) ? amount * 60 : amount) : null };
|
|
84
|
+
}
|
|
72
85
|
}
|
|
73
86
|
return wanted;
|
|
74
87
|
}
|
|
88
|
+
|
|
89
|
+
// The windows a key may open, as the project allows them (src/override.mjs): what the agent asked
|
|
90
|
+
// for becomes the smallest one that covers it, or the longest there is.
|
|
91
|
+
export const MODE_WINDOWS = Object.freeze({ 3: Object.freeze([5, 15, 30]), 4: Object.freeze([5]) });
|
|
92
|
+
export function windowFor(mode, minutes) {
|
|
93
|
+
const allowed = MODE_WINDOWS[mode];
|
|
94
|
+
if (!allowed || !Number.isFinite(minutes) || minutes <= 0) return 0;
|
|
95
|
+
return allowed.find((one) => one >= minutes) ?? allowed.at(-1);
|
|
96
|
+
}
|