agentbox-app 0.1.6 → 0.1.11
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/README.md +209 -55
- package/bin/agentbox.mjs +6 -0
- package/briefs/message-rules.md +13 -3
- package/briefs/worker.md +63 -49
- package/briefs/writing-rules.md +90 -131
- package/main/account-discovery.mjs +21 -20
- package/main/account-tooling.mjs +9 -10
- package/main/agent-activity.mjs +45 -5
- package/main/agent-schedule.mjs +14 -14
- package/main/agent-sessions.mjs +94 -10
- package/main/agent-updates.mjs +114 -0
- package/main/agents.mjs +52 -46
- package/main/analytics.mjs +27 -0
- package/main/approval-prompt-server.mjs +2 -2
- package/main/artifact-path.mjs +11 -0
- package/main/claude-bin.mjs +31 -5
- package/main/claude-input.mjs +45 -3
- package/main/claude-plan.mjs +11 -11
- package/main/code-change.mjs +3 -3
- package/main/codex-account.mjs +1 -1
- package/main/codex-bin.mjs +17 -0
- package/main/codex-memory-gate.mjs +260 -0
- package/main/codex-models.mjs +12 -7
- package/main/codex-threads.mjs +46 -23
- package/main/codex-usage-file.mjs +7 -7
- package/main/codex-usage.mjs +4 -4
- package/main/codex-watch.mjs +12 -12
- package/main/config.mjs +68 -8
- package/main/dev-window.mjs +9 -9
- package/main/doc-scheme.mjs +2 -0
- package/main/engine-setup.mjs +193 -0
- package/main/feedback.mjs +55 -0
- package/main/folder-pictures.mjs +48 -0
- package/main/frame-scrollbars.mjs +90 -0
- package/main/fresh-user.mjs +6 -3
- package/main/git-change-offthread.mjs +70 -0
- package/main/git-change-thread.mjs +11 -0
- package/main/git-change.mjs +1 -1
- package/main/img-scheme.mjs +70 -1
- package/main/instruction-settings.mjs +92 -54
- package/main/ipc.mjs +316 -42
- package/main/leftovers.mjs +518 -0
- package/main/live-replies.mjs +43 -5
- package/main/machine.mjs +47 -0
- package/main/main.mjs +119 -15
- package/main/memory-gate-history.mjs +254 -0
- package/main/memory-gate-server.mjs +461 -0
- package/main/memory-gate.mjs +206 -0
- package/main/message-priority.mjs +87 -0
- package/main/rail-note.mjs +2 -2
- package/main/refresh-agent-models.mjs +20 -0
- package/main/repeats.mjs +4 -4
- package/main/row-label.mjs +114 -51
- package/main/serve.mjs +67 -5
- package/main/settings.mjs +223 -26
- package/main/ship-queue.mjs +279 -0
- package/main/sign-in-files.mjs +39 -0
- package/main/source-updater.mjs +298 -0
- package/main/store/home.mjs +47 -2
- package/main/store/work-items.mjs +150 -6
- package/main/store.mjs +235 -9
- package/main/supervisor.mjs +1444 -406
- package/main/task-commands.mjs +8 -10
- package/main/task-folders.mjs +74 -13
- package/main/task-remote-control.mjs +3 -3
- package/main/task-terminals.mjs +2 -1
- package/main/team/index.mjs +440 -0
- package/main/team/memory-cloud.mjs +247 -0
- package/main/team/projects.mjs +162 -0
- package/main/team/session.mjs +225 -0
- package/main/team/sign-in.mjs +106 -0
- package/main/team/supabase-backend.mjs +231 -0
- package/main/team/sync.mjs +163 -0
- package/main/updater.mjs +15 -5
- package/main/write-before-reload.mjs +50 -0
- package/mcp/core/page.mjs +9 -11
- package/mcp/core/work.mjs +91 -25
- package/mcp/tools.mjs +12 -6
- package/package.json +21 -9
- package/renderer/dist/assets/agentbox-icon-F1oN9nj_.svg +15 -0
- package/renderer/dist/assets/index-B-2Az952.css +32 -0
- package/renderer/dist/assets/index-D6qncgai.js +1168 -0
- package/renderer/dist/index.html +2 -2
- package/scripts/memory-gate-hook.sh +59 -0
- package/shared/agent-import.mjs +38 -15
- package/shared/agents.d.mts +26 -8
- package/shared/agents.mjs +100 -108
- package/shared/analytics-events.mjs +19 -2
- package/shared/answers.mjs +12 -0
- package/shared/bridge-map.d.mts +12 -0
- package/shared/bridge-map.mjs +37 -1
- package/shared/claude-commands.generated.mjs +2 -2
- package/shared/claude-models.generated.mjs +4 -4
- package/shared/claude-usage.mjs +6 -6
- package/shared/codex-import.mjs +7 -7
- package/shared/codex-modes.d.mts +50 -0
- package/shared/codex-usage.mjs +7 -8
- package/shared/demo-world.mjs +5 -5
- package/shared/engines.mjs +27 -10
- package/shared/feedback.d.mts +14 -0
- package/shared/feedback.mjs +44 -0
- package/shared/first-run-examples.mjs +4 -4
- package/shared/first-run-practice.d.mts +16 -0
- package/shared/first-run-practice.mjs +176 -70
- package/shared/fresh-user-home.mjs +22 -3
- package/shared/instruction-defaults.json +2 -2
- package/shared/product-name.mjs +4 -2
- package/shared/project-folder-check.mjs +6 -0
- package/shared/rank.d.mts +1 -0
- package/shared/rank.mjs +22 -0
- package/shared/referenced-files.mjs +1 -1
- package/shared/schemes.d.mts +11 -0
- package/shared/schemes.mjs +1 -1
- package/shared/shortcuts.d.mts +41 -0
- package/shared/shortcuts.mjs +236 -0
- package/shared/spawn-trouble.d.mts +2 -0
- package/shared/spawn-trouble.mjs +39 -18
- package/shared/team-rules.d.mts +17 -0
- package/shared/team-rules.mjs +230 -0
- package/shared/team-status.d.mts +11 -0
- package/shared/team-status.mjs +90 -0
- package/shared/terminal-links.d.mts +2 -0
- package/shared/terminal-links.mjs +55 -0
- package/shared/terminal-state.d.mts +1 -0
- package/shared/terminal-state.mjs +16 -0
- package/shared/thread-cards.d.mts +19 -0
- package/shared/thread-cards.mjs +254 -0
- package/shared/usage.d.mts +1 -1
- package/shared/usage.mjs +6 -7
- package/shared/work-items.mjs +255 -27
- package/shared/work-lines.mjs +393 -16
- package/worker-permissions.json +1 -1
- package/renderer/dist/assets/cel-dusk-CS5I7kJS.webp +0 -0
- package/renderer/dist/assets/cel-dusk-DUslqS6B.webp +0 -0
- package/renderer/dist/assets/cel-dusk-Jt_xVGxp.webp +0 -0
- package/renderer/dist/assets/cel-dusk-sm-BBkV-tWT.webp +0 -0
- package/renderer/dist/assets/frost-haze-CxPSOBEg.webp +0 -0
- package/renderer/dist/assets/frost-haze-sm-C_w21qgd.webp +0 -0
- package/renderer/dist/assets/ice-BC8luINc.webp +0 -0
- package/renderer/dist/assets/ice-CP9PrKHo.webp +0 -0
- package/renderer/dist/assets/ice-river-D6ziOhLY.webp +0 -0
- package/renderer/dist/assets/ice-river-UVM2-JY_.webp +0 -0
- package/renderer/dist/assets/ice-river-bErJwYWW.webp +0 -0
- package/renderer/dist/assets/ice-river-sm-Bg1U-SIj.webp +0 -0
- package/renderer/dist/assets/ice-sm-CbVcg3_D.webp +0 -0
- package/renderer/dist/assets/index-CwiDv5bL.css +0 -32
- package/renderer/dist/assets/index-D9hCAVPl.js +0 -684
- package/renderer/dist/assets/lake-C0WaW-6E.webp +0 -0
- package/renderer/dist/assets/lake-CSKjLC5K.webp +0 -0
- package/renderer/dist/assets/lake-ETGcOb25.webp +0 -0
- package/renderer/dist/assets/lake-harbour-BCQRbrHb.webp +0 -0
- package/renderer/dist/assets/lake-harbour-B_wfXTmE.webp +0 -0
- package/renderer/dist/assets/lake-harbour-Te1pEvBh.webp +0 -0
- package/renderer/dist/assets/lake-harbour-sm-Cme_ShEg.webp +0 -0
- package/renderer/dist/assets/lake-sm-CbG72Hbv.webp +0 -0
- package/renderer/dist/assets/lino-coast-CUZHcucI.webp +0 -0
- package/renderer/dist/assets/lino-coast-DP4J7cgd.webp +0 -0
- package/renderer/dist/assets/lino-coast-kOIAffr_.webp +0 -0
- package/renderer/dist/assets/lino-coast-sm-C1Mdbgit.webp +0 -0
- package/renderer/dist/assets/moon-pines-BskgnnXR.webp +0 -0
- package/renderer/dist/assets/moon-pines-CFSIIwt0.webp +0 -0
- package/renderer/dist/assets/moon-pines-PNhdOYww.webp +0 -0
- package/renderer/dist/assets/moon-pines-sm-C6K1NomK.webp +0 -0
- package/renderer/dist/assets/orbit-rings-2XV36Ch3.webp +0 -0
- package/renderer/dist/assets/orbit-rings-C4NrcYGQ.webp +0 -0
- package/renderer/dist/assets/orbit-rings-DGLk07dT.webp +0 -0
- package/renderer/dist/assets/orbit-rings-sm-Dky3YdvL.webp +0 -0
- package/renderer/dist/assets/peach-haze-2-C6f7xnWw.webp +0 -0
- package/renderer/dist/assets/peach-haze-2-sm-Dj_Ez_Sb.webp +0 -0
- package/renderer/dist/assets/pixel-harbour-DQjqMROg.webp +0 -0
- package/renderer/dist/assets/pixel-harbour-Dw71H_bc.webp +0 -0
- package/renderer/dist/assets/pixel-harbour-kOZfm-GM.webp +0 -0
- package/renderer/dist/assets/pixel-harbour-sm-Dturjuky.webp +0 -0
- package/renderer/dist/assets/pixel-orbit-C296JVMO.webp +0 -0
- package/renderer/dist/assets/pixel-orbit-C4oMRDSx.webp +0 -0
- package/renderer/dist/assets/pixel-orbit-CqVmQ4eh.webp +0 -0
- package/renderer/dist/assets/pixel-orbit-sm-CHagC_nO.webp +0 -0
- package/renderer/dist/assets/pixel-ridge-C6LYu6uE.webp +0 -0
- package/renderer/dist/assets/pixel-ridge-CIUCEESs.webp +0 -0
- package/renderer/dist/assets/pixel-ridge-sm-BnE0F_w-.webp +0 -0
- package/renderer/dist/assets/riso-hills-7heKVtry.webp +0 -0
- package/renderer/dist/assets/riso-hills-CIjAL3J6.webp +0 -0
- package/renderer/dist/assets/riso-hills-sm-DHsnbCfP.webp +0 -0
- package/renderer/dist/assets/slate-haze-BPWdkNsw.webp +0 -0
- package/renderer/dist/assets/slate-haze-sm-B0Cb5a2W.webp +0 -0
- package/renderer/dist/assets/valley-haze-BDHPqoJy.webp +0 -0
- package/renderer/dist/assets/valley-haze-sm-CTyjmPAG.webp +0 -0
- package/renderer/dist/assets/vector-dunes-DzzWLdKo.webp +0 -0
- package/renderer/dist/assets/vector-dunes-Yr9NBQUy.webp +0 -0
- package/renderer/dist/assets/vector-dunes-sm-D8MYY6ms.webp +0 -0
- package/renderer/dist/assets/watercolour-mist-BCGKN4u4.webp +0 -0
- package/renderer/dist/assets/watercolour-mist-BF-jk5MC.webp +0 -0
- package/renderer/dist/assets/watercolour-mist-sm-Ds1xzTw9.webp +0 -0
- package/renderer/dist/assets/woodblock-sea-B1um67Z9.webp +0 -0
- package/renderer/dist/assets/woodblock-sea-DKQdYs32.webp +0 -0
- package/renderer/dist/assets/woodblock-sea-sm-BJzNq8xh.webp +0 -0
- package/renderer/dist/emulator/audio-rules.mjs +0 -74
- package/renderer/dist/emulator/data/compression/README.md +0 -11
- package/renderer/dist/emulator/data/compression/extract7z.js +0 -1
- package/renderer/dist/emulator/data/compression/extractzip.js +0 -1
- package/renderer/dist/emulator/data/compression/libunrar.js +0 -519
- package/renderer/dist/emulator/data/compression/libunrar.wasm +0 -0
- package/renderer/dist/emulator/data/cores/README.md +0 -22
- package/renderer/dist/emulator/data/cores/mgba-legacy-wasm.data +0 -0
- package/renderer/dist/emulator/data/cores/mgba-thread-legacy-wasm.data +0 -0
- package/renderer/dist/emulator/data/cores/mgba-thread-wasm.data +0 -0
- package/renderer/dist/emulator/data/cores/mgba-wasm.data +0 -0
- package/renderer/dist/emulator/data/cores/package.json +0 -65
- package/renderer/dist/emulator/data/cores/reports/mgba.json +0 -1
- package/renderer/dist/emulator/data/emulator.css +0 -1614
- package/renderer/dist/emulator/data/loader.js +0 -170
- package/renderer/dist/emulator/data/localization/README.md +0 -63
- package/renderer/dist/emulator/data/localization/af-FR.json +0 -339
- package/renderer/dist/emulator/data/localization/ar-AR.json +0 -301
- package/renderer/dist/emulator/data/localization/ben-BEN.json +0 -301
- package/renderer/dist/emulator/data/localization/de-GER.json +0 -301
- package/renderer/dist/emulator/data/localization/el-GR.json +0 -301
- package/renderer/dist/emulator/data/localization/en-US.json +0 -339
- package/renderer/dist/emulator/data/localization/es-ES.json +0 -310
- package/renderer/dist/emulator/data/localization/fa-AF.json +0 -310
- package/renderer/dist/emulator/data/localization/hi-HI.json +0 -301
- package/renderer/dist/emulator/data/localization/it-IT.json +0 -302
- package/renderer/dist/emulator/data/localization/ja-JA.json +0 -301
- package/renderer/dist/emulator/data/localization/jv-JV.json +0 -301
- package/renderer/dist/emulator/data/localization/ko-KO.json +0 -336
- package/renderer/dist/emulator/data/localization/pt-BR.json +0 -361
- package/renderer/dist/emulator/data/localization/retroarch.json +0 -617
- package/renderer/dist/emulator/data/localization/ro-RO.json +0 -310
- package/renderer/dist/emulator/data/localization/ru-RU.json +0 -301
- package/renderer/dist/emulator/data/localization/tr-TR.json +0 -310
- package/renderer/dist/emulator/data/localization/vi-VN.json +0 -302
- package/renderer/dist/emulator/data/localization/zh-CN.json +0 -351
- package/renderer/dist/emulator/data/src/GameManager.js +0 -464
- package/renderer/dist/emulator/data/src/compression.js +0 -142
- package/renderer/dist/emulator/data/src/emulator.js +0 -6158
- package/renderer/dist/emulator/data/src/gamepad.js +0 -167
- package/renderer/dist/emulator/data/src/nipplejs.js +0 -1
- package/renderer/dist/emulator/data/src/shaders.js +0 -236
- package/renderer/dist/emulator/data/src/socket.io.min.js +0 -7
- package/renderer/dist/emulator/data/src/storage.js +0 -125
- package/renderer/dist/emulator/data/version.json +0 -5
- package/renderer/dist/emulator/host.js +0 -299
- package/renderer/dist/emulator/index.html +0 -28
- package/renderer/dist/emulator/provenance.json +0 -6
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
// A fixed allowlist exposes the instruction files, never arbitrary paths.
|
|
2
2
|
// Defaults are shipped separately so an edited live file can always be reset.
|
|
3
3
|
//
|
|
4
|
-
// THERE ARE THREE OF THEM NOW, NOT FOUR (w-3dc46f3a67
|
|
5
|
-
//
|
|
6
|
-
// prompts that the user can adjust might be overkill. Maybe we decide not to
|
|
7
|
-
// expose some of them, or maybe we would best aggregate others."
|
|
4
|
+
// THERE ARE THREE OF THEM NOW, NOT FOUR (w-3dc46f3a67). Five editable layers of
|
|
5
|
+
// prompts was too many for a person to manage, so some were merged.
|
|
8
6
|
//
|
|
9
7
|
// A person opening that page is answering two questions, what should agents do
|
|
10
8
|
// and how should they talk to me, so the writing rules and the finishing rules
|
|
11
|
-
// became ONE document: `message-rules.md`, "How agents write to you".
|
|
12
|
-
//
|
|
13
|
-
//
|
|
9
|
+
// became ONE document: `message-rules.md`, "How agents write to you". In
|
|
10
|
+
// practice a rules file is mostly about how agents write to the person rather
|
|
11
|
+
// than what they do, which is why the two were one thing all along.
|
|
14
12
|
// `joinMessageRules` below carries the two old files into the new one.
|
|
15
13
|
import fs from 'node:fs';
|
|
16
14
|
import path from 'node:path';
|
|
@@ -19,12 +17,11 @@ import {fileURLToPath} from 'node:url';
|
|
|
19
17
|
// one place that holds it. Typing it here is what left three dead names in the
|
|
20
18
|
// code through two renames (tests/the-app-is-named-in-one-place).
|
|
21
19
|
import {nameSlug} from '../shared/product-name.mjs';
|
|
22
|
-
// ADHD MODE IS A FOURTH FILE, NOT A PARAGRAPH INSIDE THE THIRD (w-5737fe67cf
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
// while the mode is off. Whether it is on lives in her config (`adhdMode`).
|
|
20
|
+
// ADHD MODE IS A FOURTH FILE, NOT A PARAGRAPH INSIDE THE THIRD (w-5737fe67cf).
|
|
21
|
+
// Its text is appended to the instructions while the mode is on and removed when
|
|
22
|
+
// it is off. Kept in its own file so edits to it never mix with the user's own
|
|
23
|
+
// rules, and survive while the mode is off. Whether it is on lives in the
|
|
24
|
+
// config (`adhdMode`).
|
|
28
25
|
const files = {rules:'founder.md',messages:'message-rules.md',adhd:'adhd-mode.md',system:'worker.md'};
|
|
29
26
|
// The two names the joined document replaced, read only by the migration.
|
|
30
27
|
const WAS_MESSAGES = ['writing-rules.md','finishing.md'];
|
|
@@ -33,35 +30,38 @@ function fileFor(id) {
|
|
|
33
30
|
if (!Object.hasOwn(files,id)) throw new Error('Unknown instruction section');
|
|
34
31
|
return files[id];
|
|
35
32
|
}
|
|
33
|
+
// WHAT THE BOX OPENS ON when the user has written nothing. The message rules
|
|
34
|
+
// box starts empty like the general one (w-3ec9f07978): the app's own message
|
|
35
|
+
// rules are not the user's to edit, because the inbox reads every message by
|
|
36
|
+
// them, so they ride on every run from the checkout and never sit in the box.
|
|
37
|
+
const boxDefault=(id)=>(id==='rules'||id==='messages') ? '' : defaults[id];
|
|
36
38
|
export function readInstruction(appDir,id,shippedDir=appDir) {
|
|
37
39
|
const file=fileFor(id);
|
|
38
|
-
const defaultText=id
|
|
40
|
+
const defaultText=boxDefault(id);
|
|
39
41
|
let text=defaultText;
|
|
40
42
|
try {text=fs.readFileSync(path.join(appDir,'briefs',file),'utf8');} catch(e) {if(e.code!=='ENOENT') throw e; if(id==='system') text=readSystemTemplate(shippedDir,appDir);}
|
|
41
43
|
return {text,defaultText};
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
44
46
|
* RESTORE POINTS, BECAUSE A SAVE USED TO BE THE END OF THE OLD TEXT
|
|
45
|
-
* (w-94b3af4e70
|
|
47
|
+
* (w-94b3af4e70).
|
|
46
48
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* app doesn't work the way they want it or they think, 'It worked better
|
|
50
|
-
* before. I want to restore it.'"
|
|
49
|
+
* Why the page needs this at all: a user can edit the agent instructions, lose
|
|
50
|
+
* something that mattered, and want an earlier version back.
|
|
51
51
|
*
|
|
52
|
-
* Until this, the only thing the page could hand back was our shipped text,
|
|
53
|
-
*
|
|
54
|
-
*
|
|
52
|
+
* Until this, the only thing the page could hand back was our shipped text, so
|
|
53
|
+
* recovering meant throwing away everything the user had written to get the
|
|
54
|
+
* default. The box saves 400ms after a keystroke, straight over
|
|
55
55
|
* the file, so a paragraph deleted at noon was gone at noon.
|
|
56
56
|
*
|
|
57
57
|
* WHAT COUNTS AS A VERSION: the text that was in the file before a save, kept
|
|
58
58
|
* under the time that text was itself saved, so the list reads as the versions
|
|
59
|
-
*
|
|
59
|
+
* the user wrote rather than as a log of keystrokes. A burst of typing is one
|
|
60
60
|
* version and not two hundred, because text that has been sitting untouched for
|
|
61
61
|
* less than QUIET_MS is still being written and is not a place to come back to.
|
|
62
62
|
*
|
|
63
63
|
* It never throws into a save. Losing a restore point is a small thing and
|
|
64
|
-
* failing to write what
|
|
64
|
+
* failing to write what the user just typed is not.
|
|
65
65
|
*/
|
|
66
66
|
const HISTORY='instruction-history';
|
|
67
67
|
const KEEP=20;
|
|
@@ -84,13 +84,13 @@ export function readVersion(appDir,id,ts) {
|
|
|
84
84
|
if(!Number.isFinite(at)) throw new Error('Unknown version');
|
|
85
85
|
return {text:fs.readFileSync(path.join(historyDir(appDir,id),`${at}.md`),'utf8')};
|
|
86
86
|
}
|
|
87
|
-
function keepVersion(appDir,id,now=Date.now()) {
|
|
87
|
+
function keepVersion(appDir,id,now=Date.now(),always=false) {
|
|
88
88
|
try {
|
|
89
89
|
const live=path.join(appDir,'briefs',fileFor(id));
|
|
90
90
|
let stat,text;
|
|
91
91
|
try {stat=fs.statSync(live); text=fs.readFileSync(live,'utf8');}
|
|
92
92
|
catch(e) {if(e.code!=='ENOENT') throw e; return;}
|
|
93
|
-
if(now-stat.mtimeMs<QUIET_MS) return;
|
|
93
|
+
if(!always&&now-stat.mtimeMs<QUIET_MS) return;
|
|
94
94
|
const ts=Math.floor(stat.mtimeMs);
|
|
95
95
|
const have=listVersions(appDir,id);
|
|
96
96
|
if(have.some(v=>v.ts===ts)) return;
|
|
@@ -123,21 +123,20 @@ export function readSystemTemplate(appDir,dataDir=appDir) {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
/**
|
|
126
|
-
*
|
|
126
|
+
* THE USER'S OWN WRITING, CARRIED OUT OF THE CHECKOUT ONCE (w-3dc46f3a67).
|
|
127
127
|
*
|
|
128
128
|
* Until this ran, the four boxes in Settings read and wrote `dataDir/briefs`,
|
|
129
129
|
* and running from source `dataDir` is the git checkout the whole fleet works
|
|
130
|
-
* in.
|
|
131
|
-
*
|
|
132
|
-
* were being kept in the one folder every worker is allowed to `git checkout`.
|
|
130
|
+
* in. So the user's rules were being kept in the one folder every worker is
|
|
131
|
+
* allowed to `git checkout`, and agents had been committing to them.
|
|
133
132
|
*
|
|
134
|
-
* WHAT MOVES IS ONLY WHAT
|
|
133
|
+
* WHAT MOVES IS ONLY WHAT THE USER WROTE, and the test for that is the shipped
|
|
135
134
|
* default. A file whose text IS the default is our file sitting where we put
|
|
136
|
-
* it, and copying it into
|
|
137
|
-
* worker brief would never reach
|
|
138
|
-
* forever. So a file is carried across only when it differs from the
|
|
139
|
-
* which
|
|
140
|
-
* ship. Those two are the same pair package.json keeps out of the download.
|
|
135
|
+
* it, and copying it into the user's folder would freeze it there: the next
|
|
136
|
+
* release's worker brief would never reach them, because the "edit" would
|
|
137
|
+
* shadow it forever. So a file is carried across only when it differs from the
|
|
138
|
+
* default, which is typically founder.md and writing-rules.md and neither of the
|
|
139
|
+
* two we ship. Those two are the same pair package.json keeps out of the download.
|
|
141
140
|
*
|
|
142
141
|
* It is a COPY, not a move, and it never overwrites. The checkout keeps its
|
|
143
142
|
* copy so that merging this cannot lose a word, and a second run finds the
|
|
@@ -165,24 +164,33 @@ export function carryHerBriefsAcross(fromDir,toDir) {
|
|
|
165
164
|
}
|
|
166
165
|
|
|
167
166
|
/**
|
|
168
|
-
* THE TWO OLD MESSAGE FILES, JOINED INTO ONE, ONCE (w-3dc46f3a67
|
|
167
|
+
* THE TWO OLD MESSAGE FILES, JOINED INTO ONE, ONCE (w-3dc46f3a67).
|
|
169
168
|
*
|
|
170
|
-
* `writing-rules.md` said how an agent writes to
|
|
169
|
+
* `writing-rules.md` said how an agent writes to the user during a task and
|
|
171
170
|
* `finishing.md` said how it writes the last message. They are one box now, so
|
|
172
171
|
* they have to become one document, and this is where that happens: on the
|
|
173
172
|
* first boot after the change, before anything reads the new name.
|
|
174
173
|
*
|
|
175
|
-
* WHAT IT DOES WITH THE HALF
|
|
176
|
-
* anything in that file is
|
|
177
|
-
* of text, so most people have never touched them. When
|
|
178
|
-
* the other, the joined document takes the shipped
|
|
179
|
-
* half rather than leaving it out:
|
|
180
|
-
* and dropping it would quietly stop every
|
|
174
|
+
* WHAT IT DOES WITH THE HALF THE USER NEVER WROTE. The writing rules ship
|
|
175
|
+
* empty, so anything in that file is the user's. The finishing rules ship with
|
|
176
|
+
* 5,794 characters of text, so most people have never touched them. When the
|
|
177
|
+
* user has the one and not the other, the joined document takes the shipped
|
|
178
|
+
* finishing text as its second half rather than leaving it out: the user's copy
|
|
179
|
+
* shadows the default from here on, and dropping it would quietly stop every
|
|
180
|
+
* task ending the way it does today.
|
|
181
181
|
*
|
|
182
|
-
* AND WHEN
|
|
183
|
-
* install, and leaving
|
|
184
|
-
* release's default reaching
|
|
185
|
-
* never freeze our own text into
|
|
182
|
+
* AND WHEN THE USER WROTE NEITHER, IT WRITES NOTHING AT ALL. That is the fresh
|
|
183
|
+
* install, and leaving them with no file of their own is what keeps a later
|
|
184
|
+
* release's default reaching them. Same rule as `carryHerBriefsAcross` above:
|
|
185
|
+
* never freeze our own text into the user's folder.
|
|
186
|
+
*
|
|
187
|
+
* IT READS ONLY THE USER'S FOLDER, AND ADDS NOTHING OF OURS (w-3ec9f07978).
|
|
188
|
+
* It used to fall back to the checkout's copies and to put the shipped ending
|
|
189
|
+
* under whatever it found. In this repository `writing-rules.md` ships 16,000
|
|
190
|
+
* characters long, so every fresh copy run from source joined our two files
|
|
191
|
+
* and saved them as the user's, and the box showed nothing but our machinery.
|
|
192
|
+
* The shipped ending rides on every run anyway now (`messageRules` in the
|
|
193
|
+
* supervisor), so there is nothing of ours left to carry.
|
|
186
194
|
*
|
|
187
195
|
* Never throws, never overwrites. Returns what it joined, or null.
|
|
188
196
|
*/
|
|
@@ -190,16 +198,46 @@ export function joinMessageRules(shippedDir,toDir) {
|
|
|
190
198
|
try {
|
|
191
199
|
const target=path.join(toDir,'briefs',files.messages);
|
|
192
200
|
if(fs.existsSync(target)) return null;
|
|
193
|
-
const read=(
|
|
194
|
-
const
|
|
195
|
-
const [writing,finishing]=WAS_MESSAGES.map((name)=>(either(name) ?? '').trim());
|
|
201
|
+
const read=(name)=>{try {return fs.readFileSync(path.join(toDir,'briefs',name),'utf8');} catch {return null;}};
|
|
202
|
+
const [writing,finishing]=WAS_MESSAGES.map((name)=>(read(name) ?? '').trim());
|
|
196
203
|
if(!writing && !finishing) return null;
|
|
197
|
-
const
|
|
198
|
-
const joined=[writing,ending].filter(Boolean).join('\n\n');
|
|
204
|
+
const joined=[writing,finishing].filter(Boolean).join('\n\n');
|
|
199
205
|
writeInstruction(toDir,'messages',`${joined}\n`);
|
|
200
|
-
return {writing:writing.length,ending:
|
|
206
|
+
return {writing:writing.length,ending:finishing.length,total:joined.length+1};
|
|
201
207
|
} catch(e) {
|
|
202
208
|
console.warn(`${nameSlug}: could not join the message rules: ${e.message}`);
|
|
203
209
|
return null;
|
|
204
210
|
}
|
|
205
211
|
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* A MESSAGE BOX THAT HOLDS ONLY OUR TEXT IS NOT THE USER'S, ONCE (w-3ec9f07978).
|
|
215
|
+
*
|
|
216
|
+
* The old join above wrote the checkout's writing rules and ending rules into
|
|
217
|
+
* the user's folder as if they had typed them, so their box opened on 21,743
|
|
218
|
+
* characters of the app's own rules. A file whose text is EXACTLY one of the
|
|
219
|
+
* things we ship, alone or joined the way the old join joined them, is set
|
|
220
|
+
* aside: kept as a restore point and removed, so the box opens empty and our
|
|
221
|
+
* rules reach the run from the checkout as they should.
|
|
222
|
+
*
|
|
223
|
+
* Exact only. One line of the user's own makes the whole file theirs, and
|
|
224
|
+
* nothing here tries to cut it apart. Never throws. Returns whether it acted.
|
|
225
|
+
*/
|
|
226
|
+
export function setAsideShippedMessageRules(shippedDir,toDir) {
|
|
227
|
+
try {
|
|
228
|
+
const target=path.join(toDir,'briefs',files.messages);
|
|
229
|
+
if(path.resolve(shippedDir)===path.resolve(toDir)||!fs.existsSync(target)) return false;
|
|
230
|
+
const read=(name)=>{try {return fs.readFileSync(path.join(shippedDir,'briefs',name),'utf8').trim();} catch {return '';}};
|
|
231
|
+
const writing=read(WAS_MESSAGES[0]);
|
|
232
|
+
const endings=[...new Set([read(files.messages),defaults.messages.trim()])].filter(Boolean);
|
|
233
|
+
const ours=new Set([...endings,...endings.map((e)=>[writing,e].filter(Boolean).join('\n\n'))]);
|
|
234
|
+
const text=fs.readFileSync(target,'utf8').trim();
|
|
235
|
+
if(!text||!ours.has(text)) return false;
|
|
236
|
+
keepVersion(toDir,'messages',Date.now(),true);
|
|
237
|
+
fs.rmSync(target,{force:true});
|
|
238
|
+
return true;
|
|
239
|
+
} catch(e) {
|
|
240
|
+
console.warn(`${nameSlug}: could not set aside the shipped message rules: ${e.message}`);
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
}
|