eidosmd 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +50 -29
  2. package/browser/dist/assets/index-Cc3cNWHY.css +1 -0
  3. package/browser/dist/assets/index-DQgCQRa5.js +46 -0
  4. package/browser/dist/favicon.svg +5 -0
  5. package/browser/dist/index.html +15 -0
  6. package/browser/dist/mark.svg +4 -0
  7. package/dist/src/cli.js +7 -0
  8. package/dist/src/commands/agents.js +1 -1
  9. package/dist/src/commands/canvas.js +77 -0
  10. package/dist/src/commands/check.js +10 -4
  11. package/dist/src/commands/configure.js +201 -0
  12. package/dist/src/commands/framework.js +37 -7
  13. package/dist/src/commands/index.js +4 -4
  14. package/dist/src/commands/init.js +5 -0
  15. package/dist/src/commands/instructions.js +1 -1
  16. package/dist/src/commands/list.js +8 -8
  17. package/dist/src/commands/migrate.js +32 -0
  18. package/dist/src/commands/new.js +3 -3
  19. package/dist/src/commands/property.js +125 -0
  20. package/dist/src/commands/seeds.js +5 -5
  21. package/dist/src/commands/setup.js +131 -0
  22. package/dist/src/commands/version.js +44 -0
  23. package/dist/src/commands/whoami.js +4 -4
  24. package/dist/src/context.js +5 -5
  25. package/dist/src/core/blueprint.js +16 -11
  26. package/dist/src/core/canvas-schema.js +148 -0
  27. package/dist/src/core/canvas.js +732 -0
  28. package/dist/src/core/check.js +221 -70
  29. package/dist/src/core/convert.js +7 -6
  30. package/dist/src/core/edits.js +1381 -0
  31. package/dist/src/core/framework-markdown.js +119 -34
  32. package/dist/src/core/framework-model.js +62 -10
  33. package/dist/src/core/framework-structured.js +222 -47
  34. package/dist/src/core/framework.js +13 -13
  35. package/dist/src/core/frontmatter.js +61 -1
  36. package/dist/src/core/git.js +84 -0
  37. package/dist/src/core/index-leaf.js +2 -2
  38. package/dist/src/core/links.js +87 -0
  39. package/dist/src/core/markdown.js +16 -9
  40. package/dist/src/core/me.js +16 -8
  41. package/dist/src/core/migrate.js +319 -0
  42. package/dist/src/core/naming.js +1 -1
  43. package/dist/src/core/regions.js +117 -0
  44. package/dist/src/core/root.js +2 -2
  45. package/dist/src/core/scaffold.js +33 -27
  46. package/dist/src/core/seed.js +187 -71
  47. package/dist/src/core/server.js +1410 -53
  48. package/dist/src/core/settings.js +232 -0
  49. package/dist/src/core/store.js +315 -0
  50. package/dist/src/core/template.js +32 -0
  51. package/dist/src/core/versions.js +84 -0
  52. package/dist/src/output.js +4 -1
  53. package/dist/src/program.js +421 -41
  54. package/instructions/authoring.md +15 -12
  55. package/instructions/configuring.md +81 -34
  56. package/instructions/init-required.md +4 -4
  57. package/instructions/overview.md +21 -9
  58. package/instructions/validating.md +9 -6
  59. package/package.json +21 -12
  60. package/standard/EIDOS.md +142 -259
  61. package/standard/seeds/README.md +12 -16
  62. package/standard/seeds/book/Framework.yaml +61 -0
  63. package/standard/seeds/book/README.md +10 -5
  64. package/standard/seeds/book/_gitignore +9 -3
  65. package/standard/seeds/book/me.md +1 -1
  66. package/standard/seeds/book/roles/README.md +3 -3
  67. package/standard/seeds/book/roles/framework-owner.md +2 -2
  68. package/standard/seeds/book/{shapes → templates}/chapter.full.md +0 -8
  69. package/standard/seeds/book/{shapes → templates}/chapter.sketch.md +0 -7
  70. package/standard/seeds/book/{shapes → templates}/frame.market.md +0 -6
  71. package/standard/seeds/book/templates/frame.premise.md +17 -0
  72. package/standard/seeds/book/{shapes → templates}/frame.reader.md +0 -6
  73. package/standard/seeds/book/{shapes → templates}/frame.voice.md +0 -7
  74. package/standard/seeds/research/Framework.yaml +61 -0
  75. package/standard/seeds/research/README.md +10 -5
  76. package/standard/seeds/research/_gitignore +9 -3
  77. package/standard/seeds/research/me.md +1 -1
  78. package/standard/seeds/research/roles/README.md +3 -3
  79. package/standard/seeds/research/roles/framework-owner.md +2 -2
  80. package/standard/seeds/research/{shapes → templates}/frame.ethics.md +0 -6
  81. package/standard/seeds/research/{shapes → templates}/frame.method.md +0 -7
  82. package/standard/seeds/research/{shapes → templates}/frame.prior-work.md +0 -6
  83. package/standard/seeds/research/{shapes → templates}/frame.question.md +0 -7
  84. package/standard/seeds/research/{shapes → templates}/investigation.full.md +0 -8
  85. package/standard/seeds/research/{shapes → templates}/investigation.note.md +0 -7
  86. package/standard/seeds/software/Framework.yaml +62 -0
  87. package/standard/seeds/software/README.md +7 -6
  88. package/standard/seeds/software/_gitignore +9 -3
  89. package/standard/seeds/software/me.md +1 -1
  90. package/standard/seeds/software/roles/README.md +3 -3
  91. package/standard/seeds/software/roles/framework-owner.md +2 -2
  92. package/standard/seeds/software/roles/project-manager.md +2 -2
  93. package/standard/seeds/software/roles/stakeholder.md +1 -1
  94. package/standard/seeds/software/{shapes → templates}/frame.architecture.md +0 -7
  95. package/standard/seeds/software/{shapes → templates}/frame.audience.md +1 -8
  96. package/standard/seeds/software/{shapes → templates}/frame.criteria.md +0 -8
  97. package/standard/seeds/software/{shapes → templates}/frame.market.md +0 -8
  98. package/standard/seeds/software/{shapes → templates}/spec.full.md +0 -8
  99. package/standard/seeds/software/{shapes → templates}/spec.micro.md +0 -9
  100. package/browser/index.html +0 -268
  101. package/dist/src/commands/convert.js +0 -30
  102. package/dist/src/core/shape.js +0 -26
  103. package/standard/seeds/book/Framework.md +0 -87
  104. package/standard/seeds/book/shapes/frame.premise.md +0 -24
  105. package/standard/seeds/research/Framework.md +0 -88
  106. package/standard/seeds/software/Framework.md +0 -88
  107. /package/standard/seeds/software/{shapes → templates}/.gitkeep +0 -0
