@latysh-development/monolith 0.1.0-alpha.0 → 0.1.0-alpha.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/README.md +63 -16
- package/dist/brief/collect.d.ts.map +1 -1
- package/dist/brief/collect.js +41 -1
- package/dist/brief/constants.d.ts +2 -0
- package/dist/brief/constants.d.ts.map +1 -1
- package/dist/brief/constants.js +2 -0
- package/dist/brief/render.d.ts +7 -0
- package/dist/brief/render.d.ts.map +1 -1
- package/dist/brief/render.js +52 -1
- package/dist/brief/types.d.ts +17 -1
- package/dist/brief/types.d.ts.map +1 -1
- package/dist/cli/index.js +45 -0
- package/dist/discovery/compose.d.ts +28 -0
- package/dist/discovery/compose.d.ts.map +1 -0
- package/dist/discovery/compose.js +159 -0
- package/dist/discovery/contracts.d.ts +211 -0
- package/dist/discovery/contracts.d.ts.map +1 -0
- package/dist/discovery/contracts.js +555 -0
- package/dist/discovery/docs.d.ts +278 -0
- package/dist/discovery/docs.d.ts.map +1 -0
- package/dist/discovery/docs.js +1182 -0
- package/dist/discovery/facts.d.ts +49 -0
- package/dist/discovery/facts.d.ts.map +1 -0
- package/dist/discovery/facts.js +541 -0
- package/dist/discovery/index.d.ts +8 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +9 -0
- package/dist/discovery/orchestrate.d.ts +35 -0
- package/dist/discovery/orchestrate.d.ts.map +1 -0
- package/dist/discovery/orchestrate.js +32 -0
- package/dist/discovery/render.d.ts +36 -0
- package/dist/discovery/render.d.ts.map +1 -0
- package/dist/discovery/render.js +278 -0
- package/dist/discovery/traverse.d.ts +197 -0
- package/dist/discovery/traverse.d.ts.map +1 -0
- package/dist/discovery/traverse.js +510 -0
- package/dist/durable/errors.d.ts +6 -2
- package/dist/durable/errors.d.ts.map +1 -1
- package/dist/durable/errors.js +9 -3
- package/dist/durable/fs-store.d.ts +21 -0
- package/dist/durable/fs-store.d.ts.map +1 -1
- package/dist/durable/fs-store.js +103 -3
- package/dist/durable/prune-check.d.ts +17 -0
- package/dist/durable/prune-check.d.ts.map +1 -1
- package/dist/durable/prune-check.js +27 -0
- package/dist/durable/runtime.d.ts +5 -3
- package/dist/durable/runtime.d.ts.map +1 -1
- package/dist/durable/runtime.js +23 -6
- package/dist/durable/seams.d.ts +4 -0
- package/dist/durable/seams.d.ts.map +1 -1
- package/dist/durable/testing.js +2 -2
- package/dist/finalize/cli.d.ts +10 -0
- package/dist/finalize/cli.d.ts.map +1 -0
- package/dist/finalize/cli.js +134 -0
- package/dist/finalize/core.d.ts +108 -0
- package/dist/finalize/core.d.ts.map +1 -0
- package/dist/finalize/core.js +767 -0
- package/dist/finalize/index.d.ts +5 -0
- package/dist/finalize/index.d.ts.map +1 -0
- package/dist/finalize/index.js +2 -0
- package/dist/finalize/proposal.d.ts +97 -0
- package/dist/finalize/proposal.d.ts.map +1 -0
- package/dist/finalize/proposal.js +213 -0
- package/dist/ideas/cli.d.ts +33 -0
- package/dist/ideas/cli.d.ts.map +1 -0
- package/dist/ideas/cli.js +158 -0
- package/dist/ideas/format.d.ts +38 -0
- package/dist/ideas/format.d.ts.map +1 -0
- package/dist/ideas/format.js +194 -0
- package/dist/ideas/index.d.ts +6 -0
- package/dist/ideas/index.d.ts.map +1 -0
- package/dist/ideas/index.js +3 -0
- package/dist/ideas/store.d.ts +55 -0
- package/dist/ideas/store.d.ts.map +1 -0
- package/dist/ideas/store.js +262 -0
- package/dist/ideas/types.d.ts +54 -0
- package/dist/ideas/types.d.ts.map +1 -0
- package/dist/ideas/types.js +26 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/init/scaffold.d.ts +4 -0
- package/dist/init/scaffold.d.ts.map +1 -1
- package/dist/init/scaffold.js +6 -2
- package/dist/managed/index.d.ts +73 -0
- package/dist/managed/index.d.ts.map +1 -0
- package/dist/managed/index.js +222 -0
- package/dist/root/index.d.ts +7 -0
- package/dist/root/index.d.ts.map +1 -1
- package/dist/root/index.js +13 -1
- package/dist/update/cli.d.ts +8 -0
- package/dist/update/cli.d.ts.map +1 -0
- package/dist/update/cli.js +115 -0
- package/dist/update/index.d.ts +78 -0
- package/dist/update/index.d.ts.map +1 -0
- package/dist/update/index.js +285 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/templates/default-instance/instruction/.cursorrules +6 -0
- package/templates/default-instance/instruction/.windsurfrules +6 -0
- package/templates/default-instance/instruction/CLAUDE.md +4 -0
- package/templates/default-instance/managed/agent.md +20 -0
- package/templates/default-instance/managed/bootstrap.md +7 -0
- package/templates/default-instance/managed/index-idea.md +5 -0
- package/templates/default-instance/managed/routing-idea.md +14 -0
- package/templates/default-instance/monolith/AGENT.md +1 -0
- package/templates/default-instance/monolith/context/maps/routing-map.md +4 -0
- package/templates/default-instance/monolith/context/maps/semantic-map.md +2 -0
- package/templates/default-instance/monolith/memory/working/active.md +11 -0
- package/templates/default-instance/monolith/skills/INDEX.md +4 -0
- package/templates/default-instance/monolith/skills/finalize-story/SKILL.md +51 -1
- package/templates/default-instance/monolith/skills/idea-capture/SKILL.md +157 -0
- package/templates/default-instance/projectroot/AGENTS.md +4 -0
package/README.md
CHANGED
|
@@ -29,34 +29,64 @@ decisions — instead of relying on an assistant's unaided memory.
|
|
|
29
29
|
|
|
30
30
|
## Why MONOLITH?
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
You are deep in a task when a good idea arrives — one that has nothing to do
|
|
33
|
+
with what you are doing right now. Switching to it would break your focus, so
|
|
34
|
+
you postpone it. A few hours later it is buried in a long chat, or simply gone.
|
|
35
|
+
|
|
36
|
+
A conversation history is a poor place to keep it. It is tied to one session,
|
|
37
|
+
it is hard to search, and an AI assistant that starts a new session does not
|
|
38
|
+
carry it over. A thought that only lives in a chat lasts as long as the chat.
|
|
39
|
+
|
|
40
|
+
MONOLITH keeps that knowledge in the project itself: ideas, structured project
|
|
41
|
+
context and recorded decisions, as plain Markdown that both a person and an
|
|
42
|
+
assistant can read, check and commit. You save the idea, and keep working.
|
|
43
|
+
|
|
44
|
+
> **Your AI assistant may forget the conversation. Your project shouldn't forget the ideas.**
|
|
45
|
+
|
|
46
|
+
Ideas are where MONOLITH started, not where it ends: the same approach — durable,
|
|
47
|
+
inspectable, deterministic — also covers project state and execution governance.
|
|
36
48
|
|
|
37
49
|
## What MONOLITH Does
|
|
38
50
|
|
|
51
|
+
- **Idea Capture** — save a thought that is unrelated to the current task, without losing focus. You decide what to save; ideas are stored as one Markdown file each in `.monolith/memory/long-term/ideas/`, independent of the active story, and are managed with `monolith idea add|list|show` or by an assistant that follows your project's instructions.
|
|
39
52
|
- **Observable** — `monolith brief` summarizes project state in the terminal, including whether it looks stale; Mission Control shows it in a local, read-only web interface.
|
|
40
53
|
- **Structured** — structure is extracted from a project's own markdown (frontmatter, headings, explicit links) into an explicit relationship graph. No embeddings, no LLM, no fuzzy matching.
|
|
41
54
|
- **Governed** — protocols, skills and cognitive modes describe how an assistant reads and updates project memory; missions and checkpoints record progress. This is a recorded discipline, not a runtime gate.
|
|
42
55
|
- **Reproducible** — same input, same output. State lives in a schema-versioned file written with a lock and atomic replace; Durable State adds a hash-chained event log.
|
|
43
56
|
- **Bounded** — managed files are read and written through strict primitives that refuse symlinks; `monolith validate` never executes project code; Mission Control has no write endpoint.
|
|
44
57
|
|
|
58
|
+
## Idea Capture Example
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
monolith idea add \
|
|
62
|
+
--title 'Automatic Tool Tests' \
|
|
63
|
+
--description 'Generate tests from business tool contracts'
|
|
64
|
+
|
|
65
|
+
monolith idea list
|
|
66
|
+
monolith idea show IDEA-001
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`IDEA-001` is a demonstration ID; the real ID is printed by `idea add`, and
|
|
70
|
+
`idea list` shows every saved idea.
|
|
71
|
+
|
|
72
|
+
With an AI assistant, you can simply say: *"Save this idea for later."* The
|
|
73
|
+
assistant then saves it by running `monolith idea add` — it does not edit idea
|
|
74
|
+
files itself. This works because `monolith init` installs instructions and an
|
|
75
|
+
`idea-capture` skill for the assistant; it is not guaranteed for an arbitrary
|
|
76
|
+
model without that setup. Details and limits: [`monolith idea` in the CLI reference](./docs/reference/cli.md#monolith-idea).
|
|
77
|
+
|
|
78
|
+
Ideas are saved and recalled **manually**. There is no automatic idea detection,
|
|
79
|
+
no automatic recall or reminders, no idea status management and no idea UI yet.
|
|
80
|
+
|
|
45
81
|
## Quick Start
|
|
46
82
|
|
|
47
|
-
Requires Node.js >= 20.
|
|
48
|
-
to npm**. Build it from a clone:
|
|
83
|
+
Requires Node.js >= 20. Install the published alpha package from npm:
|
|
49
84
|
|
|
50
85
|
```bash
|
|
51
|
-
|
|
52
|
-
cd the_monolith
|
|
53
|
-
pnpm install
|
|
54
|
-
pnpm build
|
|
55
|
-
npm link # exposes the `monolith` command (or run: node dist/cli/index.js)
|
|
86
|
+
npm install -g @latysh-development/monolith@alpha
|
|
56
87
|
```
|
|
57
88
|
|
|
58
|
-
|
|
59
|
-
becomes the primary install path ([release notes](./docs/release/alpha-installation.md)).
|
|
89
|
+
To build from source instead, see the [installation and release guide](./docs/release/alpha-installation.md).
|
|
60
90
|
|
|
61
91
|
Then, in a project directory:
|
|
62
92
|
|
|
@@ -71,6 +101,23 @@ monolith ui # Mission Control at http://127.0.0.1:4173 ; Ctrl+C to stop
|
|
|
71
101
|
instance, and it does not open a browser — open the printed address yourself.
|
|
72
102
|
All commands: [CLI reference](./docs/reference/cli.md).
|
|
73
103
|
|
|
104
|
+
## Updating an Existing Project
|
|
105
|
+
|
|
106
|
+
If a project was initialised with an earlier MONOLITH version, bring it up to the current agent integration (agent entry point and Idea Capture) with:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
monolith update # preview: shows the plan, writes nothing
|
|
110
|
+
monolith update --apply # applies the safe changes
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
- The first command only prints a plan and does not modify the project.
|
|
114
|
+
- The second applies the safe changes (missing MONOLITH-owned files and managed blocks).
|
|
115
|
+
- Your project memory (`active.md`, `decisions.md`, roadmap, stories, ideas) and your own files are preserved.
|
|
116
|
+
- A managed block you have edited is never overwritten automatically.
|
|
117
|
+
- On a conflict the command writes nothing to that file and reports that manual resolution is required.
|
|
118
|
+
|
|
119
|
+
Details and the full list of verdicts: [`monolith update` in the CLI reference](./docs/reference/cli.md#monolith-update).
|
|
120
|
+
|
|
74
121
|
## Architecture
|
|
75
122
|
|
|
76
123
|
```text
|
|
@@ -104,7 +151,7 @@ listing — not an official partnership, endorsement or certification.
|
|
|
104
151
|
|
|
105
152
|
## Documentation
|
|
106
153
|
|
|
107
|
-
- [CLI reference](./docs/reference/cli.md) — every command, `init`, `validate`, `brief`, `mission`, `durable`, `ui`
|
|
154
|
+
- [CLI reference](./docs/reference/cli.md) — every command, `init`, `validate`, `brief`, `idea`, `mission`, `durable`, `ui`
|
|
108
155
|
- [Mission Control](./docs/reference/mission-control.md) — sections, LIVE/DEMO, skins, limitations
|
|
109
156
|
- [Security & Limitations](./docs/reference/security-and-limitations.md) — threat model, platform and filesystem caveats
|
|
110
157
|
- [Programmatic API](./docs/reference/write-scope-api.md) · [Development](./docs/reference/development.md)
|
|
@@ -113,8 +160,8 @@ listing — not an official partnership, endorsement or certification.
|
|
|
113
160
|
|
|
114
161
|
## Project Status
|
|
115
162
|
|
|
116
|
-
**Alpha** (`0.1.0-alpha.
|
|
117
|
-
without notice.
|
|
163
|
+
**Alpha** (`0.1.0-alpha.2`). The API and CLI are experimental and may change
|
|
164
|
+
without notice. Published to npm under the alpha dist-tag. Durable State and the Coordinatorium
|
|
118
165
|
(`monolith durable`, `monolith mission`) are experimental and are not part of
|
|
119
166
|
the Quick Start.
|
|
120
167
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../src/brief/collect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAwBH,OAAO,KAAK,EACV,UAAU,
|
|
1
|
+
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../src/brief/collect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAwBH,OAAO,KAAK,EACV,UAAU,EAOX,MAAM,YAAY,CAAC;AAiBpB,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,QAAa,CAAC;AA8TnD,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAqEpE"}
|
package/dist/brief/collect.js
CHANGED
|
@@ -18,9 +18,11 @@ import { discoverDocs } from './docs.js';
|
|
|
18
18
|
import { extractCurrentStory } from './story.js';
|
|
19
19
|
import { selectActiveMissions, selectRecentFinishedMissions, selectLatestCheckpoint, hasCheckpointOrderMismatch, } from './selectors.js';
|
|
20
20
|
import { stateFilePath, validateState, createInitialState, MAX_STATE_BYTES } from '../coordinatorium/index.js';
|
|
21
|
-
import { ACTIVE_MD_REL, PROTOCOLS_DIR, ROADMAP_INDEX_REL, STORY_INDEX_REL, HANDOFF_REL } from './constants.js';
|
|
21
|
+
import { ACTIVE_MD_REL, PARKED_IDEAS_LIMIT, PROTOCOLS_DIR, ROADMAP_INDEX_REL, STORY_INDEX_REL, HANDOFF_REL } from './constants.js';
|
|
22
22
|
import { evaluateFreshness, parseActiveStoryClaim, parseRoadmapActiveStory, parseRoadmapStatuses, parseStoryIndexStatuses, } from './freshness.js';
|
|
23
23
|
import { readGitSignals } from './git-signals.js';
|
|
24
|
+
import { ideaStore, listIdeas } from '../ideas/index.js';
|
|
25
|
+
import { ideaNumber } from '../ideas/format.js';
|
|
24
26
|
const RECENT_FINISHED_MISSIONS_LIMIT = 5;
|
|
25
27
|
/** SEC-001B.1: `active.md` is a short hand-written context file (~3 KB today). */
|
|
26
28
|
export const MAX_ACTIVE_CONTEXT_BYTES = 256 * 1024;
|
|
@@ -211,6 +213,42 @@ function collectStory(targetDir, monolithRoot, root, diagnostics) {
|
|
|
211
213
|
provenance: { source: extraction.lineRange ? `${relPath}:${extraction.lineRange}` : relPath },
|
|
212
214
|
};
|
|
213
215
|
}
|
|
216
|
+
const IDEAS_UNREADABLE_LISTED = 3;
|
|
217
|
+
/**
|
|
218
|
+
* IDEA-002A: the `inbox` ideas, via the Idea Capture reader (`listIdeas`: bounded,
|
|
219
|
+
* symlink/hardlink/special-file refusing, never writes). A file that cannot be read
|
|
220
|
+
* as an idea is not counted and is reported as one warning — it never breaks the
|
|
221
|
+
* brief. Idea content is untrusted; only ids and titles are kept.
|
|
222
|
+
*/
|
|
223
|
+
function collectParkedIdeas(targetDir, diagnostics) {
|
|
224
|
+
const empty = { total: 0, items: [] };
|
|
225
|
+
let entries;
|
|
226
|
+
try {
|
|
227
|
+
entries = listIdeas(ideaStore(targetDir));
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
const code = err instanceof Error && 'code' in err ? String(err.code) : 'ERROR';
|
|
231
|
+
diagnostics.push({
|
|
232
|
+
code: 'IDEAS_UNREADABLE',
|
|
233
|
+
severity: 'warn',
|
|
234
|
+
message: `The ideas directory was not read (${code}); parked ideas are not shown.`,
|
|
235
|
+
});
|
|
236
|
+
return empty;
|
|
237
|
+
}
|
|
238
|
+
const inbox = entries.flatMap((e) => (e.ok && e.idea.status === 'inbox' ? [e.idea] : []));
|
|
239
|
+
inbox.sort((a, b) => ideaNumber(b.id) - ideaNumber(a.id));
|
|
240
|
+
const bad = entries.flatMap((e) => (e.ok ? [] : [e]));
|
|
241
|
+
if (bad.length > 0) {
|
|
242
|
+
const listed = bad.slice(0, IDEAS_UNREADABLE_LISTED).map((e) => `${e.id} (${e.code})`).join(', ');
|
|
243
|
+
const more = bad.length > IDEAS_UNREADABLE_LISTED ? `, and ${bad.length - IDEAS_UNREADABLE_LISTED} more` : '';
|
|
244
|
+
diagnostics.push({
|
|
245
|
+
code: 'IDEAS_UNREADABLE',
|
|
246
|
+
severity: 'warn',
|
|
247
|
+
message: `${bad.length} idea file(s) could not be read and are not counted as parked: ${listed}${more}. Run \`monolith idea show <id>\`.`,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
return { total: inbox.length, items: inbox.slice(0, PARKED_IDEAS_LIMIT).map((i) => ({ id: i.id, title: i.title })) };
|
|
251
|
+
}
|
|
214
252
|
/**
|
|
215
253
|
* Best-effort read of one state document for the freshness check. A missing,
|
|
216
254
|
* refused or unreadable file simply contributes no evidence — freshness never
|
|
@@ -286,6 +324,7 @@ export async function collect(targetDir) {
|
|
|
286
324
|
items: discoverDocs(targetDir, adrDirs, (fields) => fields.get('status') === 'accepted', diagnostics),
|
|
287
325
|
provenance: { source: adrDirs.join(', ') },
|
|
288
326
|
};
|
|
327
|
+
const parkedIdeas = monolithInitialized ? collectParkedIdeas(targetDir, diagnostics) : { total: 0, items: [] };
|
|
289
328
|
return {
|
|
290
329
|
identity,
|
|
291
330
|
monolithInitialized,
|
|
@@ -295,6 +334,7 @@ export async function collect(targetDir) {
|
|
|
295
334
|
story,
|
|
296
335
|
mandatoryProtocols,
|
|
297
336
|
adrs,
|
|
337
|
+
parkedIdeas,
|
|
298
338
|
diagnostics,
|
|
299
339
|
freshness,
|
|
300
340
|
freshnessEvidence,
|
|
@@ -7,4 +7,6 @@ export declare const PROTOCOLS_DIR = "protocols";
|
|
|
7
7
|
export declare const ROADMAP_INDEX_REL = "context/maps/roadmap-index.md";
|
|
8
8
|
export declare const STORY_INDEX_REL = "memory/working/story-index.md";
|
|
9
9
|
export declare const HANDOFF_REL = "context/boot/HANDOFF.md";
|
|
10
|
+
/** IDEA-002A: most parked ideas the brief ever lists; the rest is a "+N more" count. */
|
|
11
|
+
export declare const PARKED_IDEAS_LIMIT = 3;
|
|
10
12
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/brief/constants.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,eAAO,MAAM,aAAa,6BAA6B,CAAC;AACxD,sIAAsI;AACtI,eAAO,MAAM,eAAe,aAAa,CAAC;AAC1C,eAAO,MAAM,aAAa,cAAc,CAAC;AACzC,qGAAqG;AACrG,eAAO,MAAM,iBAAiB,kCAAkC,CAAC;AACjE,eAAO,MAAM,eAAe,kCAAkC,CAAC;AAC/D,eAAO,MAAM,WAAW,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/brief/constants.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,eAAO,MAAM,aAAa,6BAA6B,CAAC;AACxD,sIAAsI;AACtI,eAAO,MAAM,eAAe,aAAa,CAAC;AAC1C,eAAO,MAAM,aAAa,cAAc,CAAC;AACzC,qGAAqG;AACrG,eAAO,MAAM,iBAAiB,kCAAkC,CAAC;AACjE,eAAO,MAAM,eAAe,kCAAkC,CAAC;AAC/D,eAAO,MAAM,WAAW,4BAA4B,CAAC;AACrD,wFAAwF;AACxF,eAAO,MAAM,kBAAkB,IAAI,CAAC"}
|
package/dist/brief/constants.js
CHANGED
|
@@ -7,3 +7,5 @@ export const PROTOCOLS_DIR = 'protocols';
|
|
|
7
7
|
export const ROADMAP_INDEX_REL = 'context/maps/roadmap-index.md';
|
|
8
8
|
export const STORY_INDEX_REL = 'memory/working/story-index.md';
|
|
9
9
|
export const HANDOFF_REL = 'context/boot/HANDOFF.md';
|
|
10
|
+
/** IDEA-002A: most parked ideas the brief ever lists; the rest is a "+N more" count. */
|
|
11
|
+
export const PARKED_IDEAS_LIMIT = 3;
|
package/dist/brief/render.d.ts
CHANGED
|
@@ -48,6 +48,13 @@
|
|
|
48
48
|
* two forces INCOMPLETE. P0 is never dropped. All project-controlled
|
|
49
49
|
* strings, provenance pointers included, pass through
|
|
50
50
|
* `sanitizeSingleLine` (N-1).
|
|
51
|
+
*
|
|
52
|
+
* Advisory section (IDEA-002B): Parked Ideas is the one data-holding section whose
|
|
53
|
+
* budget degradation does NOT force INCOMPLETE. It is user-saved side context, not
|
|
54
|
+
* project state; its degradation stays visible (fewer items, count, or a marker
|
|
55
|
+
* whenever they fit) but `Completeness` and `--strict` keep describing only the
|
|
56
|
+
* project context that existed before ideas did. Unreadable idea files are
|
|
57
|
+
* reported by the `IDEAS_UNREADABLE` warning, which is not an error.
|
|
51
58
|
*/
|
|
52
59
|
import type { BriefModel } from './types.js';
|
|
53
60
|
export declare const DEFAULT_MAX_CHARS = 6000;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/brief/render.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/brief/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AAEH,OAAO,KAAK,EAAE,UAAU,EAA0F,MAAM,YAAY,CAAC;AAYrI,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAGtC,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,YAAY,CAAC;AAErD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,YAAY,CAAC;CAC5B;AAwXD,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,GAAE,MAA0B,GAAG,YAAY,CAgF5F"}
|
package/dist/brief/render.js
CHANGED
|
@@ -48,8 +48,15 @@
|
|
|
48
48
|
* two forces INCOMPLETE. P0 is never dropped. All project-controlled
|
|
49
49
|
* strings, provenance pointers included, pass through
|
|
50
50
|
* `sanitizeSingleLine` (N-1).
|
|
51
|
+
*
|
|
52
|
+
* Advisory section (IDEA-002B): Parked Ideas is the one data-holding section whose
|
|
53
|
+
* budget degradation does NOT force INCOMPLETE. It is user-saved side context, not
|
|
54
|
+
* project state; its degradation stays visible (fewer items, count, or a marker
|
|
55
|
+
* whenever they fit) but `Completeness` and `--strict` keep describing only the
|
|
56
|
+
* project context that existed before ideas did. Unreadable idea files are
|
|
57
|
+
* reported by the `IDEAS_UNREADABLE` warning, which is not an error.
|
|
51
58
|
*/
|
|
52
|
-
import { ACTIVE_MD_REL } from './constants.js';
|
|
59
|
+
import { ACTIVE_MD_REL, PARKED_IDEAS_LIMIT } from './constants.js';
|
|
53
60
|
import { sanitizeSingleLine, sanitizeMultiLine } from './sanitize.js';
|
|
54
61
|
// Shorthand for the existing single-line sanitizer — applied to every string
|
|
55
62
|
// that originates in project files or configuration (N-1), including
|
|
@@ -352,6 +359,41 @@ function fitItemList(header, items, footer, remaining, omittedMarkerFn, minimalF
|
|
|
352
359
|
}
|
|
353
360
|
return { text: '', consumed: 0, lossFlag: true };
|
|
354
361
|
}
|
|
362
|
+
const PARKED_IDEA_TITLE_MAX = 80;
|
|
363
|
+
function formatParkedIdea(i) {
|
|
364
|
+
const title = san(i.title);
|
|
365
|
+
const shown = title.length > PARKED_IDEA_TITLE_MAX ? `${title.slice(0, PARKED_IDEA_TITLE_MAX - 1).replace(/[\ud800-\udbff]$/, '')}…` : title;
|
|
366
|
+
return ` ${san(i.id)} ${shown}\n`;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* IDEA-002A: Parked Ideas — the lowest-priority section. Nothing at all when there
|
|
370
|
+
* are none (so a project without ideas renders exactly as before). Under budget
|
|
371
|
+
* pressure it first lists fewer ideas, then only the count, then a one-line
|
|
372
|
+
* marker, then nothing. Each step is flagged in `lossFlag`, but `render` does not
|
|
373
|
+
* count it towards Completeness (advisory section, see the Completeness contract).
|
|
374
|
+
* Listing at most `PARKED_IDEAS_LIMIT` ideas is the design, not a loss.
|
|
375
|
+
*/
|
|
376
|
+
function buildParkedIdeasSection(ideas, remaining) {
|
|
377
|
+
if (!ideas || ideas.total === 0)
|
|
378
|
+
return { text: '', consumed: 0, lossFlag: false };
|
|
379
|
+
const header = `\n## Parked Ideas (${ideas.total})\n`;
|
|
380
|
+
const explore = ' Explore: `monolith idea list`\n';
|
|
381
|
+
const wanted = Math.min(PARKED_IDEAS_LIMIT, ideas.items.length);
|
|
382
|
+
const noun = (n) => (n === 1 ? 'idea' : 'ideas');
|
|
383
|
+
const candidates = [];
|
|
384
|
+
for (let k = wanted; k >= 1; k--) {
|
|
385
|
+
const rest = ideas.total - k;
|
|
386
|
+
const body = ideas.items.slice(0, k).map(formatParkedIdea).join('');
|
|
387
|
+
const more = rest > 0 ? `\n +${rest} more ${noun(rest)}\n` : '';
|
|
388
|
+
const text = header + body + more + explore;
|
|
389
|
+
candidates.push({ text, consumed: text.length, lossFlag: k < wanted });
|
|
390
|
+
}
|
|
391
|
+
const countOnly = `${header} ${ideas.total} ${noun(ideas.total)}, not listed (budget)\n${explore}`;
|
|
392
|
+
const marker = `\n[Parked Ideas (${ideas.total}) omitted — budget; \`monolith idea list\`]\n`;
|
|
393
|
+
for (const text of [countOnly, marker, BARE_OMIT_MARKER])
|
|
394
|
+
candidates.push({ text, consumed: text.length, lossFlag: true });
|
|
395
|
+
return candidates.find((c) => c.consumed <= remaining) ?? { text: '', consumed: 0, lossFlag: true };
|
|
396
|
+
}
|
|
355
397
|
const P3_TEXT = '\n## More\n' +
|
|
356
398
|
' Full checkpoint history: `monolith mission checkpoints <id>`\n' +
|
|
357
399
|
' Mission detail: `monolith mission show <id>`\n' +
|
|
@@ -394,6 +436,15 @@ export function render(model, maxChars = DEFAULT_MAX_CHARS) {
|
|
|
394
436
|
p2 += finishedSection.text;
|
|
395
437
|
remaining -= finishedSection.consumed;
|
|
396
438
|
budgetLoss = budgetLoss || finishedSection.lossFlag;
|
|
439
|
+
// Parked ideas are optional extra context: they get what is left after everything
|
|
440
|
+
// else, and never the room the static P3 pointer block would have had. Their
|
|
441
|
+
// budget loss is shown locally (fewer ideas / count / marker) but deliberately does
|
|
442
|
+
// not feed `budgetLoss`: saving an idea must not flip an unchanged project's brief
|
|
443
|
+
// to INCOMPLETE and break `--strict` checks of the main project context.
|
|
444
|
+
const p3Fits = P3_TEXT.length <= remaining;
|
|
445
|
+
const ideasSection = buildParkedIdeasSection(model.parkedIdeas, p3Fits ? remaining - P3_TEXT.length : remaining);
|
|
446
|
+
p2 += ideasSection.text;
|
|
447
|
+
remaining -= ideasSection.consumed;
|
|
397
448
|
if (P3_TEXT.length <= remaining) {
|
|
398
449
|
p3 = P3_TEXT;
|
|
399
450
|
remaining -= p3.length;
|
package/dist/brief/types.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export type DiagnosticSeverity = 'info' | 'warn' | 'error';
|
|
|
17
17
|
* budget decision is made, which is what lets render() reserve space for
|
|
18
18
|
* them deterministically (see render.ts's two-phase budget accounting).
|
|
19
19
|
*/
|
|
20
|
-
export type BriefDiagnosticCode = 'MONOLITH_NOT_INITIALIZED' | 'STATE_NOT_INITIALIZED' | 'STATE_EMPTY' | 'STATE_UNREADABLE' | 'STATE_LEGACY_SCHEMA_MIGRATED' | 'MULTIPLE_ACTIVE_MISSIONS' | 'CHECKPOINT_ORDER_MISMATCH' | 'ACTIVE_MD_MISSING' | 'ACTIVE_MD_REJECTED' | 'ACTIVE_MD_UNREADABLE' | 'ACTIVE_MD_NO_CURRENT_STORY' | 'CONFIG_UNREADABLE' | 'CONFIG_ADR_DIRS_INVALID' | 'DOC_DIR_UNREADABLE' | 'DOC_FILE_UNREADABLE' | 'DOC_DIR_OUTSIDE_PROJECT' | 'PATH_OUTSIDE_PROJECT' | 'WRITE_ARTIFACTS_PRESENT';
|
|
20
|
+
export type BriefDiagnosticCode = 'MONOLITH_NOT_INITIALIZED' | 'STATE_NOT_INITIALIZED' | 'STATE_EMPTY' | 'STATE_UNREADABLE' | 'STATE_LEGACY_SCHEMA_MIGRATED' | 'MULTIPLE_ACTIVE_MISSIONS' | 'CHECKPOINT_ORDER_MISMATCH' | 'ACTIVE_MD_MISSING' | 'ACTIVE_MD_REJECTED' | 'ACTIVE_MD_UNREADABLE' | 'ACTIVE_MD_NO_CURRENT_STORY' | 'CONFIG_UNREADABLE' | 'CONFIG_ADR_DIRS_INVALID' | 'DOC_DIR_UNREADABLE' | 'DOC_FILE_UNREADABLE' | 'DOC_DIR_OUTSIDE_PROJECT' | 'PATH_OUTSIDE_PROJECT' | 'WRITE_ARTIFACTS_PRESENT' | 'IDEAS_UNREADABLE';
|
|
21
21
|
export interface BriefDiagnostic {
|
|
22
22
|
code: BriefDiagnosticCode;
|
|
23
23
|
severity: DiagnosticSeverity;
|
|
@@ -84,6 +84,20 @@ export interface ProjectIdentity {
|
|
|
84
84
|
monolithRoot: string;
|
|
85
85
|
provenance: Provenance;
|
|
86
86
|
}
|
|
87
|
+
/** IDEA-002A: one parked (status `inbox`) idea, as shown by the brief. */
|
|
88
|
+
export interface ParkedIdeaRef {
|
|
89
|
+
id: string;
|
|
90
|
+
title: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* IDEA-002A: the `inbox` ideas, projected from the Idea Capture store (never
|
|
94
|
+
* re-parsed here). `items` holds at most `PARKED_IDEAS_LIMIT` entries, newest
|
|
95
|
+
* numeric id first; `total` counts every readable `inbox` idea.
|
|
96
|
+
*/
|
|
97
|
+
export interface ParkedIdeasSummary {
|
|
98
|
+
total: number;
|
|
99
|
+
items: ParkedIdeaRef[];
|
|
100
|
+
}
|
|
87
101
|
export interface BriefModel {
|
|
88
102
|
identity: ProjectIdentity;
|
|
89
103
|
monolithInitialized: boolean;
|
|
@@ -93,6 +107,8 @@ export interface BriefModel {
|
|
|
93
107
|
story: StorySummary;
|
|
94
108
|
mandatoryProtocols: ProtocolIndex;
|
|
95
109
|
adrs: AdrIndex;
|
|
110
|
+
/** IDEA-002A: optional so a hand-built model without it renders as before. */
|
|
111
|
+
parkedIdeas?: ParkedIdeasSummary;
|
|
96
112
|
/** Collect-time diagnostics, in deterministic (collection-order) sequence. */
|
|
97
113
|
diagnostics: BriefDiagnostic[];
|
|
98
114
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/brief/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC3B,0BAA0B,GAC1B,uBAAuB,GACvB,aAAa,GACb,kBAAkB,GAClB,8BAA8B,GAC9B,0BAA0B,GAC1B,2BAA2B,GAC3B,mBAAmB,GACnB,oBAAoB,GACpB,sBAAsB,GACtB,4BAA4B,GAC5B,mBAAmB,GACnB,yBAAyB,GACzB,oBAAoB,GACpB,qBAAqB,GACrB,yBAAyB,GACzB,sBAAsB,GACtB,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/brief/types.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
* monolith mission — manage Tactical Coordinatorium mission lifecycle
|
|
12
12
|
* monolith brief — deterministic, bounded project context summary
|
|
13
13
|
* monolith durable — inspect/verify/maintain Durable State task logs
|
|
14
|
+
* monolith idea — capture and recall deferred ideas (add/list/show)
|
|
15
|
+
* monolith finalize — plan/apply a controlled story finalization (documentation sync)
|
|
16
|
+
* monolith update — add missing Idea Capture infrastructure to an existing instance
|
|
14
17
|
* monolith ui — launch Mission Control (read-only dashboard)
|
|
15
18
|
*/
|
|
16
19
|
import { MONOLITH_VERSION } from '../version.js';
|
|
@@ -38,6 +41,15 @@ Commands:
|
|
|
38
41
|
accepted ADRs) — read-only, no LLM/network/ERG involved.
|
|
39
42
|
durable Inspect and maintain Durable State (long-running task logs):
|
|
40
43
|
list | show | assess | packet | verify | retention.
|
|
44
|
+
idea Capture a deferred thought without leaving the current task, and
|
|
45
|
+
recall it later: add | list | show. Plain Markdown files, no LLM.
|
|
46
|
+
finalize Close a story with checked preconditions and controlled documentation
|
|
47
|
+
updates: plan (read-only) | apply --approve <digest>.
|
|
48
|
+
update Bring an existing instance up to Idea Capture & Recall. Preview by
|
|
49
|
+
default (changes nothing). --apply creates MONOLITH-managed files
|
|
50
|
+
and may add or refresh managed sections inside your existing
|
|
51
|
+
files; your text outside those sections is kept, and conflicting
|
|
52
|
+
edits are never overwritten (see 'monolith update --help').
|
|
41
53
|
ui Launch Mission Control, the read-only web dashboard, on
|
|
42
54
|
127.0.0.1 (default port 4173). 'ui dev' adds Vite hot reload
|
|
43
55
|
(source checkout only). See 'monolith ui --help'.
|
|
@@ -60,6 +72,18 @@ Durable usage:
|
|
|
60
72
|
monolith durable verify [taskId] (exit 2 if a log fails verification)
|
|
61
73
|
monolith durable retention --retain-days N [--compact-after N] [--apply]
|
|
62
74
|
|
|
75
|
+
Idea usage:
|
|
76
|
+
monolith idea add --title "..." (--description "..." | --description-stdin) [--context "..."]
|
|
77
|
+
monolith idea list
|
|
78
|
+
monolith idea show <id>
|
|
79
|
+
|
|
80
|
+
Finalize usage:
|
|
81
|
+
monolith finalize plan --proposal <file|-> [--json]
|
|
82
|
+
monolith finalize apply --proposal <file|-> --approve <digest> [--json]
|
|
83
|
+
|
|
84
|
+
Update usage:
|
|
85
|
+
monolith update [--apply]
|
|
86
|
+
|
|
63
87
|
UI usage:
|
|
64
88
|
monolith ui [--port N]
|
|
65
89
|
monolith ui dev [--port N]
|
|
@@ -72,6 +96,12 @@ async function main() {
|
|
|
72
96
|
const args = process.argv.slice(2);
|
|
73
97
|
// `ui` owns its own --help / --version-like flags (`monolith ui dev --help`).
|
|
74
98
|
const ownsHelp = args[0] === 'ui';
|
|
99
|
+
if (args[0] === 'update' && (args.includes('--help') || args.includes('-h'))) {
|
|
100
|
+
const { UPDATE_USAGE } = await import('../update/cli.js');
|
|
101
|
+
console.log(UPDATE_USAGE);
|
|
102
|
+
process.exit(0);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
75
105
|
if (args.length === 0 || (!ownsHelp && (args.includes('--help') || args.includes('-h')))) {
|
|
76
106
|
console.log(USAGE);
|
|
77
107
|
process.exit(0);
|
|
@@ -141,6 +171,21 @@ async function main() {
|
|
|
141
171
|
await runDurableCommand(args.slice(1));
|
|
142
172
|
break;
|
|
143
173
|
}
|
|
174
|
+
case 'idea': {
|
|
175
|
+
const { runIdeaCommand } = await import('../ideas/cli.js');
|
|
176
|
+
await runIdeaCommand(args.slice(1));
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
case 'finalize': {
|
|
180
|
+
const { runFinalizeCommand } = await import('../finalize/cli.js');
|
|
181
|
+
process.exitCode = await runFinalizeCommand(args.slice(1));
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
case 'update': {
|
|
185
|
+
const { runUpdate } = await import('../update/cli.js');
|
|
186
|
+
process.exitCode = await runUpdate(args.slice(1));
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
144
189
|
case 'ui': {
|
|
145
190
|
const { runUi } = await import('./ui.js');
|
|
146
191
|
process.exit(await runUi(args.slice(1)));
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DISCOVERY-001C — unified Project Map composer (ADR-021). Internal.
|
|
3
|
+
*
|
|
4
|
+
* A pure transformation of TWO finished results into one Markdown text: a `DiscoveryResult`
|
|
5
|
+
* (structural facts, evidence OBSERVED_FILE-class) and a `DocumentationResult` (what documents
|
|
6
|
+
* claim, evidence DOCUMENT_TEXT). It reads no file, starts no analyzer, calls no model, opens no
|
|
7
|
+
* connection, keeps no clock and modifies neither input.
|
|
8
|
+
*
|
|
9
|
+
* Identity. Neither contract carries a project identity (no id, no root, no digest); both only say
|
|
10
|
+
* that they were derived from "a traversal". So the composer cannot confirm that the two results
|
|
11
|
+
* describe the same project and says so in the output. It does not guess from paths or names.
|
|
12
|
+
*
|
|
13
|
+
* Trust. The two sources are never merged: structure comes from the existing renderer, unchanged;
|
|
14
|
+
* documentation gets its own section, and every statement made by a document is shown as an
|
|
15
|
+
* unverified claim. The statuses of the two analyzers are shown side by side, never combined.
|
|
16
|
+
*
|
|
17
|
+
* Markdown safety. Every untrusted string goes through the renderer's `markdownCodeSpan` (control and
|
|
18
|
+
* bidi characters are shown as [U+XXXX], an inline code span cannot be closed by its content) and sits
|
|
19
|
+
* in a list item; headings and structure are fixed text. Document text is never interpreted.
|
|
20
|
+
*/
|
|
21
|
+
import { type DiscoveryResult } from './contracts.js';
|
|
22
|
+
import { type DocumentationResult } from './docs.js';
|
|
23
|
+
/**
|
|
24
|
+
* Composes the unified Project Map. Throws `DiscoveryError('RESULT_INVALID')` if either input fails
|
|
25
|
+
* its own validator (the message names which input and the first violations, never a value).
|
|
26
|
+
*/
|
|
27
|
+
export declare function composeProjectMap(discovery: DiscoveryResult, documentation: DocumentationResult): string;
|
|
28
|
+
//# sourceMappingURL=compose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/discovery/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAqD,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACzG,OAAO,EAKL,KAAK,mBAAmB,EAEzB,MAAM,WAAW,CAAC;AAgCnB;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,mBAAmB,GAAG,MAAM,CAoGxG"}
|