agentic-mermaid 0.1.1 → 0.1.2
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/CHANGELOG.md +144 -4
- package/LICENSES/Apache-2.0.txt +202 -0
- package/README.md +25 -32
- package/THIRD_PARTY_NOTICES.md +29 -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 +33632 -40445
- package/dist/chunk-4QECACIA.js +4702 -0
- package/dist/chunk-CDPKJ2BQ.js +37 -0
- package/dist/chunk-QKDLMOJJ.js +3487 -0
- package/dist/chunk-WI35L7IR.js +615 -0
- package/dist/chunk-WN3YDOBG.js +149 -0
- package/dist/chunk-ZYMMKQ3I.js +62637 -0
- package/dist/index-D54dqSdC.d.ts +6777 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +310 -33014
- package/dist/mcp-cli-SBQSTJFC.js +17 -0
- package/docs/README.md +14 -6
- package/docs/schemas/style-spec.schema.json +1221 -30
- 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 +68 -43
- 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/AGENT_NATIVE.md +0 -607
- package/Instructions_for_agents.md +0 -89
- package/TODO.md +0 -684
- package/assets/hero.png +0 -0
- package/dist/index-wjRjbsP-.d.ts +0 -1102
- package/docs/agent-api-cookbook.md +0 -308
- package/docs/agent-mutation-policy.md +0 -104
- package/docs/agent-workflow-examples.md +0 -46
- package/docs/api.md +0 -211
- package/docs/ascii.md +0 -103
- 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/comparison.md +0 -94
- package/docs/config.md +0 -105
- 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/custom-style-cookbook.md +0 -154
- 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/diagram-families.md +0 -193
- package/docs/features.md +0 -147
- package/docs/fork-differences.md +0 -130
- package/docs/getting-started.md +0 -175
- package/docs/issue-derived-test-cases.md +0 -156
- 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/mcp-code-mode-rationale.md +0 -101
- package/docs/mcp-http-transport.md +0 -223
- package/docs/mermaid-layout-complaints.md +0 -837
- package/docs/mutation-testing.md +0 -206
- 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/docs/quality.md +0 -215
- package/docs/react.md +0 -97
- package/docs/style-authoring.md +0 -133
- package/docs/testing-strategy.md +0 -335
- package/docs/theming.md +0 -162
- 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
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
// ============================================================================
|
|
2
|
-
// Stadium (pill) shape renderer — special parentheses-based rendering
|
|
3
|
-
// ============================================================================
|
|
4
|
-
//
|
|
5
|
-
// Stadium has unique rendering: single-line is inline `(Label)`, multi-line
|
|
6
|
-
// uses parentheses or rounded corners. This differs from other shapes that
|
|
7
|
-
// use corner decorators with box lines.
|
|
8
|
-
|
|
9
|
-
import type { Canvas, DrawingCoord, Direction } from '../types.ts'
|
|
10
|
-
import { drawText, mkCanvas } from '../canvas.ts'
|
|
11
|
-
import { splitLines } from '../multiline-utils.ts'
|
|
12
|
-
import { visualWidth } from '../width.ts'
|
|
13
|
-
import type { ShapeRenderer, ShapeDimensions, ShapeRenderOptions } from './types.ts'
|
|
14
|
-
import { getBoxAttachmentPoint } from './rectangle.ts'
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Stadium (pill) shape renderer.
|
|
18
|
-
*
|
|
19
|
-
* Single-line: ( Label )
|
|
20
|
-
*
|
|
21
|
-
* Multi-line unicode:
|
|
22
|
-
* ╭──────────╮
|
|
23
|
-
* │ Label │
|
|
24
|
-
* ╰──────────╯
|
|
25
|
-
*
|
|
26
|
-
* Multi-line ASCII:
|
|
27
|
-
* (----------)
|
|
28
|
-
* ( Label )
|
|
29
|
-
* (----------)
|
|
30
|
-
*/
|
|
31
|
-
export const stadiumRenderer: ShapeRenderer = {
|
|
32
|
-
getDimensions(label: string, options: ShapeRenderOptions): ShapeDimensions {
|
|
33
|
-
const lines = splitLines(label)
|
|
34
|
-
const maxLineWidth = Math.max(...lines.map(l => visualWidth(l)), 0)
|
|
35
|
-
const lineCount = lines.length
|
|
36
|
-
|
|
37
|
-
const innerWidth = 2 * options.padding + maxLineWidth
|
|
38
|
-
const width = innerWidth + 4 // Extra for rounded ends
|
|
39
|
-
const innerHeight = lineCount + 2 * options.padding
|
|
40
|
-
const height = Math.max(innerHeight + 2, 3)
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
width,
|
|
44
|
-
height,
|
|
45
|
-
labelArea: {
|
|
46
|
-
x: 2 + options.padding,
|
|
47
|
-
y: 1 + options.padding,
|
|
48
|
-
width: maxLineWidth,
|
|
49
|
-
height: lineCount,
|
|
50
|
-
},
|
|
51
|
-
gridColumns: [2, innerWidth, 2],
|
|
52
|
-
gridRows: [1, innerHeight, 1],
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
render(label: string, dimensions: ShapeDimensions, options: ShapeRenderOptions): Canvas {
|
|
57
|
-
const { width, height } = dimensions
|
|
58
|
-
const canvas = mkCanvas(width - 1, height - 1)
|
|
59
|
-
|
|
60
|
-
const centerY = Math.floor(height / 2)
|
|
61
|
-
const hChar = options.useAscii ? '-' : '─'
|
|
62
|
-
|
|
63
|
-
if (height === 3) {
|
|
64
|
-
// Single row pill: ( Label )
|
|
65
|
-
canvas[0]![centerY] = '('
|
|
66
|
-
canvas[width - 1]![centerY] = ')'
|
|
67
|
-
} else if (!options.useAscii) {
|
|
68
|
-
// Multi-row stadium with rounded corners (unicode)
|
|
69
|
-
canvas[0]![0] = '╭'
|
|
70
|
-
for (let x = 1; x < width - 1; x++) canvas[x]![0] = hChar
|
|
71
|
-
canvas[width - 1]![0] = '╮'
|
|
72
|
-
|
|
73
|
-
for (let y = 1; y < height - 1; y++) {
|
|
74
|
-
canvas[0]![y] = '│'
|
|
75
|
-
canvas[width - 1]![y] = '│'
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
canvas[0]![height - 1] = '╰'
|
|
79
|
-
for (let x = 1; x < width - 1; x++) canvas[x]![height - 1] = hChar
|
|
80
|
-
canvas[width - 1]![height - 1] = '╯'
|
|
81
|
-
} else {
|
|
82
|
-
// Multi-row stadium ASCII — parentheses on all sides
|
|
83
|
-
for (let y = 0; y < height; y++) {
|
|
84
|
-
canvas[0]![y] = '('
|
|
85
|
-
canvas[width - 1]![y] = ')'
|
|
86
|
-
}
|
|
87
|
-
for (let x = 1; x < width - 1; x++) {
|
|
88
|
-
canvas[x]![0] = hChar
|
|
89
|
-
canvas[x]![height - 1] = hChar
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Center the label
|
|
94
|
-
const lines = splitLines(label)
|
|
95
|
-
const startY = centerY - Math.floor((lines.length - 1) / 2)
|
|
96
|
-
|
|
97
|
-
for (let i = 0; i < lines.length; i++) {
|
|
98
|
-
const line = lines[i]!
|
|
99
|
-
const textX = Math.floor(width / 2) - Math.floor(visualWidth(line) / 2)
|
|
100
|
-
const y = startY + i
|
|
101
|
-
if (textX > 0 && y >= 0 && y < height) {
|
|
102
|
-
drawText(canvas, { x: textX, y }, line, true)
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return canvas
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
getAttachmentPoint: getBoxAttachmentPoint,
|
|
110
|
-
}
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
// ============================================================================
|
|
2
|
-
// State pseudo-state renderers — UML start and end states
|
|
3
|
-
// ============================================================================
|
|
4
|
-
|
|
5
|
-
import type { Canvas, DrawingCoord, Direction } from '../types.ts'
|
|
6
|
-
import { Up, Down, Left, Right, UpperLeft, UpperRight, LowerLeft, LowerRight } from '../types.ts'
|
|
7
|
-
import { mkCanvas } from '../canvas.ts'
|
|
8
|
-
import type { ShapeRenderer, ShapeDimensions, ShapeRenderOptions } from './types.ts'
|
|
9
|
-
import { dirEquals } from '../edge-routing.ts'
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* State start pseudo-state renderer — filled circle in rounded box.
|
|
13
|
-
* Renders as:
|
|
14
|
-
* ╭───╮
|
|
15
|
-
* │ ● │ (Unicode)
|
|
16
|
-
* ╰───╯
|
|
17
|
-
*
|
|
18
|
-
* .---.
|
|
19
|
-
* | * | (ASCII)
|
|
20
|
-
* '---'
|
|
21
|
-
*
|
|
22
|
-
* This represents the UML initial pseudo-state.
|
|
23
|
-
*/
|
|
24
|
-
export const stateStartRenderer: ShapeRenderer = {
|
|
25
|
-
getDimensions(_label: string, _options: ShapeRenderOptions): ShapeDimensions {
|
|
26
|
-
// Start state is a 5x3 rounded box with centered symbol
|
|
27
|
-
const width = 5
|
|
28
|
-
const height = 3
|
|
29
|
-
|
|
30
|
-
return {
|
|
31
|
-
width,
|
|
32
|
-
height,
|
|
33
|
-
labelArea: { x: 2, y: 1, width: 1, height: 1 },
|
|
34
|
-
gridColumns: [1, 3, 1],
|
|
35
|
-
gridRows: [1, 1, 1],
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
render(_label: string, dimensions: ShapeDimensions, options: ShapeRenderOptions): Canvas {
|
|
40
|
-
const { width, height } = dimensions
|
|
41
|
-
const canvas = mkCanvas(width - 1, height - 1)
|
|
42
|
-
|
|
43
|
-
const centerX = Math.floor(width / 2) // = 2
|
|
44
|
-
|
|
45
|
-
if (!options.useAscii) {
|
|
46
|
-
// Unicode rounded box with filled circle: ╭───╮ │ ● │ ╰───╯
|
|
47
|
-
canvas[0]![0] = '╭'
|
|
48
|
-
canvas[1]![0] = '─'
|
|
49
|
-
canvas[2]![0] = '─'
|
|
50
|
-
canvas[3]![0] = '─'
|
|
51
|
-
canvas[4]![0] = '╮'
|
|
52
|
-
|
|
53
|
-
canvas[0]![1] = '│'
|
|
54
|
-
canvas[centerX]![1] = '●'
|
|
55
|
-
canvas[4]![1] = '│'
|
|
56
|
-
|
|
57
|
-
canvas[0]![2] = '╰'
|
|
58
|
-
canvas[1]![2] = '─'
|
|
59
|
-
canvas[2]![2] = '─'
|
|
60
|
-
canvas[3]![2] = '─'
|
|
61
|
-
canvas[4]![2] = '╯'
|
|
62
|
-
} else {
|
|
63
|
-
// ASCII rounded box: .---. | * | '---'
|
|
64
|
-
canvas[0]![0] = '.'
|
|
65
|
-
canvas[1]![0] = '-'
|
|
66
|
-
canvas[2]![0] = '-'
|
|
67
|
-
canvas[3]![0] = '-'
|
|
68
|
-
canvas[4]![0] = '.'
|
|
69
|
-
|
|
70
|
-
canvas[0]![1] = '|'
|
|
71
|
-
canvas[centerX]![1] = '*'
|
|
72
|
-
canvas[4]![1] = '|'
|
|
73
|
-
|
|
74
|
-
canvas[0]![2] = '\''
|
|
75
|
-
canvas[1]![2] = '-'
|
|
76
|
-
canvas[2]![2] = '-'
|
|
77
|
-
canvas[3]![2] = '-'
|
|
78
|
-
canvas[4]![2] = '\''
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return canvas
|
|
82
|
-
},
|
|
83
|
-
|
|
84
|
-
getAttachmentPoint(
|
|
85
|
-
dir: Direction,
|
|
86
|
-
dimensions: ShapeDimensions,
|
|
87
|
-
baseCoord: DrawingCoord
|
|
88
|
-
): DrawingCoord {
|
|
89
|
-
const { width, height } = dimensions
|
|
90
|
-
const centerX = baseCoord.x + Math.floor(width / 2)
|
|
91
|
-
const centerY = baseCoord.y + Math.floor(height / 2)
|
|
92
|
-
|
|
93
|
-
if (dirEquals(dir, Up)) return { x: centerX, y: baseCoord.y }
|
|
94
|
-
if (dirEquals(dir, Down)) return { x: centerX, y: baseCoord.y + height - 1 }
|
|
95
|
-
if (dirEquals(dir, Left)) return { x: baseCoord.x, y: centerY }
|
|
96
|
-
if (dirEquals(dir, Right)) return { x: baseCoord.x + width - 1, y: centerY }
|
|
97
|
-
// All diagonals and middle point to center
|
|
98
|
-
return { x: centerX, y: centerY }
|
|
99
|
-
},
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* State end pseudo-state renderer — bullseye in double-bordered box.
|
|
104
|
-
* Renders as:
|
|
105
|
-
* ╔═══╗
|
|
106
|
-
* ║ ◎ ║ (Unicode)
|
|
107
|
-
* ╚═══╝
|
|
108
|
-
*
|
|
109
|
-
* #===#
|
|
110
|
-
* # * # (ASCII)
|
|
111
|
-
* #===#
|
|
112
|
-
*
|
|
113
|
-
* This represents the UML final state. The double border distinguishes it
|
|
114
|
-
* from the start state's single rounded border.
|
|
115
|
-
*/
|
|
116
|
-
export const stateEndRenderer: ShapeRenderer = {
|
|
117
|
-
getDimensions(_label: string, _options: ShapeRenderOptions): ShapeDimensions {
|
|
118
|
-
// End state is a 5x3 double-bordered box with centered symbol
|
|
119
|
-
const width = 5
|
|
120
|
-
const height = 3
|
|
121
|
-
|
|
122
|
-
return {
|
|
123
|
-
width,
|
|
124
|
-
height,
|
|
125
|
-
labelArea: { x: 2, y: 1, width: 1, height: 1 },
|
|
126
|
-
gridColumns: [1, 3, 1],
|
|
127
|
-
gridRows: [1, 1, 1],
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
render(_label: string, dimensions: ShapeDimensions, options: ShapeRenderOptions): Canvas {
|
|
132
|
-
const { width, height } = dimensions
|
|
133
|
-
const canvas = mkCanvas(width - 1, height - 1)
|
|
134
|
-
|
|
135
|
-
const centerX = Math.floor(width / 2) // = 2
|
|
136
|
-
|
|
137
|
-
if (!options.useAscii) {
|
|
138
|
-
// Unicode double-bordered box with bullseye: ╔═══╗ ║ ◎ ║ ╚═══╝
|
|
139
|
-
canvas[0]![0] = '╔'
|
|
140
|
-
canvas[1]![0] = '═'
|
|
141
|
-
canvas[2]![0] = '═'
|
|
142
|
-
canvas[3]![0] = '═'
|
|
143
|
-
canvas[4]![0] = '╗'
|
|
144
|
-
|
|
145
|
-
canvas[0]![1] = '║'
|
|
146
|
-
canvas[centerX]![1] = '◎'
|
|
147
|
-
canvas[4]![1] = '║'
|
|
148
|
-
|
|
149
|
-
canvas[0]![2] = '╚'
|
|
150
|
-
canvas[1]![2] = '═'
|
|
151
|
-
canvas[2]![2] = '═'
|
|
152
|
-
canvas[3]![2] = '═'
|
|
153
|
-
canvas[4]![2] = '╝'
|
|
154
|
-
} else {
|
|
155
|
-
// ASCII double-bordered box: #===# # * # #===#
|
|
156
|
-
canvas[0]![0] = '#'
|
|
157
|
-
canvas[1]![0] = '='
|
|
158
|
-
canvas[2]![0] = '='
|
|
159
|
-
canvas[3]![0] = '='
|
|
160
|
-
canvas[4]![0] = '#'
|
|
161
|
-
|
|
162
|
-
canvas[0]![1] = '#'
|
|
163
|
-
canvas[centerX]![1] = '*'
|
|
164
|
-
canvas[4]![1] = '#'
|
|
165
|
-
|
|
166
|
-
canvas[0]![2] = '#'
|
|
167
|
-
canvas[1]![2] = '='
|
|
168
|
-
canvas[2]![2] = '='
|
|
169
|
-
canvas[3]![2] = '='
|
|
170
|
-
canvas[4]![2] = '#'
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return canvas
|
|
174
|
-
},
|
|
175
|
-
|
|
176
|
-
getAttachmentPoint(
|
|
177
|
-
dir: Direction,
|
|
178
|
-
dimensions: ShapeDimensions,
|
|
179
|
-
baseCoord: DrawingCoord
|
|
180
|
-
): DrawingCoord {
|
|
181
|
-
const { width, height } = dimensions
|
|
182
|
-
const centerX = baseCoord.x + Math.floor(width / 2)
|
|
183
|
-
const centerY = baseCoord.y + Math.floor(height / 2)
|
|
184
|
-
|
|
185
|
-
if (dirEquals(dir, Up)) return { x: centerX, y: baseCoord.y }
|
|
186
|
-
if (dirEquals(dir, Down)) return { x: centerX, y: baseCoord.y + height - 1 }
|
|
187
|
-
if (dirEquals(dir, Left)) return { x: baseCoord.x, y: centerY }
|
|
188
|
-
if (dirEquals(dir, Right)) return { x: baseCoord.x + width - 1, y: centerY }
|
|
189
|
-
// All diagonals and middle point to center
|
|
190
|
-
return { x: centerX, y: centerY }
|
|
191
|
-
},
|
|
192
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
// ============================================================================
|
|
2
|
-
// Shape renderer types — interface for pluggable ASCII shape renderers
|
|
3
|
-
// ============================================================================
|
|
4
|
-
|
|
5
|
-
import type { Canvas, DrawingCoord, Direction, AsciiNodeShape } from '../types.ts'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Dimensions calculated for a shape, used by layout and rendering.
|
|
9
|
-
*/
|
|
10
|
-
export interface ShapeDimensions {
|
|
11
|
-
/** Total width in characters including borders */
|
|
12
|
-
width: number
|
|
13
|
-
/** Total height in characters including borders */
|
|
14
|
-
height: number
|
|
15
|
-
/** Label area bounds (where text can be placed) */
|
|
16
|
-
labelArea: {
|
|
17
|
-
x: number
|
|
18
|
-
y: number
|
|
19
|
-
width: number
|
|
20
|
-
height: number
|
|
21
|
-
}
|
|
22
|
-
/** Grid column widths for the 3-column layout [left, center, right] */
|
|
23
|
-
gridColumns: [number, number, number]
|
|
24
|
-
/** Grid row heights for the 3-row layout [top, middle, bottom] */
|
|
25
|
-
gridRows: [number, number, number]
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Options passed to shape renderers.
|
|
30
|
-
*/
|
|
31
|
-
export interface ShapeRenderOptions {
|
|
32
|
-
/** Use ASCII chars (+,-,|) vs Unicode box-drawing (┌,─,│) */
|
|
33
|
-
useAscii: boolean
|
|
34
|
-
/** Padding inside the shape */
|
|
35
|
-
padding: number
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Interface for pluggable shape renderers.
|
|
40
|
-
* Each shape type implements this interface.
|
|
41
|
-
*/
|
|
42
|
-
export interface ShapeRenderer {
|
|
43
|
-
/**
|
|
44
|
-
* Calculate dimensions for this shape given a label.
|
|
45
|
-
* Used during layout to determine node size.
|
|
46
|
-
*/
|
|
47
|
-
getDimensions(label: string, options: ShapeRenderOptions): ShapeDimensions
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Render the shape to a canvas.
|
|
51
|
-
* Returns a standalone canvas containing just the shape.
|
|
52
|
-
*/
|
|
53
|
-
render(
|
|
54
|
-
label: string,
|
|
55
|
-
dimensions: ShapeDimensions,
|
|
56
|
-
options: ShapeRenderOptions
|
|
57
|
-
): Canvas
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Get the edge attachment point for a given direction.
|
|
61
|
-
* Used by edge routing to determine where edges connect.
|
|
62
|
-
*/
|
|
63
|
-
getAttachmentPoint(
|
|
64
|
-
dir: Direction,
|
|
65
|
-
dimensions: ShapeDimensions,
|
|
66
|
-
baseCoord: DrawingCoord
|
|
67
|
-
): DrawingCoord
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Registry of shape renderers keyed by shape type.
|
|
72
|
-
*/
|
|
73
|
-
export type ShapeRegistry = Map<AsciiNodeShape, ShapeRenderer>
|
package/src/ascii/timeline.ts
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
// ============================================================================
|
|
2
|
-
// ASCII renderer — timeline diagrams
|
|
3
|
-
//
|
|
4
|
-
// Renders Mermaid timeline syntax as a chronological outline with per-period
|
|
5
|
-
// markers and indented milestone lists. This keeps the ASCII variant compact
|
|
6
|
-
// and readable in terminals while preserving chronology and section grouping.
|
|
7
|
-
// ============================================================================
|
|
8
|
-
|
|
9
|
-
import { parseTimelineDiagram } from '../timeline/parser.ts'
|
|
10
|
-
import { colorizeLine, DEFAULT_ASCII_THEME } from './ansi.ts'
|
|
11
|
-
import type { AsciiConfig, AsciiTheme, CharRole, ColorMode } from './types.ts'
|
|
12
|
-
import { wrapText } from './wrap.ts'
|
|
13
|
-
|
|
14
|
-
interface StyledSegment {
|
|
15
|
-
text: string
|
|
16
|
-
role: CharRole | null
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function renderStyledLine(
|
|
20
|
-
segments: StyledSegment[],
|
|
21
|
-
colorMode: ColorMode,
|
|
22
|
-
theme: AsciiTheme,
|
|
23
|
-
): string {
|
|
24
|
-
const chars: string[] = []
|
|
25
|
-
const roles: (CharRole | null)[] = []
|
|
26
|
-
|
|
27
|
-
for (const segment of segments) {
|
|
28
|
-
for (const char of segment.text) {
|
|
29
|
-
chars.push(char)
|
|
30
|
-
roles.push(segment.role)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return colorizeLine(chars, roles, theme, colorMode)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Render a Mermaid timeline diagram to ASCII/Unicode text.
|
|
39
|
-
*/
|
|
40
|
-
export function renderTimelineAscii(
|
|
41
|
-
lines: string[],
|
|
42
|
-
config: AsciiConfig,
|
|
43
|
-
colorMode: ColorMode = 'none',
|
|
44
|
-
theme: AsciiTheme = DEFAULT_ASCII_THEME,
|
|
45
|
-
maxWidth?: number,
|
|
46
|
-
): string {
|
|
47
|
-
const diagram = parseTimelineDiagram(lines)
|
|
48
|
-
const useAscii = config.useAscii
|
|
49
|
-
|
|
50
|
-
const marker = useAscii ? 'o' : '○'
|
|
51
|
-
const vertical = useAscii ? '|' : '│'
|
|
52
|
-
const branch = useAscii ? '|' : '├'
|
|
53
|
-
const lastBranch = useAscii ? '`' : '└'
|
|
54
|
-
const horizontal = useAscii ? '-' : '─'
|
|
55
|
-
const periodContinuation = ' '
|
|
56
|
-
|
|
57
|
-
const out: string[] = []
|
|
58
|
-
const pushLine = (segments: StyledSegment[] = []): void => {
|
|
59
|
-
out.push(segments.length === 0 ? '' : renderStyledLine(segments, colorMode, theme))
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (diagram.title) {
|
|
63
|
-
for (const line of wrapText(diagram.title, maxWidth)) {
|
|
64
|
-
pushLine([{ text: line, role: 'text' }])
|
|
65
|
-
}
|
|
66
|
-
pushLine()
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
for (let sectionIndex = 0; sectionIndex < diagram.sections.length; sectionIndex++) {
|
|
70
|
-
const section = diagram.sections[sectionIndex]!
|
|
71
|
-
|
|
72
|
-
if (section.label) {
|
|
73
|
-
// Bracket only the first line of a wrapped label — bracketing every
|
|
74
|
-
// line would read as one section per line. Continuations indent by
|
|
75
|
-
// one cell to align inside the opening bracket.
|
|
76
|
-
const labelLines = wrapText(section.label.replace(/\n/g, ' / '), maxWidth ? Math.max(1, maxWidth - 2) : undefined)
|
|
77
|
-
labelLines.forEach((line, index) => {
|
|
78
|
-
const segments: StyledSegment[] = [
|
|
79
|
-
index === 0
|
|
80
|
-
? { text: '[', role: 'border' }
|
|
81
|
-
: { text: ' ', role: null },
|
|
82
|
-
{ text: line, role: 'text' },
|
|
83
|
-
]
|
|
84
|
-
if (index === labelLines.length - 1) segments.push({ text: ']', role: 'border' })
|
|
85
|
-
pushLine(segments)
|
|
86
|
-
})
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
for (let periodIndex = 0; periodIndex < section.periods.length; periodIndex++) {
|
|
90
|
-
const period = section.periods[periodIndex]!
|
|
91
|
-
// Continuation lines carry the wider 3-cell prefix, so wrap to that.
|
|
92
|
-
const periodLines = wrapText(period.label, maxWidth ? Math.max(1, maxWidth - 3) : undefined)
|
|
93
|
-
|
|
94
|
-
pushLine([
|
|
95
|
-
{ text: marker, role: 'junction' },
|
|
96
|
-
{ text: ' ', role: null },
|
|
97
|
-
{ text: periodLines[0] ?? '', role: 'text' },
|
|
98
|
-
])
|
|
99
|
-
for (const line of periodLines.slice(1)) {
|
|
100
|
-
pushLine([
|
|
101
|
-
{ text: `${periodContinuation} `, role: null },
|
|
102
|
-
{ text: line, role: 'text' },
|
|
103
|
-
])
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
for (let eventIndex = 0; eventIndex < period.events.length; eventIndex++) {
|
|
107
|
-
const event = period.events[eventIndex]!
|
|
108
|
-
// First-line prefix ('│ ├─ ') is 6 cells wide.
|
|
109
|
-
const eventLines = wrapText(event.text, maxWidth ? Math.max(1, maxWidth - 6) : undefined)
|
|
110
|
-
const junction = eventIndex === period.events.length - 1 ? lastBranch : branch
|
|
111
|
-
pushLine([
|
|
112
|
-
{ text: vertical, role: 'line' },
|
|
113
|
-
{ text: ' ', role: null },
|
|
114
|
-
{ text: junction, role: eventIndex === period.events.length - 1 ? 'corner' : 'junction' },
|
|
115
|
-
{ text: horizontal, role: 'line' },
|
|
116
|
-
{ text: ' ', role: null },
|
|
117
|
-
{ text: eventLines[0] ?? '', role: 'text' },
|
|
118
|
-
])
|
|
119
|
-
|
|
120
|
-
for (const line of eventLines.slice(1)) {
|
|
121
|
-
pushLine(eventIndex === period.events.length - 1
|
|
122
|
-
? [
|
|
123
|
-
{ text: ' ', role: null },
|
|
124
|
-
{ text: line, role: 'text' },
|
|
125
|
-
]
|
|
126
|
-
: [
|
|
127
|
-
{ text: vertical, role: 'line' },
|
|
128
|
-
{ text: ' ', role: null },
|
|
129
|
-
{ text: line, role: 'text' },
|
|
130
|
-
])
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const morePeriods = periodIndex < section.periods.length - 1
|
|
135
|
-
const moreSections = sectionIndex < diagram.sections.length - 1
|
|
136
|
-
if (morePeriods || moreSections) pushLine()
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return out.join('\n').trimEnd()
|
|
141
|
-
}
|