@@ -1,34 +1,37 @@
1
1
  ## Authoring a blueprint
2
2
 
3
- A blueprint is one markdown file defining one unit completely: a frontmatter contract plus a body that follows a shape. You scaffold it with the CLI and fill it with the owner.
3
+ A blueprint is one markdown file defining one unit completely: a frontmatter contract plus a body that follows a template. You scaffold it with the CLI and fill it with the owner.
4
4
 
5
5
  ### 1. Place it
6
6
 
7
- Run `eidos framework`. Decide with the owner which collection the blueprint belongs to, which flavor (the collection's default unless they choose another), and which group if the collection groups its blueprints. If the idea is still rough, question it first: what it is, what it is not, and how it sits beside the blueprints already there (`eidos list`, `eidos show <id>`). Write nothing until that holds still.
7
+ Run `eidos framework`. Decide with the owner which collection the blueprint belongs to, which variant (the collection's default unless they choose another), and which group if the collection groups its blueprints. If the idea is still rough, question it first: what it is, what it is not, and how it sits beside the blueprints already there (`eidos list`, `eidos show <id>`). Write nothing until that holds still.
8
8
 
9
9
  ### 2. Scaffold it
10
10
 
11
11
  ```bash
12
- eidos new <collection> "<Title>" [--flavor <flavor>] [--group <group>] [--summary "<one line>"]
12
+ eidos new <collection> "<Title>" [--variant <variant>] [--group <group>] [--summary "<one line>"]
13
13
  ```
14
14
 
15
- `new` generates the frontmatter from the properties that apply to the collection, renders the body from the flavor's shape with its guidance kept, names the file in the framework's convention, and puts a permanent kebab-case `id` inside. Set a property at creation with `--set key=value`. Use `--dry-run` to see the file before writing it, and `--json` to get its path.
15
+ `new` generates the frontmatter from the required properties that apply to the collection, adding an optional one only when it is given a value (`--set`, `--summary`), renders the body from the variant's template with its guidance kept, names the file in the framework's convention, and puts a permanent `id` inside (a kebab-case slug by default; any stable, unique form is allowed with `--id`). Set a property at creation with `--set key=value`. Use `--dry-run` to see the file before writing it, and `--json` to get its path.
16
16
 
17
17
  Write the `summary` at creation when you can: one plain line saying what the blueprint is, so the collection index lists it the moment it exists.
18
18
 
19
19
  ### 3. Fill it, with the owner
20
20
 
21
- Open the file. The shape's sections are in order, each with an italic prompt saying what belongs there. Work through them top to bottom:
21
+ Open the file. The template's sections are in order, each with an italic prompt saying what belongs there. Work through them top to bottom:
22
22
 
23
23
  - Lead with the opening sections, the ones saying why the unit exists and what it observably does.
24
24
  - Press hardest on the section for what the blueprint deliberately will not do. That is where scope is held; a blueprint without it is rarely finished. Prompt for non-goals if the owner has not named them.
25
25
  - Where the owner is vague, ask. Do not fill the gap with plausible prose.
26
- - Keep the shape's section order and names. Leave a section out when it genuinely does not apply rather than leaving it empty. Beneath the sections, write it the way a person would read it: sub-headings, tables, lists.
27
- - Follow whatever labeling the shape asks for (for example `**AC1:**` on acceptance criteria) and keep checkable statements short.
26
+ - Keep the template's section order and names. Leave a section out when it genuinely does not apply rather than leaving it empty. Beneath the sections, write it the way a person would read it: sub-headings, tables, lists.
27
+ - Follow whatever labeling the template asks for (for example `**AC1:**` on acceptance criteria) and keep checkable statements short.
28
+ - Write with the framework's declared terms (`vocabulary` in `eidos framework`). Where the owner reaches for a near-miss the Vocabulary names, say which term it declares and ask; never swap the word in silently.
28
29
  - Reference other blueprints with markdown links, never bare names, in prose and in properties alike: `[Session Management](../identity/session-management.md)`. If the target has no blueprint yet, name it plainly rather than fabricating a link.
29
30
  - Delete each italic prompt as its section is filled.
30
31
 
31
- Frontmatter stays what `new` generated. Fill values; do not add keys the Schema does not declare (`eidos instructions configuring` is how a property is added). Leave a property blank rather than guessing it.
32
+ Frontmatter stays what `new` generated. Set a value with the command, never by opening the file: `eidos property set @<id> <property> <value>` (a List comma-separated, a Checkbox true or false, a Date YYYY-MM-DD; `eidos property get @<id>` reads, `unset` removes). It is typed by the Properties table, applies the root's on-save rules, and refuses a key the table does not declare for the collection. Where a property declares `options` (`eidos framework` lists them, in order), offer the owner that list and set one of them, exactly as declared, case included; the command refuses a value off the list unless `--force`, and `check` reports one it finds. Leave a required property blank rather than guessing it; an optional one absent is not a gap.
33
+
34
+ A span between `<!-- <tool>:<region> <args> -->` and `<!-- /<tool>:<region> -->`, each marker alone on its line, is a region that tool owns: leave its contents alone, and when you edit the file around it, carry it across as found. `eidosmd` is this CLI's name; a region under it is the CLI's.
32
35
 
33
36
  ### 4. Check and index
34
37
 
@@ -37,14 +40,14 @@ eidos check <path-to-blueprint>
37
40
  eidos index
38
41
  ```
39
42
 
40
- `check` reports what is missing or malformed against this framework and the blueprint's flavor. Surface the findings; the owner decides what to act on. `index` rebuilds the collection's `index.md` so the new blueprint is listed.
43
+ `check` reports what is missing or malformed against this framework and the blueprint's variant. Surface the findings; the owner decides what to act on. `index` rebuilds the index so the new blueprint is listed.
41
44
 
42
45
  ### Frames and top-level docs
43
46
 
44
- A frame is a blueprint in the framing collection (the first one `eidos framework` lists): same procedure, kept as loose prose. Fill what is known and leave the rest; a declared frame left unwritten is a gap to surface, not a failure.
47
+ A frame is a blueprint in the framing collection (the one `eidos framework` marks `framing`, its unit `frame`): same procedure, kept as loose prose. The standard requires no such collection; this CLI recommends one for every product and installs the seed's unless told `--no-framing`. Fill what is known and leave the rest; a declared frame left unwritten is a gap to surface, not a failure.
45
48
 
46
- A top-level doc (a Roadmap, a Vision) is one-of-a-kind and free-form: no shape, no validation, edited in place. Draft it with the owner, then register it under `top_level` in `_eidos/Framework.yaml`.
49
+ A top-level doc (a Vision, a map a tool generates) is one-of-a-kind and free-form: no template, no validation, edited in place. Draft it with the owner, then register it under `top_level` in `.eidos/Framework.yaml`.
47
50
 
48
51
  ### Reshaping a draft the owner already wrote
49
52
 
50
- When the thinking is already on the page and only needs shape, scaffold nothing. Read the flavor's shape (`_eidos/shapes/<kind>.<flavor>.md`), move the author's own words under the right sections in the shape's order, keep their wording, add nothing, and run `eidos check` on the result. What does not fit any section stays in the file, under a note, for the owner to place.
53
+ When the thinking is already on the page and only needs template, scaffold nothing. Read the variant's template (`.eidos/templates/<unit>.<variant>.md`), move the author's own words under the right sections in the template's order, keep their wording, add nothing, and run `eidos check` on the result. What does not fit any section stays in the file, under a note, for the owner to place.
@@ -1,65 +1,112 @@
1
1
  ## Configuring the framework
2
2
 
3
- The framework is the structure a root is written in: the framework document (version, naming, the Top-Level index, the Collections, and the property Schema) plus `_eidos/shapes/` (one file per flavor) and `_eidos/roles/`. This CLI reads it; changing it is an edit to those files, made with the owner and verified with `eidos check`.
3
+ The framework is the structure a root is written in: the framework document (version, naming, the top-level index, the folders, the Properties table, and the Vocabulary) plus `.eidos/templates/` (one file per variant) and `.eidos/roles/`. This CLI reads it; changing it is an edit to those files, made with the owner and verified with `eidos check`.
4
4
 
5
- The document is `_eidos/Framework.yaml`: `top_level`, `collections[]` (each with `flavors`, `canvas`, `grouping`), and `schema.custom[]`, documented field by field in `eidos standard`. The procedures below show the markdown form the standard documents; the fields are the same. Never touch the `index` key: `eidos index` owns it.
5
+ The document is `.eidos/Framework.yaml`: `top_level` (every file at the root), `folders[]` (every folder at the root, each with a `type`: a `collection` with its `variants` and `grouping`, an `assets` folder of files that are not markdown, or an `other` folder described and left alone), `properties.custom[]` (yours), `properties.tools.<tool>[]` (a tool's), and `vocabulary[]`, documented field by field in `eidos standard`. Everything at the root is declared: a folder under `folders`, a file under `top_level`, and `eidos check` names what is missing on either side. Never touch the `index` key: `eidos index` owns it. Never touch `.eidos/plugins/` (each folder is a tool's own; its `local.yaml` is one person's and never committed) or a key on a Properties row past the standard's six (a tool's field, named for the tool); carry both across unchanged.
6
6
 
7
- Press the owner to decide. A collection, flavor, or property nobody thought through reads as meaningful while no one knows what it holds. If they offer only a name, ask for the rest.
7
+ Press the owner to decide. A collection, variant, or property nobody thought through reads as meaningful while no one knows what it holds. If they offer only a name, ask for the rest.
8
8
 
9
- Never touch `### Eidos Core`: those properties move with the standard's version. And never change the naming convention on a root with files in it without renaming every file and link.
9
+ Never touch `properties.core`: those properties move with the standard's version. Never touch a tool's block, `properties.tools.<tool>`: that tool alone writes it, the way Eidos alone writes the core; the one exception is retiring the block of a tool that has left the root, on the owner's say-so, its values surfaced first. And never change the naming convention on a root with files in it without renaming every file and link.
10
10
 
11
11
  ### Adding a collection
12
12
 
13
- Decide its **name** (the folder, in the naming convention `eidos framework` shows), a one-line **description**, how it **groups** its blueprints (one level of sub-folders, or flat), at least one **flavor** with a **default**, and how it **draws** on a canvas (`file` for prose read whole; `card from ## <Section>` for blueprints scanned by a headline; ask, do not assume the section).
13
+ Decide its **name** (the folder, in the naming convention `eidos framework` shows), a one-line **description**, how it **groups** its blueprints (one level of sub-folders, or flat), and at least one **variant** with a **default**.
14
14
 
15
15
  1. Create the folder under the root.
16
- 2. Create the default flavor's shape in `_eidos/shapes/<kind>.<flavor>.md`: body only, `# {{title}}` first, then the `##` sections in order, each with an italic guidance prompt. Pattern it on the shapes already there.
17
- 3. Register it under `## Collections` in `Framework.md` with a `###` heading, the description, then bullets in this form (bullets, so the next flavor is a copied line):
16
+ 2. Create the default variant's template in `.eidos/templates/<unit>.<variant>.md`: body only, `# {{title}}` first, then the `##` sections in order, each with an italic guidance prompt. Pattern it on the templates already there.
17
+ 3. Register it under `folders` in `Framework.yaml`: an entry with its name, `type: collection`, description, variants (one default), and grouping, one variant per line so the next one is a copied line:
18
+
19
+ ```yaml
20
+ - name: Decisions
21
+ type: collection
22
+ description: Architecture decision records, one per significant choice.
23
+ variants:
24
+ - { name: full, template: templates/decision.full.md, description: "context, decision, consequences", default: true }
25
+ grouping:
26
+ label: Kinds
27
+ groups:
28
+ - { name: Runtime, description: decisions about what runs where }
29
+ ```
18
30
 
19
- ```markdown
20
- ### Decisions
31
+ The `grouping` key is optional; its label is the collection's own, and each entry under `groups` is one group. A property carrying the group (`grouping.property`) is a Properties table change, below.
32
+ 4. Run `eidos index` so the new collection has its list, and `eidos check` to confirm the framework parses as intended.
21
33
 
22
- Architecture decision records, one per significant choice.
34
+ `eidos configure:collection add <name> --unit <unit> [--description <text>] [--grouping <label>]` does all four in one plan.
23
35
 
24
- - **Leaf:** [Decisions/index.md](../Decisions/index.md)
25
- - **Flavors:**
26
- - [full](shapes/decision.full.md) — context, decision, consequences (default).
27
- - **Canvas:** card from `## Decision`
28
- - **Kinds:**
29
- - **Runtime** — decisions about what runs where.
30
- ```
36
+ ### Declaring a folder that is not a collection
37
+
38
+ A folder at the root that holds no blueprints is declared too, with a type: `assets` for files that are not markdown (the images, diagrams, and documents blueprints link to, each by a relative markdown link, as `![Login flow](../assets/login-flow.png)`), or `other` for whatever the owner's description says. Nothing inside either is read or checked, and the files keep the names their tools gave them. Decide the **name** (in the naming convention) and the one-line **description**, then run it:
31
39
 
32
- The grouping bullet (`**Kinds:**` above) is optional; its label is the collection's own, and each nested bullet is one group. A property carrying the group is a Schema change, below.
33
- 4. Run `eidos index` for the new leaf and `eidos check` to confirm the framework parses as intended.
40
+ ```bash
41
+ eidos configure:folder add assets --type assets --description "Images and diagrams the blueprints link to." --yes
42
+ eidos configure:folder show
43
+ ```
34
44
 
35
- ### Adding a flavor
45
+ `configure:folder rename` moves the folder and rewrites every link into it; `set` changes the type or the description; `remove` removes the entry and, unless `--preserve`, the folder and every file in it, each listed before the question. A folder or file `eidos check` reports as undeclared (`folder-undeclared`, `file-undeclared`) is the owner's to declare or move; never delete one.
36
46
 
37
- Decide its **name** (lowercase), a one-line **description**, and its **shape**. A second flavor is a deliberate variant, a lighter one to grow out of or a genuine split in kind, never a fork per category label.
47
+ ### Adding a variant
38
48
 
39
- 1. Create `_eidos/shapes/<kind>.<flavor>.md`, starting from the collection's default flavor and trimming or extending it. Keep the order and names of whatever it shares with the default.
40
- 2. Add it to the collection's **Flavors** bullets. Move `(default)` to it only if it should be the default; exactly one flavor carries the marker.
41
- 3. Existing blueprints are untouched: an absent `flavor` still means the default. `eidos new --flavor <name>` scaffolds in it from here on.
49
+ Decide its **name** (lowercase), a one-line **description**, and its **template**. A second variant is a deliberate variant, a lighter one to grow out of or a genuine split in kind, never a fork per category label.
50
+
51
+ 1. Create `.eidos/templates/<unit>.<variant>.md`, starting from the collection's default variant and trimming or extending it. Keep the order and names of whatever it shares with the default.
52
+ 2. Add it to the collection's `variants`, with its `template` path. Move `default: true` to it only if it should be the default; exactly one variant carries it.
53
+ 3. Existing blueprints are untouched: an absent `variant` still means the default. `eidos new --variant <name>` scaffolds in it from here on.
42
54
 
43
55
  ### Adding a property
44
56
 
45
- Decide all four: **name** (lowercase, words joined by underscores), **type** (Text, List, Number, Checkbox, Date, or Date & time; anything richer belongs in the body), **applies to** (`all`, or a list of collections), and **meaning** (one line).
57
+ Decide all five: **name** (lowercase, words joined by underscores), **type** (Text, List, Number, Checkbox, Date, or Date & time; anything richer belongs in the body), **applies to** (`all`, or a list of collections), **required** (`true` or `false`, absent meaning `false`: a required property is generated into every new blueprint it applies to and a missing one is a gap `eidos check` notes; an optional one is written when it has a value, left out otherwise, and never a gap; default to optional, and require only what the owner says every blueprint must answer), and **meaning** (one line). And the sixth, **options**, only when the value is one of a closed set the owner controls (a lifecycle, a tier): the list, non-empty, on a Text or List property, in the order the values run, so a lifecycle reads first stage to last and a dropdown or a board keeps that order. The comparison is exact, case included. A value off the list is surfaced by `eidos check` (`property-option`, with the list beside it), never refused. Without `options` any value is valid, so a label the owner wants open takes none; a `meaning` that lists values in prose is a set the entry should declare, and `meaning` then says what the property is for. No default rides with it: a required property with options is generated blank and the author picks. `variant` and a grouping property never carry it; their sets are the collection's declared variants and groups. Every property has an owner, and the owner is the block it sits in: yours go in `properties.custom`; a tool's go in `properties.tools.<tool>`, written by the tool. How blueprints relate to each other is better said in the body, as links in prose, than as a frontmatter list; a `connects_to` a root still carries is the framework's own custom property, kept or retired like any other.
46
58
 
47
- 1. Add a row to `### Custom Properties` in `## Schema`:
59
+ Run it, never hand-edit it:
48
60
 
49
- ```markdown
50
- | team | Text | all | Owning team, for filtering. |
51
- ```
61
+ ```bash
62
+ eidos configure:property add team --type Text --applies-to all --required --meaning "Owning team, for filtering." --dry-run
63
+ eidos configure:property add team --type Text --applies-to all --required --meaning "Owning team, for filtering." --yes
64
+ eidos configure:property add tier --type Text --applies-to all --options Core,Extended,Experimental --meaning "How central the unit is to the product." --yes
65
+ ```
52
66
 
53
- 2. Backfill the blueprints it applies to with an empty or owner-supplied stub, so each is fillable; `eidos check` lists the ones still missing it as `property-missing`. New blueprints get it from `eidos new`.
67
+ The command appends the entry and, when required, backfills the key blank into every blueprint it applies to; an optional property backfills nothing. New blueprints get a required one from `eidos new`, and an optional one when `--set` gives it a value. Every `configure:` command prints its plan first: `--dry-run` shows it and stops, `--yes` proceeds, and without a terminal you need one or the other (the error names it).
68
+
69
+ A tool's fields on the entry (this CLI's `eidosmd: { canvas: … }`, which styles a canvas node by the property's value) are not the standard's and not yours to fill in; keep whatever is there.
54
70
 
55
71
  ### Renaming or retiring a property
56
72
 
57
- Renaming: change the `Name` cell, then the key in every blueprint's frontmatter, carrying values across unchanged. Retiring: first show the owner every value that would be lost and ask whether to fold them somewhere or drop them; only then remove the row and the keys. Never silently drop values.
73
+ Renaming is `eidos configure:property rename <name> <new>`: the entry, the key in every blueprint, a grouping that names it, and the CLI's settings, in one plan. Changing a value everywhere is `configure:property remap <name> old=new`, and a value the property's `options` declare follows the rename in the list. Declaring or changing a list is `configure:property set <name> --options A,B,C` (`--open` drops it): widening a list touches no blueprint; declaring one, or narrowing one, is retiring values, so the plan names every blueprint carrying a value off the new list and needs `--force`, and `check` reports each afterwards. Show the owner that list and settle where each value goes before narrowing. Retiring is `configure:property remove <name>`: the plan lists every value that would be gone before it asks, and without a terminal it needs `--force`; show the owner that list and ask whether anything should be folded into a body first. `--preserve` leaves the keys in the files, which `check` then reports as `property-unknown`. The same family edits a collection (`configure:collection add|rename|remove`, the folder, templates, `applies_to`, and links following), a folder that is not a collection (`configure:folder`), a group (`configure:group`), a variant (`configure:variant`), a term (`configure:term`), and a role (`configure:role`). Never make these moves by hand or with a script when the command exists; every one rewrites the index and runs `check` afterwards and reports anything it introduced.
74
+
75
+ ### Declaring a term
76
+
77
+ The Vocabulary is the contract for words, beside the Properties table's contract for properties. Decide all three: the **term** (the word as prose uses it), what it **means** (one line), and what it is **not** (the near-misses, each opening with the word and saying why it is a different thing). A term with nothing in `not` is a dictionary entry, not an entry worth keeping; a concept that needs a body of its own is a blueprint, and the entry points at it with `see`.
78
+
79
+ 1. Add an entry under `vocabulary` in `Framework.yaml`:
80
+
81
+ ```yaml
82
+ vocabulary:
83
+ - term: team member
84
+ means: Someone on the product team, whatever their contract.
85
+ not:
86
+ - staff, who are the company's employees
87
+ - teammate, the informal word; use it in speech, not in a blueprint
88
+ see: ../specs/team-member.md # optional
89
+ ```
90
+
91
+ 2. Run `eidos check`: every blueprint that uses a near-miss is listed as `term-near-miss` with the declared term beside it. Show the list; the edits are the owner's and yours in the file, never a silent swap.
92
+
93
+ Renaming a term keeps the old word in `not` when the distinction is the point. Retiring one: show where the word is used first.
94
+
95
+ ### Recording a version
96
+
97
+ Only when the owner asks. A version is a snapshot of the root a team holds the definition against later: the root's own number (not the product's release version), a commit that exists in the repository the root lives in, and, if wanted, a tag named `blueprints/<version>`. It is this CLI's own record, kept under `.eidos/plugins/eidosmd/versions.yaml`; the standard keeps no versions in the framework document.
98
+
99
+ ```bash
100
+ eidos version record 1.0.0 # HEAD, no tag
101
+ eidos version record 1.0.0 --commit a1b2c3d --tag
102
+ ```
103
+
104
+ Ask which commit (HEAD unless they name one) and whether to tag; create the tag only on a yes. The commit that adds the entry is not the one the entry names, the way a tag follows the commit it marks. Never propose a version, and never read an empty list as a gap.
58
105
 
59
- ### Refreshing the Top-Level index
106
+ ### Refreshing the top-level index
60
107
 
61
- `## Top-Level` lists the root's one-of-a-kind documents, `README` first, one bullet each: `- [Title](../Title.md) — one-line description`. Frames are a collection, not top-level. Keep the owner's existing descriptions; a doc with none gets a `<!-- TODO: describe -->`, and you ask. `eidos check` reports an entry whose file does not exist.
108
+ `top_level` lists every file at the root, the one-of-a-kind documents, in the order they are read, one entry each: `{ title: Vision, path: ../Vision.md, description: one line }`, the path relative to `.eidos/`. The order is the owner's, the way a property's options are: the browser lists the docs in it and lands on the first, so an orientation doc (a README, when the root has one; every seed ships one and lists it first, and nothing requires it) goes first. Frames are a collection, not top-level. Keep the owner's existing descriptions; a doc with none gets an empty description, and you ask. `eidos check` reports an entry whose file does not exist (`top-level-missing`) and a file at the root no entry lists (`file-undeclared`); `eidos configure:doc add|rename|set|remove` edits the list.
62
109
 
63
110
  ### After
64
111
 
65
- Run `eidos check`. It will tell you whether the collection, its flavors, its shapes, and its groups are declared consistently, and which blueprints the change left with a gap.
112
+ Run `eidos check`. It will tell you whether the collection, its variants, its templates, and its groups are declared consistently, and which blueprints the change left with a gap.
@@ -1,6 +1,6 @@
1
1
  ## Eidos root required
2
2
 
3
- No root was found from this directory: nothing here holds a `_eidos/` folder with a `Framework.md` inside it. A root is found by that marker, never by its name.
3
+ No root was found from this directory: nothing here holds a `.eidos/` folder with a `Framework.yaml` inside it. A root is found by that marker, never by its name.
4
4
 
5
5
  If the root lives elsewhere in the repository, pass it explicitly:
6
6
 
@@ -18,11 +18,11 @@ eidos init Blueprints --seed book --naming "Title Case" --group "Part One" --pro
18
18
 
19
19
  `init` asks the owner nothing: choose the seed, the root folder name, the naming convention, the first groups, and the product name with them first, then run it. Everything a seed ships is reshapeable later, so a seed that is merely close is the right choice. `--dry-run` prints every write and touches nothing.
20
20
 
21
- If there is a root but it keeps its framework as `_eidos/Framework.md`, the CLI's first job is to convert it:
21
+ If there is a root but it is on an older standard (a `_eidos/` folder, or a markdown `Framework.md`), the CLI's first job is to move it:
22
22
 
23
23
  ```bash
24
- eidos convert --dry-run # the writes it would make
25
- eidos convert # Framework.yaml with the index inside; Framework.md and each index.md removed
24
+ eidos migrate --dry-run # the moves it would make
25
+ eidos migrate # .eidos/, templates/, Framework.yaml with the index inside, variant on every blueprint
26
26
  ```
27
27
 
28
28
  After that, run:
@@ -1,6 +1,6 @@
1
1
  ## Eidos Overview (CLI)
2
2
 
3
- This repository keeps a root of Eidos blueprints. One markdown file is the complete source of truth for one unit of the thing being made, true whether or not it has been built. A blueprint captures state and intent, not work: no sprint, estimate, or assignee, and no progress notes in the body.
3
+ This repository keeps a root of Eidos blueprints. One markdown file is the complete source of truth for one unit of the product being made, true whether or not it has been built. A blueprint captures state and intent, not work: no sprint, estimate, or assignee, and no progress notes in the body.
4
4
 
5
5
  ### The one rule: facilitate, do not author
6
6
 
@@ -8,30 +8,42 @@ Eidos is human-first. The owner holds the intent, the scope, and the decisions;
8
8
 
9
9
  ### Start every request here
10
10
 
11
- 1. `eidos framework` reads the root's own framework: its collections, their flavors and groups, and the property Schema. Never assume a collection, flavor, or section name; read what this framework declares. The document behind it is `_eidos/Framework.yaml`; if a root still keeps `Framework.md` (the form for people), every command says so and `eidos convert` moves it first.
12
- 2. `eidos whoami` says who is in the seat. Open the role file it names under `_eidos/roles/` and respond as that contract says (vocabulary, depth, what to surface, who decides). A blank actor means full, framework-owner-style facilitation.
11
+ 1. `eidos framework` reads the root's own framework: its folders (each with a type: a collection with its variants and groups, an assets folder, an other folder), the Properties table, and the Vocabulary (the root's own terms). Never assume a collection, variant, or section name; read what this framework declares. The document behind it is `.eidos/Framework.yaml`; a root still on the 4.x `Framework.md` is moved by `eidos migrate` first, and every command says so.
12
+ 2. `eidos whoami` says who is in the seat. Open the role file it names under `.eidos/roles/` and respond as that contract says (vocabulary, depth, what to surface, who decides). A blank me.md means full, framework-owner-style facilitation.
13
13
  3. `eidos list` and `eidos show <id>` read what already exists. Read before writing.
