agentic-mermaid 0.1.1 → 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/AGENT_NATIVE.md +155 -91
- package/CHANGELOG.md +163 -4
- package/Instructions_for_agents.md +10 -10
- package/LICENSES/Apache-2.0.txt +202 -0
- package/README.md +31 -38
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/assets/hero.png +0 -0
- package/dist/agent-core.d.ts +463 -0
- package/dist/agent-core.js +397 -0
- package/dist/agent.d.ts +73 -1868
- package/dist/agent.js +336 -37325
- package/dist/agentic-mermaid-mcp.js +7 -38399
- package/dist/am.js +33626 -40446
- package/dist/chunk-2P5FKUQC.js +3485 -0
- package/dist/chunk-2S3VSS6I.js +149 -0
- package/dist/chunk-2SILJDW2.js +37 -0
- package/dist/chunk-BJYMBT4I.js +61963 -0
- package/dist/chunk-FDM43XU7.js +615 -0
- package/dist/chunk-MYPDVZCO.js +4702 -0
- package/dist/index-DWPa2MJs.d.ts +6780 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +310 -33014
- package/dist/mcp-cli-5J47WEY3.js +17 -0
- package/docs/README.md +39 -31
- package/docs/agent-api-cookbook.md +44 -35
- package/docs/agent-mutation-policy.md +1 -1
- package/docs/agent-workflow-examples.md +2 -2
- package/docs/api.md +284 -77
- package/docs/ascii.md +26 -16
- package/docs/code-mode-impact.md +214 -0
- package/docs/comparison.md +23 -11
- package/docs/computational-aesthetics-prototype-plan.md +252 -0
- package/docs/config.md +26 -10
- package/docs/custom-fonts.md +265 -0
- package/docs/custom-style-cookbook.md +130 -9
- package/docs/diagram-families.md +48 -23
- package/docs/features.md +59 -52
- package/docs/fork-differences.md +6 -3
- package/docs/getting-started.md +23 -16
- package/docs/issue-derived-test-cases.md +29 -22
- package/docs/mcp-code-mode-rationale.md +13 -6
- package/docs/mcp-http-transport.md +20 -13
- package/docs/mermaid-layout-complaints.md +66 -52
- package/docs/mutation-testing.md +145 -66
- package/docs/quality.md +23 -14
- package/docs/react.md +2 -2
- package/docs/schemas/style-spec.schema.json +1221 -30
- package/docs/style-authoring.md +241 -38
- package/docs/svg-semantic-contract.md +49 -0
- package/docs/testing-strategy.md +166 -58
- package/docs/theming.md +19 -32
- package/examples/styles/catalog.json +54 -0
- package/examples/styles/cloudflare-workers-inspired-prototype.mmd +9 -0
- package/examples/styles/cloudflare-workers-inspired-prototype.style.json +110 -0
- package/examples/styles/cupertino-prototype.mmd +10 -0
- package/examples/styles/cupertino-prototype.style.json +63 -0
- package/examples/styles/mid-century-report.style.json +2 -2
- package/examples/styles/star-chart-atlas.style.json +2 -1
- package/examples/styles/transit-route-map.style.json +2 -2
- package/examples/styles/vercel-inspired-prototype.mmd +6 -0
- package/examples/styles/vercel-inspired-prototype.style.json +87 -0
- package/package.json +85 -45
- package/server.json +2 -2
- package/skills/agentic-mermaid-diagram-workflow/SKILL.md +17 -36
- package/skills/agentic-mermaid-diagram-workflow/references/cli.md +4 -5
- package/skills/agentic-mermaid-diagram-workflow/references/code-mode.md +15 -31
- package/skills/agentic-mermaid-diagram-workflow/references/sequence.md +10 -14
- package/skills/agentic-mermaid-live-editor/SKILL.md +100 -206
- package/TODO.md +0 -684
- package/dist/index-wjRjbsP-.d.ts +0 -1102
- package/docs/assets/improvements/box-start-connector.png +0 -0
- package/docs/assets/improvements/comment-dropped-lint.png +0 -0
- package/docs/assets/improvements/er-content-loss.png +0 -0
- package/docs/assets/improvements/fan-in-trunks.png +0 -0
- package/docs/assets/improvements/gantt-family.png +0 -0
- package/docs/assets/improvements/gantt-milestone-clamp.png +0 -0
- package/docs/assets/improvements/gantt-verify-seam.png +0 -0
- package/docs/assets/improvements/subgraph-container-edges.png +0 -0
- package/docs/assets/improvements/wrapper-frontmatter.png +0 -0
- package/docs/assets/improvements/wrapper-init-directive.png +0 -0
- package/docs/assets/improvements/wrapper-leading-comment.png +0 -0
- package/docs/assets/style-cookbook/mid-century-report.png +0 -0
- package/docs/assets/style-cookbook/star-chart-atlas.png +0 -0
- package/docs/assets/style-cookbook/transit-route-map.png +0 -0
- package/docs/contributing/adding-diagram-types.md +0 -144
- package/docs/contributing/diagram-family-citizenship.matrix.json +0 -2127
- package/docs/contributing/diagram-family-citizenship.md +0 -82
- package/docs/contributing/harvesting-upstream-tests.md +0 -126
- package/docs/contributing/lessons-learned.md +0 -276
- package/docs/contributing/releasing.md +0 -82
- package/docs/contributing/visual-review-evidence.md +0 -53
- package/docs/design/families/README.md +0 -26
- package/docs/design/families/architecture-beta.md +0 -48
- package/docs/design/families/flowchart-parser-conformance.md +0 -22
- package/docs/design/families/gantt-research.md +0 -137
- package/docs/design/families/gantt.md +0 -329
- package/docs/design/families/journey-agentic-cards-before.png +0 -0
- package/docs/design/families/journey-experience-curve-implementation.png +0 -0
- package/docs/design/families/journey-mermaid-classic-implementation.png +0 -0
- package/docs/design/families/journey-mermaid-classic-prototype.png +0 -0
- package/docs/design/families/journey-mermaid-classic-prototype.svg +0 -163
- package/docs/design/families/journey-mermaid-classic-prototype.svg.png +0 -0
- package/docs/design/families/journey-migration-parity.md +0 -439
- package/docs/design/families/journey-section-overlap-after.png +0 -0
- package/docs/design/families/journey-section-overlap-before.png +0 -0
- package/docs/design/families/journey-usage-research.md +0 -423
- package/docs/design/families/journey.md +0 -153
- package/docs/design/families/xychart.md +0 -85
- package/docs/design/system/README.md +0 -45
- package/docs/design/system/abstraction-audit.md +0 -224
- package/docs/design/system/abstraction-recommendations.md +0 -655
- package/docs/design/system/architecture.mmd +0 -29
- package/docs/design/system/architecture.svg +0 -137
- package/docs/design/system/layout-guarantees-and-robustness.md +0 -351
- package/docs/design/system/layout-rubric.md +0 -138
- package/docs/design/system/route-contracts.md +0 -848
- package/docs/design/system/source-preservation-ladder.md +0 -52
- package/docs/design/system/styles-rollout.md +0 -216
- package/docs/design/system/ugly-layouts.md +0 -119
- package/docs/layout-characterization/README.md +0 -245
- package/docs/layout-characterization/contact-sheet-families.md +0 -498
- package/docs/layout-characterization/contact-sheet.md +0 -638
- package/docs/layout-characterization/properties.md +0 -281
- package/docs/layout-characterization/visual-quality.md +0 -160
- package/docs/layout-characterization/visual-snapshots/architecture.svg +0 -79
- package/docs/layout-characterization/visual-snapshots/class.svg +0 -60
- package/docs/layout-characterization/visual-snapshots/er.svg +0 -61
- package/docs/layout-characterization/visual-snapshots/flowchart.svg +0 -58
- package/docs/layout-characterization/visual-snapshots/gantt.svg +0 -52
- package/docs/layout-characterization/visual-snapshots/journey.svg +0 -98
- package/docs/layout-characterization/visual-snapshots/pie.svg +0 -36
- package/docs/layout-characterization/visual-snapshots/quadrant.svg +0 -47
- package/docs/layout-characterization/visual-snapshots/sequence.svg +0 -59
- package/docs/layout-characterization/visual-snapshots/state.svg +0 -52
- package/docs/layout-characterization/visual-snapshots/timeline.svg +0 -64
- package/docs/layout-characterization/visual-snapshots/xychart.svg +0 -97
- package/docs/project/divergences.md +0 -98
- package/docs/project/dogfooding-docs-strategy.md +0 -66
- package/docs/project/hosted-mcp-cloudflare-plan.md +0 -338
- package/docs/project/lessons-learned.md +0 -1019
- package/docs/project/remove-role-styling-plan.md +0 -176
- package/examples/agent-improve-auth-flow.ts +0 -206
- package/examples/agent-loop.ts +0 -53
- package/examples/mcp-vs-cli-complex-diagrams.ts +0 -133
- package/llms.txt +0 -104
- package/skill-evals/README.md +0 -77
- package/skill-evals/fixtures/architecture-cache/input.mmd +0 -5
- package/skill-evals/fixtures/class-payment/input.mmd +0 -4
- package/skill-evals/fixtures/er-orders/input.mmd +0 -10
- package/skill-evals/fixtures/flowchart-cache/input.mmd +0 -3
- package/skill-evals/fixtures/gantt-release/input.mmd +0 -7
- package/skill-evals/fixtures/journey-checkout/input.mmd +0 -6
- package/skill-evals/fixtures/pie-exports/input.mmd +0 -5
- package/skill-evals/fixtures/quadrant-priorities/input.mmd +0 -11
- package/skill-evals/fixtures/sequence-retry/input.mmd +0 -8
- package/skill-evals/fixtures/state-lifecycle/input.mmd +0 -5
- package/skill-evals/fixtures/timeline-release/input.mmd +0 -6
- package/skill-evals/fixtures/xychart-growth/input.mmd +0 -5
- package/skill-evals/shared-benchmark.json +0 -510
- package/src/agent/analyze.ts +0 -157
- package/src/agent/apply.ts +0 -146
- package/src/agent/architecture-body.ts +0 -458
- package/src/agent/certificates.ts +0 -110
- package/src/agent/class-body.ts +0 -319
- package/src/agent/core.ts +0 -207
- package/src/agent/create.ts +0 -106
- package/src/agent/describe.ts +0 -368
- package/src/agent/er-body.ts +0 -224
- package/src/agent/facts.ts +0 -360
- package/src/agent/families-builtin.ts +0 -920
- package/src/agent/families.ts +0 -232
- package/src/agent/family-layouts.ts +0 -832
- package/src/agent/flowchart-body.ts +0 -372
- package/src/agent/flowchart-unsupported.ts +0 -243
- package/src/agent/font-coverage.ts +0 -288
- package/src/agent/gantt-body.ts +0 -495
- package/src/agent/index.ts +0 -10
- package/src/agent/journey-body.ts +0 -374
- package/src/agent/label-metrics.ts +0 -28
- package/src/agent/layout-to-rendered.ts +0 -63
- package/src/agent/mutate.ts +0 -97
- package/src/agent/mutation-ops.ts +0 -51
- package/src/agent/op-schema.ts +0 -443
- package/src/agent/parse.ts +0 -223
- package/src/agent/pie-body.ts +0 -270
- package/src/agent/png.ts +0 -171
- package/src/agent/quadrant-body.ts +0 -336
- package/src/agent/quality.ts +0 -363
- package/src/agent/readability-audit.ts +0 -92
- package/src/agent/rendered-route-audit.ts +0 -61
- package/src/agent/sequence-body.ts +0 -345
- package/src/agent/serialize.ts +0 -214
- package/src/agent/state-body.ts +0 -589
- package/src/agent/structural-count.ts +0 -150
- package/src/agent/timeline-body.ts +0 -280
- package/src/agent/trace-log.ts +0 -43
- package/src/agent/types.ts +0 -995
- package/src/agent/verify.ts +0 -603
- package/src/agent/xychart-body.ts +0 -472
- package/src/architecture/config.ts +0 -282
- package/src/architecture/layout.ts +0 -496
- package/src/architecture/parser.ts +0 -375
- package/src/architecture/renderer.ts +0 -611
- package/src/architecture/types.ts +0 -113
- package/src/ascii/ansi.ts +0 -423
- package/src/ascii/architecture.ts +0 -210
- package/src/ascii/canvas.ts +0 -443
- package/src/ascii/class-diagram.ts +0 -697
- package/src/ascii/converter.ts +0 -475
- package/src/ascii/draw.ts +0 -1693
- package/src/ascii/edge-bundling.ts +0 -328
- package/src/ascii/edge-routing.ts +0 -330
- package/src/ascii/er-diagram.ts +0 -439
- package/src/ascii/gantt.ts +0 -276
- package/src/ascii/grid.ts +0 -747
- package/src/ascii/index.ts +0 -196
- package/src/ascii/journey.ts +0 -169
- package/src/ascii/meta.ts +0 -244
- package/src/ascii/multiline-utils.ts +0 -80
- package/src/ascii/pathfinder.ts +0 -301
- package/src/ascii/pie.ts +0 -67
- package/src/ascii/quadrant.ts +0 -158
- package/src/ascii/reverse.ts +0 -216
- package/src/ascii/sequence.ts +0 -499
- package/src/ascii/shapes/circle.ts +0 -27
- package/src/ascii/shapes/corners.ts +0 -143
- package/src/ascii/shapes/diamond.ts +0 -27
- package/src/ascii/shapes/hexagon.ts +0 -27
- package/src/ascii/shapes/index.ts +0 -106
- package/src/ascii/shapes/rectangle.ts +0 -168
- package/src/ascii/shapes/rounded.ts +0 -27
- package/src/ascii/shapes/special.ts +0 -332
- package/src/ascii/shapes/stadium.ts +0 -110
- package/src/ascii/shapes/state.ts +0 -192
- package/src/ascii/shapes/types.ts +0 -73
- package/src/ascii/timeline.ts +0 -141
- package/src/ascii/types.ts +0 -312
- package/src/ascii/validate.ts +0 -120
- package/src/ascii/width.ts +0 -81
- package/src/ascii/wrap.ts +0 -131
- package/src/ascii/xychart.ts +0 -919
- package/src/browser.ts +0 -29
- package/src/class/layout.ts +0 -240
- package/src/class/parser.ts +0 -332
- package/src/class/renderer.ts +0 -638
- package/src/class/types.ts +0 -129
- package/src/cli/agent-instructions.ts +0 -1
- package/src/cli/am-bin.ts +0 -6
- package/src/cli/exit-codes.ts +0 -18
- package/src/cli/index.ts +0 -1132
- package/src/cli/init-agent.ts +0 -147
- package/src/cli/run-entrypoint.ts +0 -10
- package/src/color-resolver.ts +0 -152
- package/src/elk-instance.ts +0 -114
- package/src/er/layout.ts +0 -187
- package/src/er/parser.ts +0 -226
- package/src/er/renderer.ts +0 -792
- package/src/er/types.ts +0 -99
- package/src/family-rubric.ts +0 -425
- package/src/font-manifest.ts +0 -31
- package/src/gantt/layout.ts +0 -365
- package/src/gantt/parser.ts +0 -282
- package/src/gantt/pipeline.ts +0 -27
- package/src/gantt/renderer.ts +0 -414
- package/src/gantt/schedule.ts +0 -513
- package/src/gantt/types.ts +0 -255
- package/src/index.ts +0 -368
- package/src/journey/layout.ts +0 -554
- package/src/journey/parse-core.ts +0 -251
- package/src/journey/parser.ts +0 -101
- package/src/journey/renderer.ts +0 -917
- package/src/journey/types.ts +0 -144
- package/src/layout/geometry.ts +0 -182
- package/src/layout/pass.ts +0 -142
- package/src/layout/passes/index.ts +0 -3916
- package/src/layout-engine.ts +0 -1565
- package/src/layout-rubric.ts +0 -659
- package/src/mcp/artifacts.ts +0 -137
- package/src/mcp/dynamic-harness.ts +0 -31
- package/src/mcp/dynamic-modules.d.ts +0 -7
- package/src/mcp/facade.ts +0 -608
- package/src/mcp/harness-runtime.ts +0 -203
- package/src/mcp/hosted-server.ts +0 -468
- package/src/mcp/mcp-bin.ts +0 -3
- package/src/mcp/mcp-cli.ts +0 -82
- package/src/mcp/protocol.ts +0 -13
- package/src/mcp/sandbox.ts +0 -195
- package/src/mcp/sdk-decl.ts +0 -391
- package/src/mcp/server.ts +0 -362
- package/src/mcp/tool-surface.ts +0 -146
- package/src/mermaid-source.ts +0 -655
- package/src/multiline-utils.ts +0 -228
- package/src/parser.ts +0 -1031
- package/src/pie/layout.ts +0 -168
- package/src/pie/parser.ts +0 -136
- package/src/pie/renderer.ts +0 -234
- package/src/pie/types.ts +0 -82
- package/src/quadrant/layout.ts +0 -191
- package/src/quadrant/parser.ts +0 -183
- package/src/quadrant/renderer.ts +0 -322
- package/src/quadrant/types.ts +0 -113
- package/src/render-family-hooks.ts +0 -244
- package/src/renderer.ts +0 -1099
- package/src/route-contracts.ts +0 -2723
- package/src/scene/backend.ts +0 -76
- package/src/scene/fidelity.ts +0 -183
- package/src/scene/hybrid-backend.ts +0 -174
- package/src/scene/ir.ts +0 -181
- package/src/scene/marks.ts +0 -127
- package/src/scene/rough-backend.ts +0 -378
- package/src/scene/seed.ts +0 -46
- package/src/scene/style-registry.ts +0 -556
- package/src/sequence/layout.ts +0 -456
- package/src/sequence/parser.ts +0 -255
- package/src/sequence/renderer.ts +0 -604
- package/src/sequence/types.ts +0 -154
- package/src/shape-clipping.ts +0 -351
- package/src/shared/accessibility-directives.ts +0 -22
- package/src/shared/batched.ts +0 -61
- package/src/shared/color-math.ts +0 -93
- package/src/shared/svg-a11y.ts +0 -29
- package/src/shared/syntax-error.ts +0 -17
- package/src/shared/unicode-ranges.ts +0 -135
- package/src/styles.ts +0 -318
- package/src/svg-paths.ts +0 -28
- package/src/text-metrics.ts +0 -248
- package/src/theme.ts +0 -710
- package/src/timeline/layout.ts +0 -381
- package/src/timeline/parser.ts +0 -215
- package/src/timeline/renderer.ts +0 -538
- package/src/timeline/types.ts +0 -105
- package/src/types.ts +0 -462
- package/src/website-worker-modules.d.ts +0 -18
- package/src/xychart/axis-utils.ts +0 -109
- package/src/xychart/colors.ts +0 -124
- package/src/xychart/config.ts +0 -88
- package/src/xychart/layout.ts +0 -656
- package/src/xychart/parser.ts +0 -504
- package/src/xychart/renderer.ts +0 -640
- package/src/xychart/types.ts +0 -282
package/src/agent/analyze.ts
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
// ============================================================================
|
|
2
|
-
// analyzeMermaid — deterministic facts without inventing Mermaid syntax.
|
|
3
|
-
//
|
|
4
|
-
// Issue #26 WS14 / issue #38 closure slice: expose the analysis facts that
|
|
5
|
-
// already exist in the implementation (graph feedback classification, Gantt
|
|
6
|
-
// critical path/slack, and source-only action records) through a stable API.
|
|
7
|
-
// This module never executes callbacks and never mutates source/render output.
|
|
8
|
-
// ============================================================================
|
|
9
|
-
|
|
10
|
-
import { parseMermaid } from './parse.ts'
|
|
11
|
-
import type { DiagramActionRecord, DiagramAnalysis, ParseError, Result, ValidDiagram } from './types.ts'
|
|
12
|
-
import { err, ok } from './types.ts'
|
|
13
|
-
import { classifyRoutes } from '../route-contracts.ts'
|
|
14
|
-
import { parseMermaid as parseFlowchartLegacy } from '../parser.ts'
|
|
15
|
-
import { stateBodyToGraph } from './state-body.ts'
|
|
16
|
-
import { parseGanttModel, applyGanttFrontmatterConfig } from '../gantt/parser.ts'
|
|
17
|
-
import { resolveGanttSchedule } from '../gantt/schedule.ts'
|
|
18
|
-
import { normalizeMermaidSource, toMermaidLines } from '../mermaid-source.ts'
|
|
19
|
-
import type { MermaidGraph } from '../types.ts'
|
|
20
|
-
|
|
21
|
-
export function analyzeMermaid(d: ValidDiagram): DiagramAnalysis {
|
|
22
|
-
return {
|
|
23
|
-
kind: d.kind,
|
|
24
|
-
feedbackEdges: feedbackEdges(d),
|
|
25
|
-
actions: collectActionRecords(d),
|
|
26
|
-
...(d.body.kind === 'gantt' ? ganttAnalysis(d) : {}),
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function analyzeMermaidSource(source: string): Result<DiagramAnalysis, ParseError[]> {
|
|
31
|
-
const parsed = parseMermaid(source)
|
|
32
|
-
return parsed.ok ? ok(analyzeMermaid(parsed.value)) : err(parsed.error)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function feedbackEdges(d: ValidDiagram): DiagramAnalysis['feedbackEdges'] {
|
|
36
|
-
let graph: MermaidGraph | null = null
|
|
37
|
-
if (d.body.kind === 'flowchart') graph = d.body.graph
|
|
38
|
-
else if (d.body.kind === 'state') graph = stateBodyToGraph(d.body)
|
|
39
|
-
else if (d.kind === 'flowchart' && d.body.kind === 'opaque') {
|
|
40
|
-
try { graph = parseFlowchartLegacy(d.canonicalSource) } catch { graph = null }
|
|
41
|
-
}
|
|
42
|
-
if (!graph) return []
|
|
43
|
-
|
|
44
|
-
const classes = classifyRoutes(graph)
|
|
45
|
-
return graph.edges.flatMap((edge, edgeIndex) => classes[edgeIndex] === 'feedback'
|
|
46
|
-
? [{ edgeIndex, from: edge.source, to: edge.target, label: edge.label, routeClass: 'feedback' as const }]
|
|
47
|
-
: [])
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function ganttAnalysis(d: ValidDiagram): Pick<DiagramAnalysis, 'gantt'> {
|
|
51
|
-
if (d.body.kind !== 'gantt') return {}
|
|
52
|
-
try {
|
|
53
|
-
const normalized = normalizeMermaidSource(d.canonicalSource)
|
|
54
|
-
const model = applyGanttFrontmatterConfig(parseGanttModel(normalized.lines), normalized.frontmatter)
|
|
55
|
-
const schedule = resolveGanttSchedule(model)
|
|
56
|
-
return schedule.analysis ? { gantt: {
|
|
57
|
-
criticalPathTaskIds: [...schedule.analysis.criticalPathTaskIds],
|
|
58
|
-
slackByTaskId: { ...schedule.analysis.slackByTaskId },
|
|
59
|
-
projectStart: schedule.analysis.projectStart,
|
|
60
|
-
projectEnd: schedule.analysis.projectEnd,
|
|
61
|
-
entryTaskIds: [...schedule.analysis.entryTaskIds],
|
|
62
|
-
sinkTaskIds: [...schedule.analysis.sinkTaskIds],
|
|
63
|
-
} } : {}
|
|
64
|
-
} catch {
|
|
65
|
-
return {}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function collectActionRecords(d: ValidDiagram): DiagramActionRecord[] {
|
|
70
|
-
const source = d.body.kind === 'opaque' ? d.body.source : d.canonicalSource
|
|
71
|
-
const records: DiagramActionRecord[] = []
|
|
72
|
-
if (d.kind === 'flowchart') records.push(...collectFlowchartActions(source))
|
|
73
|
-
if (d.body.kind === 'gantt') records.push(...collectGanttActions(d))
|
|
74
|
-
const seen = new Map<string, number>()
|
|
75
|
-
return records.map(record => {
|
|
76
|
-
const key = `${record.family}:${record.target}`
|
|
77
|
-
const n = seen.get(key) ?? 0
|
|
78
|
-
seen.set(key, n + 1)
|
|
79
|
-
return { id: `action:${record.family}:${record.target}:${n}`, regionId: `node:${record.target}`, ...record }
|
|
80
|
-
})
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function collectFlowchartActions(source: string): DiagramActionRecord[] {
|
|
84
|
-
const out: DiagramActionRecord[] = []
|
|
85
|
-
const lines = source.split(/\r?\n/)
|
|
86
|
-
for (let i = 0; i < lines.length; i++) {
|
|
87
|
-
const text = lines[i]!.trim()
|
|
88
|
-
if (!text || text.startsWith('%%')) continue
|
|
89
|
-
let m = text.match(/^href\s+(\S+)\s+(.+)$/i)
|
|
90
|
-
if (m) {
|
|
91
|
-
out.push(actionRecord('flowchart', m[1]!, 'href', m[2]!, i + 1))
|
|
92
|
-
continue
|
|
93
|
-
}
|
|
94
|
-
m = text.match(/^click\s+(\S+)\s+(.+)$/i)
|
|
95
|
-
if (!m) continue
|
|
96
|
-
const target = m[1]!
|
|
97
|
-
const rest = m[2]!.trim()
|
|
98
|
-
const explicit = rest.match(/^(href|call)\s+(.+)$/i)
|
|
99
|
-
if (explicit?.[1]?.toLowerCase() === 'href') out.push(actionRecord('flowchart', target, 'href', explicit[2]!, i + 1))
|
|
100
|
-
else if (explicit?.[1]?.toLowerCase() === 'call') out.push(actionRecord('flowchart', target, 'call', explicit[2]!, i + 1))
|
|
101
|
-
else out.push(actionRecord('flowchart', target, looksLikeHref(rest) ? 'href' : 'callback', rest, i + 1))
|
|
102
|
-
}
|
|
103
|
-
return out
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function collectGanttActions(d: ValidDiagram): DiagramActionRecord[] {
|
|
107
|
-
if (d.body.kind !== 'gantt') return []
|
|
108
|
-
try {
|
|
109
|
-
const model = parseGanttModel(toMermaidLines(d.canonicalSource))
|
|
110
|
-
return model.clicks.map(click => actionRecord('gantt', click.taskId, click.action, click.rest, click.line))
|
|
111
|
-
} catch {
|
|
112
|
-
return []
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function actionRecord(
|
|
117
|
-
family: DiagramActionRecord['family'],
|
|
118
|
-
target: string,
|
|
119
|
-
action: DiagramActionRecord['action'],
|
|
120
|
-
raw: string,
|
|
121
|
-
line?: number,
|
|
122
|
-
): DiagramActionRecord {
|
|
123
|
-
const href = action === 'href' ? firstActionToken(raw) : undefined
|
|
124
|
-
const unsafe = href !== undefined && !isSafeHref(href)
|
|
125
|
-
return {
|
|
126
|
-
family,
|
|
127
|
-
target,
|
|
128
|
-
action,
|
|
129
|
-
raw,
|
|
130
|
-
line,
|
|
131
|
-
href,
|
|
132
|
-
executable: false,
|
|
133
|
-
security: action === 'href' ? (unsafe ? 'unsafe' : 'safe') : 'source-only',
|
|
134
|
-
message: action === 'href'
|
|
135
|
-
? (unsafe ? 'Unsafe href is source-only and must be stripped by strict renderers.' : 'Href is an action record; non-SVG renderers keep it as source-only metadata.')
|
|
136
|
-
: 'Callbacks/calls are recorded for analysis but are never executed.',
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function firstActionToken(raw: string): string {
|
|
141
|
-
const trimmed = raw.trim()
|
|
142
|
-
const quoted = trimmed.match(/^["']([^"']+)["']/)
|
|
143
|
-
if (quoted) return quoted[1]!
|
|
144
|
-
return trimmed.split(/\s+/)[0] ?? ''
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function isSafeHref(href: string): boolean {
|
|
148
|
-
const trimmed = href.trim()
|
|
149
|
-
if (/^(?:https?:|mailto:)/i.test(trimmed)) return true
|
|
150
|
-
if (/^[a-z][a-z0-9+.-]*:/i.test(trimmed)) return false
|
|
151
|
-
return trimmed.length > 0
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function looksLikeHref(raw: string): boolean {
|
|
155
|
-
const token = firstActionToken(raw)
|
|
156
|
-
return isSafeHref(token) && (/^(?:https?:|mailto:|#|\/|\.\/|\.\.)/i.test(token) || !/^[a-z][a-z0-9+.-]*:/i.test(token))
|
|
157
|
-
}
|
package/src/agent/apply.ts
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
// ============================================================================
|
|
2
|
-
// apply: the declarative, plain-JSON edit surface — the shape a hosted MCP
|
|
3
|
-
// `mutate`/`build` tool and the CLI expose, and the counterpart to the Code
|
|
4
|
-
// Mode `execute` path. Where `execute` hands an LLM the raw typed SDK behind a
|
|
5
|
-
// sandbox, this hands it a validated op list and one canonical result DTO.
|
|
6
|
-
//
|
|
7
|
-
// Three jobs, one shared core (mutateChecked):
|
|
8
|
-
// - buildChecked(): author from blank — createMermaid then fold mutateChecked
|
|
9
|
-
// over the ops. Validates shape; same Result shape as buildMermaid.
|
|
10
|
-
// - applyOps(): the batch entrypoint — parse `source` (edit) or `family`
|
|
11
|
-
// (build), fold the ops, and return ONE canonical OpEnvelope: always
|
|
12
|
-
// `{ok, …}`, always plain JSON (no Result-vs-plain split, no provenance
|
|
13
|
-
// proxy, no Map), so a caller reads success and failure the same way.
|
|
14
|
-
//
|
|
15
|
-
// Both entrypoints, the Code Mode facade, and the CLI funnel op application
|
|
16
|
-
// through mutateChecked — there is no second validator to drift from.
|
|
17
|
-
// ============================================================================
|
|
18
|
-
|
|
19
|
-
import { parseMermaid } from './parse.ts'
|
|
20
|
-
import { serializeMermaid } from './serialize.ts'
|
|
21
|
-
import { createMermaid, type CreateMermaidOptions } from './create.ts'
|
|
22
|
-
import { mutateChecked } from './mutate.ts'
|
|
23
|
-
import { verifyMermaid } from './verify.ts'
|
|
24
|
-
import { hasOpSchema, type OpFamily, type OpValidationError } from './op-schema.ts'
|
|
25
|
-
import type { MutableValidDiagram, VerifyResult, DiagramKind, MutationError, Result } from './types.ts'
|
|
26
|
-
import { ok, err } from './types.ts'
|
|
27
|
-
|
|
28
|
-
// ---- Canonical result envelope --------------------------------------------
|
|
29
|
-
|
|
30
|
-
/** A verify summary reduced to plain JSON (no RenderedLayout proxy graph). */
|
|
31
|
-
export interface VerifySummary {
|
|
32
|
-
ok: boolean
|
|
33
|
-
warnings: VerifyResult['warnings']
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** A mutation failure annotated with which op in the list failed. */
|
|
37
|
-
export type CheckedBuildError = MutationError & { opIndex: number }
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* THE single output DTO for the declarative surface. Success and failure share
|
|
41
|
-
* one shape: `ok` discriminates. Every field is plain JSON — safe to return
|
|
42
|
-
* straight out as an MCP tool result and safe to JSON round-trip: no
|
|
43
|
-
* `{ok,value}`-vs-plain split, no provenance proxy, no Map.
|
|
44
|
-
*/
|
|
45
|
-
export type OpEnvelope =
|
|
46
|
-
| {
|
|
47
|
-
ok: true
|
|
48
|
-
family: DiagramKind
|
|
49
|
-
/** canonical Mermaid source of the mutated diagram */
|
|
50
|
-
source: string
|
|
51
|
-
verify: VerifySummary
|
|
52
|
-
}
|
|
53
|
-
| {
|
|
54
|
-
ok: false
|
|
55
|
-
family: OpFamily | DiagramKind | null
|
|
56
|
-
/** index of the failing op within the batch, when the failure is op-scoped */
|
|
57
|
-
opIndex?: number
|
|
58
|
-
error: OpValidationError | { code: string; message: string }
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/** Drop the layout proxy graph; keep the model-actionable verdict. The JSON
|
|
62
|
-
* round-trip guarantees no residual Map / prototype leaks through. */
|
|
63
|
-
export function verifySummary(v: VerifyResult): VerifySummary {
|
|
64
|
-
return JSON.parse(JSON.stringify({ ok: v.ok, warnings: v.warnings }))
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// ---- Blank-slate build through the checked core ---------------------------
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* buildMermaid's contract (createMermaid → fold ops) with the shape check in
|
|
71
|
-
* front of every op. Same Result shape as buildMermaid, so it is a drop-in for
|
|
72
|
-
* the untyped build path (Code Mode facade `buildMermaid`, declarative `build`).
|
|
73
|
-
*/
|
|
74
|
-
export function buildChecked(kind: DiagramKind, ops: unknown[], opts?: CreateMermaidOptions): Result<MutableValidDiagram, CheckedBuildError> {
|
|
75
|
-
let d: MutableValidDiagram
|
|
76
|
-
try {
|
|
77
|
-
d = createMermaid(kind, opts)
|
|
78
|
-
} catch (e) {
|
|
79
|
-
return err({ code: 'INVALID_OP', message: e instanceof Error ? e.message : String(e), opIndex: -1 })
|
|
80
|
-
}
|
|
81
|
-
for (let i = 0; i < ops.length; i++) {
|
|
82
|
-
const r = mutateChecked(d, ops[i])
|
|
83
|
-
if (!r.ok) {
|
|
84
|
-
const kindLabel = (ops[i] as { kind?: unknown } | null)?.kind
|
|
85
|
-
return err({ ...r.error, opIndex: i, message: `op[${i}]${typeof kindLabel === 'string' ? ` (${kindLabel})` : ''}: ${r.error.message}` })
|
|
86
|
-
}
|
|
87
|
-
d = r.value
|
|
88
|
-
}
|
|
89
|
-
return ok(d)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// ---- Declarative batch entrypoint -----------------------------------------
|
|
93
|
-
|
|
94
|
-
export interface ApplyOpsInput {
|
|
95
|
-
/** Existing Mermaid `source` to edit, OR `family` to author from blank. */
|
|
96
|
-
source?: string
|
|
97
|
-
family?: string
|
|
98
|
-
ops: unknown
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Plain-JSON-in / plain-JSON-out batch edit. Fail-fast, all-or-nothing: ops
|
|
103
|
-
* apply in order over a working copy; the first invalid or semantically-rejected
|
|
104
|
-
* op stops the batch and reports its index — nothing is committed (the input
|
|
105
|
-
* `source` is untouched, mirroring buildMermaid). Returns the canonical envelope.
|
|
106
|
-
*/
|
|
107
|
-
export function applyOps(input: ApplyOpsInput): OpEnvelope {
|
|
108
|
-
const { source, family, ops } = input
|
|
109
|
-
|
|
110
|
-
if (!Array.isArray(ops)) {
|
|
111
|
-
return { ok: false, family: (typeof family === 'string' && hasOpSchema(family)) ? family : null, error: { code: 'INVALID_OP', message: '`ops` must be an array of op objects' } }
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
let d: MutableValidDiagram
|
|
115
|
-
|
|
116
|
-
if (typeof source === 'string' && source.trim().length > 0) {
|
|
117
|
-
const parsed = parseMermaid(source)
|
|
118
|
-
if (!parsed.ok) {
|
|
119
|
-
return { ok: false, family: null, error: { code: 'PARSE_ERROR', message: parsed.error.map(e => e.message).join('; ') || 'could not parse source' } }
|
|
120
|
-
}
|
|
121
|
-
d = parsed.value as MutableValidDiagram
|
|
122
|
-
if (!hasOpSchema(d.kind)) {
|
|
123
|
-
return { ok: false, family: d.kind, error: { code: 'INVALID_OP', message: `family "${d.kind}" has no structured ops; edit it as source text` } }
|
|
124
|
-
}
|
|
125
|
-
} else if (typeof family === 'string') {
|
|
126
|
-
if (!hasOpSchema(family)) {
|
|
127
|
-
return { ok: false, family: null, error: { code: 'INVALID_OP', message: `unknown family "${family}"` } }
|
|
128
|
-
}
|
|
129
|
-
const built = buildChecked(family, ops)
|
|
130
|
-
if (!built.ok) {
|
|
131
|
-
const { opIndex, ...error } = built.error
|
|
132
|
-
return { ok: false, family, opIndex: opIndex >= 0 ? opIndex : undefined, error }
|
|
133
|
-
}
|
|
134
|
-
return { ok: true, family: built.value.kind, source: serializeMermaid(built.value), verify: verifySummary(verifyMermaid(built.value)) }
|
|
135
|
-
} else {
|
|
136
|
-
return { ok: false, family: null, error: { code: 'INVALID_OP', message: 'applyOps requires either `source` (to edit) or `family` (to build)' } }
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Edit path: fold ops over the parsed diagram.
|
|
140
|
-
for (let i = 0; i < ops.length; i++) {
|
|
141
|
-
const r = mutateChecked(d, ops[i])
|
|
142
|
-
if (!r.ok) return { ok: false, family: d.kind, opIndex: i, error: r.error }
|
|
143
|
-
d = r.value
|
|
144
|
-
}
|
|
145
|
-
return { ok: true, family: d.kind, source: serializeMermaid(d), verify: verifySummary(verifyMermaid(d)) }
|
|
146
|
-
}
|