@runcontext/cli 0.3.2 → 0.3.4

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Eric Kittelson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,108 @@
1
+ # @runcontext/cli
2
+
3
+ CLI for [ContextKit](https://github.com/erickittelson/ContextKit) — AI-ready metadata governance over OSI.
4
+
5
+ **Your data already has a schema. ContextKit gives it meaning.**
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ # Global install
11
+ npm install -g @runcontext/cli
12
+
13
+ # Or per-project
14
+ npm install -D @runcontext/cli
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ # Point at any database — interactive wizard does the rest
21
+ context setup
22
+
23
+ # Or step by step
24
+ context introspect --db duckdb://warehouse.duckdb
25
+ context enrich --target silver --apply
26
+ context tier
27
+ ```
28
+
29
+ ## Commands
30
+
31
+ ### Core Workflow
32
+
33
+ ```bash
34
+ context setup # Interactive wizard — database to metadata in one flow
35
+ context introspect # Scan a database → scaffold Bronze-level OSI metadata
36
+ context enrich --target silver # Auto-enrich metadata toward a target tier
37
+ context lint # Run 37 lint rules against context files
38
+ context fix --write # Auto-fix lint issues where possible
39
+ context build # Compile context files → emit manifest JSON
40
+ context tier [model] # Show Bronze/Silver/Gold scorecard
41
+ ```
42
+
43
+ ### Exploration
44
+
45
+ ```bash
46
+ context explain <name> # Look up any model, term, or owner
47
+ context rules # List all lint rules with tier, severity, fixability
48
+ context validate-osi <file> # Validate a single OSI file against the schema
49
+ context verify # Check metadata accuracy against a live database
50
+ ```
51
+
52
+ ### Serving
53
+
54
+ ```bash
55
+ context serve --stdio # Start MCP server over stdio (for Claude, Cursor, etc.)
56
+ context serve --http --port 3000 # Start MCP server over HTTP
57
+ context site # Generate a static documentation site
58
+ context dev # Watch mode — re-lint on file changes
59
+ context init # Scaffold a new project structure
60
+ ```
61
+
62
+ ## The Tier System
63
+
64
+ | Tier | What it means | How to get there |
65
+ |---|---|---|
66
+ | **Bronze** | Discoverable — described, owned, classified | `context introspect` |
67
+ | **Silver** | Trusted — lineage, glossary, sample values, trust status | `context enrich --target silver` |
68
+ | **Gold** | AI-Ready — semantic roles, golden queries, guardrails, business rules | Human curation + `context enrich --target gold` |
69
+
70
+ ## Database Support
71
+
72
+ | Adapter | Connection |
73
+ |---|---|
74
+ | DuckDB | `--db duckdb://path/to/file.duckdb` |
75
+ | PostgreSQL | `--db postgres://user:pass@host:5432/db` |
76
+
77
+ ## MCP Server
78
+
79
+ Expose your metadata to AI agents:
80
+
81
+ ```bash
82
+ # For Claude Code / Cursor
83
+ context serve --stdio
84
+
85
+ # For multi-agent setups
86
+ context serve --http --port 3000
87
+ ```
88
+
89
+ Add to `.claude/mcp.json`:
90
+
91
+ ```json
92
+ {
93
+ "mcpServers": {
94
+ "contextkit": {
95
+ "command": "npx",
96
+ "args": ["@runcontext/cli", "serve", "--stdio"]
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
102
+ ## Full Documentation
103
+
104
+ See the [ContextKit repository](https://github.com/erickittelson/ContextKit) for complete docs, file structure, tier requirements, and examples.
105
+
106
+ ## License
107
+
108
+ MIT
package/dist/index.js CHANGED
@@ -1201,15 +1201,14 @@ var siteCommand = new Command10("site").description("Build a static documentatio
1201
1201
  // src/commands/serve.ts
1202
1202
  import { Command as Command11 } from "commander";
1203
1203
  import chalk12 from "chalk";
1204
- var serveCommand = new Command11("serve").description("Start the MCP server (stdio transport)").option("--context-dir <path>", "Path to context directory").action(async (opts) => {
1204
+ var serveCommand = new Command11("serve").description("Start the MCP server (stdio or HTTP transport)").option("--context-dir <path>", "Path to context directory").option("--http", "Serve over HTTP instead of stdio").option("--port <number>", "HTTP port (default: 3000)", "3000").option("--host <address>", "HTTP host (default: 0.0.0.0)", "0.0.0.0").action(async (opts) => {
1205
1205
  try {
1206
- let startServer;
1206
+ let mcpModule;
1207
1207
  try {
1208
- const mcpModule = await import("@runcontext/mcp");
1209
- startServer = mcpModule.startServer;
1208
+ mcpModule = await import("@runcontext/mcp");
1210
1209
  } catch {
1211
1210
  }
1212
- if (!startServer) {
1211
+ if (!mcpModule) {
1213
1212
  console.log(
1214
1213
  chalk12.yellow(
1215
1214
  "MCP server is not available. Install @runcontext/mcp to enable this command."
@@ -1217,11 +1216,24 @@ var serveCommand = new Command11("serve").description("Start the MCP server (std
1217
1216
  );
1218
1217
  process.exit(1);
1219
1218
  }
1220
- console.log(chalk12.blue("Starting MCP server (stdio transport)..."));
1221
- await startServer({
1222
- contextDir: opts.contextDir,
1223
- rootDir: process.cwd()
1224
- });
1219
+ if (opts.http) {
1220
+ const startServerHttp = mcpModule.startServerHttp;
1221
+ const port = parseInt(opts.port, 10);
1222
+ console.log(chalk12.blue(`Starting MCP server (HTTP on port ${port})...`));
1223
+ await startServerHttp({
1224
+ contextDir: opts.contextDir,
1225
+ rootDir: process.cwd(),
1226
+ port,
1227
+ host: opts.host
1228
+ });
1229
+ } else {
1230
+ const startServer = mcpModule.startServer;
1231
+ console.log(chalk12.blue("Starting MCP server (stdio transport)..."));
1232
+ await startServer({
1233
+ contextDir: opts.contextDir,
1234
+ rootDir: process.cwd()
1235
+ });
1236
+ }
1225
1237
  } catch (err) {
1226
1238
  console.error(formatError(err.message));
1227
1239
  process.exit(1);
@@ -2444,7 +2456,93 @@ ${failingSection}
2444
2456
 
2445
2457
  **Bronze (7):** descriptions, owner, security, grain, table_type
2446
2458
  **Silver (+6):** trust, 2+ tags, glossary linked, lineage, refresh, 2+ sample_values
2447
- **Gold (+21):** semantic_role on ALL fields, metric aggregation/additive, 1+ guardrail, 3+ golden queries, 1+ business rule, 1+ hierarchy, 1+ default_filter, trust=endorsed, contactable owner, 1+ relationship, description \u226550 chars, ai_context (no TODO), 1+ business_context, version, field descriptions not lazy, glossary definitions substantive, lineage references real sources, grain statements specific, ai_context filled in
2459
+ **Gold (+24):** semantic_role on ALL fields, metric aggregation/additive, 1+ guardrail, 3+ golden queries, 1+ business rule, 1+ hierarchy, 1+ default_filter, trust=endorsed, contactable owner, 1+ relationship, description \u226550 chars, ai_context (no TODO), 1+ business_context, version, field descriptions not lazy, glossary definitions substantive, lineage references real sources, grain statements specific, ai_context filled in, 3+ relationships (models with 3+ datasets), 1+ computed metric, 3+ glossary terms (models with 5+ datasets)
2460
+
2461
+ ## How to Reach Gold: Curation Recipes
2462
+
2463
+ ### Metrics (gold/metrics-defined)
2464
+
2465
+ Inspect computed views in the database. Any calculated column is a candidate metric.
2466
+
2467
+ \`\`\`sql
2468
+ -- Find computed columns in views
2469
+ SELECT column_name, data_type
2470
+ FROM information_schema.columns
2471
+ WHERE table_name LIKE 'vw_%' AND data_type IN ('DOUBLE', 'FLOAT', 'INTEGER', 'BIGINT', 'DECIMAL');
2472
+ \`\`\`
2473
+
2474
+ For each computed column (e.g., \`opportunity_score\`, \`shops_per_10k\`, \`demand_signal_pct\`):
2475
+ 1. Query it to understand what it measures
2476
+ 2. Add it to the model's \`metrics[]\` array in the OSI YAML
2477
+ 3. Include the SQL expression, aggregation type (SUM/AVG), and a human description
2478
+ 4. Mark whether it's additive (can be summed across dimensions)
2479
+
2480
+ Example:
2481
+ \`\`\`yaml
2482
+ metrics:
2483
+ - name: opportunity_score
2484
+ expression:
2485
+ dialects:
2486
+ - dialect: DuckDB
2487
+ expression: "(population/10000)*2 + (income/50000)*2 + (10-shops_per_10k)*3 + transit*1.5 + demand*0.5"
2488
+ description: Composite score ranking census tracts for coffee shop viability
2489
+ aggregation: AVG
2490
+ additive: false
2491
+ \`\`\`
2492
+
2493
+ ### Glossary Terms (gold/glossary-coverage)
2494
+
2495
+ For each key business concept your model measures, create a glossary term file.
2496
+
2497
+ Think about the terms a new analyst would need defined:
2498
+ - What is "supply saturation"? (> 5.0 shops per 10k people)
2499
+ - What is a "demand signal"? (review mentioning wait/line/crowded/busy)
2500
+ - What is "opportunity score"? (composite ranking formula)
2501
+
2502
+ For each term, create \`context/glossary/<term-name>.term.yaml\`:
2503
+ \`\`\`yaml
2504
+ term: supply-saturation
2505
+ definition: >
2506
+ A measure of coffee shop density per census tract. Calculated as
2507
+ shops per 10,000 residents. Tracts with > 5.0 are considered saturated.
2508
+ owner: analytics-team
2509
+ tags: [coffee-analytics]
2510
+ \`\`\`
2511
+
2512
+ Models with 5+ datasets need at least 3 glossary terms linked by shared tags or owner.
2513
+
2514
+ ### Relationships (gold/relationships-coverage)
2515
+
2516
+ For each join in the SQL views, define a relationship in the OSI model.
2517
+
2518
+ \`\`\`sql
2519
+ -- Find joins by examining view definitions
2520
+ -- Look for patterns: ON table_a.col = table_b.col
2521
+ -- Or spatial joins: ABS(a.lat - b.lat) < threshold
2522
+ \`\`\`
2523
+
2524
+ For each join:
2525
+ \`\`\`yaml
2526
+ relationships:
2527
+ - name: business-to-tract
2528
+ left_dataset: yelp_business
2529
+ right_dataset: census_tract
2530
+ join_type: spatial
2531
+ cardinality: many-to-one
2532
+ description: Businesses assigned to nearest census tract within 0.02 degrees (~1 mile)
2533
+ \`\`\`
2534
+
2535
+ Models with 3+ datasets need at least 3 relationships.
2536
+
2537
+ ### Golden Queries
2538
+
2539
+ Write 3-5 SQL queries answering common business questions. **Test each query first!**
2540
+
2541
+ \`\`\`sql
2542
+ -- Run the query, verify it returns sensible results, then document:
2543
+ SELECT geoid, tract_name, opportunity_score
2544
+ FROM vw_candidate_zones ORDER BY opportunity_score DESC LIMIT 10;
2545
+ \`\`\`
2448
2546
 
2449
2547
  ## YAML Formats
2450
2548