14
14
  4. `eidos instructions <guide>` before authoring, validating, or changing the framework. The overview says when to act; the guides say how.
15
15
 
16
- Add `--json` to `framework`, `list`, `show`, and `check` when a script needs stable fields.
16
+ Add `--json` to `framework`, `list`, `show`, `check`, `property`, and every `configure:` command when a script needs stable fields. `eidos list` filters with `--group`, `--variant`, and `--where key=value` (any property, case-insensitive; a list matches any item).
17
17
 
18
18
  ### The CLI owns structure; the conversation owns the words
19
19
 
20
- - `eidos new <collection> "<Title>"` scaffolds a blueprint that is born conforming: frontmatter from the Schema, body from the flavor's shape, filename in the naming convention, a permanent kebab-case `id` inside. Never hand-assemble frontmatter.
20
+ - `eidos new <collection> "<Title>"` scaffolds a blueprint that is born conforming: frontmatter from the Properties table (every block: the core, the framework's, a tool's), body from the variant's template, filename in the naming convention, a permanent `id` inside. Never hand-assemble frontmatter.
21
21
  - `eidos check` validates the root against its own framework. Its findings are a review the owner acts on; surface them, do not block on them.
22
22
  - `eidos index` regenerates the indexes, the `index` key inside `Framework.yaml`. Never edit it by hand.
