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
|
@@ -4,10 +4,13 @@
|
|
|
4
4
|
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { parseFrontmatter } from './frontmatter.js';
|
|
7
|
-
import {
|
|
7
|
+
import { defaultVariant, findVariant } from './framework.js';
|
|
8
8
|
import { headings, sections } from './markdown.js';
|
|
9
9
|
import { kebab } from './naming.js';
|
|
10
|
-
|
|
10
|
+
// Under a markdown framework each collection's `index.md` is the generated
|
|
11
|
+
// leaf, not a blueprint. Under a YAML one the index lives in the document, so
|
|
12
|
+
// `index.md` is an ordinary filename (a blueprint with the id `index`).
|
|
13
|
+
export function blueprintFiles(dir, leafIsIndexMd) {
|
|
11
14
|
let entries;
|
|
12
15
|
try {
|
|
13
16
|
entries = readdirSync(dir);
|
|
@@ -16,7 +19,7 @@ export function blueprintFiles(dir) {
|
|
|
16
19
|
return [];
|
|
17
20
|
}
|
|
18
21
|
return entries
|
|
19
|
-
.filter((entry) => /\.md$/i.test(entry) && entry.toLowerCase()
|
|
22
|
+
.filter((entry) => /\.md$/i.test(entry) && !(leafIsIndexMd && entry.toLowerCase() === 'index.md') && !entry.startsWith('.'))
|
|
20
23
|
.filter((entry) => {
|
|
21
24
|
try {
|
|
22
25
|
return statSync(path.join(dir, entry)).isFile();
|
|
@@ -69,11 +72,12 @@ export function listBlueprints(framework, collections = framework.collections) {
|
|
|
69
72
|
const out = [];
|
|
70
73
|
for (const collection of collections) {
|
|
71
74
|
const dir = path.join(framework.root, collection.name);
|
|
72
|
-
|
|
75
|
+
const leafIsIndexMd = framework.format === 'md';
|
|
76
|
+
for (const file of blueprintFiles(dir, leafIsIndexMd)) {
|
|
73
77
|
out.push(loadBlueprint(framework.root, collection, null, file));
|
|
74
78
|
}
|
|
75
79
|
for (const group of groupDirs(dir)) {
|
|
76
|
-
for (const file of blueprintFiles(path.join(dir, group))) {
|
|
80
|
+
for (const file of blueprintFiles(path.join(dir, group), leafIsIndexMd)) {
|
|
77
81
|
out.push(loadBlueprint(framework.root, collection, group, file));
|
|
78
82
|
}
|
|
79
83
|
}
|
|
@@ -99,14 +103,15 @@ export function blueprintId(blueprint) {
|
|
|
99
103
|
export function blueprintTitle(blueprint) {
|
|
100
104
|
return propertyString(blueprint, 'title') ?? blueprint.stem;
|
|
101
105
|
}
|
|
102
|
-
// The
|
|
103
|
-
export function
|
|
104
|
-
|
|
106
|
+
// The variant a blueprint follows: the one it names, else its collection's default.
|
|
107
|
+
export function resolveVariant(blueprint) {
|
|
108
|
+
// `flavor` is the name before 5.0.0; a root not yet migrated still resolves
|
|
109
|
+
const declared = propertyString(blueprint, 'variant') ?? propertyString(blueprint, 'flavor');
|
|
105
110
|
if (declared === null) {
|
|
106
|
-
return {
|
|
111
|
+
return { variant: defaultVariant(blueprint.collection), declared: null, known: true };
|
|
107
112
|
}
|
|
108
|
-
const
|
|
109
|
-
return {
|
|
113
|
+
const variant = findVariant(blueprint.collection, declared);
|
|
114
|
+
return { variant, declared, known: variant !== null };
|
|
110
115
|
}
|
|
111
116
|
// A blueprint by path, by id, or by filename stem, in that order.
|
|
112
117
|
export function resolveBlueprint(ref, blueprints, cwd) {
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// The canvas file, as a JSON Schema (draft 7): what `.eidos/plugins/eidosmd/maps/<id>.yaml`
|
|
2
|
+
// may hold. The file is the whole truth of a canvas; the browser draws it and writes it
|
|
3
|
+
// back, and anything else (a person, an agent) edits it directly.
|
|
4
|
+
import { ANCHORS, EDGE_CAPS } from './canvas.js';
|
|
5
|
+
const hex = { type: 'string', pattern: '^#[0-9a-fA-F]{6}$', description: 'A color as #rrggbb.' };
|
|
6
|
+
const size = { type: 'string', enum: ['small', 'medium', 'large'] };
|
|
7
|
+
const point = { type: 'object', required: ['x', 'y'], additionalProperties: false, properties: { x: { type: 'number' }, y: { type: 'number' } } };
|
|
8
|
+
export const CANVAS_SCHEMA = {
|
|
9
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
10
|
+
title: 'Eidos canvas map',
|
|
11
|
+
description: 'One canvas of the eidosmd browser: a title and pages, each with frames, nodes, edges, layout, and comment threads. Kept at .eidos/plugins/eidosmd/maps/<id>.yaml; the id is the file name.',
|
|
12
|
+
type: 'object',
|
|
13
|
+
required: ['title', 'pages'],
|
|
14
|
+
additionalProperties: false,
|
|
15
|
+
properties: {
|
|
16
|
+
title: { type: 'string' },
|
|
17
|
+
pages: { type: 'array', minItems: 1, items: { $ref: '#/definitions/page' } },
|
|
18
|
+
},
|
|
19
|
+
definitions: {
|
|
20
|
+
page: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
required: ['id', 'title'],
|
|
23
|
+
additionalProperties: false,
|
|
24
|
+
properties: {
|
|
25
|
+
id: { type: 'string', description: 'Unique within the canvas; the URL names it.' },
|
|
26
|
+
title: { type: 'string' },
|
|
27
|
+
frames: { type: 'array', items: { $ref: '#/definitions/frame' } },
|
|
28
|
+
nodes: { type: 'array', items: { $ref: '#/definitions/node' } },
|
|
29
|
+
edges: { type: 'array', items: { $ref: '#/definitions/edge' } },
|
|
30
|
+
layout: { type: 'object', description: 'Where each node sits, by node id. A node without a place is laid out by the browser and given one when it first moves.', additionalProperties: point },
|
|
31
|
+
comments: { type: 'array', items: { $ref: '#/definitions/comment' } },
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
node: {
|
|
35
|
+
type: 'object',
|
|
36
|
+
required: ['id'],
|
|
37
|
+
additionalProperties: false,
|
|
38
|
+
description: 'Exactly one of blueprint, sketch, sticky, text, or annotation says what the node is.',
|
|
39
|
+
oneOf: [{ required: ['blueprint'] }, { required: ['sketch'] }, { required: ['sticky'] }, { required: ['text'] }, { required: ['annotation'] }],
|
|
40
|
+
properties: {
|
|
41
|
+
id: { type: 'string', description: 'Unique within the page; edges name it.' },
|
|
42
|
+
blueprint: { type: 'string', description: "A blueprint's id; its title, summary, and styled properties are read from the file when drawn." },
|
|
43
|
+
sketch: { $ref: '#/definitions/sketch' },
|
|
44
|
+
sticky: { $ref: '#/definitions/sticky' },
|
|
45
|
+
text: { $ref: '#/definitions/text' },
|
|
46
|
+
annotation: { $ref: '#/definitions/annotation' },
|
|
47
|
+
frame: { type: 'string', description: 'The frame this node is attached to; it moves with the frame.' },
|
|
48
|
+
link: { type: 'object', additionalProperties: false, properties: { page: { type: 'string' }, canvas: { type: 'string' } }, description: 'What the card opens: another page, or another canvas.' },
|
|
49
|
+
locked: { type: 'boolean' },
|
|
50
|
+
style: { $ref: '#/definitions/style' },
|
|
51
|
+
styled: { type: 'boolean', description: 'Styled by hand: a change to a styling property asks before the default is applied.' },
|
|
52
|
+
box: { type: 'object', required: ['w', 'h'], additionalProperties: false, properties: { w: { type: 'number', minimum: 40 }, h: { type: 'number', minimum: 24 } }, description: 'An exact size; text wraps and scrolls inside it.' },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
sketch: {
|
|
56
|
+
type: 'object',
|
|
57
|
+
required: ['label'],
|
|
58
|
+
additionalProperties: false,
|
|
59
|
+
description: 'A node that is not a blueprint yet; eidos new promotes it.',
|
|
60
|
+
properties: {
|
|
61
|
+
label: { type: 'string', description: 'The title; may be empty until written.' },
|
|
62
|
+
kind: { type: 'string' },
|
|
63
|
+
status: { type: 'string' },
|
|
64
|
+
note: { type: 'string', description: 'The description.' },
|
|
65
|
+
properties: { type: 'object', additionalProperties: { type: 'string' }, description: 'Values of schema properties that apply to every collection, held until promotion.' },
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
sticky: { type: 'object', required: ['text'], additionalProperties: false, properties: { text: { type: 'string' }, color: { type: 'string', enum: ['yellow', 'pink', 'blue', 'green', 'purple', 'orange'] } } },
|
|
69
|
+
text: { type: 'object', required: ['text'], additionalProperties: false, properties: { text: { type: 'string' }, size, font: { type: 'integer', minimum: 8, maximum: 64, description: 'An exact size in pixels; wins over size.' } } },
|
|
70
|
+
annotation: { type: 'object', required: ['text'], additionalProperties: false, description: 'A note that points at a node or a frame through an edge from it; one that points at nothing is removed.', properties: { text: { type: 'string' }, color: hex } },
|
|
71
|
+
style: {
|
|
72
|
+
type: 'object',
|
|
73
|
+
additionalProperties: false,
|
|
74
|
+
description: "A node's own look over the default its properties give it.",
|
|
75
|
+
properties: {
|
|
76
|
+
shape: { type: 'string', enum: ['box', 'pill', 'parallelogram'] },
|
|
77
|
+
color: { ...hex, description: 'The highlight: the bar and the border.' },
|
|
78
|
+
fill: { type: 'string', enum: ['solid', 'tint', 'none'] },
|
|
79
|
+
fill_color: hex,
|
|
80
|
+
size,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
edge: {
|
|
84
|
+
type: 'object',
|
|
85
|
+
required: ['from', 'to'],
|
|
86
|
+
additionalProperties: false,
|
|
87
|
+
description: 'A flow between two nodes, or to a frame border as frame:<id>.',
|
|
88
|
+
properties: {
|
|
89
|
+
from: { type: 'string' },
|
|
90
|
+
to: { type: 'string' },
|
|
91
|
+
label: { type: 'string' },
|
|
92
|
+
label_at: { type: 'number', minimum: 0, maximum: 1, description: 'Where along the line the label sits.' },
|
|
93
|
+
bend: { type: 'number', description: 'Where the middle segment turns, along its axis.' },
|
|
94
|
+
from_anchor: { type: 'string', enum: [...ANCHORS] },
|
|
95
|
+
to_anchor: { type: 'string', enum: [...ANCHORS] },
|
|
96
|
+
color: hex,
|
|
97
|
+
style: { type: 'string', enum: ['solid', 'dashed'] },
|
|
98
|
+
start: { type: 'string', enum: [...EDGE_CAPS] },
|
|
99
|
+
end: { type: 'string', enum: [...EDGE_CAPS], description: 'A solid arrowhead (triangle) when absent.' },
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
frame: {
|
|
103
|
+
type: 'object',
|
|
104
|
+
required: ['id', 'title'],
|
|
105
|
+
additionalProperties: false,
|
|
106
|
+
description: 'A region drawn around nodes; what is attached moves with it.',
|
|
107
|
+
properties: {
|
|
108
|
+
id: { type: 'string' },
|
|
109
|
+
title: { type: 'string' },
|
|
110
|
+
x: { type: 'number' },
|
|
111
|
+
y: { type: 'number' },
|
|
112
|
+
w: { type: 'number' },
|
|
113
|
+
h: { type: 'number' },
|
|
114
|
+
color: { type: 'string', enum: ['none', 'sand', 'sky', 'mint', 'rose', 'lilac'] },
|
|
115
|
+
locked: { type: 'boolean' },
|
|
116
|
+
frame: { type: 'string', description: 'The frame this frame is attached to.' },
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
comment: {
|
|
120
|
+
type: 'object',
|
|
121
|
+
required: ['id', 'x', 'y', 'messages'],
|
|
122
|
+
additionalProperties: false,
|
|
123
|
+
description: 'A thread pinned to a point, or to a node with x and y as the offset from it.',
|
|
124
|
+
properties: {
|
|
125
|
+
id: { type: 'string' },
|
|
126
|
+
x: { type: 'number' },
|
|
127
|
+
y: { type: 'number' },
|
|
128
|
+
node: { type: 'string' },
|
|
129
|
+
resolved: { type: 'boolean' },
|
|
130
|
+
messages: {
|
|
131
|
+
type: 'array',
|
|
132
|
+
items: {
|
|
133
|
+
type: 'object',
|
|
134
|
+
required: ['author', 'text', 'at'],
|
|
135
|
+
additionalProperties: false,
|
|
136
|
+
properties: {
|
|
137
|
+
author: { type: 'string' },
|
|
138
|
+
role: { type: 'string', description: 'The role the author held in this root when they wrote it.' },
|
|
139
|
+
user: { type: 'string', description: 'The user (alias, else name) from the root\'s settings, when one was known.' },
|
|
140
|
+
text: { type: 'string' },
|
|
141
|
+
at: { type: 'string', description: 'When, as an ISO 8601 time.' },
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
};
|