@skill-map/cli 0.3.1

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/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # skill-map
2
+
3
+ Map, inspect, and manage collections of interrelated Markdown files — skills, agents, commands, hooks, and notes that compose AI-agent ecosystems (Claude Code, Codex, Gemini, Copilot, Obsidian vaults, docs sites).
4
+
5
+ **Status**: pre-MVP / preview release. Steps 0a (spec), 0b (kernel shell), 0c (UI prototype), 1a-1c (kernel + registry + orchestrator), 2 (first extensions), and 3 (UI design refinement) are complete; the CLI currently exposes `sm scan` as a stub (full scan lands at Step 4). See [`ROADMAP.md`](../ROADMAP.md) for the full execution plan and the canonical completeness marker. Subsequent versions follow the standard changeset flow.
6
+
7
+ ## Requirements
8
+
9
+ - **Node.js ≥ 24.0** (active LTS since October 2025). Older versions are unsupported.
10
+ - Any platform Node 24 supports (Linux, macOS, Windows).
11
+
12
+ `skill-map` checks the runtime version at the first `sm` invocation and exits with a human-readable message if Node is too old — no silent partial runs.
13
+
14
+ If your system is on Node 22 or 20, install the latest LTS from [nodejs.org](https://nodejs.org) (or via `nvm`, `fnm`, `volta`, …) before installing this package.
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ # Global
20
+ npm install --global @skill-map/cli
21
+
22
+ # Or run without installing
23
+ npx @skill-map/cli --version
24
+ ```
25
+
26
+ Both `sm` (short, daily use) and `skill-map` (full name, scripts) are registered as binaries after install. The package name is scoped (`@skill-map/cli`) to sit alongside `@skill-map/spec` under the same npm org; the binaries keep the unprefixed names for ergonomics.
27
+
28
+ ## Usage
29
+
30
+ ```bash
31
+ sm --version # single-line version
32
+ sm version # multi-line matrix (sm / kernel / spec / runtime / db-schema)
33
+ sm --help # top-level help
34
+ sm scan [roots...] [--json] # stub in 0b; full scan in Step 4
35
+ ```
36
+
37
+ Exit codes follow [`spec/cli-contract.md`](../spec/cli-contract.md):
38
+
39
+ | Code | Meaning |
40
+ |---|---|
41
+ | `0` | OK |
42
+ | `1` | Issues found at error severity |
43
+ | `2` | Operational error (bad flags, missing DB, unreadable file, runtime too old) |
44
+ | `3` | Duplicate job conflict |
45
+ | `4` | Nonce mismatch |
46
+ | `5` | Resource not found |
47
+
48
+ ## Spec
49
+
50
+ This binary implements the [skill-map spec](https://www.npmjs.com/package/@skill-map/spec). The spec package ships JSON Schemas, conformance cases, and prose contracts; `skill-map` conforms to a declared range via its `specCompat`.
51
+
52
+ ## License
53
+
54
+ MIT. See [`LICENSE`](../LICENSE).
package/bin/sm.mjs ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ // Runtime guard — fail fast with a human message before importing anything
3
+ // that uses Node 24 APIs (node:sqlite stable, built-in WebSocket, modern
4
+ // ESM loader). Without this, a user on Node 20/22 gets an obscure
5
+ // SyntaxError or "module not found" instead of guidance.
6
+ const [major] = process.versions.node.split('.').map(Number);
7
+ if (major < 24) {
8
+ process.stderr.write(
9
+ `skill-map requires Node.js >= 24 (found v${process.versions.node}).
10
+
11
+ Node 24 is the active LTS since October 2025 and brings:
12
+ - stable node:sqlite (used for the skill-map database)
13
+ - built-in WebSocket client
14
+ - modern ESM loader
15
+
16
+ Install the latest LTS from https://nodejs.org and retry.
17
+ `,
18
+ );
19
+ process.exit(2);
20
+ }
21
+
22
+ import('../dist/cli.js').catch((err) => {
23
+ process.stderr.write(`sm: failed to load CLI — ${err.message}\n`);
24
+ process.exit(2);
25
+ });
@@ -0,0 +1,185 @@
1
+ -- Kernel initial migration. Provisions the 11 kernel tables per
2
+ -- spec/db-schema.md. Up-only. Wrapped in BEGIN / COMMIT by the runner.
3
+
4
+ -- --- Scan zone -------------------------------------------------------------
5
+
6
+ CREATE TABLE scan_nodes (
7
+ path TEXT PRIMARY KEY,
8
+ kind TEXT NOT NULL,
9
+ adapter TEXT NOT NULL,
10
+ title TEXT,
11
+ description TEXT,
12
+ stability TEXT,
13
+ version TEXT,
14
+ author TEXT,
15
+ frontmatter_json TEXT NOT NULL,
16
+ body_hash TEXT NOT NULL,
17
+ frontmatter_hash TEXT NOT NULL,
18
+ bytes_frontmatter INTEGER NOT NULL,
19
+ bytes_body INTEGER NOT NULL,
20
+ bytes_total INTEGER NOT NULL,
21
+ tokens_frontmatter INTEGER,
22
+ tokens_body INTEGER,
23
+ tokens_total INTEGER,
24
+ links_out_count INTEGER NOT NULL DEFAULT 0,
25
+ links_in_count INTEGER NOT NULL DEFAULT 0,
26
+ external_refs_count INTEGER NOT NULL DEFAULT 0,
27
+ scanned_at INTEGER NOT NULL,
28
+ CONSTRAINT ck_scan_nodes_kind CHECK (kind IN ('skill','agent','command','hook','note')),
29
+ CONSTRAINT ck_scan_nodes_stability CHECK (stability IS NULL OR stability IN ('experimental','stable','deprecated'))
30
+ );
31
+ CREATE INDEX ix_scan_nodes_kind ON scan_nodes(kind);
32
+ CREATE INDEX ix_scan_nodes_adapter ON scan_nodes(adapter);
33
+ CREATE INDEX ix_scan_nodes_body_hash ON scan_nodes(body_hash);
34
+
35
+ CREATE TABLE scan_links (
36
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
37
+ source_path TEXT NOT NULL,
38
+ target_path TEXT NOT NULL,
39
+ kind TEXT NOT NULL,
40
+ confidence TEXT NOT NULL,
41
+ sources_json TEXT NOT NULL,
42
+ original_trigger TEXT,
43
+ normalized_trigger TEXT,
44
+ location_line INTEGER,
45
+ location_column INTEGER,
46
+ location_offset INTEGER,
47
+ raw TEXT,
48
+ CONSTRAINT ck_scan_links_kind CHECK (kind IN ('invokes','references','mentions','supersedes')),
49
+ CONSTRAINT ck_scan_links_confidence CHECK (confidence IN ('high','medium','low'))
50
+ );
51
+ CREATE INDEX ix_scan_links_source_path ON scan_links(source_path);
52
+ CREATE INDEX ix_scan_links_target_path ON scan_links(target_path);
53
+ CREATE INDEX ix_scan_links_normalized_trigger ON scan_links(normalized_trigger);
54
+
55
+ CREATE TABLE scan_issues (
56
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
57
+ rule_id TEXT NOT NULL,
58
+ severity TEXT NOT NULL,
59
+ node_ids_json TEXT NOT NULL,
60
+ link_indices_json TEXT,
61
+ message TEXT NOT NULL,
62
+ detail TEXT,
63
+ fix_json TEXT,
64
+ data_json TEXT,
65
+ CONSTRAINT ck_scan_issues_severity CHECK (severity IN ('error','warn','info'))
66
+ );
67
+ CREATE INDEX ix_scan_issues_rule_id ON scan_issues(rule_id);
68
+ CREATE INDEX ix_scan_issues_severity ON scan_issues(severity);
69
+
70
+ -- --- State zone ------------------------------------------------------------
71
+
72
+ CREATE TABLE state_jobs (
73
+ id TEXT PRIMARY KEY,
74
+ action_id TEXT NOT NULL,
75
+ action_version TEXT NOT NULL,
76
+ node_id TEXT NOT NULL,
77
+ content_hash TEXT NOT NULL,
78
+ nonce TEXT NOT NULL,
79
+ priority INTEGER NOT NULL DEFAULT 0,
80
+ status TEXT NOT NULL,
81
+ failure_reason TEXT,
82
+ runner TEXT,
83
+ ttl_seconds INTEGER NOT NULL,
84
+ file_path TEXT,
85
+ created_at INTEGER NOT NULL,
86
+ claimed_at INTEGER,
87
+ finished_at INTEGER,
88
+ expires_at INTEGER,
89
+ submitted_by TEXT,
90
+ CONSTRAINT ck_state_jobs_status CHECK (status IN ('queued','running','completed','failed')),
91
+ CONSTRAINT ck_state_jobs_failure_reason CHECK (failure_reason IS NULL OR failure_reason IN ('runner-error','report-invalid','timeout','abandoned','job-file-missing','user-cancelled')),
92
+ CONSTRAINT ck_state_jobs_runner CHECK (runner IS NULL OR runner IN ('cli','skill','in-process'))
93
+ );
94
+ CREATE INDEX ix_state_jobs_status ON state_jobs(status);
95
+ -- Unique partial index for duplicate-job detection: at most one
96
+ -- queued/running job per (action_id, node_id, content_hash).
97
+ CREATE UNIQUE INDEX ix_state_jobs_action_node_hash
98
+ ON state_jobs(action_id, node_id, content_hash)
99
+ WHERE status IN ('queued','running');
100
+
101
+ CREATE TABLE state_executions (
102
+ id TEXT PRIMARY KEY,
103
+ kind TEXT NOT NULL,
104
+ extension_id TEXT NOT NULL,
105
+ extension_version TEXT NOT NULL,
106
+ node_ids_json TEXT NOT NULL DEFAULT '[]',
107
+ content_hash TEXT,
108
+ status TEXT NOT NULL,
109
+ failure_reason TEXT,
110
+ exit_code INTEGER,
111
+ runner TEXT,
112
+ started_at INTEGER NOT NULL,
113
+ finished_at INTEGER NOT NULL,
114
+ duration_ms INTEGER,
115
+ tokens_in INTEGER,
116
+ tokens_out INTEGER,
117
+ report_path TEXT,
118
+ job_id TEXT,
119
+ CONSTRAINT ck_state_executions_kind CHECK (kind IN ('action','audit')),
120
+ CONSTRAINT ck_state_executions_status CHECK (status IN ('completed','failed','cancelled'))
121
+ );
122
+ CREATE INDEX ix_state_executions_extension_id ON state_executions(extension_id);
123
+ CREATE INDEX ix_state_executions_started_at ON state_executions(started_at);
124
+ CREATE INDEX ix_state_executions_job_id ON state_executions(job_id);
125
+
126
+ CREATE TABLE state_summaries (
127
+ node_id TEXT NOT NULL,
128
+ kind TEXT NOT NULL,
129
+ summarizer_action_id TEXT NOT NULL,
130
+ summarizer_version TEXT NOT NULL,
131
+ body_hash_at_generation TEXT NOT NULL,
132
+ generated_at INTEGER NOT NULL,
133
+ summary_json TEXT NOT NULL,
134
+ PRIMARY KEY (node_id, summarizer_action_id),
135
+ CONSTRAINT ck_state_summaries_kind CHECK (kind IN ('skill','agent','command','hook','note'))
136
+ );
137
+ CREATE INDEX ix_state_summaries_generated_at ON state_summaries(generated_at);
138
+
139
+ CREATE TABLE state_enrichments (
140
+ node_id TEXT NOT NULL,
141
+ provider_id TEXT NOT NULL,
142
+ data_json TEXT NOT NULL,
143
+ verified INTEGER,
144
+ fetched_at INTEGER NOT NULL,
145
+ stale_after INTEGER,
146
+ PRIMARY KEY (node_id, provider_id),
147
+ CONSTRAINT ck_state_enrichments_verified CHECK (verified IS NULL OR verified IN (0,1))
148
+ );
149
+ CREATE INDEX ix_state_enrichments_stale_after ON state_enrichments(stale_after);
150
+
151
+ CREATE TABLE state_plugin_kvs (
152
+ plugin_id TEXT NOT NULL,
153
+ node_id TEXT NOT NULL DEFAULT '',
154
+ key TEXT NOT NULL,
155
+ value_json TEXT NOT NULL,
156
+ updated_at INTEGER NOT NULL,
157
+ PRIMARY KEY (plugin_id, node_id, key)
158
+ );
159
+ CREATE INDEX ix_state_plugin_kvs_plugin_id ON state_plugin_kvs(plugin_id);
160
+
161
+ -- --- Config zone -----------------------------------------------------------
162
+
163
+ CREATE TABLE config_plugins (
164
+ plugin_id TEXT PRIMARY KEY,
165
+ enabled INTEGER NOT NULL DEFAULT 1,
166
+ config_json TEXT,
167
+ updated_at INTEGER NOT NULL,
168
+ CONSTRAINT ck_config_plugins_enabled CHECK (enabled IN (0,1))
169
+ );
170
+
171
+ CREATE TABLE config_preferences (
172
+ key TEXT PRIMARY KEY,
173
+ value_json TEXT NOT NULL,
174
+ updated_at INTEGER NOT NULL
175
+ );
176
+
177
+ CREATE TABLE config_schema_versions (
178
+ scope TEXT NOT NULL,
179
+ owner_id TEXT NOT NULL,
180
+ version INTEGER NOT NULL,
181
+ description TEXT NOT NULL,
182
+ applied_at INTEGER NOT NULL,
183
+ PRIMARY KEY (scope, owner_id, version),
184
+ CONSTRAINT ck_config_schema_versions_scope CHECK (scope IN ('kernel','plugin'))
185
+ );
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@skill-map/cli",
3
+ "version": "0.3.1",
4
+ "description": "skill-map reference implementation — kernel + CLI + adapters.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "homepage": "https://skill-map.dev",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/crystian/skill-map.git",
11
+ "directory": "src"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/crystian/skill-map/issues"
15
+ },
16
+ "keywords": [
17
+ "skill-map",
18
+ "markdown",
19
+ "ai-agents",
20
+ "claude-code",
21
+ "graph"
22
+ ],
23
+ "bin": {
24
+ "sm": "bin/sm.mjs",
25
+ "skill-map": "bin/sm.mjs"
26
+ },
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ },
32
+ "./kernel": {
33
+ "types": "./dist/kernel/index.d.ts",
34
+ "import": "./dist/kernel/index.js"
35
+ },
36
+ "./conformance": {
37
+ "types": "./dist/conformance/index.d.ts",
38
+ "import": "./dist/conformance/index.js"
39
+ }
40
+ },
41
+ "files": [
42
+ "bin/",
43
+ "dist/",
44
+ "migrations/",
45
+ "README.md"
46
+ ],
47
+ "scripts": {
48
+ "build": "tsup",
49
+ "dev": "tsup --watch",
50
+ "typecheck": "tsc --noEmit",
51
+ "test": "node --import tsx --test --test-reporter=spec 'test/**/*.test.ts' 'extensions/**/*.test.ts' 'kernel/**/*.test.ts'",
52
+ "test:ci": "node --import tsx --test 'test/**/*.test.ts' 'extensions/**/*.test.ts' 'kernel/**/*.test.ts'",
53
+ "clean": "rm -rf dist"
54
+ },
55
+ "dependencies": {
56
+ "@skill-map/spec": "*",
57
+ "ajv": "8.18.0",
58
+ "ajv-formats": "3.0.1",
59
+ "clipanion": "4.0.0-rc.4",
60
+ "js-yaml": "4.1.1",
61
+ "kysely": "0.28.16",
62
+ "semver": "7.7.4",
63
+ "typanion": "3.14.0"
64
+ },
65
+ "devDependencies": {
66
+ "@types/js-yaml": "4.0.9",
67
+ "@types/node": "24.12.2",
68
+ "@types/semver": "7.7.1",
69
+ "tsup": "8.5.1",
70
+ "tsx": "4.21.0",
71
+ "typescript": "5.9.3"
72
+ },
73
+ "engines": {
74
+ "node": ">=24.0"
75
+ },
76
+ "publishConfig": {
77
+ "access": "public"
78
+ }
79
+ }