23
- - The prose inside a blueprint is written in the file, with the owner, by you. The CLI never writes a sentence of it.
24
- - `eidos browser` opens the root in a local web page for a person. Everything the page can do runs the same code as a command (`new`, `check`, `index`), so it adds nothing you cannot do from the shell. Use the commands; leave the page to people.
23
+ - `eidos property set @<id> <property> <value>` sets one property on one blueprint (`get` reads it, `unset` removes it), typed by the Properties table, with the root's on-save rules applied. Never open a file to change a frontmatter value; a key the table does not declare for the collection is refused, which is the answer, not a reason to edit the file.
24
+ - `eidos configure:<noun> <operation>` changes the framework: `configure:property add|show|rename|set|remap|remove`, `configure:collection add|show|rename|remove`, `configure:folder add|show|rename|set|remove` (a folder at the root that is not a collection: `assets` or `other`), `configure:group add|rename|remove`, `configure:variant add|rename|set-default|remove`, `configure:term add|set|remove`, `configure:doc add|rename|set|remove`, `configure:role add|show|rename|remove`. Each prints its plan (every entry, key, file, and link it will touch, and every value that will be gone) and asks; run it first with `--dry-run` to show the owner the plan, then with `--yes` once they agree, and `--force` only where the plan says values or files go. Without a terminal a command refuses and names the switch. Never rename a property, move a group, or retire anything by editing files: the command reaches every blueprint and link and reruns the check, and a hand edit misses some.
25
+ - The rule behind all of it: anything mechanical is the CLI's. The prose inside a blueprint is written in the file, with the owner, by you. The CLI never writes a sentence of it.
26
+ - `eidos browser` opens the root in a local web page for a person, landing on its canvas maps: the design tool where a sketch becomes a blueprint. A canvas is one YAML file, `.eidos/plugins/eidosmd/maps/<id>.yaml`, that an agent edits directly: `eidos canvas schema` prints its JSON Schema, `eidos canvas show <id>` prints one, `eidos canvas new` creates one, and the browser reflects the file as it changes (or take the same JSON API, `/api/canvas/`, while it runs). Everything the page can do runs the same code as a command (`new`, `check`, `index`), so it adds nothing you cannot do from the shell. Use the commands; leave the page to people.
27
+
28
+ ### Speak the root's terms
29
+
30
+ The framework's `vocabulary` says which word is the word and what it is not. Use the declared term in what you write; where the owner's draft or speech uses a near-miss, say which term the Vocabulary declares and ask, rather than substituting silently (`eidos check` flags one as `term-near-miss`). A word the owner keeps using that no row declares is worth naming as a candidate; declaring it is a framework change (`eidos instructions configuring`) and the owner's call.
25
31
 
