egregore-artifacts 0.2.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.
- package/bin/cli.js +3 -3
- package/lib/components.js +2 -2
- package/lib/index.js +6 -2
- package/lib/markdown.js +54 -17
- package/lib/parsers/board.js +109 -0
- package/lib/parsers/network.js +73 -0
- package/lib/registry.js +15 -15
- package/lib/shell.js +160 -9
- package/lib/templates/activity.js +28 -28
- package/lib/templates/board.js +459 -0
- package/lib/templates/handoff.js +9 -9
- package/lib/templates/network.js +189 -0
- package/lib/tokens.js +12 -0
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import { execSync } from 'node:child_process';
|
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
|
|
7
|
-
const KNOWN_TYPES = ['quest', 'handoff', 'activity', 'document'];
|
|
7
|
+
const KNOWN_TYPES = ['quest', 'handoff', 'activity', 'document', 'board', 'network'];
|
|
8
8
|
const args = process.argv.slice(2);
|
|
9
9
|
|
|
10
10
|
let type, filePath;
|
|
@@ -47,7 +47,7 @@ if (KNOWN_TYPES.includes(positional[0])) {
|
|
|
47
47
|
type = inferType(filePath);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
if (!filePath && type !== 'activity') {
|
|
50
|
+
if (!filePath && type !== 'activity' && type !== 'board' && type !== 'network') {
|
|
51
51
|
console.error(`✗ Missing file path for type "${type}"`);
|
|
52
52
|
process.exit(1);
|
|
53
53
|
}
|
|
@@ -82,7 +82,7 @@ function resolveFile(fp) {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
try {
|
|
85
|
-
const input = type === 'activity' ? (filePath || 'live') : resolveFile(filePath);
|
|
85
|
+
const input = (type === 'activity' || type === 'board' || type === 'network') ? (filePath || 'live') : resolveFile(filePath);
|
|
86
86
|
const html = await generateArtifact(type, input);
|
|
87
87
|
const slug = filePath ? filePath.split('/').pop().replace('.md', '') : new Date().toISOString().split('T')[0];
|
|
88
88
|
|
package/lib/components.js
CHANGED
|
@@ -74,7 +74,7 @@ export function ArtifactList({ artifacts }) {
|
|
|
74
74
|
h('span', { className: 'eg-artifact-date' }, a.date),
|
|
75
75
|
h('span', { className: 'eg-artifact-type' }, a.type),
|
|
76
76
|
h('span', { className: 'eg-artifact-title' }, a.title),
|
|
77
|
-
a.author && h('span', { style: { color:
|
|
77
|
+
a.author && h('span', { style: { color: 'var(--muted)', fontSize: '13px', fontFamily: fonts.mono } }, `(${a.author})`),
|
|
78
78
|
)
|
|
79
79
|
),
|
|
80
80
|
);
|
|
@@ -92,7 +92,7 @@ export function ContributorRow({ contributors }) {
|
|
|
92
92
|
(c.name || '?')[0].toUpperCase()
|
|
93
93
|
),
|
|
94
94
|
h('span', null, c.name),
|
|
95
|
-
c.role && h('span', { style: { color:
|
|
95
|
+
c.role && h('span', { style: { color: 'var(--muted)', fontSize: '12px' } }, c.role),
|
|
96
96
|
)
|
|
97
97
|
),
|
|
98
98
|
);
|
package/lib/index.js
CHANGED
|
@@ -7,14 +7,18 @@ import { parseQuest } from './parsers/quest.js';
|
|
|
7
7
|
import { parseHandoff } from './parsers/handoff.js';
|
|
8
8
|
import { parseActivity } from './parsers/activity.js';
|
|
9
9
|
import { parseDocument } from './parsers/document.js';
|
|
10
|
+
import { parseBoard } from './parsers/board.js';
|
|
11
|
+
import { parseNetwork } from './parsers/network.js';
|
|
10
12
|
import { questTemplate } from './templates/quest.js';
|
|
11
13
|
import { handoffTemplate } from './templates/handoff.js';
|
|
12
14
|
import { activityTemplate } from './templates/activity.js';
|
|
13
15
|
import { documentTemplate } from './templates/document.js';
|
|
16
|
+
import { boardTemplate } from './templates/board.js';
|
|
17
|
+
import { networkTemplate } from './templates/network.js';
|
|
14
18
|
import { openInBrowser } from './open.js';
|
|
15
19
|
|
|
16
|
-
const PARSERS = { quest: parseQuest, handoff: parseHandoff, activity: parseActivity, document: parseDocument };
|
|
17
|
-
const TEMPLATES = { quest: questTemplate, handoff: handoffTemplate, activity: activityTemplate, document: documentTemplate };
|
|
20
|
+
const PARSERS = { quest: parseQuest, handoff: parseHandoff, activity: parseActivity, document: parseDocument, board: parseBoard, network: parseNetwork };
|
|
21
|
+
const TEMPLATES = { quest: questTemplate, handoff: handoffTemplate, activity: activityTemplate, document: documentTemplate, board: boardTemplate, network: networkTemplate };
|
|
18
22
|
|
|
19
23
|
export async function generateArtifact(type, input) {
|
|
20
24
|
const template = TEMPLATES[type];
|
package/lib/markdown.js
CHANGED
|
@@ -26,6 +26,40 @@ export function renderMarkdown(text) {
|
|
|
26
26
|
continue;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
// H1 heading (rare inside a document body; render as section-sized)
|
|
30
|
+
if (line.startsWith('# ')) {
|
|
31
|
+
elements.push(h('h2', {
|
|
32
|
+
key: elements.length,
|
|
33
|
+
style: {
|
|
34
|
+
fontFamily: fonts.serif,
|
|
35
|
+
fontSize: '28px',
|
|
36
|
+
fontWeight: 400,
|
|
37
|
+
lineHeight: 1.2,
|
|
38
|
+
margin: '1.75rem 0 0.75rem',
|
|
39
|
+
color: 'var(--black)',
|
|
40
|
+
},
|
|
41
|
+
}, inlineMarkdown(line.slice(2))));
|
|
42
|
+
i++;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// H2 heading
|
|
47
|
+
if (line.startsWith('## ')) {
|
|
48
|
+
elements.push(h('h3', {
|
|
49
|
+
key: elements.length,
|
|
50
|
+
style: {
|
|
51
|
+
fontFamily: fonts.serif,
|
|
52
|
+
fontSize: '22px',
|
|
53
|
+
fontWeight: 400,
|
|
54
|
+
lineHeight: 1.25,
|
|
55
|
+
margin: '1.5rem 0 0.5rem',
|
|
56
|
+
color: 'var(--black)',
|
|
57
|
+
},
|
|
58
|
+
}, inlineMarkdown(line.slice(3))));
|
|
59
|
+
i++;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
29
63
|
// H3 heading
|
|
30
64
|
if (line.startsWith('### ')) {
|
|
31
65
|
elements.push(h('h3', {
|
|
@@ -36,7 +70,7 @@ export function renderMarkdown(text) {
|
|
|
36
70
|
fontWeight: 600,
|
|
37
71
|
lineHeight: 1.3,
|
|
38
72
|
margin: '1.5rem 0 0.5rem',
|
|
39
|
-
color:
|
|
73
|
+
color: 'var(--black)',
|
|
40
74
|
},
|
|
41
75
|
}, inlineMarkdown(line.slice(4))));
|
|
42
76
|
i++;
|
|
@@ -52,7 +86,7 @@ export function renderMarkdown(text) {
|
|
|
52
86
|
fontSize: '15px',
|
|
53
87
|
fontWeight: 600,
|
|
54
88
|
margin: '1rem 0 0.25rem',
|
|
55
|
-
color:
|
|
89
|
+
color: 'var(--black)',
|
|
56
90
|
},
|
|
57
91
|
}, inlineMarkdown(line.slice(5))));
|
|
58
92
|
i++;
|
|
@@ -79,7 +113,7 @@ export function renderMarkdown(text) {
|
|
|
79
113
|
marginBottom: '0.35rem',
|
|
80
114
|
fontSize: '15px',
|
|
81
115
|
lineHeight: 1.55,
|
|
82
|
-
color:
|
|
116
|
+
color: 'var(--dark)',
|
|
83
117
|
},
|
|
84
118
|
},
|
|
85
119
|
h('span', {
|
|
@@ -90,7 +124,7 @@ export function renderMarkdown(text) {
|
|
|
90
124
|
width: '5px',
|
|
91
125
|
height: '5px',
|
|
92
126
|
borderRadius: '50%',
|
|
93
|
-
background:
|
|
127
|
+
background: 'var(--terracotta)',
|
|
94
128
|
},
|
|
95
129
|
}),
|
|
96
130
|
inlineMarkdown(item),
|
|
@@ -128,8 +162,8 @@ export function renderMarkdown(text) {
|
|
|
128
162
|
width: '20px',
|
|
129
163
|
height: '20px',
|
|
130
164
|
borderRadius: '50%',
|
|
131
|
-
background:
|
|
132
|
-
color:
|
|
165
|
+
background: 'var(--terracotta)',
|
|
166
|
+
color: 'var(--cream)',
|
|
133
167
|
display: 'flex',
|
|
134
168
|
alignItems: 'center',
|
|
135
169
|
justifyContent: 'center',
|
|
@@ -158,7 +192,7 @@ export function renderMarkdown(text) {
|
|
|
158
192
|
elements.push(h('pre', {
|
|
159
193
|
key: elements.length,
|
|
160
194
|
style: {
|
|
161
|
-
background:
|
|
195
|
+
background: 'var(--terminal-bg)',
|
|
162
196
|
color: 'rgba(255, 255, 255, 0.85)',
|
|
163
197
|
fontFamily: fonts.mono,
|
|
164
198
|
fontSize: '13px',
|
|
@@ -190,12 +224,15 @@ export function renderMarkdown(text) {
|
|
|
190
224
|
if (paraLines.length > 0) {
|
|
191
225
|
elements.push(h('p', {
|
|
192
226
|
key: elements.length,
|
|
193
|
-
style: { margin: '0.5rem 0', fontSize: '15px', lineHeight: 1.6, color:
|
|
227
|
+
style: { margin: '0.5rem 0', fontSize: '15px', lineHeight: 1.6, color: 'var(--dark)' },
|
|
194
228
|
}, inlineMarkdown(paraLines.join(' '))));
|
|
229
|
+
} else {
|
|
230
|
+
// Safety: nothing consumed this line. Skip it to avoid an infinite loop.
|
|
231
|
+
i++;
|
|
195
232
|
}
|
|
196
233
|
}
|
|
197
234
|
|
|
198
|
-
return h('div',
|
|
235
|
+
return h('div', { style: { color: 'var(--dark)' } }, ...elements);
|
|
199
236
|
}
|
|
200
237
|
|
|
201
238
|
// Inline markdown: **bold**, *italic*, `code`, [link](url)
|
|
@@ -210,11 +247,11 @@ function inlineMarkdown(text) {
|
|
|
210
247
|
const patterns = [
|
|
211
248
|
{ re: /`([^`]+)`/, render: (m) => h('code', {
|
|
212
249
|
key: key++,
|
|
213
|
-
|
|
250
|
+
className: 'eg-code',
|
|
214
251
|
}, m[1]) },
|
|
215
252
|
{ re: /\*\*(.+?)\*\*/, render: (m) => h('strong', { key: key++, style: { fontWeight: 600 } }, m[1]) },
|
|
216
253
|
{ re: /\[([^\]]+)\]\(([^)]+)\)/, render: (m) => h('a', {
|
|
217
|
-
key: key++, href: m[2], style: { color:
|
|
254
|
+
key: key++, href: m[2], style: { color: 'var(--terracotta)', textDecoration: 'underline' },
|
|
218
255
|
}, m[1]) },
|
|
219
256
|
];
|
|
220
257
|
|
|
@@ -285,11 +322,11 @@ function renderTable(lines, key) {
|
|
|
285
322
|
style: {
|
|
286
323
|
textAlign: 'left',
|
|
287
324
|
padding: '8px 12px',
|
|
288
|
-
borderBottom:
|
|
325
|
+
borderBottom: '2px solid var(--border)',
|
|
289
326
|
fontFamily: fonts.mono,
|
|
290
327
|
fontSize: '12px',
|
|
291
328
|
fontWeight: 500,
|
|
292
|
-
color:
|
|
329
|
+
color: 'var(--muted)',
|
|
293
330
|
textTransform: 'uppercase',
|
|
294
331
|
letterSpacing: '0.04em',
|
|
295
332
|
whiteSpace: 'nowrap',
|
|
@@ -306,8 +343,8 @@ function renderTable(lines, key) {
|
|
|
306
343
|
key: j,
|
|
307
344
|
style: {
|
|
308
345
|
padding: '6px 12px',
|
|
309
|
-
borderBottom:
|
|
310
|
-
color:
|
|
346
|
+
borderBottom: '1px solid var(--border)',
|
|
347
|
+
color: 'var(--dark)',
|
|
311
348
|
},
|
|
312
349
|
}, cell.trim())
|
|
313
350
|
),
|
|
@@ -347,7 +384,7 @@ export function renderMarkdownLite(text) {
|
|
|
347
384
|
|
|
348
385
|
// H2/H3 heading
|
|
349
386
|
if (line.startsWith('## ')) {
|
|
350
|
-
elements.push(h('h3', { key: elements.length, style: { fontFamily: fonts.serif, fontSize: '18px', fontWeight: 600, margin: '1.5rem 0 0.5rem', color:
|
|
387
|
+
elements.push(h('h3', { key: elements.length, style: { fontFamily: fonts.serif, fontSize: '18px', fontWeight: 600, margin: '1.5rem 0 0.5rem', color: 'var(--black)' } }, line.slice(3)));
|
|
351
388
|
i++;
|
|
352
389
|
continue;
|
|
353
390
|
}
|
|
@@ -369,7 +406,7 @@ export function renderMarkdownLite(text) {
|
|
|
369
406
|
if (line.trim() === '') { i++; continue; }
|
|
370
407
|
|
|
371
408
|
// Paragraph
|
|
372
|
-
elements.push(h('p', { key: elements.length, style: { margin: '0.5rem 0', fontSize: '14px', lineHeight: 1.6, color:
|
|
409
|
+
elements.push(h('p', { key: elements.length, style: { margin: '0.5rem 0', fontSize: '14px', lineHeight: 1.6, color: 'var(--dark)' } }, line));
|
|
373
410
|
i++;
|
|
374
411
|
}
|
|
375
412
|
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Parse board data (JSON from memory/board/board.json) into structured data
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { execSync } from 'node:child_process';
|
|
4
|
+
|
|
5
|
+
export function parseBoard(input) {
|
|
6
|
+
let data;
|
|
7
|
+
|
|
8
|
+
if (typeof input === 'string' && fs.existsSync(input)) {
|
|
9
|
+
data = JSON.parse(fs.readFileSync(input, 'utf-8'));
|
|
10
|
+
} else if (typeof input === 'string' && input.startsWith('{')) {
|
|
11
|
+
data = JSON.parse(input);
|
|
12
|
+
} else if (typeof input === 'object') {
|
|
13
|
+
data = input;
|
|
14
|
+
} else {
|
|
15
|
+
// Try to find board.json relative to git root
|
|
16
|
+
try {
|
|
17
|
+
const root = execSync('git rev-parse --show-toplevel 2>/dev/null', { encoding: 'utf-8' }).trim();
|
|
18
|
+
const boardPath = `${root}/memory/board/board.json`;
|
|
19
|
+
if (fs.existsSync(boardPath)) {
|
|
20
|
+
data = JSON.parse(fs.readFileSync(boardPath, 'utf-8'));
|
|
21
|
+
}
|
|
22
|
+
} catch {}
|
|
23
|
+
if (!data) throw new Error('No board data found. Expected memory/board/board.json');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const today = new Date().toISOString().split('T')[0];
|
|
27
|
+
|
|
28
|
+
// Flatten all cards from the hierarchy for person and timeline views
|
|
29
|
+
const allCards = [];
|
|
30
|
+
for (const activity of data.activities || []) {
|
|
31
|
+
if (activity.subactivities) {
|
|
32
|
+
for (const sub of activity.subactivities) {
|
|
33
|
+
for (const card of sub.cards || []) {
|
|
34
|
+
allCards.push({ ...card, activity: activity.label, subactivity: sub.label, activityId: activity.id, subactivityId: sub.id });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
for (const card of activity.cards || []) {
|
|
39
|
+
allCards.push({ ...card, activity: activity.label, subactivity: null, activityId: activity.id, subactivityId: null });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Group by person
|
|
44
|
+
const personMap = {};
|
|
45
|
+
for (const card of allCards) {
|
|
46
|
+
for (const owner of card.owners || []) {
|
|
47
|
+
if (!personMap[owner]) personMap[owner] = [];
|
|
48
|
+
personMap[owner].push(card);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const people = Object.entries(personMap)
|
|
52
|
+
.map(([name, cards]) => ({
|
|
53
|
+
name,
|
|
54
|
+
cards: cards.sort((a, b) => a.priority - b.priority),
|
|
55
|
+
stats: {
|
|
56
|
+
total: cards.length,
|
|
57
|
+
p0: cards.filter(c => c.priority === 0).length,
|
|
58
|
+
p1: cards.filter(c => c.priority === 1).length,
|
|
59
|
+
p2: cards.filter(c => c.priority === 2).length,
|
|
60
|
+
p3: cards.filter(c => c.priority === 3).length,
|
|
61
|
+
inProgress: cards.filter(c => c.status === 'in-progress').length,
|
|
62
|
+
todo: cards.filter(c => c.status === 'todo').length,
|
|
63
|
+
review: cards.filter(c => c.status === 'review').length,
|
|
64
|
+
done: cards.filter(c => c.status === 'done').length,
|
|
65
|
+
},
|
|
66
|
+
}))
|
|
67
|
+
.sort((a, b) => b.stats.p0 - a.stats.p0 || b.stats.total - a.stats.total);
|
|
68
|
+
|
|
69
|
+
// Timeline: cards with dates, sorted by startDate
|
|
70
|
+
const timeline = allCards
|
|
71
|
+
.filter(c => c.startDate || c.dueDate)
|
|
72
|
+
.sort((a, b) => (a.startDate || a.dueDate || '').localeCompare(b.startDate || b.dueDate || ''));
|
|
73
|
+
|
|
74
|
+
// Summary stats
|
|
75
|
+
const summary = {
|
|
76
|
+
totalCards: allCards.length,
|
|
77
|
+
byPriority: { P0: 0, P1: 0, P2: 0, P3: 0 },
|
|
78
|
+
byStatus: { todo: 0, 'in-progress': 0, review: 0, done: 0 },
|
|
79
|
+
};
|
|
80
|
+
for (const card of allCards) {
|
|
81
|
+
const pKey = `P${card.priority}`;
|
|
82
|
+
if (summary.byPriority[pKey] !== undefined) summary.byPriority[pKey]++;
|
|
83
|
+
if (summary.byStatus[card.status] !== undefined) summary.byStatus[card.status]++;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Read org name
|
|
87
|
+
let org = 'Egregore';
|
|
88
|
+
try {
|
|
89
|
+
const root = execSync('git rev-parse --show-toplevel 2>/dev/null', { encoding: 'utf-8' }).trim();
|
|
90
|
+
const configPath = `${root}/egregore.json`;
|
|
91
|
+
if (fs.existsSync(configPath)) {
|
|
92
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
93
|
+
org = config.org_name || org;
|
|
94
|
+
}
|
|
95
|
+
} catch {}
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
title: `Project Board — ${org}`,
|
|
99
|
+
date: today,
|
|
100
|
+
org,
|
|
101
|
+
updatedBy: data.updatedBy,
|
|
102
|
+
updatedAt: data.updated,
|
|
103
|
+
activities: data.activities,
|
|
104
|
+
allCards,
|
|
105
|
+
people,
|
|
106
|
+
timeline,
|
|
107
|
+
summary,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Parse network/people data (JSON from memory/network/people.json)
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { execSync } from 'node:child_process';
|
|
4
|
+
|
|
5
|
+
export function parseNetwork(input) {
|
|
6
|
+
let data;
|
|
7
|
+
|
|
8
|
+
if (typeof input === 'string' && fs.existsSync(input)) {
|
|
9
|
+
data = JSON.parse(fs.readFileSync(input, 'utf-8'));
|
|
10
|
+
} else if (typeof input === 'string' && input.startsWith('{')) {
|
|
11
|
+
data = JSON.parse(input);
|
|
12
|
+
} else if (typeof input === 'object') {
|
|
13
|
+
data = input;
|
|
14
|
+
} else {
|
|
15
|
+
try {
|
|
16
|
+
const root = execSync('git rev-parse --show-toplevel 2>/dev/null', { encoding: 'utf-8' }).trim();
|
|
17
|
+
const peoplePath = `${root}/memory/network/people.json`;
|
|
18
|
+
if (fs.existsSync(peoplePath)) {
|
|
19
|
+
data = JSON.parse(fs.readFileSync(peoplePath, 'utf-8'));
|
|
20
|
+
}
|
|
21
|
+
} catch {}
|
|
22
|
+
if (!data) throw new Error('No network data found. Expected memory/network/people.json');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const people = data.people || [];
|
|
26
|
+
|
|
27
|
+
// Collect all unique roles
|
|
28
|
+
const allRoles = [...new Set(people.flatMap(p => p.roles || []))].sort();
|
|
29
|
+
|
|
30
|
+
// Group by role
|
|
31
|
+
const byRole = {};
|
|
32
|
+
for (const role of allRoles) {
|
|
33
|
+
byRole[role] = people.filter(p => (p.roles || []).includes(role));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Group by organization
|
|
37
|
+
const byOrg = {};
|
|
38
|
+
for (const person of people) {
|
|
39
|
+
const org = person.organization || 'Independent';
|
|
40
|
+
if (!byOrg[org]) byOrg[org] = [];
|
|
41
|
+
byOrg[org].push(person);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Summary
|
|
45
|
+
const summary = {
|
|
46
|
+
totalPeople: people.length,
|
|
47
|
+
totalOrgs: Object.keys(byOrg).length,
|
|
48
|
+
byRole: Object.fromEntries(allRoles.map(r => [r, byRole[r].length])),
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Read org name
|
|
52
|
+
let org = 'Egregore';
|
|
53
|
+
try {
|
|
54
|
+
const root = execSync('git rev-parse --show-toplevel 2>/dev/null', { encoding: 'utf-8' }).trim();
|
|
55
|
+
const configPath = `${root}/egregore.json`;
|
|
56
|
+
if (fs.existsSync(configPath)) {
|
|
57
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
58
|
+
org = config.org_name || org;
|
|
59
|
+
}
|
|
60
|
+
} catch {}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
title: `Network — ${org}`,
|
|
64
|
+
date: new Date().toISOString().split('T')[0],
|
|
65
|
+
org,
|
|
66
|
+
updatedBy: data.updatedBy,
|
|
67
|
+
people,
|
|
68
|
+
allRoles,
|
|
69
|
+
byRole,
|
|
70
|
+
byOrg,
|
|
71
|
+
summary,
|
|
72
|
+
};
|
|
73
|
+
}
|
package/lib/registry.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { defineRegistry } from '@json-render/react';
|
|
4
4
|
import { catalog } from './catalog.js';
|
|
5
|
-
import {
|
|
5
|
+
import { fonts } from './tokens.js';
|
|
6
6
|
import { renderMarkdown } from './markdown.js';
|
|
7
7
|
|
|
8
8
|
const h = React.createElement;
|
|
@@ -70,12 +70,12 @@ export const { registry, handlers, executeAction } = defineRegistry(catalog, {
|
|
|
70
70
|
h('div', {
|
|
71
71
|
key: i,
|
|
72
72
|
style: {
|
|
73
|
-
background: '
|
|
73
|
+
background: 'var(--surface)', border: '1px solid var(--border)',
|
|
74
74
|
borderRadius: '12px', padding: '1.25rem', textAlign: 'center',
|
|
75
75
|
},
|
|
76
76
|
},
|
|
77
|
-
h('div', { style: { fontSize: '28px', fontFamily: fonts.serif, fontWeight: 400, color:
|
|
78
|
-
h('div', { style: { fontSize: '12px', fontFamily: fonts.mono, color:
|
|
77
|
+
h('div', { style: { fontSize: '28px', fontFamily: fonts.serif, fontWeight: 400, color: 'var(--black)', lineHeight: 1.2 } }, m.value),
|
|
78
|
+
h('div', { style: { fontSize: '12px', fontFamily: fonts.mono, color: 'var(--muted)', marginTop: '4px', textTransform: 'uppercase', letterSpacing: '0.04em' } }, m.label),
|
|
79
79
|
)
|
|
80
80
|
),
|
|
81
81
|
),
|
|
@@ -97,7 +97,7 @@ export const { registry, handlers, executeAction } = defineRegistry(catalog, {
|
|
|
97
97
|
h('span', { className: 'eg-artifact-date' }, a.date),
|
|
98
98
|
h('span', { className: 'eg-artifact-type' }, a.type),
|
|
99
99
|
h('span', { className: 'eg-artifact-title' }, a.title),
|
|
100
|
-
a.author && h('span', { style: { color:
|
|
100
|
+
a.author && h('span', { style: { color: 'var(--muted)', fontSize: '13px', fontFamily: fonts.mono } }, `(${a.author})`),
|
|
101
101
|
)
|
|
102
102
|
),
|
|
103
103
|
),
|
|
@@ -108,7 +108,7 @@ export const { registry, handlers, executeAction } = defineRegistry(catalog, {
|
|
|
108
108
|
h('div', { key: i, className: 'eg-contributor' },
|
|
109
109
|
h('span', { className: 'eg-contributor-avatar' }, (p.name || '?')[0].toUpperCase()),
|
|
110
110
|
h('span', null, p.name),
|
|
111
|
-
p.role && h('span', { style: { color:
|
|
111
|
+
p.role && h('span', { style: { color: 'var(--muted)', fontSize: '12px' } }, p.role),
|
|
112
112
|
)
|
|
113
113
|
),
|
|
114
114
|
),
|
|
@@ -121,8 +121,8 @@ export const { registry, handlers, executeAction } = defineRegistry(catalog, {
|
|
|
121
121
|
NumberedSteps: ({ props }) =>
|
|
122
122
|
h('ol', { style: { listStyle: 'none', padding: 0 } },
|
|
123
123
|
...props.steps.map((step, i) =>
|
|
124
|
-
h('li', { key: i, style: { display: 'flex', gap: '12px', padding: '8px 0', borderBottom: i < props.steps.length - 1 ? '1px solid
|
|
125
|
-
h('span', { style: { flexShrink: 0, width: '24px', height: '24px', borderRadius: '50%', background:
|
|
124
|
+
h('li', { key: i, style: { display: 'flex', gap: '12px', padding: '8px 0', borderBottom: i < props.steps.length - 1 ? '1px solid var(--hairline)' : 'none', fontSize: '15px', lineHeight: 1.5 } },
|
|
125
|
+
h('span', { style: { flexShrink: 0, width: '24px', height: '24px', borderRadius: '50%', background: 'var(--terracotta)', color: 'var(--cream)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '12px', fontFamily: fonts.mono, fontWeight: 600 } }, String(i + 1)),
|
|
126
126
|
h('span', null, step),
|
|
127
127
|
)
|
|
128
128
|
),
|
|
@@ -131,11 +131,11 @@ export const { registry, handlers, executeAction } = defineRegistry(catalog, {
|
|
|
131
131
|
SessionList: ({ props }) =>
|
|
132
132
|
h('div', null,
|
|
133
133
|
...props.sessions.map((s, i) =>
|
|
134
|
-
h('div', { key: i, style: { display: 'flex', alignItems: 'baseline', gap: '12px', padding: '6px 0', borderBottom: '1px solid
|
|
135
|
-
h('span', { style: { fontFamily: fonts.mono, fontSize: '12px', color:
|
|
136
|
-
s.by && h('span', { style: { fontFamily: fonts.mono, fontSize: '11px', color:
|
|
137
|
-
h('span', { style: { color:
|
|
138
|
-
s.handedTo && h('span', { style: { fontFamily: fonts.mono, fontSize: '11px', color:
|
|
134
|
+
h('div', { key: i, style: { display: 'flex', alignItems: 'baseline', gap: '12px', padding: '6px 0', borderBottom: '1px solid var(--hairline)', fontSize: '14px' } },
|
|
135
|
+
h('span', { style: { fontFamily: fonts.mono, fontSize: '12px', color: 'var(--muted)', minWidth: '72px', flexShrink: 0 } }, s.date),
|
|
136
|
+
s.by && h('span', { style: { fontFamily: fonts.mono, fontSize: '11px', color: 'var(--blue-muted)', background: 'var(--blue-chip)', padding: '1px 6px', borderRadius: '3px', flexShrink: 0 } }, s.by),
|
|
137
|
+
h('span', { style: { color: 'var(--black)', flex: 1 } }, s.topic),
|
|
138
|
+
s.handedTo && h('span', { style: { fontFamily: fonts.mono, fontSize: '11px', color: 'var(--terracotta)' } }, `→ ${s.handedTo}`),
|
|
139
139
|
)
|
|
140
140
|
),
|
|
141
141
|
),
|
|
@@ -146,9 +146,9 @@ export const { registry, handlers, executeAction } = defineRegistry(catalog, {
|
|
|
146
146
|
Callout: ({ props }) =>
|
|
147
147
|
h('div', {
|
|
148
148
|
style: {
|
|
149
|
-
background: '
|
|
149
|
+
background: 'var(--terracotta-soft)', border: '1px solid var(--terracotta-hair)',
|
|
150
150
|
borderRadius: '12px', padding: '1.25rem 1.5rem', marginBottom: '1.5rem',
|
|
151
|
-
fontSize: '15px', lineHeight: 1.6, color:
|
|
151
|
+
fontSize: '15px', lineHeight: 1.6, color: 'var(--dark)',
|
|
152
152
|
},
|
|
153
153
|
}, renderMarkdown(props.text)),
|
|
154
154
|
|