@skill-map/spec 0.20.0 → 0.22.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/CHANGELOG.md +306 -0
- package/architecture.md +73 -13
- package/cli-contract.md +47 -25
- package/conformance/coverage.md +1 -1
- package/conformance/fixtures/plugin-missing-ui/.skill-map/plugins/bad-provider/provider.js +0 -1
- package/db-schema.md +4 -1
- package/index.json +13 -13
- package/package.json +3 -2
- package/plugin-author-guide.md +30 -13
- package/plugin-kv-api.md +1 -1
- package/schemas/api/rest-envelope.schema.json +5 -1
- package/schemas/extensions/provider.schema.json +2 -7
- package/schemas/project-config.schema.json +7 -7
- package/schemas/view-slots.schema.json +8 -7
|
@@ -58,19 +58,15 @@
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
},
|
|
61
|
-
"
|
|
62
|
-
"type": "boolean",
|
|
63
|
-
"description": "**Privacy-sensitive** — opens disk access outside the project. Default false. When true, `sm scan` (without `-g`) appends every active Provider's `explorationDir` resolved against `~` (typically `~/.claude`, `~/.gemini`, `~/.agents`) to the scan roots. Files there are walked, parsed, and indexed as nodes alongside the project content. Reference impl: `sm config set scan.includeHome true` requires `--yes` to confirm; the Settings UI's Project section requires an explicit confirm dialog. The scan emits a stderr line listing the HOME paths it added so the operator sees the expanded surface."
|
|
64
|
-
},
|
|
65
|
-
"extraRoots": {
|
|
61
|
+
"extraFolders": {
|
|
66
62
|
"type": "array",
|
|
67
63
|
"items": { "type": "string" },
|
|
68
|
-
"description": "**Privacy-sensitive** when entries point outside the project — opens disk access there. Default `[]`. Additional directories appended to the scan roots; same parsing / indexing as the project root. Paths starting with `~` resolve against the user home; relative paths resolve against the project root. Reference impl gates writes that introduce out-of-project paths behind `--yes` (CLI) and a confirm dialog (UI)
|
|
64
|
+
"description": "**Privacy-sensitive, project-local only** (per `core/config/helper:PROJECT_LOCAL_ONLY_KEYS`) when entries point outside the project — opens disk access there. Default `[]`. Additional directories appended to the scan roots; same parsing / indexing as the project root. Paths starting with `~` resolve against the user home; relative paths resolve against the project root. Reference impl gates writes that introduce out-of-project paths behind `--yes` (CLI) and a confirm dialog (UI). **Stripped with a warning when found in the committed `project` layer** — paths are inherently per-machine and must not travel via the shared repo. This is the ONLY mechanism to extend the scan beyond the project root: skill-map does NOT auto-include the user's HOME based on Provider hints — every out-of-project path must be listed here explicitly."
|
|
69
65
|
},
|
|
70
66
|
"referencePaths": {
|
|
71
67
|
"type": "array",
|
|
72
68
|
"items": { "type": "string" },
|
|
73
|
-
"description": "**Privacy-sensitive** when entries point outside the project — opens read-only disk access for link validation only. Default `[]`. Directories walked in parallel by the scan to collect existing absolute paths into a side set; the kernel passes the set to analyzers via `IAnalyzerContext.referenceablePaths` so `core/broken-ref` can resolve a link against the filesystem when the in-graph lookup misses. Files under these paths are NOT parsed and NOT indexed as nodes — the only effect is suppressing `broken-ref` warnings for targets that exist on disk outside the scan. Same write-gate analyzers as `
|
|
69
|
+
"description": "**Privacy-sensitive, project-local only** (per `core/config/helper:PROJECT_LOCAL_ONLY_KEYS`) when entries point outside the project — opens read-only disk access for link validation only. Default `[]`. Directories walked in parallel by the scan to collect existing absolute paths into a side set; the kernel passes the set to analyzers via `IAnalyzerContext.referenceablePaths` so `core/broken-ref` can resolve a link against the filesystem when the in-graph lookup misses. Files under these paths are NOT parsed and NOT indexed as nodes — the only effect is suppressing `broken-ref` warnings for targets that exist on disk outside the scan. Same write-gate analyzers as `extraFolders`. **Stripped with a warning when found in the committed `project` layer**."
|
|
74
70
|
}
|
|
75
71
|
}
|
|
76
72
|
},
|
|
@@ -144,6 +140,10 @@
|
|
|
144
140
|
"locale": { "type": "string", "description": "BCP-47 tag. Default `en`." }
|
|
145
141
|
}
|
|
146
142
|
},
|
|
143
|
+
"allowEditSmFiles": {
|
|
144
|
+
"type": "boolean",
|
|
145
|
+
"description": "**Project-local only** (per `core/config/helper:PROJECT_LOCAL_ONLY_KEYS`). Grants this project permission to create / modify `.sm` annotation sidecars next to source files. Default `false`. The first time a verb or BFF route attempts a `.sm` write while this is `false`, the kernel raises `EConsentRequiredError`. The CLI surfaces it as an interactive `confirm()` prompt (or `--yes` bypass); the BFF returns 412 `confirm-required` so the UI can open a `ConfirmationService` dialog. On accept the flag is persisted to `<cwd>/.skill-map/settings.local.json` (gitignored, per-checkout) and never asked again. On decline the operation aborts WITHOUT persisting the rejection — the next attempt re-asks. **Stripped with a warning when found in the committed `project` layer** (`<cwd>/.skill-map/settings.json`) — each developer consents independently."
|
|
146
|
+
},
|
|
147
147
|
"updateCheck": {
|
|
148
148
|
"type": "object",
|
|
149
149
|
"additionalProperties": false,
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"enum": [
|
|
11
11
|
"card.title.right",
|
|
12
12
|
"card.subtitle.left",
|
|
13
|
-
"card.footer.left
|
|
13
|
+
"card.footer.left",
|
|
14
14
|
"card.footer.right",
|
|
15
15
|
"graph.node.alert",
|
|
16
16
|
"inspector.header.badge.counter",
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"inspector.body.panel.key-values",
|
|
22
22
|
"inspector.body.panel.link-list",
|
|
23
23
|
"inspector.body.panel.markdown",
|
|
24
|
-
"topbar.
|
|
24
|
+
"topbar.nav.start"
|
|
25
25
|
],
|
|
26
|
-
"description": "Closed enum of slot identifiers. Adding an entry requires the full spec/UI/scaffolder/conformance round-trip per ROADMAP.md §UI contribution system. Removing or renaming an entry is a catalog-major-bump and triggers `sm plugins upgrade` migration. Slots that share a payload shape (e.g. `card.subtitle.left`, `card.footer.right`, and `card.footer.left
|
|
26
|
+
"description": "Closed enum of slot identifiers. Adding an entry requires the full spec/UI/scaffolder/conformance round-trip per ROADMAP.md §UI contribution system. Removing or renaming an entry is a catalog-major-bump and triggers `sm plugins upgrade` migration. Slots that share a payload shape (e.g. `card.subtitle.left`, `card.footer.right`, and `card.footer.left` all carry a counter) reference the same payload schema in `$defs.payloads`."
|
|
27
27
|
},
|
|
28
28
|
"Severity": {
|
|
29
29
|
"type": "string",
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"type": "string",
|
|
35
35
|
"minLength": 1,
|
|
36
36
|
"maxLength": 64,
|
|
37
|
-
"
|
|
37
|
+
"pattern": "^(?:pi pi-[a-z0-9-]+|pi-[a-z0-9-]+|fa-(?:solid|regular|brands) fa-[a-z0-9-]+|fa-[a-z0-9-]+|[^a-zA-Z].*)$",
|
|
38
|
+
"description": "Single string, prefix-discriminated by the UI. Four valid shapes: (1) emoji — any value starting with a non-ASCII-letter codepoint renders as text; (2) PrimeIcons — `pi-foo` or `pi pi-foo` renders as `<i class=\"pi pi-foo\">`; (3) FontAwesome explicit family — `fa-solid fa-foo` / `fa-regular fa-foo` / `fa-brands fa-foo` passes through as-is; (4) FontAwesome shorthand — `fa-foo` (no family token) defaults to `fa-solid fa-foo`. Bare class names without a `pi-` / `fa-` prefix are rejected at manifest load (invalid-manifest). Unknown PrimeIcons / FontAwesome names render no icon (silent fallback) plus a console warning."
|
|
38
39
|
},
|
|
39
40
|
"IViewContribution": {
|
|
40
41
|
"type": "object",
|
|
@@ -76,7 +77,7 @@
|
|
|
76
77
|
"slot": {
|
|
77
78
|
"enum": [
|
|
78
79
|
"card.subtitle.left",
|
|
79
|
-
"card.footer.left
|
|
80
|
+
"card.footer.left",
|
|
80
81
|
"card.footer.right",
|
|
81
82
|
"inspector.header.badge.counter"
|
|
82
83
|
]
|
|
@@ -108,7 +109,7 @@
|
|
|
108
109
|
"description": "Single icon per node — small standalone marker rendered next to the card title. The manifest requires `icon`; the payload optionally overrides it per node and may add `severity` (color tint) and `tooltip`. No counts, no labels — for chip + number use a counter slot; for label + severity use a tag slot. 'Empty' for `emitWhenEmpty` is the absence of both payload `icon` and a manifest fallback (in practice never empty since the manifest icon is required)."
|
|
109
110
|
},
|
|
110
111
|
"card.subtitle.left": { "$ref": "#/$defs/payloads/_counter" },
|
|
111
|
-
"card.footer.left
|
|
112
|
+
"card.footer.left": { "$ref": "#/$defs/payloads/_counter" },
|
|
112
113
|
"card.footer.right": { "$ref": "#/$defs/payloads/_counter" },
|
|
113
114
|
"inspector.header.badge.counter": { "$ref": "#/$defs/payloads/_counter" },
|
|
114
115
|
"_counter": {
|
|
@@ -312,7 +313,7 @@
|
|
|
312
313
|
}
|
|
313
314
|
}
|
|
314
315
|
},
|
|
315
|
-
"topbar.
|
|
316
|
+
"topbar.nav.start": {
|
|
316
317
|
"type": "object",
|
|
317
318
|
"additionalProperties": false,
|
|
318
319
|
"required": ["value"],
|