26
32
  ### Version
27
33
 
28
- The framework records the standard it targets as `eidos_version` in `_eidos/Framework.yaml`; `eidos standard --version` prints the one this CLI carries. `eidos check` notes a gap once. A gap never blocks the work: the framework in front of you is the operative contract either way.
34
+ The framework records the standard it targets as `eidos_version` in `.eidos/Framework.yaml`; `eidos standard --version` prints the one this CLI carries. `eidos check` notes a gap once. A gap never blocks the work: the framework in front of you is the operative contract either way.
35
+
36
+ The root's own versions are this CLI's, not the standard's: snapshots taken on purpose, kept under `.eidos/plugins/eidosmd/versions.yaml` because they need git. Never propose one, never ask whether to take one, and never fault a root without any; an empty list is the normal state. When the owner asks, `eidos version record <version> [--commit <sha>] [--tag]` writes the row from a commit that exists; ask about the tag (`blueprints/<version>`) rather than assuming. To see the root as it was at a version, read the blueprint at that commit (`git show <commit>:<path>`).
37
+
38
+ ### What is not yours
39
+
40
+ `.eidos/plugins/<name>/` is a tool's own folder (this CLI keeps its canvas maps under `plugins/eidosmd/`); the one file in it named `local.yaml` is one person's on one machine, never committed, kept out by the `plugins/*/local.yaml` line in `.eidos/.gitignore`. Leave every folder there alone unless you are the tool that owns it; a folder you don't recognize is not a problem to report. At the root, a folder declared as `assets` or `other` is the owner's too: nothing inside it is read, checked, or held to the naming convention, and a blueprint links into it with a relative markdown link like any other. On a Properties row, a key past the standard's six (`name`, `type`, `applies_to`, `required`, `options`, `meaning`) is a tool's, named for the tool; carry it across an edit unchanged and never fill it in. A whole block a tool declared, `properties.tools.<tool>`, is that tool's alone. Inside a markdown file, a span between `<!-- <tool>:<region> <args> -->` and `<!-- /<tool>:<region> -->` is a region that tool owns, the same name as its plugin folder: read it if it helps, write in it only if you are that tool, carry it across as found when you edit around it, and never fault its contents.
29
41
 
