eidosmd 0.1.0 → 0.2.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.
- package/README.md +50 -29
- package/browser/dist/assets/index-C2NMN_D4.css +1 -0
- package/browser/dist/assets/index-C65k1ihb.js +46 -0
- package/browser/dist/favicon.svg +5 -0
- package/browser/dist/index.html +15 -0
- package/browser/dist/mark.svg +4 -0
- package/dist/src/cli.js +7 -0
- package/dist/src/commands/agents.js +1 -1
- package/dist/src/commands/canvas.js +77 -0
- package/dist/src/commands/check.js +1 -1
- package/dist/src/commands/framework.js +24 -5
- package/dist/src/commands/index.js +4 -4
- package/dist/src/commands/init.js +1 -0
- package/dist/src/commands/instructions.js +1 -1
- package/dist/src/commands/list.js +8 -8
- package/dist/src/commands/migrate.js +32 -0
- package/dist/src/commands/new.js +3 -3
- package/dist/src/commands/seeds.js +5 -5
- package/dist/src/commands/setup.js +119 -0
- package/dist/src/commands/version.js +44 -0
- package/dist/src/commands/whoami.js +4 -4
- package/dist/src/context.js +5 -5
- package/dist/src/core/blueprint.js +16 -11
- package/dist/src/core/canvas-schema.js +148 -0
- package/dist/src/core/canvas.js +722 -0
- package/dist/src/core/check.js +127 -51
- package/dist/src/core/convert.js +7 -6
- package/dist/src/core/framework-markdown.js +113 -34
- package/dist/src/core/framework-model.js +27 -10
- package/dist/src/core/framework-structured.js +132 -33
- package/dist/src/core/framework.js +13 -13
- package/dist/src/core/git.js +59 -0
- package/dist/src/core/index-leaf.js +2 -2
- package/dist/src/core/me.js +16 -8
- package/dist/src/core/migrate.js +243 -0
- package/dist/src/core/naming.js +1 -1
- package/dist/src/core/root.js +2 -2
- package/dist/src/core/scaffold.js +19 -19
- package/dist/src/core/seed.js +151 -60
- package/dist/src/core/server.js +1236 -52
- package/dist/src/core/settings.js +181 -0
- package/dist/src/core/store.js +259 -0
- package/dist/src/core/template.js +32 -0
- package/dist/src/core/versions.js +79 -0
- package/dist/src/output.js +4 -1
- package/dist/src/program.js +134 -39
- package/instructions/authoring.md +13 -12
- package/instructions/configuring.md +65 -34
- package/instructions/init-required.md +4 -4
- package/instructions/overview.md +17 -7
- package/instructions/validating.md +5 -4
- package/package.json +21 -12
- package/standard/EIDOS.md +129 -188
- package/standard/seeds/README.md +6 -6
- package/standard/seeds/book/Framework.yaml +81 -0
- package/standard/seeds/book/README.md +9 -5
- package/standard/seeds/book/_gitignore +3 -3
- package/standard/seeds/book/me.md +1 -1
- package/standard/seeds/book/roles/README.md +3 -3
- package/standard/seeds/book/roles/framework-owner.md +2 -2
- package/standard/seeds/book/{shapes → templates}/chapter.full.md +0 -8
- package/standard/seeds/book/{shapes → templates}/chapter.sketch.md +0 -7
- package/standard/seeds/book/{shapes → templates}/frame.market.md +0 -6
- package/standard/seeds/book/templates/frame.premise.md +17 -0
- package/standard/seeds/book/{shapes → templates}/frame.reader.md +0 -6
- package/standard/seeds/book/{shapes → templates}/frame.voice.md +0 -7
- package/standard/seeds/research/Framework.yaml +81 -0
- package/standard/seeds/research/README.md +9 -5
- package/standard/seeds/research/_gitignore +3 -3
- package/standard/seeds/research/me.md +1 -1
- package/standard/seeds/research/roles/README.md +3 -3
- package/standard/seeds/research/roles/framework-owner.md +2 -2
- package/standard/seeds/research/{shapes → templates}/frame.ethics.md +0 -6
- package/standard/seeds/research/{shapes → templates}/frame.method.md +0 -7
- package/standard/seeds/research/{shapes → templates}/frame.prior-work.md +0 -6
- package/standard/seeds/research/{shapes → templates}/frame.question.md +0 -7
- package/standard/seeds/research/{shapes → templates}/investigation.full.md +0 -8
- package/standard/seeds/research/{shapes → templates}/investigation.note.md +0 -7
- package/standard/seeds/software/Framework.yaml +82 -0
- package/standard/seeds/software/README.md +5 -5
- package/standard/seeds/software/_gitignore +3 -3
- package/standard/seeds/software/me.md +1 -1
- package/standard/seeds/software/roles/README.md +3 -3
- package/standard/seeds/software/roles/framework-owner.md +2 -2
- package/standard/seeds/software/roles/project-manager.md +2 -2
- package/standard/seeds/software/roles/stakeholder.md +1 -1
- package/standard/seeds/software/{shapes → templates}/frame.architecture.md +0 -7
- package/standard/seeds/software/{shapes → templates}/frame.audience.md +1 -8
- package/standard/seeds/software/{shapes → templates}/frame.criteria.md +0 -8
- package/standard/seeds/software/{shapes → templates}/frame.market.md +0 -8
- package/standard/seeds/software/{shapes → templates}/spec.full.md +0 -8
- package/standard/seeds/software/{shapes → templates}/spec.micro.md +0 -9
- package/browser/index.html +0 -268
- package/dist/src/commands/convert.js +0 -30
- package/dist/src/core/shape.js +0 -26
- package/standard/seeds/book/Framework.md +0 -87
- package/standard/seeds/book/shapes/frame.premise.md +0 -24
- package/standard/seeds/research/Framework.md +0 -88
- package/standard/seeds/software/Framework.md +0 -88
- /package/standard/seeds/software/{shapes → templates}/.gitkeep +0 -0
package/dist/src/program.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
// The eidos command line, assembled: every command, its options, and its help.
|
|
2
2
|
// `cli.ts` is the executable entry; this module is what tests build.
|
|
3
|
+
import path from 'node:path';
|
|
3
4
|
import { Command } from 'commander';
|
|
4
5
|
import { loadRoot } from './context.js';
|
|
5
6
|
import { runAgents } from './commands/agents.js';
|
|
6
7
|
import { DEFAULT_PORT, runBrowser } from './commands/browser.js';
|
|
8
|
+
import { runCanvasList, runCanvasNew, runCanvasSchema, runCanvasShow } from './commands/canvas.js';
|
|
9
|
+
import { runMigrate } from './commands/migrate.js';
|
|
7
10
|
import { runCheck } from './commands/check.js';
|
|
8
|
-
import { runConvert } from './commands/convert.js';
|
|
9
11
|
import { runFramework } from './commands/framework.js';
|
|
10
12
|
import { runIndex } from './commands/index.js';
|
|
11
13
|
import { runInit } from './commands/init.js';
|
|
@@ -13,7 +15,9 @@ import { runInstructions, runStandard } from './commands/instructions.js';
|
|
|
13
15
|
import { runList } from './commands/list.js';
|
|
14
16
|
import { runNew } from './commands/new.js';
|
|
15
17
|
import { runSeeds } from './commands/seeds.js';
|
|
18
|
+
import { offerGit, runSetup } from './commands/setup.js';
|
|
16
19
|
import { runShow } from './commands/show.js';
|
|
20
|
+
import { runVersionList, runVersionRecord } from './commands/version.js';
|
|
17
21
|
import { runRoles, runWhoami } from './commands/whoami.js';
|
|
18
22
|
import { CliError, EXIT_USAGE, printError, today } from './output.js';
|
|
19
23
|
import { packageVersion, standardVersion } from './paths.js';
|
|
@@ -42,7 +46,7 @@ export function buildProgram() {
|
|
|
42
46
|
.name('eidos')
|
|
43
47
|
.description(`Eidos: one markdown file is the complete source of truth for one unit of a thing.\nScaffold, validate, and index a root of blueprints; hand an agent the workflow with \`eidos instructions\`.`)
|
|
44
48
|
.version(`eidosmd ${packageVersion()} (standard ${standardVersion()})`, '-v, --version', 'print the CLI version and the standard it carries')
|
|
45
|
-
.option('--root <path>', 'the root to work in (default: found from the working directory by its
|
|
49
|
+
.option('--root <path>', 'the root to work in (default: found from the working directory by its .eidos/ marker)')
|
|
46
50
|
.enablePositionalOptions()
|
|
47
51
|
.showHelpAfterError('(run with --help for usage)')
|
|
48
52
|
.addHelpText('after', `
|
|
@@ -52,11 +56,12 @@ Start with \`eidos instructions\` for the workflow, or \`eidos seeds\` and \`eid
|
|
|
52
56
|
program
|
|
53
57
|
.command('init')
|
|
54
58
|
.argument('[root]', 'the root folder to create', 'Blueprints')
|
|
55
|
-
.description('create a root from a bundled seed: its framework as
|
|
59
|
+
.description('create a root from a bundled seed: its framework as .eidos/Framework.yaml, a folder per collection, a blank blueprint per framing variant (the framing docs are recommended; --no-framing leaves them out)')
|
|
56
60
|
.option('--seed <name>', 'the seed to install (see `eidos seeds`)', 'software')
|
|
57
61
|
.option('--naming <convention>', 'kebab-case | TitleCase | "Title Case"; governs every human-facing name, settled once', 'kebab-case')
|
|
58
62
|
.option('--group <name>', 'a starting group under the grouped collection (repeatable)', collect, [])
|
|
59
63
|
.option('--product <name>', "fills the README's {{Product}} placeholder")
|
|
64
|
+
.option('--no-framing', 'leave out the seed\'s framing collection (the docs about the whole product, recommended for every product)')
|
|
60
65
|
.option('--date <YYYY-MM-DD>', 'the date written into the scaffolded frames', today())
|
|
61
66
|
.option('--dry-run', 'print every write and touch nothing', false)
|
|
62
67
|
.option('--json', 'machine-readable result', false)
|
|
@@ -68,47 +73,40 @@ Examples:
|
|
|
68
73
|
eidos init Blueprints --seed software --group Identity --group Billing --product "Care Connect"
|
|
69
74
|
eidos init docs/product --seed research --naming TitleCase --dry-run
|
|
70
75
|
|
|
71
|
-
Writes Framework.yaml
|
|
72
|
-
.action((root, options) => {
|
|
76
|
+
Writes the seed's Framework.yaml into the root with its guidance as comments, the naming, the starting groups, and the collection names set in it.`)
|
|
77
|
+
.action(async (root, options) => {
|
|
73
78
|
run(() => runInit(root, options));
|
|
79
|
+
// In a terminal, the one setting worth asking for right away; the rest is `eidos setup`.
|
|
80
|
+
if (process.exitCode === 0 && !options.json && !options.dryRun)
|
|
81
|
+
await offerGit(path.resolve(root ?? 'Blueprints'));
|
|
74
82
|
});
|
|
75
83
|
program
|
|
76
84
|
.command('seeds')
|
|
77
|
-
.description('list the bundled seeds: each one a complete starting framework, with its collections and
|
|
85
|
+
.description('list the bundled seeds: each one a complete starting framework, with its collections and variants')
|
|
78
86
|
.option('--json', 'machine-readable result', false)
|
|
79
87
|
.action((options) => {
|
|
80
88
|
run(() => runSeeds(options));
|
|
81
89
|
});
|
|
82
90
|
withRoot(program.command('framework'))
|
|
83
|
-
.description("show the root's framework: version, naming, top-level docs, collections (
|
|
91
|
+
.description("show the root's framework: version, naming, top-level docs, collections (variants, groups), the Properties table, and the Vocabulary")
|
|
84
92
|
.option('--json', 'the framework as JSON: the document form plus root, file, and format', false)
|
|
85
|
-
.option('--as <format>', 'print the framework as the yaml document
|
|
93
|
+
.option('--as <format>', 'print the framework as the yaml document, normalized, with this CLI\'s guidance as comments')
|
|
86
94
|
.addHelpText('after', `
|
|
87
|
-
Read this before assuming any collection,
|
|
88
|
-
The document is
|
|
95
|
+
Read this before assuming any collection, variant, section, or property name; the framework declares its own.
|
|
96
|
+
The document is .eidos/Framework.yaml. A root still on the 4.x Framework.md is moved by \`eidos migrate\` first.
|
|
89
97
|
|
|
90
|
-
Output (--json): { root, file, format, eidos_version, naming, top_level[], collections[{ name, description,
|
|
91
|
-
|
|
92
|
-
This is the one command that also reads a Framework.md root, so a root can be inspected before \`eidos convert\` moves it.`)
|
|
93
|
-
.action((options) => {
|
|
94
|
-
run(() => runFramework(loadRoot(globals(options), process.cwd(), { allowMarkdown: true }), options));
|
|
95
|
-
});
|
|
96
|
-
withRoot(program.command('convert'))
|
|
97
|
-
.description('move a markdown root to Framework.yaml, the form the CLI works in: the same framework with the index inside it; Framework.md and each index.md removed')
|
|
98
|
-
.option('--dry-run', 'print the writes and touch nothing', false)
|
|
99
|
-
.option('--json', 'machine-readable result', false)
|
|
100
|
-
.addHelpText('after', `
|
|
101
|
-
Every command except this one and \`framework\` needs Framework.yaml, so on a markdown root this is the first thing to run. The markdown form's prose (section intros, comments) has no field to land in and is left behind; each collection's description travels. Blueprints are untouched.`)
|
|
98
|
+
Output (--json): { root, file, format, eidos_version, naming, top_level[], collections[{ name, description, variants[{ name, template, description, default }], grouping{ label, property, groups[] } }], properties{ core[], custom[{ name, type, applies_to, meaning, <tool>… }], tools{ <tool>: [...] } }, vocabulary[{ term, means, not[], see? }] }
|
|
99
|
+
A key past the standard's four on a property entry is a tool's, named for the tool (this CLI's is eidosmd, carrying a canvas hint); properties.tools.<tool> is a block of properties a tool declared and alone writes.`)
|
|
102
100
|
.action((options) => {
|
|
103
|
-
run(() =>
|
|
101
|
+
run(() => runFramework(loadRoot(globals(options), process.cwd()), options));
|
|
104
102
|
});
|
|
105
103
|
withRoot(program.command('list'))
|
|
106
104
|
.argument('[collection]', 'only this collection')
|
|
107
105
|
.description('list the blueprints in the root')
|
|
108
106
|
.option('--group <name>', 'only this group (sub-folder)')
|
|
109
|
-
.option('--
|
|
107
|
+
.option('--variant <name>', 'only blueprints on this variant (resolved, so the default counts)')
|
|
110
108
|
.option('--where <key=value>', 'only blueprints whose property equals the value, case-insensitive (repeatable; a list matches any item)', collect, [])
|
|
111
|
-
.option('--json', 'one object per blueprint: id, title, summary, collection, group,
|
|
109
|
+
.option('--json', 'one object per blueprint: id, title, summary, collection, group, variant, path, properties', false)
|
|
112
110
|
.addHelpText('after', `
|
|
113
111
|
Examples:
|
|
114
112
|
eidos list
|
|
@@ -120,39 +118,39 @@ Examples:
|
|
|
120
118
|
withRoot(program.command('show'))
|
|
121
119
|
.argument('<blueprint>', 'an id, a filename, or a path')
|
|
122
120
|
.description('print one blueprint as written; with --json, its properties and sections parsed out')
|
|
123
|
-
.option('--json', '{ id, title, summary, collection, group,
|
|
121
|
+
.option('--json', '{ id, title, summary, collection, group, variant, path, absolute_path, properties, sections[{ heading, body }], body }', false)
|
|
124
122
|
.action((ref, options) => {
|
|
125
123
|
run(() => runShow(loadRoot(globals(options)), ref, options));
|
|
126
124
|
});
|
|
127
125
|
withRoot(program.command('new'))
|
|
128
126
|
.argument('<collection>', 'the collection the blueprint belongs to')
|
|
129
127
|
.argument('<title...>', 'the human-readable title')
|
|
130
|
-
.description("scaffold a blueprint that is born conforming: frontmatter from the
|
|
131
|
-
.option('--
|
|
128
|
+
.description("scaffold a blueprint that is born conforming: frontmatter from the Properties table, body from the variant's template, filename in the naming convention, a permanent kebab-case id")
|
|
129
|
+
.option('--variant <name>', "one of the collection's declared variants (default: the collection's default)")
|
|
132
130
|
.option('--group <name>', 'the sub-folder to place it in')
|
|
133
131
|
.option('--id <kebab-case>', 'the permanent id (default: the title in kebab-case)')
|
|
134
132
|
.option('--summary <line>', 'the one-line summary, so the index lists it at once')
|
|
135
133
|
.option('--set <key=value>', 'a property value at creation (repeatable; lists are comma-separated)', collect, [])
|
|
136
|
-
.option('--date <YYYY-MM-DD>', 'the date written into date properties the
|
|
134
|
+
.option('--date <YYYY-MM-DD>', 'the date written into date properties the Properties table declares', today())
|
|
137
135
|
.option('--dry-run', 'print the file instead of writing it', false)
|
|
138
|
-
.option('--json', '{ path, id, collection, group,
|
|
136
|
+
.option('--json', '{ path, id, collection, group, variant, notes[] }', false)
|
|
139
137
|
.addHelpText('after', `
|
|
140
|
-
The body keeps the
|
|
138
|
+
The body keeps the template's guidance prompts; fill them with the owner and delete them as you go. The CLI writes no prose.
|
|
141
139
|
|
|
142
140
|
Examples:
|
|
143
141
|
eidos new Specs "Session Management" --group Identity --summary "Keeps a signed-in user signed in across tabs and devices."
|
|
144
|
-
eidos new Specs "Passkeys" --
|
|
142
|
+
eidos new Specs "Passkeys" --variant micro --set status=Intake --set tags=auth,security
|
|
145
143
|
eidos new Frames Market --dry-run`)
|
|
146
144
|
.action((collection, title, options) => {
|
|
147
145
|
run(() => runNew(loadRoot(globals(options)), collection, title, options));
|
|
148
146
|
});
|
|
149
147
|
withRoot(program.command('check'))
|
|
150
148
|
.argument('[blueprint...]', 'only these blueprints (paths); default: the whole root')
|
|
151
|
-
.description("validate the root against its own framework: the
|
|
149
|
+
.description("validate the root against its own framework: the framework document and templates, every blueprint's frontmatter and body, the layout, and the indexes")
|
|
152
150
|
.option('--strict', 'warnings fail too', false)
|
|
153
151
|
.option('--json', '{ ok, root, eidos_version, naming, blueprints, errors, warnings, findings[{ level, code, path, message }] }', false)
|
|
154
152
|
.addHelpText('after', `
|
|
155
|
-
Errors are wrong on any reading (unparseable frontmatter, a missing or duplicate id, an undeclared
|
|
153
|
+
Errors are wrong on any reading (unparseable frontmatter, a missing or duplicate id, an undeclared variant, a broken link). Warnings are gaps the standard says to surface, never refuse (a missing property or section, a stale index, a version gap). Exit 1 on an error; with --strict, on a warning too.
|
|
156
154
|
|
|
157
155
|
Examples:
|
|
158
156
|
eidos check
|
|
@@ -162,28 +160,28 @@ Examples:
|
|
|
162
160
|
run(() => runCheck(loadRoot(globals(options)), blueprints, options));
|
|
163
161
|
});
|
|
164
162
|
withRoot(program.command('index'))
|
|
165
|
-
.description("regenerate each collection's index
|
|
163
|
+
.description("regenerate each collection's index: every blueprint as a link with its summary, grouped by sub-folder")
|
|
166
164
|
.option('--collection <name>', 'only this collection (repeatable)', collect, [])
|
|
167
165
|
.option('--check', 'write nothing; exit 1 if any index is stale', false)
|
|
168
166
|
.option('--json', '{ ok, indexes[{ collection, path, status, blueprints }], missing_summary[] }', false)
|
|
169
167
|
.addHelpText('after', `
|
|
170
|
-
|
|
168
|
+
Every collection's index is written into the framework document under \`index\`, and the rest of the document is left as written. A blueprint without a summary is listed with a null summary and named on stderr.`)
|
|
171
169
|
.action((options) => {
|
|
172
170
|
run(() => runIndex(loadRoot(globals(options)), options));
|
|
173
171
|
});
|
|
174
172
|
withRoot(program.command('roles'))
|
|
175
|
-
.description('list the roles the framework installed under
|
|
173
|
+
.description('list the roles the framework installed under .eidos/roles/')
|
|
176
174
|
.option('--json', 'machine-readable result', false)
|
|
177
175
|
.action((options) => {
|
|
178
176
|
run(() => runRoles(loadRoot(globals(options)), options));
|
|
179
177
|
});
|
|
180
178
|
withRoot(program.command('whoami'))
|
|
181
|
-
.description('show
|
|
179
|
+
.description('show who is in the seat (.eidos/me.md: role and calibration), or set it')
|
|
182
180
|
.option('--role <name>', 'a role from `eidos roles`')
|
|
183
181
|
.option('--ownership <text>', 'what you own on this root, in your own words')
|
|
184
182
|
.option('--experience <text>', 'your experience with the scope: new, familiar, deep')
|
|
185
183
|
.option('--capacity <text>', 'your technical capacity: non-technical, some, fluent')
|
|
186
|
-
.option('--clear', 'blank
|
|
184
|
+
.option('--clear', 'blank me.md (full facilitation)', false)
|
|
187
185
|
.option('--json', 'machine-readable result', false)
|
|
188
186
|
.addHelpText('after', `
|
|
189
187
|
me.md is personal and gitignored: one per person, never shared. An agent reads it before acting and responds as the role file says.
|
|
@@ -194,6 +192,103 @@ Examples:
|
|
|
194
192
|
.action((options) => {
|
|
195
193
|
run(() => runWhoami(loadRoot(globals(options)), options));
|
|
196
194
|
});
|
|
195
|
+
const canvas = program.command('canvas').description('the canvas maps under .eidos/plugins/eidosmd/maps/: the design tool the browser draws');
|
|
196
|
+
withRoot(canvas.command('list'))
|
|
197
|
+
.description('list the canvases and their pages')
|
|
198
|
+
.option('--json', 'machine-readable result', false)
|
|
199
|
+
.action((options) => {
|
|
200
|
+
run(() => runCanvasList(loadRoot(globals(options)), options));
|
|
201
|
+
});
|
|
202
|
+
withRoot(canvas.command('new'))
|
|
203
|
+
.argument('<title...>', 'the canvas title; its id is the title in kebab-case')
|
|
204
|
+
.description('create a canvas with one empty page; the browser is where it is drawn')
|
|
205
|
+
.option('--json', 'machine-readable result', false)
|
|
206
|
+
.action((title, options) => {
|
|
207
|
+
run(() => runCanvasNew(loadRoot(globals(options)), title.join(' '), options));
|
|
208
|
+
});
|
|
209
|
+
withRoot(canvas.command('show'))
|
|
210
|
+
.argument('<id>', 'the canvas id, its file name without .yaml')
|
|
211
|
+
.description('print a canvas file as it is, or one page of it, before editing it by hand')
|
|
212
|
+
.option('--page <id>', 'one page only')
|
|
213
|
+
.option('--json', 'machine-readable result', false)
|
|
214
|
+
.action((id, options) => {
|
|
215
|
+
run(() => runCanvasShow(loadRoot(globals(options)), id, options));
|
|
216
|
+
});
|
|
217
|
+
canvas
|
|
218
|
+
.command('schema')
|
|
219
|
+
.description('print the JSON Schema of a canvas file, for editing one without the browser')
|
|
220
|
+
.action(() => {
|
|
221
|
+
run(() => runCanvasSchema());
|
|
222
|
+
});
|
|
223
|
+
canvas.addHelpText('after', `
|
|
224
|
+
A canvas is one YAML file in this tool's folder, .eidos/plugins/eidosmd/maps/<id>.yaml: a title and pages (each with frames, nodes, edges, layout, and comment threads).
|
|
225
|
+
The file is the whole truth of a canvas: the browser draws it and writes it back, and a person or an agent edits it directly; \`eidos canvas schema\` prints what it may hold and \`eidos canvas show <id>\` prints one.
|
|
226
|
+
A node is { id, blueprint: <id> }, { id, sketch: { label, note? } }, a sticky, a text, or an annotation, optionally attached to a frame; edges join node ids (or frame:<id> for a frame's border).
|
|
227
|
+
Nodes are styled by the properties whose schema row carries this tool's hint, eidosmd.canvas (shape by value, color by value, show); a node's own style in the file wins over that.
|
|
228
|
+
The search index the browser keeps is SQLite in memory, rebuilt on every start and never written to disk; nothing but the YAML is checked in.
|
|
229
|
+
A snapshot of the root as a whole is a version: \`eidos version record\`.`);
|
|
230
|
+
const version = program.command('version').description("the root's own versions: snapshots taken on purpose, this CLI's own record under .eidos/plugins/eidosmd/ (they need git)");
|
|
231
|
+
withRoot(version.command('list', { isDefault: true }))
|
|
232
|
+
.description('list the recorded versions, newest first')
|
|
233
|
+
.option('--json', 'machine-readable result', false)
|
|
234
|
+
.action((options) => {
|
|
235
|
+
run(() => runVersionList(loadRoot(globals(options)), options));
|
|
236
|
+
});
|
|
237
|
+
withRoot(version.command('record'))
|
|
238
|
+
.argument('<version>', "the root's own number, e.g. 1.0.0 (not the product's release version)")
|
|
239
|
+
.description('record a snapshot: a row naming a commit that exists; --tag also tags it blueprints/<version>')
|
|
240
|
+
.option('--commit <ref>', 'the commit that is the snapshot (a sha, HEAD, a tag); HEAD when absent')
|
|
241
|
+
.option('--tag', 'create the tag blueprints/<version> on that commit', false)
|
|
242
|
+
.option('--json', 'machine-readable result', false)
|
|
243
|
+
.action((given, options) => {
|
|
244
|
+
run(() => runVersionRecord(loadRoot(globals(options)), given, options));
|
|
245
|
+
});
|
|
246
|
+
version.addHelpText('after', `
|
|
247
|
+
A version is a fixed point a team holds the definition against later. Nothing proposes one; record one only when asked.
|
|
248
|
+
The commit is the snapshot (git holds every blueprint as it was), nothing is copied, and the commit that adds the row is not the one it names.`);
|
|
249
|
+
program
|
|
250
|
+
.command('migrate')
|
|
251
|
+
.description('move a root to the standard this CLI carries: .eidos/, templates/, Framework.yaml, Properties, variants, the version; mechanical, nothing dropped')
|
|
252
|
+
.option('--root <path>', 'the root to migrate; default: the one found from here (.eidos/ or the older _eidos/)')
|
|
253
|
+
.option('--dry-run', 'list what would move and change nothing', false)
|
|
254
|
+
.option('--json', 'machine-readable result', false)
|
|
255
|
+
.addHelpText('after', `
|
|
256
|
+
The 4.x → 5.0.0 hop: _eidos/ becomes .eidos/, shapes/ becomes templates/, the framework document takes the 5.0.0 keys (schema → properties, flavors → variants, shape → template), a root that kept Framework.md gets Framework.yaml in its place (the index inside it; Framework.md and each collection's index.md removed), every blueprint's flavor becomes variant, and eidos_version is set.
|
|
257
|
+
A template that opens with frontmatter loses the block; one named off its unit (<unit>.<variant>.md) is reported for you to rename. Run eidos check afterwards.`)
|
|
258
|
+
.action((options) => {
|
|
259
|
+
run(() => runMigrate(options));
|
|
260
|
+
});
|
|
261
|
+
withRoot(program.command('setup'))
|
|
262
|
+
.description("the CLI's own settings for this root: whether git is read, the people who work here, and who this machine acts as")
|
|
263
|
+
.option('--git <on|off>', 'read git in the browser: history, authors, versions')
|
|
264
|
+
.option('--add-user <name>', 'add (or update) a user by display name (repeatable)', collect, [])
|
|
265
|
+
.option('--alias <alias>', 'the @mention handle of the user being added, no spaces')
|
|
266
|
+
.option('--role <name>', 'the role of the user being added, from `eidos roles`')
|
|
267
|
+
.option('--email <email>', 'the email of the user being added; ties them to a git identity')
|
|
268
|
+
.option('--as <alias>', 'act as this user on this machine (blank for the git identity)')
|
|
269
|
+
.option('--json', 'machine-readable result', false)
|
|
270
|
+
.addHelpText('after', `
|
|
271
|
+
Without flags, asks in the terminal. Writes .eidos/plugins/eidosmd/settings.yaml (shared with the root) and local.yaml (yours, gitignored).
|
|
272
|
+
|
|
273
|
+
Examples:
|
|
274
|
+
eidos setup
|
|
275
|
+
eidos setup --git on --add-user "Ada Lovelace" --alias ada --role developer --email ada@example.com --as ada
|
|
276
|
+
eidos setup --as client`)
|
|
277
|
+
.action(async (options) => {
|
|
278
|
+
try {
|
|
279
|
+
process.exitCode = await runSetup(loadRoot(globals(options)), options);
|
|
280
|
+
}
|
|
281
|
+
catch (cause) {
|
|
282
|
+
if (cause instanceof CliError) {
|
|
283
|
+
printError(`error: ${cause.message}`);
|
|
284
|
+
process.exitCode = cause.exitCode;
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
printError(`error: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
288
|
+
process.exitCode = EXIT_USAGE;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
});
|
|
197
292
|
withRoot(program.command('browser'))
|
|
198
293
|
.description('open the root in a local web page: browse and read blueprints, create one, edit one, run the check, rebuild the index')
|
|
199
294
|
.option('-p, --port <port>', 'the port to serve on; the next free one is used if it is busy', (value) => Number.parseInt(value, 10), DEFAULT_PORT)
|
|
@@ -1,34 +1,35 @@
|
|
|
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
|
|
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
|
|
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>" [--
|
|
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
|
|
15
|
+
`new` generates the frontmatter from the properties that apply to the collection, 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
|
|
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
|
|
27
|
-
- Follow whatever labeling the
|
|
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
|
|
32
|
+
Frontmatter stays what `new` generated. Fill values; do not add keys the Properties table does not declare (`eidos instructions configuring` is how a property is added). Leave a property blank rather than guessing it.
|
|
32
33
|
|
|
33
34
|
### 4. Check and index
|
|
34
35
|
|
|
@@ -37,14 +38,14 @@ eidos check <path-to-blueprint>
|
|
|
37
38
|
eidos index
|
|
38
39
|
```
|
|
39
40
|
|
|
40
|
-
`check` reports what is missing or malformed against this framework and the blueprint's
|
|
41
|
+
`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
42
|
|
|
42
43
|
### Frames and top-level docs
|
|
43
44
|
|
|
44
|
-
A frame is a blueprint in the framing collection (the
|
|
45
|
+
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
46
|
|
|
46
|
-
A top-level doc (a
|
|
47
|
+
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
48
|
|
|
48
49
|
### Reshaping a draft the owner already wrote
|
|
49
50
|
|
|
50
|
-
When the thinking is already on the page and only needs
|
|
51
|
+
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,96 @@
|
|
|
1
1
|
## Configuring the framework
|
|
2
2
|
|
|
3
|
-
The framework is the structure a root is written in: the framework document (version, naming, the
|
|
3
|
+
The framework is the structure a root is written in: the framework document (version, naming, the top-level index, the collections, 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
|
|
5
|
+
The document is `.eidos/Framework.yaml`: `top_level`, `collections[]` (each with `variants` and `grouping`), `properties.custom[]` (yours), `properties.tools.<tool>[]` (a tool's), and `vocabulary[]`, documented field by field in `eidos standard`. Never touch the `index` key: `eidos index` owns it. Never touch `.eidos/plugins/` (each folder is a tool's own) or a key on a Properties row past the standard's four (a tool's field, named for the tool); carry both across unchanged.
|
|
6
6
|
|
|
7
|
-
Press the owner to decide. A collection,
|
|
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
|
|
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 **
|
|
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
|
|
17
|
-
3. Register it under
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- **Kinds:**
|
|
29
|
-
- **Runtime** — decisions about what runs where.
|
|
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 `collections` in `Framework.yaml`: an entry with its name, 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
|
+
description: Architecture decision records, one per significant choice.
|
|
22
|
+
variants:
|
|
23
|
+
- { name: full, template: templates/decision.full.md, description: "context, decision, consequences", default: true }
|
|
24
|
+
grouping:
|
|
25
|
+
label: Kinds
|
|
26
|
+
groups:
|
|
27
|
+
- { name: Runtime, description: decisions about what runs where }
|
|
30
28
|
```
|
|
31
29
|
|
|
32
|
-
The grouping
|
|
33
|
-
4. Run `eidos index`
|
|
30
|
+
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.
|
|
31
|
+
4. Run `eidos index` so the new collection has its list, and `eidos check` to confirm the framework parses as intended.
|
|
34
32
|
|
|
35
|
-
### Adding a
|
|
33
|
+
### Adding a variant
|
|
36
34
|
|
|
37
|
-
Decide its **name** (lowercase), a one-line **description**, and its **
|
|
35
|
+
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.
|
|
38
36
|
|
|
39
|
-
1. Create
|
|
40
|
-
2. Add it to the collection's
|
|
41
|
-
3. Existing blueprints are untouched: an absent `
|
|
37
|
+
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.
|
|
38
|
+
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.
|
|
39
|
+
3. Existing blueprints are untouched: an absent `variant` still means the default. `eidos new --variant <name>` scaffolds in it from here on.
|
|
42
40
|
|
|
43
41
|
### Adding a property
|
|
44
42
|
|
|
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).
|
|
43
|
+
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). 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
44
|
|
|
47
|
-
1. Add
|
|
45
|
+
1. Add an entry to `properties.custom`:
|
|
48
46
|
|
|
49
|
-
```
|
|
50
|
-
|
|
47
|
+
```yaml
|
|
48
|
+
- { name: team, type: Text, applies_to: all, meaning: "Owning team, for filtering." }
|
|
51
49
|
```
|
|
52
50
|
|
|
53
51
|
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`.
|
|
54
52
|
|
|
53
|
+
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
|
+
|
|
55
55
|
### Renaming or retiring a property
|
|
56
56
|
|
|
57
|
-
Renaming: change the `
|
|
57
|
+
Renaming: change the entry's `name`, 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 entry and the keys. Never silently drop values.
|
|
58
|
+
|
|
59
|
+
### Declaring a term
|
|
60
|
+
|
|
61
|
+
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`.
|
|
62
|
+
|
|
63
|
+
1. Add an entry under `vocabulary` in `Framework.yaml`:
|
|
64
|
+
|
|
65
|
+
```yaml
|
|
66
|
+
vocabulary:
|
|
67
|
+
- term: team member
|
|
68
|
+
means: Someone on the product team, whatever their contract.
|
|
69
|
+
not:
|
|
70
|
+
- staff, who are the company's employees
|
|
71
|
+
- teammate, the informal word; use it in speech, not in a blueprint
|
|
72
|
+
see: ../specs/team-member.md # optional
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
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.
|
|
76
|
+
|
|
77
|
+
Renaming a term keeps the old word in `not` when the distinction is the point. Retiring one: show where the word is used first.
|
|
78
|
+
|
|
79
|
+
### Recording a version
|
|
80
|
+
|
|
81
|
+
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.
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
eidos version record 1.0.0 # HEAD, no tag
|
|
85
|
+
eidos version record 1.0.0 --commit a1b2c3d --tag
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
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
89
|
|
|
59
|
-
### Refreshing the
|
|
90
|
+
### Refreshing the top-level index
|
|
60
91
|
|
|
61
|
-
|
|
92
|
+
`top_level` lists the root's one-of-a-kind documents, `README` first, one entry each: `{ title: Vision, path: ../Vision.md, description: one line }`, the path relative to `.eidos/`. 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.
|
|
62
93
|
|
|
63
94
|
### After
|
|
64
95
|
|
|
65
|
-
Run `eidos check`. It will tell you whether the collection, its
|
|
96
|
+
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
|
|
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
|
|
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
|
|
25
|
-
eidos
|
|
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:
|
package/instructions/overview.md
CHANGED
|
@@ -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
|
|
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,8 +8,8 @@ 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
|
|
12
|
-
2. `eidos whoami` says who is in the seat. Open the role file it names under
|
|
11
|
+
1. `eidos framework` reads the root's own framework: its collections, their variants and groups, 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
|
|
|
@@ -17,21 +17,31 @@ Add `--json` to `framework`, `list`, `show`, and `check` when a script needs sta
|
|
|
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
|
|
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
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.
|
|
24
|
+
- `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.
|
|
25
|
+
|
|
26
|
+
### Speak the root's terms
|
|
27
|
+
|
|
28
|
+
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
29
|
|
|
26
30
|
### Version
|
|
27
31
|
|
|
28
|
-
The framework records the standard it targets as `eidos_version` in
|
|
32
|
+
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.
|
|
33
|
+
|
|
34
|
+
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>`).
|
|
35
|
+
|
|
36
|
+
### What is not yours
|
|
37
|
+
|
|
38
|
+
`.eidos/plugins/<name>/` is a tool's own folder (this CLI keeps its canvas maps under `plugins/eidosmd/`). 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. On a Properties row, a key past the standard's four (`name`, `type`, `applies_to`, `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.
|
|
29
39
|
|
|
30
40
|
### Guides
|
|
31
41
|
|
|
32
42
|
- `eidos instructions authoring`: read before creating or editing a blueprint
|
|
33
43
|
- `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
|
|
44
|
+
- `eidos instructions configuring`: read before changing the framework (a collection, a variant, a property, a term, a version, the Top-Level index)
|
|
35
45
|
- `eidos instructions init-required`: when there is no root here yet
|
|
36
46
|
|
|
37
47
|
`eidos <command> --help` explains any command's options and output.
|