@datasynx/agentic-ai-cartography 0.8.1 → 0.9.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/dist/{chunk-VZO6XBKX.js → chunk-WJR63RWY.js} +1 -19
- package/dist/chunk-WJR63RWY.js.map +1 -0
- package/dist/cli.js +17 -168
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -46
- package/dist/index.js +4 -354
- package/dist/index.js.map +1 -1
- package/dist/{types-RHMJ6EGX.js → types-54623ALF.js} +2 -6
- package/package.json +1 -1
- package/dist/chunk-VZO6XBKX.js.map +0 -1
- /package/dist/{types-RHMJ6EGX.js.map → types-54623ALF.js.map} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -50,30 +50,6 @@ declare const EdgeSchema: z.ZodObject<{
|
|
|
50
50
|
confidence: z.ZodDefault<z.ZodNumber>;
|
|
51
51
|
}, z.core.$strip>;
|
|
52
52
|
type DiscoveryEdge = z.infer<typeof EdgeSchema>;
|
|
53
|
-
declare const SOPStepSchema: z.ZodObject<{
|
|
54
|
-
order: z.ZodNumber;
|
|
55
|
-
instruction: z.ZodString;
|
|
56
|
-
tool: z.ZodString;
|
|
57
|
-
target: z.ZodOptional<z.ZodString>;
|
|
58
|
-
notes: z.ZodOptional<z.ZodString>;
|
|
59
|
-
}, z.core.$strip>;
|
|
60
|
-
type SOPStep = z.infer<typeof SOPStepSchema>;
|
|
61
|
-
declare const SOPSchema: z.ZodObject<{
|
|
62
|
-
title: z.ZodString;
|
|
63
|
-
description: z.ZodString;
|
|
64
|
-
steps: z.ZodArray<z.ZodObject<{
|
|
65
|
-
order: z.ZodNumber;
|
|
66
|
-
instruction: z.ZodString;
|
|
67
|
-
tool: z.ZodString;
|
|
68
|
-
target: z.ZodOptional<z.ZodString>;
|
|
69
|
-
notes: z.ZodOptional<z.ZodString>;
|
|
70
|
-
}, z.core.$strip>>;
|
|
71
|
-
involvedSystems: z.ZodArray<z.ZodString>;
|
|
72
|
-
estimatedDuration: z.ZodString;
|
|
73
|
-
frequency: z.ZodString;
|
|
74
|
-
confidence: z.ZodNumber;
|
|
75
|
-
}, z.core.$strip>;
|
|
76
|
-
type SOP = z.infer<typeof SOPSchema>;
|
|
77
53
|
declare const DataAssetSchema: z.ZodObject<{
|
|
78
54
|
id: z.ZodString;
|
|
79
55
|
name: z.ZodString;
|
|
@@ -176,7 +152,6 @@ interface TaskRow {
|
|
|
176
152
|
steps: string;
|
|
177
153
|
involvedServices: string;
|
|
178
154
|
status: 'active' | 'completed' | 'cancelled';
|
|
179
|
-
isSOPCandidate: boolean;
|
|
180
155
|
}
|
|
181
156
|
interface WorkflowRow {
|
|
182
157
|
id: string;
|
|
@@ -217,19 +192,6 @@ declare class CartographyDB {
|
|
|
217
192
|
private mapTask;
|
|
218
193
|
insertWorkflow(sessionId: string, data: Omit<WorkflowRow, 'id'>): void;
|
|
219
194
|
getWorkflows(sessionId: string): WorkflowRow[];
|
|
220
|
-
insertSOP(sop: {
|
|
221
|
-
workflowId: string;
|
|
222
|
-
} & SOP): void;
|
|
223
|
-
getSOPs(sessionId: string): Array<SOP & {
|
|
224
|
-
id: string;
|
|
225
|
-
workflowId: string;
|
|
226
|
-
}>;
|
|
227
|
-
markTaskAsSOPCandidate(taskId: string): void;
|
|
228
|
-
getAllSOPs(): Array<SOP & {
|
|
229
|
-
id: string;
|
|
230
|
-
workflowId: string;
|
|
231
|
-
generatedAt: string;
|
|
232
|
-
}>;
|
|
233
195
|
upsertConnection(sessionId: string, conn: Omit<Connection, 'id'>): string;
|
|
234
196
|
getConnections(sessionId: string): ConnectionRow[];
|
|
235
197
|
deleteConnection(sessionId: string, connectionId: string): void;
|
|
@@ -275,15 +237,8 @@ declare function runDiscovery(config: CartographyConfig, db: CartographyDB, sess
|
|
|
275
237
|
|
|
276
238
|
declare function generateTopologyMermaid(nodes: NodeRow[], edges: EdgeRow[]): string;
|
|
277
239
|
declare function generateDependencyMermaid(nodes: NodeRow[], edges: EdgeRow[]): string;
|
|
278
|
-
declare function generateWorkflowMermaid(sop: SOP): string;
|
|
279
240
|
declare function exportBackstageYAML(nodes: NodeRow[], edges: EdgeRow[], org?: string): string;
|
|
280
241
|
declare function exportJSON(db: CartographyDB, sessionId: string): string;
|
|
281
|
-
declare function exportSOPMarkdown(sop: SOP): string;
|
|
282
|
-
declare function exportSOPDashboard(sops: Array<SOP & {
|
|
283
|
-
id: string;
|
|
284
|
-
workflowId: string;
|
|
285
|
-
generatedAt?: string;
|
|
286
|
-
}>): string;
|
|
287
242
|
declare function exportDiscoveryApp(nodes: NodeRow[], edges: EdgeRow[], options?: {
|
|
288
243
|
theme?: 'light' | 'dark';
|
|
289
244
|
}): string;
|
|
@@ -385,4 +340,4 @@ declare function buildMapData(nodes: NodeRow[], edges: EdgeRow[], options?: {
|
|
|
385
340
|
|
|
386
341
|
declare function checkPrerequisites(): void;
|
|
387
342
|
|
|
388
|
-
export { type CartographyConfig, CartographyDB, type CartographyMapData, type Cluster, ClusterSchema, type Connection, ConnectionSchema, DOMAIN_COLORS, DOMAIN_PALETTE, type DataAsset, DataAssetSchema, type DiscoveryEdge, type DiscoveryEvent, type DiscoveryNode, EDGE_RELATIONSHIPS, type EdgeRelationship, type EdgeRow, EdgeSchema, NODE_TYPES, type NodeRow, NodeSchema, type NodeType, type
|
|
343
|
+
export { type CartographyConfig, CartographyDB, type CartographyMapData, type Cluster, ClusterSchema, type Connection, ConnectionSchema, DOMAIN_COLORS, DOMAIN_PALETTE, type DataAsset, DataAssetSchema, type DiscoveryEdge, type DiscoveryEvent, type DiscoveryNode, EDGE_RELATIONSHIPS, type EdgeRelationship, type EdgeRow, EdgeSchema, NODE_TYPES, type NodeRow, NodeSchema, type NodeType, type SessionRow, assignColors, buildMapData, checkPrerequisites, computeCentroid, computeClusterBounds, createCartographyTools, CartographyDB as default, defaultConfig, edgesToConnections, exportAll, exportBackstageYAML, exportDiscoveryApp, exportJGF, exportJSON, generateDependencyMermaid, generateTopologyMermaid, groupByDomain, hexCorners, hexDistance, hexNeighbors, hexRing, hexSpiral, hexToPixel, layoutClusters, nodesToAssets, pixelToHex, runDiscovery, safetyHook, shadeVariant, stripSensitive };
|
package/dist/index.js
CHANGED
|
@@ -75,8 +75,7 @@ CREATE TABLE IF NOT EXISTS tasks (
|
|
|
75
75
|
completed_at TEXT,
|
|
76
76
|
steps TEXT NOT NULL DEFAULT '[]',
|
|
77
77
|
involved_services TEXT NOT NULL DEFAULT '[]',
|
|
78
|
-
status TEXT DEFAULT 'active' CHECK (status IN ('active','completed','cancelled'))
|
|
79
|
-
is_sop_candidate INTEGER DEFAULT 0
|
|
78
|
+
status TEXT DEFAULT 'active' CHECK (status IN ('active','completed','cancelled'))
|
|
80
79
|
);
|
|
81
80
|
|
|
82
81
|
CREATE TABLE IF NOT EXISTS workflows (
|
|
@@ -92,19 +91,6 @@ CREATE TABLE IF NOT EXISTS workflows (
|
|
|
92
91
|
involved_services TEXT NOT NULL DEFAULT '[]'
|
|
93
92
|
);
|
|
94
93
|
|
|
95
|
-
CREATE TABLE IF NOT EXISTS sops (
|
|
96
|
-
id TEXT PRIMARY KEY,
|
|
97
|
-
workflow_id TEXT NOT NULL,
|
|
98
|
-
title TEXT NOT NULL,
|
|
99
|
-
description TEXT NOT NULL,
|
|
100
|
-
steps TEXT NOT NULL,
|
|
101
|
-
involved_systems TEXT NOT NULL DEFAULT '[]',
|
|
102
|
-
estimated_duration TEXT,
|
|
103
|
-
frequency TEXT,
|
|
104
|
-
generated_at TEXT NOT NULL,
|
|
105
|
-
confidence REAL DEFAULT 0.5
|
|
106
|
-
);
|
|
107
|
-
|
|
108
94
|
CREATE TABLE IF NOT EXISTS node_approvals (
|
|
109
95
|
pattern TEXT PRIMARY KEY,
|
|
110
96
|
action TEXT NOT NULL CHECK (action IN ('save','ignore','auto')),
|
|
@@ -346,8 +332,7 @@ var CartographyDB = class {
|
|
|
346
332
|
completedAt: r["completed_at"],
|
|
347
333
|
steps: r["steps"],
|
|
348
334
|
involvedServices: r["involved_services"],
|
|
349
|
-
status: r["status"]
|
|
350
|
-
isSOPCandidate: Boolean(r["is_sop_candidate"])
|
|
335
|
+
status: r["status"]
|
|
351
336
|
};
|
|
352
337
|
}
|
|
353
338
|
// ── Workflows ───────────────────────────
|
|
@@ -386,63 +371,6 @@ var CartographyDB = class {
|
|
|
386
371
|
involvedServices: r["involved_services"]
|
|
387
372
|
}));
|
|
388
373
|
}
|
|
389
|
-
// ── SOPs ────────────────────────────────
|
|
390
|
-
insertSOP(sop) {
|
|
391
|
-
const id = crypto.randomUUID();
|
|
392
|
-
this.db.prepare(`
|
|
393
|
-
INSERT INTO sops
|
|
394
|
-
(id, workflow_id, title, description, steps, involved_systems,
|
|
395
|
-
estimated_duration, frequency, generated_at, confidence)
|
|
396
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
397
|
-
`).run(
|
|
398
|
-
id,
|
|
399
|
-
sop.workflowId,
|
|
400
|
-
sop.title,
|
|
401
|
-
sop.description,
|
|
402
|
-
JSON.stringify(sop.steps),
|
|
403
|
-
JSON.stringify(sop.involvedSystems),
|
|
404
|
-
sop.estimatedDuration,
|
|
405
|
-
sop.frequency,
|
|
406
|
-
(/* @__PURE__ */ new Date()).toISOString(),
|
|
407
|
-
sop.confidence
|
|
408
|
-
);
|
|
409
|
-
}
|
|
410
|
-
getSOPs(sessionId) {
|
|
411
|
-
const rows = this.db.prepare(`
|
|
412
|
-
SELECT s.* FROM sops s
|
|
413
|
-
JOIN workflows w ON s.workflow_id = w.id
|
|
414
|
-
WHERE w.session_id = ?
|
|
415
|
-
`).all(sessionId);
|
|
416
|
-
return rows.map((r) => ({
|
|
417
|
-
id: r["id"],
|
|
418
|
-
workflowId: r["workflow_id"],
|
|
419
|
-
title: r["title"],
|
|
420
|
-
description: r["description"],
|
|
421
|
-
steps: JSON.parse(r["steps"]),
|
|
422
|
-
involvedSystems: JSON.parse(r["involved_systems"]),
|
|
423
|
-
estimatedDuration: r["estimated_duration"],
|
|
424
|
-
frequency: r["frequency"],
|
|
425
|
-
confidence: r["confidence"]
|
|
426
|
-
}));
|
|
427
|
-
}
|
|
428
|
-
markTaskAsSOPCandidate(taskId) {
|
|
429
|
-
this.db.prepare("UPDATE tasks SET is_sop_candidate = 1 WHERE id = ?").run(taskId);
|
|
430
|
-
}
|
|
431
|
-
getAllSOPs() {
|
|
432
|
-
const rows = this.db.prepare("SELECT * FROM sops ORDER BY generated_at DESC").all();
|
|
433
|
-
return rows.map((r) => ({
|
|
434
|
-
id: r["id"],
|
|
435
|
-
workflowId: r["workflow_id"],
|
|
436
|
-
title: r["title"],
|
|
437
|
-
description: r["description"],
|
|
438
|
-
steps: JSON.parse(r["steps"]),
|
|
439
|
-
involvedSystems: JSON.parse(r["involved_systems"]),
|
|
440
|
-
estimatedDuration: r["estimated_duration"],
|
|
441
|
-
frequency: r["frequency"],
|
|
442
|
-
confidence: r["confidence"],
|
|
443
|
-
generatedAt: r["generated_at"]
|
|
444
|
-
}));
|
|
445
|
-
}
|
|
446
374
|
// ── Connections (user-created hex map links) ─────────────────────────────
|
|
447
375
|
upsertConnection(sessionId, conn) {
|
|
448
376
|
const existing = this.db.prepare(
|
|
@@ -540,22 +468,6 @@ var EdgeSchema = z.object({
|
|
|
540
468
|
evidence: z.string(),
|
|
541
469
|
confidence: z.number().min(0).max(1).default(0.5)
|
|
542
470
|
});
|
|
543
|
-
var SOPStepSchema = z.object({
|
|
544
|
-
order: z.number(),
|
|
545
|
-
instruction: z.string(),
|
|
546
|
-
tool: z.string(),
|
|
547
|
-
target: z.string().optional(),
|
|
548
|
-
notes: z.string().optional()
|
|
549
|
-
});
|
|
550
|
-
var SOPSchema = z.object({
|
|
551
|
-
title: z.string(),
|
|
552
|
-
description: z.string(),
|
|
553
|
-
steps: z.array(SOPStepSchema),
|
|
554
|
-
involvedSystems: z.array(z.string()),
|
|
555
|
-
estimatedDuration: z.string(),
|
|
556
|
-
frequency: z.string(),
|
|
557
|
-
confidence: z.number().min(0).max(1)
|
|
558
|
-
});
|
|
559
471
|
var DataAssetSchema = z.object({
|
|
560
472
|
id: z.string(),
|
|
561
473
|
name: z.string(),
|
|
@@ -1497,28 +1409,6 @@ ${runAz(c)}`).join("\n\n");
|
|
|
1497
1409
|
const out = Object.entries(results).map(([k, v]) => `=== ${k} ===
|
|
1498
1410
|
${v}`).join("\n\n");
|
|
1499
1411
|
return { content: [{ type: "text", text: out }] };
|
|
1500
|
-
}),
|
|
1501
|
-
tool("save_sop", "Save a Standard Operating Procedure", {
|
|
1502
|
-
workflowId: z2.string(),
|
|
1503
|
-
title: z2.string(),
|
|
1504
|
-
description: z2.string(),
|
|
1505
|
-
steps: z2.array(SOPStepSchema),
|
|
1506
|
-
involvedSystems: z2.array(z2.string()),
|
|
1507
|
-
estimatedDuration: z2.string(),
|
|
1508
|
-
frequency: z2.string(),
|
|
1509
|
-
confidence: z2.number().min(0).max(1)
|
|
1510
|
-
}, async (args) => {
|
|
1511
|
-
db.insertSOP({
|
|
1512
|
-
workflowId: args["workflowId"],
|
|
1513
|
-
title: args["title"],
|
|
1514
|
-
description: args["description"],
|
|
1515
|
-
steps: args["steps"],
|
|
1516
|
-
involvedSystems: args["involvedSystems"],
|
|
1517
|
-
estimatedDuration: args["estimatedDuration"],
|
|
1518
|
-
frequency: args["frequency"],
|
|
1519
|
-
confidence: args["confidence"]
|
|
1520
|
-
});
|
|
1521
|
-
return { content: [{ type: "text", text: `\u2713 SOP: ${args["title"]}` }] };
|
|
1522
1412
|
})
|
|
1523
1413
|
];
|
|
1524
1414
|
return createSdkMcpServer({
|
|
@@ -2151,18 +2041,6 @@ function generateDependencyMermaid(nodes, edges) {
|
|
|
2151
2041
|
}
|
|
2152
2042
|
return lines.join("\n");
|
|
2153
2043
|
}
|
|
2154
|
-
function generateWorkflowMermaid(sop) {
|
|
2155
|
-
const lines = ["flowchart TD"];
|
|
2156
|
-
for (const step of sop.steps) {
|
|
2157
|
-
const nodeId = `S${step.order}`;
|
|
2158
|
-
const label = `${step.order}. ${step.instruction.substring(0, 60)}`;
|
|
2159
|
-
lines.push(` ${nodeId}["${label}"]`);
|
|
2160
|
-
if (step.order > 1) {
|
|
2161
|
-
lines.push(` S${step.order - 1} --> ${nodeId}`);
|
|
2162
|
-
}
|
|
2163
|
-
}
|
|
2164
|
-
return lines.join("\n");
|
|
2165
|
-
}
|
|
2166
2044
|
function exportBackstageYAML(nodes, edges, org) {
|
|
2167
2045
|
const owner = org ?? "unknown";
|
|
2168
2046
|
const docs = [];
|
|
@@ -2194,7 +2072,6 @@ function exportJSON(db, sessionId) {
|
|
|
2194
2072
|
const edges = db.getEdges(sessionId);
|
|
2195
2073
|
const events = db.getEvents(sessionId);
|
|
2196
2074
|
const tasks = db.getTasks(sessionId);
|
|
2197
|
-
const sops = db.getSOPs(sessionId);
|
|
2198
2075
|
const stats = db.getStats(sessionId);
|
|
2199
2076
|
return JSON.stringify({
|
|
2200
2077
|
sessionId,
|
|
@@ -2203,222 +2080,9 @@ function exportJSON(db, sessionId) {
|
|
|
2203
2080
|
nodes,
|
|
2204
2081
|
edges,
|
|
2205
2082
|
events,
|
|
2206
|
-
tasks
|
|
2207
|
-
sops
|
|
2083
|
+
tasks
|
|
2208
2084
|
}, null, 2);
|
|
2209
2085
|
}
|
|
2210
|
-
function exportSOPMarkdown(sop) {
|
|
2211
|
-
const lines = [
|
|
2212
|
-
`# ${sop.title}`,
|
|
2213
|
-
"",
|
|
2214
|
-
`**Description:** ${sop.description}`,
|
|
2215
|
-
`**Systems:** ${sop.involvedSystems.join(", ")}`,
|
|
2216
|
-
`**Duration:** ${sop.estimatedDuration}`,
|
|
2217
|
-
`**Frequency:** ${sop.frequency}`,
|
|
2218
|
-
`**Confidence:** ${sop.confidence.toFixed(2)}`,
|
|
2219
|
-
"",
|
|
2220
|
-
"## Steps",
|
|
2221
|
-
""
|
|
2222
|
-
];
|
|
2223
|
-
for (const step of sop.steps) {
|
|
2224
|
-
lines.push(`${step.order}. **${step.tool}**${step.target ? ` \u2192 \`${step.target}\`` : ""}`);
|
|
2225
|
-
lines.push(` ${step.instruction}`);
|
|
2226
|
-
if (step.notes) lines.push(` _${step.notes}_`);
|
|
2227
|
-
lines.push("");
|
|
2228
|
-
}
|
|
2229
|
-
return lines.join("\n");
|
|
2230
|
-
}
|
|
2231
|
-
function exportSOPDashboard(sops) {
|
|
2232
|
-
const sopsJson = JSON.stringify(sops.map((s) => ({
|
|
2233
|
-
id: s.id,
|
|
2234
|
-
title: s.title,
|
|
2235
|
-
description: s.description,
|
|
2236
|
-
steps: s.steps,
|
|
2237
|
-
systems: s.involvedSystems,
|
|
2238
|
-
duration: s.estimatedDuration,
|
|
2239
|
-
frequency: s.frequency,
|
|
2240
|
-
confidence: s.confidence,
|
|
2241
|
-
generatedAt: s.generatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
2242
|
-
})));
|
|
2243
|
-
const systemCount = {};
|
|
2244
|
-
for (const sop of sops) {
|
|
2245
|
-
for (const sys of sop.involvedSystems) {
|
|
2246
|
-
systemCount[sys] = (systemCount[sys] ?? 0) + 1;
|
|
2247
|
-
}
|
|
2248
|
-
}
|
|
2249
|
-
const systemsJson = JSON.stringify(
|
|
2250
|
-
Object.entries(systemCount).sort((a, b) => b[1] - a[1])
|
|
2251
|
-
);
|
|
2252
|
-
return `<!DOCTYPE html>
|
|
2253
|
-
<html lang="en">
|
|
2254
|
-
<head>
|
|
2255
|
-
<meta charset="UTF-8">
|
|
2256
|
-
<title>Cartography \u2014 SOP Dashboard</title>
|
|
2257
|
-
<style>
|
|
2258
|
-
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
2259
|
-
body {
|
|
2260
|
-
background: #0d1117; color: #e6edf3;
|
|
2261
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, monospace;
|
|
2262
|
-
padding: 0; line-height: 1.6;
|
|
2263
|
-
}
|
|
2264
|
-
.header {
|
|
2265
|
-
background: linear-gradient(135deg, #161b22 0%, #1a1f2e 100%);
|
|
2266
|
-
border-bottom: 1px solid #30363d; padding: 32px 40px;
|
|
2267
|
-
}
|
|
2268
|
-
.header h1 { font-size: 24px; color: #58a6ff; margin-bottom: 8px; }
|
|
2269
|
-
.header .subtitle { color: #8b949e; font-size: 14px; }
|
|
2270
|
-
.stats-row {
|
|
2271
|
-
display: flex; gap: 24px; margin-top: 16px; flex-wrap: wrap;
|
|
2272
|
-
}
|
|
2273
|
-
.stat-card {
|
|
2274
|
-
background: #21262d; border: 1px solid #30363d; border-radius: 8px;
|
|
2275
|
-
padding: 12px 20px; min-width: 140px;
|
|
2276
|
-
}
|
|
2277
|
-
.stat-card .value { font-size: 28px; font-weight: 700; color: #58a6ff; }
|
|
2278
|
-
.stat-card .label { font-size: 11px; color: #8b949e; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
2279
|
-
.container { max-width: 1200px; margin: 0 auto; padding: 24px 40px; }
|
|
2280
|
-
.section-title { font-size: 18px; color: #c9d1d9; margin: 32px 0 16px; border-bottom: 1px solid #21262d; padding-bottom: 8px; }
|
|
2281
|
-
/* Systems bar chart */
|
|
2282
|
-
.systems-grid { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 24px; }
|
|
2283
|
-
.sys-tag {
|
|
2284
|
-
background: #21262d; border: 1px solid #30363d; border-radius: 6px;
|
|
2285
|
-
padding: 6px 12px; font-size: 12px; cursor: default;
|
|
2286
|
-
}
|
|
2287
|
-
.sys-tag .count { color: #58a6ff; font-weight: 600; margin-left: 4px; }
|
|
2288
|
-
/* SOP cards */
|
|
2289
|
-
.sop-card {
|
|
2290
|
-
background: #161b22; border: 1px solid #30363d; border-radius: 8px;
|
|
2291
|
-
margin-bottom: 16px; overflow: hidden; transition: border-color 0.2s;
|
|
2292
|
-
}
|
|
2293
|
-
.sop-card:hover { border-color: #58a6ff; }
|
|
2294
|
-
.sop-header {
|
|
2295
|
-
padding: 16px 20px; cursor: pointer; display: flex;
|
|
2296
|
-
justify-content: space-between; align-items: center;
|
|
2297
|
-
}
|
|
2298
|
-
.sop-header h3 { font-size: 16px; color: #e6edf3; }
|
|
2299
|
-
.sop-meta { display: flex; gap: 16px; align-items: center; font-size: 12px; color: #8b949e; }
|
|
2300
|
-
.sop-meta .freq { color: #3fb950; font-weight: 600; }
|
|
2301
|
-
.sop-meta .dur { color: #d29922; }
|
|
2302
|
-
.sop-meta .conf {
|
|
2303
|
-
display: inline-flex; align-items: center; gap: 4px;
|
|
2304
|
-
}
|
|
2305
|
-
.conf-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
|
|
2306
|
-
.sop-body { display: none; padding: 0 20px 20px; border-top: 1px solid #21262d; }
|
|
2307
|
-
.sop-body.open { display: block; padding-top: 16px; }
|
|
2308
|
-
.sop-desc { color: #8b949e; font-size: 13px; margin-bottom: 12px; }
|
|
2309
|
-
.sop-systems { margin-bottom: 12px; }
|
|
2310
|
-
.sop-systems span { background: #0d419d33; color: #58a6ff; border-radius: 4px; padding: 2px 8px; font-size: 11px; margin-right: 4px; }
|
|
2311
|
-
.steps-list { list-style: none; counter-reset: step; }
|
|
2312
|
-
.steps-list li {
|
|
2313
|
-
counter-increment: step; position: relative;
|
|
2314
|
-
padding: 10px 12px 10px 44px; border-left: 2px solid #30363d;
|
|
2315
|
-
margin-left: 14px; font-size: 13px;
|
|
2316
|
-
}
|
|
2317
|
-
.steps-list li:last-child { border-left-color: transparent; }
|
|
2318
|
-
.steps-list li::before {
|
|
2319
|
-
content: counter(step);
|
|
2320
|
-
position: absolute; left: -14px; top: 8px;
|
|
2321
|
-
width: 26px; height: 26px; border-radius: 50%;
|
|
2322
|
-
background: #21262d; border: 2px solid #30363d;
|
|
2323
|
-
display: flex; align-items: center; justify-content: center;
|
|
2324
|
-
font-size: 12px; font-weight: 600; color: #58a6ff;
|
|
2325
|
-
}
|
|
2326
|
-
.step-tool { color: #d2a8ff; font-weight: 600; }
|
|
2327
|
-
.step-target { color: #7ee787; font-size: 12px; }
|
|
2328
|
-
.step-notes { color: #8b949e; font-style: italic; font-size: 12px; margin-top: 2px; }
|
|
2329
|
-
.step-instr { color: #c9d1d9; }
|
|
2330
|
-
.toggle-icon { color: #8b949e; font-size: 18px; transition: transform 0.2s; }
|
|
2331
|
-
.toggle-icon.open { transform: rotate(90deg); }
|
|
2332
|
-
.empty { color: #484f58; font-size: 14px; padding: 40px; text-align: center; }
|
|
2333
|
-
.gen-time { color: #484f58; font-size: 11px; margin-top: 8px; }
|
|
2334
|
-
</style>
|
|
2335
|
-
</head>
|
|
2336
|
-
<body>
|
|
2337
|
-
<div class="header">
|
|
2338
|
-
<h1>SOP Dashboard</h1>
|
|
2339
|
-
<div class="subtitle">Cartography \u2014 Standard Operating Procedures</div>
|
|
2340
|
-
<div class="stats-row">
|
|
2341
|
-
<div class="stat-card"><div class="value" id="sop-count">0</div><div class="label">SOPs</div></div>
|
|
2342
|
-
<div class="stat-card"><div class="value" id="step-count">0</div><div class="label">Total Steps</div></div>
|
|
2343
|
-
<div class="stat-card"><div class="value" id="sys-count">0</div><div class="label">Systems</div></div>
|
|
2344
|
-
<div class="stat-card"><div class="value" id="avg-conf">\u2014</div><div class="label">Avg Confidence</div></div>
|
|
2345
|
-
</div>
|
|
2346
|
-
</div>
|
|
2347
|
-
<div class="container">
|
|
2348
|
-
<h2 class="section-title">Involved Systems</h2>
|
|
2349
|
-
<div class="systems-grid" id="systems"></div>
|
|
2350
|
-
|
|
2351
|
-
<h2 class="section-title">SOPs</h2>
|
|
2352
|
-
<div id="sop-list"></div>
|
|
2353
|
-
</div>
|
|
2354
|
-
<script>
|
|
2355
|
-
const sops = ${sopsJson};
|
|
2356
|
-
const systems = ${systemsJson};
|
|
2357
|
-
|
|
2358
|
-
document.getElementById('sop-count').textContent = sops.length;
|
|
2359
|
-
document.getElementById('step-count').textContent = sops.reduce((a, s) => a + s.steps.length, 0);
|
|
2360
|
-
document.getElementById('sys-count').textContent = systems.length;
|
|
2361
|
-
const avgConf = sops.length > 0
|
|
2362
|
-
? (sops.reduce((a, s) => a + s.confidence, 0) / sops.length * 100).toFixed(0) + '%'
|
|
2363
|
-
: '\u2014';
|
|
2364
|
-
document.getElementById('avg-conf').textContent = avgConf;
|
|
2365
|
-
|
|
2366
|
-
const sysDiv = document.getElementById('systems');
|
|
2367
|
-
systems.forEach(([name, count]) => {
|
|
2368
|
-
const el = document.createElement('div');
|
|
2369
|
-
el.className = 'sys-tag';
|
|
2370
|
-
el.innerHTML = name + '<span class="count">x' + count + '</span>';
|
|
2371
|
-
sysDiv.appendChild(el);
|
|
2372
|
-
});
|
|
2373
|
-
|
|
2374
|
-
const listDiv = document.getElementById('sop-list');
|
|
2375
|
-
if (sops.length === 0) {
|
|
2376
|
-
listDiv.innerHTML = '<div class="empty">No SOPs found. Run a discovery session first.</div>';
|
|
2377
|
-
}
|
|
2378
|
-
|
|
2379
|
-
sops.forEach((sop, i) => {
|
|
2380
|
-
const confColor = sop.confidence >= 0.8 ? '#3fb950' : sop.confidence >= 0.5 ? '#d29922' : '#f85149';
|
|
2381
|
-
const card = document.createElement('div');
|
|
2382
|
-
card.className = 'sop-card';
|
|
2383
|
-
card.innerHTML = \`
|
|
2384
|
-
<div class="sop-header" onclick="toggle(\${i})">
|
|
2385
|
-
<h3>\${sop.title}</h3>
|
|
2386
|
-
<div class="sop-meta">
|
|
2387
|
-
<span class="freq">\${sop.frequency}</span>
|
|
2388
|
-
<span class="dur">\${sop.duration}</span>
|
|
2389
|
-
<span class="conf"><span class="conf-dot" style="background:\${confColor}"></span>\${Math.round(sop.confidence*100)}%</span>
|
|
2390
|
-
<span class="toggle-icon" id="icon-\${i}">\u25B8</span>
|
|
2391
|
-
</div>
|
|
2392
|
-
</div>
|
|
2393
|
-
<div class="sop-body" id="body-\${i}">
|
|
2394
|
-
<div class="sop-desc">\${sop.description}</div>
|
|
2395
|
-
<div class="sop-systems">\${sop.systems.map(s => '<span>'+s+'</span>').join('')}</div>
|
|
2396
|
-
<ol class="steps-list">
|
|
2397
|
-
\${sop.steps.map(st => \`
|
|
2398
|
-
<li>
|
|
2399
|
-
<span class="step-tool">\${st.tool}</span>
|
|
2400
|
-
\${st.target ? '<span class="step-target"> \u2192 '+st.target+'</span>' : ''}
|
|
2401
|
-
<div class="step-instr">\${st.instruction}</div>
|
|
2402
|
-
\${st.notes ? '<div class="step-notes">'+st.notes+'</div>' : ''}
|
|
2403
|
-
</li>
|
|
2404
|
-
\`).join('')}
|
|
2405
|
-
</ol>
|
|
2406
|
-
<div class="gen-time">Generated: \${sop.generatedAt ? sop.generatedAt.substring(0,19).replace('T',' ') : '\u2014'}</div>
|
|
2407
|
-
</div>
|
|
2408
|
-
\`;
|
|
2409
|
-
listDiv.appendChild(card);
|
|
2410
|
-
});
|
|
2411
|
-
|
|
2412
|
-
function toggle(i) {
|
|
2413
|
-
const body = document.getElementById('body-'+i);
|
|
2414
|
-
const icon = document.getElementById('icon-'+i);
|
|
2415
|
-
body.classList.toggle('open');
|
|
2416
|
-
icon.classList.toggle('open');
|
|
2417
|
-
}
|
|
2418
|
-
</script>
|
|
2419
|
-
</body>
|
|
2420
|
-
</html>`;
|
|
2421
|
-
}
|
|
2422
2086
|
function exportDiscoveryApp(nodes, edges, options) {
|
|
2423
2087
|
const theme = options?.theme ?? "dark";
|
|
2424
2088
|
const graphData = JSON.stringify({
|
|
@@ -3536,10 +3200,8 @@ function exportJGF(nodes, edges) {
|
|
|
3536
3200
|
};
|
|
3537
3201
|
return JSON.stringify(jgf, null, 2);
|
|
3538
3202
|
}
|
|
3539
|
-
function exportAll(db, sessionId, outputDir, formats = ["mermaid", "json", "yaml", "html", "map", "discovery"
|
|
3203
|
+
function exportAll(db, sessionId, outputDir, formats = ["mermaid", "json", "yaml", "html", "map", "discovery"]) {
|
|
3540
3204
|
mkdirSync2(outputDir, { recursive: true });
|
|
3541
|
-
mkdirSync2(join3(outputDir, "sops"), { recursive: true });
|
|
3542
|
-
mkdirSync2(join3(outputDir, "workflows"), { recursive: true });
|
|
3543
3205
|
const nodes = db.getNodes(sessionId);
|
|
3544
3206
|
const edges = db.getEdges(sessionId);
|
|
3545
3207
|
const jgfPath = join3(outputDir, "cartography-graph.jgf.json");
|
|
@@ -3557,15 +3219,6 @@ function exportAll(db, sessionId, outputDir, formats = ["mermaid", "json", "yaml
|
|
|
3557
3219
|
if (formats.includes("html") || formats.includes("map") || formats.includes("discovery")) {
|
|
3558
3220
|
writeFileSync(join3(outputDir, "discovery.html"), exportDiscoveryApp(nodes, edges));
|
|
3559
3221
|
}
|
|
3560
|
-
if (formats.includes("sops")) {
|
|
3561
|
-
const sops = db.getSOPs(sessionId);
|
|
3562
|
-
for (const sop of sops) {
|
|
3563
|
-
const filename = sop.title.toLowerCase().replace(/[^a-z0-9]+/g, "-") + ".md";
|
|
3564
|
-
writeFileSync(join3(outputDir, "sops", filename), exportSOPMarkdown(sop));
|
|
3565
|
-
const wfFilename = `workflow-${sop.workflowId.substring(0, 8)}.mermaid`;
|
|
3566
|
-
writeFileSync(join3(outputDir, "workflows", wfFilename), generateWorkflowMermaid(sop));
|
|
3567
|
-
}
|
|
3568
|
-
}
|
|
3569
3222
|
}
|
|
3570
3223
|
|
|
3571
3224
|
// src/preflight.ts
|
|
@@ -3620,11 +3273,8 @@ export {
|
|
|
3620
3273
|
exportDiscoveryApp,
|
|
3621
3274
|
exportJGF,
|
|
3622
3275
|
exportJSON,
|
|
3623
|
-
exportSOPDashboard,
|
|
3624
|
-
exportSOPMarkdown,
|
|
3625
3276
|
generateDependencyMermaid,
|
|
3626
3277
|
generateTopologyMermaid,
|
|
3627
|
-
generateWorkflowMermaid,
|
|
3628
3278
|
groupByDomain,
|
|
3629
3279
|
hexCorners,
|
|
3630
3280
|
hexDistance,
|