30
42
  ### Guides
31
43
 
32
44
  - `eidos instructions authoring`: read before creating or editing a blueprint
33
45
  - `eidos instructions validating`: read before reviewing a blueprint or reporting on a root
34
- - `eidos instructions configuring`: read before changing the framework (a collection, a flavor, a property, the Top-Level index)
46
+ - `eidos instructions configuring`: read before changing the framework (a collection, a variant, a property, a term, a version, the Top-Level index)
35
47
  - `eidos instructions init-required`: when there is no root here yet
36
48
 
37
49
  `eidos <command> --help` explains any command's options and output.
@@ -1,20 +1,20 @@
1
1
  ## Validating blueprints
2
2
 
3
- Validation is framework-defined. `eidos check` reads the root's own `_eidos/Framework.yaml` and shapes and enforces those, never a contract of its own.
3
+ Validation is framework-defined. `eidos check` reads the root's own `.eidos/Framework.yaml` and templates and enforces those, never a contract of its own.
4
4
 
5
5
  ```bash
6
6
  eidos check # the whole root: framework, layout, every blueprint
7
7
  eidos check <path> [<path>...] # only these blueprints
8
8
  eidos check --json # stable fields for a script
9
- eidos check --strict # warnings fail too (CI)
9
+ eidos check --strict # this run only: warnings fail too; the root's own setting is check.strict in settings.yaml
10
10
  ```
