ec27228a8e
Em dashes (—) and en dashes (–) had spread across comments, docs, tests, and a few UI strings, reading as AI-generated boilerplate rather than house style. Replaced each with punctuation matching its context: colon for explanatory clauses, comma for asides, plain hyphen for numeric/legal ranges (e.g. "21-23§"), "to"/"till" for date ranges, parentheses for paired-dash asides. messages/en.json and messages/sv.json were fixed by hand together to keep sv/en in sync. Left untouched where the dash is the functional subject rather than decorative punctuation: date-range-parser.ts's separator regex, charset-repair.ts's CP1252 byte-mapping table (and its test), the SIE encoding mojibake docs, generic-csv.ts's minus-sign normalizer, the agent system-prompt files that already instruct against em dashes, and a golden iXBRL test fixture compared byte-for-byte. Also fixes two bugs surfaced along the way: an off-by-one in ApiKeysPanel's scope-label split (a leftover from an earlier partial pass), and a charset-repair test that had lost the literal en-dash it exists to verify. Regenerated the agent atom seed migration (skills:generate) since 27 SKILL.md files changed. Added a CLAUDE.md rule against em/en dashes, with an explicit carve-out for the functional-dash cases above. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2.5 KiB
2.5 KiB
Manifest Format Reference
Every extension has a manifest.json in extensions/<sector>/<name>/.
Complete Schema
{
"id": "my-extension",
"sector": "general",
"exportName": "myExtensionExtension",
"entryPoint": "@/extensions/general/my-extension",
"workspace": "@/components/extensions/general/MyExtensionWorkspace",
"requiredEnvVars": ["MY_API_KEY"],
"optionalEnvVars": [],
"npmDependencies": ["some-package"],
"definition": {
"name": "My Extension",
"category": "operations",
"icon": "Box",
"dataPattern": "core",
"description": "Short marketplace card text",
"longDescription": "Longer detail page text.",
"readsCoreTables": ["invoices", "transactions"],
"hasOwnData": true,
"quickAction": { "label": "Do Thing", "description": "Short desc", "icon": "Zap", "href": "/path" },
"subscriptionNotice": "Requires external subscription to X"
}
}
Top-Level Fields
| Field | Type | Description |
|---|---|---|
id |
string | Kebab-case ID, must match directory name |
sector |
string | "general" (future: "restaurant", "construction", etc.) |
exportName |
string | camelCase export name: toCamelCase(id) + "Extension" |
entryPoint |
string | Path alias: "@/extensions/{sector}/{id}" |
workspace |
string | null | Workspace component path, or null |
requiredEnvVars |
string[] | Required env vars (empty [] if none) |
optionalEnvVars |
string[] | Optional env vars (empty [] if none) |
npmDependencies |
string[] | Package deps for documentation (empty [] if none) |
Definition Fields
| Field | Required | Description |
|---|---|---|
name |
Yes | Display name |
category |
Yes | "import" / "operations" / "reports" / "accounting" |
icon |
Yes | Lucide icon name (e.g., "Camera", "Sparkles", "Bell"): falls back to "Puzzle" |
dataPattern |
Yes | "core" (reads core tables) / "manual" (own data) / "both" |
description |
Yes | Short marketplace card text |
longDescription |
Yes | Longer detail page text |
readsCoreTables |
No | Which core tables it reads |
hasOwnData |
No | Whether it stores extension-specific data |
quickAction |
No | Dashboard quick action: { label, description, icon, href?, event?, order? } |
subscriptionNotice |
No | Warning shown when enabling |
Naming Convention
my-extension → myExtension → myExtensionExtension (export) → @/extensions/general/my-extension (entry point)