11
11
 
12
- Exit code 0 means no errors; 1 means at least one error (or, with `--strict`, any warning); 2 means the command could not run.
12
+ Exit code 0 means no errors; 1 means at least one error, or any warning when the root is strict; 2 means the command could not run. Strictness is the framework owner's decision for the root, `check.strict` in `.eidos/plugins/eidosmd/settings.yaml` (set by `eidos init` or `eidos setup --strict on|off`), so read it from `--json`'s `strict` rather than assuming; `--strict` and `--no-strict` change one run only.
13
13
 
14
14
  ### What the levels mean
15
15
 
16
- - An **error** is wrong on any reading: frontmatter that does not parse, a missing `id` or `title`, an `id` that is not kebab-case or is used twice, a `flavor` the collection does not declare, a link to a file that does not exist, a shape file the framework points at but does not have.
17
- - A **warning** is a gap the standard says to note and offer, never refuse: a missing or empty property the Schema applies to this collection, a property the Schema does not declare, a work-tracking field, a body section the flavor's shape declares but the blueprint lacks, a section the shape does not know, sections out of the shape's order, a grouping value that does not match its folder, a declared frame nobody has written, a stale `index.md`, a version gap.
16
+ - An **error** is wrong on any reading: frontmatter that does not parse, a missing `id` or `title`, an `id` used twice (its form is free: a slug, a number, a GUID), a `variant` the collection does not declare, a link to a file that does not exist, a template file the framework points at but does not have, a region opener with no closer (`region-unclosed`, whichever tool it names).
17
+ - A **warning** is a gap the standard says to note and offer, never refuse: a required property the Properties table applies to this collection but the blueprint lacks or leaves empty (every block of it: the core, yours, a tool's; an optional property absent is nothing, and present it is checked only by type), a property no block declares, a value off a property's declared `options` (`property-option`, exact match, the list beside it), a work-tracking field, a body section the variant's template declares but the blueprint lacks, a section the template does not know, sections out of the template's order, a grouping value that does not match its folder, a declared frame nobody has written, a stale index, a version gap, a near-miss the Vocabulary names (`term-near-miss`, with the declared term beside it), and, at the root, anything the framework document does not declare: a folder no entry under `folders` declares (`folder-undeclared`), a file `top_level` does not list (`file-undeclared`), a declared folder or document with nothing behind it (`folder-missing`, `collection-folder-missing`, `top-level-missing`), a sub-folder of a collection that is not a declared group (`group-undeclared`), and a folder inside a group (`folder-nested`; a group holds blueprints and nothing deeper). Nothing inside an `assets` or `other` folder is read, and a file that is not markdown inside a collection is not a blueprint.
18
18
 
19
19
  ### Reporting a review
20
20
 
@@ -25,9 +25,12 @@ The output is a review the owner acts on. When you report:
25
25
  - Offer to add a missing core property with a note on why it exists; never refuse the file.
26
26
  - Confirm no work-tracking fields crept in, and that any section describing approach reads as intent, not progress.
27
27
  - A version gap is worth one line and an offer to migrate, once per session; then carry on with the framework as it stands.
28
+ - A `term-near-miss` is a suggestion: name the declared term, ask, and leave the word to the owner. Never swap it in.
29
+ - A `property-option` is the same footing: show the value and the list, ask which option it is, and set it with `eidos property set`; never swap a value in silently. A value that belongs on no option is the owner's case for widening the list (`configure:property set --options`).
30
+ - A `folder-undeclared` or `file-undeclared` is the owner's decision: declare it (`configure:folder add`, `configure:collection add`, `configure:doc add`) or move it. Never delete a file or folder, and never invent a description for one.
28
31
 
29
32
  Do not fix silently. Show the finding, propose the change, and let the owner decide, unless the change is purely mechanical and they have asked for it (regenerating an index, adding a blank property stub).
30
33
 
31
34
  ### Things `check` cannot judge
32
35
 
33
- Whether the prose is true, whether the scope is right, and whether an open question should be settled are the owner's. `check` tells you the file is well-formed against its framework; it says nothing about whether the thing described is the thing they mean. Read the blueprint with the frames in mind and raise what does not fit.
36
+ Whether the prose is true, whether the scope is right, and whether an open question should be settled are the owner's. `check` tells you the file is well-formed against its framework; it says nothing about whether the product described is the one they mean. Read the blueprint with the frames in mind and raise what does not fit.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eidosmd",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "The Eidos CLI: scaffold, validate, index, and browse a root of Eidos blueprints, and hand any agent the workflow it needs to work in one.",
5
5
  "keywords": [
6
6
  "eidos",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "files": [
27
27
  "dist/src",
28
- "browser",
28
+ "browser/dist",
29
29
  "instructions",
30
30
  "standard",
31
31
  "NOTICE"
@@ -33,21 +33,30 @@
33
33
  "engines": {
34
34
  "node": ">=20"
35
35
  },
36
+ "scripts": {
37
+ "build": "tsc -p tsconfig.json && vite build browser",
38
+ "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
39
+ "test": "pnpm build && node --test \"dist/test/**/*.test.js\"",
40
+ "check": "tsc -p tsconfig.json --noEmit && tsc -p browser/tsconfig.json --noEmit",
41
+ "prepublishOnly": "pnpm clean && pnpm test",
42
+ "sync-standard": "node scripts/sync-standard.mjs",
43
+ "build:browser": "vite build browser",
44
+ "dev:browser": "vite browser"
45
+ },
36
46
  "dependencies": {
37
47
  "commander": "^14.0.0",
38
48
  "marked": "^18.0.13",
39
49
  "yaml": "^2.8.0"
40
50
  },
41
51
  "devDependencies": {
52
+ "@preact/preset-vite": "^2.10.6",
42
53
  "@types/node": "^22.0.0",
43
- "typescript": "^5.9.0"
54
+ "@types/react": "^19.3.0",
55
+ "@types/react-dom": "^19.3.0",
56
+ "html-to-image": "^1.11.13",
57
+ "preact": "^10.29.8",
58
+ "typescript": "^5.9.0",
59
+ "vite": "^8.3.0"
44
60
  },
45
- "bugs": "https://gitlab.com/the-virtual-panda/eidosmd/-/issues",
46
- "scripts": {
47
- "build": "tsc -p tsconfig.json",
48
- "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
49
- "test": "pnpm build && node --test \"dist/test/**/*.test.js\"",
50
- "check": "tsc -p tsconfig.json --noEmit",
51
- "sync-standard": "node scripts/sync-standard.mjs"
52
- }
53
- }
61
+ "bugs": "https://gitlab.com/the-virtual-panda/eidosmd/-/issues"
62
+ }