@overscore/cli 0.13.5 → 0.13.7

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/dist/index.js CHANGED
@@ -2599,8 +2599,14 @@ async function templatePull(slug) {
2599
2599
  console.error(" npx @overscore/cli template pull mrr-tracker\n");
2600
2600
  process.exit(1);
2601
2601
  }
2602
- const targetDir = path.resolve(process.cwd(), process.argv[4] || slug);
2603
- const url = `https://overscore.dev/api/templates/${slug}/source`;
2602
+ // Refs come in as handle/slug; the stored/API key is handle_slug, and the
2603
+ // extract directory is just the local slug.
2604
+ const apiSlug = slug.replace("/", "_");
2605
+ const localSlug = apiSlug.includes("_")
2606
+ ? apiSlug.slice(apiSlug.indexOf("_") + 1)
2607
+ : apiSlug;
2608
+ const targetDir = path.resolve(process.cwd(), process.argv[5] || localSlug);
2609
+ const url = `https://overscore.dev/api/templates/${apiSlug}/source`;
2604
2610
  console.log(`\n Pulling template: ${slug}...`);
2605
2611
  let res;
2606
2612
  try {
@@ -36,7 +36,8 @@ import path from "path";
36
36
  import { execSync } from "child_process";
37
37
  const HUB_URL = "https://overscore.dev";
38
38
  // Mirrors the templates_slug_format CHECK in the marketplace migration.
39
- const TEMPLATE_SLUG_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
39
+ // `_` is the handle namespace delimiter in the stored slug ({handle}_{local}).
40
+ const TEMPLATE_SLUG_RE = /^[a-z0-9]([a-z0-9_-]*[a-z0-9])?$/;
40
41
  function isValidTemplateSlug(slug) {
41
42
  return (slug.length >= 1 &&
42
43
  slug.length <= 100 &&
@@ -185,7 +186,10 @@ function collectTemplateSourceFiles(dir, prefix, skipped) {
185
186
  }
186
187
  // ── Command ──────────────────────────────────────────────────────────────────
187
188
  export async function templatePush(slugArg) {
188
- const slug = slugArg || readPulledTemplateSlug();
189
+ // Refs come in as handle/slug; the stored/API key is handle_slug. A pulled
190
+ // template's .overscore/template.json already stores the handle_slug form.
191
+ const rawSlug = slugArg || readPulledTemplateSlug();
192
+ const slug = rawSlug ? rawSlug.replace("/", "_") : null;
189
193
  if (!slug) {
190
194
  console.error(`
191
195
  Usage: npx @overscore/cli template push [template-slug]
@@ -296,7 +300,7 @@ export async function templatePush(slugArg) {
296
300
  const sourceCount = sourceFiles.length;
297
301
  const listingUrl = data.detail_url
298
302
  ? `${HUB_URL}${data.detail_url}`
299
- : `${HUB_URL}/explore/${slug}`;
303
+ : `${HUB_URL}/explore/${slug.replace("_", "/")}`;
300
304
  console.log(`
301
305
  Pushed successfully!
302
306
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@overscore/cli",
3
- "version": "0.13.5",
3
+ "version": "0.13.7",
4
4
  "description": "CLI for deploying Overscore dashboards and publishing analyses",
5
5
  "bin": {
6
6
  "overscore": "dist/index.js"
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: bind-to-my-data
3
+ description: Binds a pulled or forked Overscore template to the user's own warehouse by regenerating SQL against their real schema and registering it under the template's query names, turning a sample-data demo into a live dashboard. Use after pulling or forking a template, when a dashboard shows mock or sample data and the user wants their own numbers, or when the user says "connect this template to my data", "bind to my warehouse", "make this use my real data", "wire up the queries", "regenerate the queries for my schema".
4
+ ---
5
+
6
+ # Bind a template to your data
7
+
8
+ A pulled or forked template ships design + sample data + query **names** — never the author's SQL. To go live, you regenerate SQL against the user's OWN warehouse and register it under the same names. **All SQL generation runs here, on the user's own Claude tokens;** Overscore only stores and executes the result.
9
+
10
+ ## Step 0 — detect state
11
+
12
+ | You see… | State | Do |
13
+ | --- | --- | --- |
14
+ | `.overscore/template.json`, no `.env` | **unbound demo** (`template pull`) | a pulled template has no project binding and runs on baked sample data. Land it in a project first: `npx create-overscore --template <handle>/<slug>`, or fork it in the hub and then `npx @overscore/cli pull <dashboard-slug>` to get a bound copy. Then continue. |
15
+ | `.env` with `VITE_OVERSCORE_DASHBOARD_SLUG` | **bound dashboard** (forked + pulled) | ready to bind — continue. |
16
+
17
+ ## Process
18
+
19
+ 1. **Ensure a data source exists.** The project needs either a BigQuery connection (hub → the project's **Settings** page → **Connect BigQuery**, paste a read-only service-account JSON) or a dataset. New accounts auto-seed a sample dataset; the user can also upload one. Without one of these there is nothing real to bind to.
20
+ 2. **Read the contract.** Find every query the template expects. If the template still calls `useQuery("<name>")`, grep those names. If it was already converted for publishing, the `useQuery` calls are gone — the contract now lives in `src/mockData.ts`: each `MOCK_*` export's shape, plus any `// query:` annotation naming it. If names aren't annotated, infer them from the export names and how each component consumes the array. Run `npx @overscore/cli query list` to see what's already registered (a fresh fork has none).
21
+ 3. **Inspect the real schema.** Look at the user's actual tables and columns. Design SQL that produces each query's required shape from THEIR data — explore with `npx @overscore/cli query run "<sql>"` (ad-hoc; results land in `./data` and are never deployed).
22
+ 4. **Register SQL under the SAME names.** For each query name:
23
+ ```bash
24
+ npx @overscore/cli query add <name> "<sql>" # BigQuery-backed
25
+ npx @overscore/cli query add <name> --dataset <name> # or dataset-backed
26
+ ```
27
+ The name MUST match the template's `useQuery` call exactly, or that chart stays empty.
28
+ 5. **Go live in the components.** If the template renders from `src/mockData.ts` (converted for publishing), rewire each `import { MOCK_X }` back to `const { data } = useQuery("x")`. Keep the charts and layout identical — only the data source changes.
29
+ 6. **Verify and deploy.**
30
+ ```bash
31
+ npx @overscore/cli dev # resolves the names against your registered SQL
32
+ npx @overscore/cli deploy --message "Bound <template> to my data"
33
+ ```
34
+
35
+ ## What this skill does NOT do
36
+
37
+ - **It does not generate SQL on Overscore's servers.** Every query is reasoned out here, against the user's schema, on the user's own Claude tokens.
38
+ - **It does not invent query names.** Register under the EXACT names the template references — that mapping is the contract.
39
+ - **It does not write SQL inside React.** Queries are referenced by name via `useQuery`; the SQL lives in the registry via `query add` only.
40
+ - **It does not need the author's queries.** Query SQL isn't registered with a template — queries live by name only — so you rebuild it from the design + names against your own data.
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: regenerate-clean
3
+ description: Converts an Overscore dashboard or pulled template into a publishable template by replacing every live query with typed synthetic mock data in src/mockData.ts, so the frozen bundle renders standalone and no real warehouse data ever ships. Use when preparing a dashboard to publish to the marketplace, when a pulled template still shows "Failed to load" or runs live queries, or when the user says "publish this as a template", "convert this to mock data", "regenerate clean", "make this template safe to share", "prep this for the marketplace".
4
+ ---
5
+
6
+ # Regenerate clean — convert a dashboard into a safe template
7
+
8
+ Run this in a pulled template directory (or a from-scratch dashboard) to swap every live `useQuery(...)` for fresh **synthetic** mock data, so the published template renders on its own. A template carries design + sample data + query **names** — never the creator's real SQL, schema, or rows. You generate the mock data here, locally, on the user's own Claude tokens. **Overscore's servers never generate anything.**
9
+
10
+ ## Step 0 — detect context
11
+
12
+ | You see… | You're in… | Do |
13
+ | --- | --- | --- |
14
+ | `.overscore/template.json` | a **pulled template** (`template pull`) | convert it in place, then `template push` |
15
+ | `.env` with `VITE_OVERSCORE_DASHBOARD_SLUG` + live `useQuery` calls | a **live dashboard** | DON'T convert in place. Tell the user to open the dashboard's **Publish as template** modal first — for a live-data dashboard it creates a **private draft** copy. Then `npx @overscore/cli template pull <handle>/<slug>` that draft and run this skill on the copy. **Never touch the live dashboard.** |
16
+ | `src/mockData.ts` present, no `useQuery` left | already converted | skip to Verify |
17
+
18
+ The original live dashboard is never modified. If it has live queries, the rule is **convert a private copy, attest, then promote** — never push a live-data dashboard straight to public.
19
+
20
+ ## Process
21
+
22
+ 1. **Inventory the data contract.** Grep the source for every `useQuery("<name>")` call. For each, record (a) the query **name** and (b) the row **shape** the component consumes — every column key and its type. These names + shapes ARE the template's contract; preserve them exactly.
23
+ 2. **Generate synthetic data — locally, on the user's tokens.** Create `src/mockData.ts`: one exported `interface` + one exported `MOCK_<NAME>` array per query, with realistic-but-fabricated rows matching each shape (same column names, types, rough cardinality). Annotate each export with its query name, e.g. `// query: mrr_monthly` — once `useQuery` is gone (step 3) this comment is the only record of the name a consumer needs to rebind. **Scrub every real company name, customer name, and identifying number** — invent plausible substitutes.
24
+ 3. **Rewire the components.** Replace each `const { data } = useQuery("x")` with `import { MOCK_X } from "./mockData"`. Change ONLY the data source — keep every chart, metric, filter, and layout byte-for-byte identical.
25
+ 4. **Strip real data.** Delete any `data/` directory (raw query dumps) and any `fixtures/`, `dumps/`, or `exports/` holding real rows. Confirm there is no `.env*`, `*.log`, or credential file in the tree.
26
+ 5. **Self-review for inline leaks.** The publish floor rejects `data/`, `.env*`, `*.log`, and secret-named files — but it is **content-blind**. Read `src/mockData.ts` and the components and confirm no real value (a real revenue figure, a real account name) was left inline.
27
+
28
+ ## Verify, then publish
29
+
30
+ ```bash
31
+ npx @overscore/cli dev # renders on mock data — no API key or warehouse needed
32
+ npm run build # confirm the rewire compiles
33
+ npx @overscore/cli template push # upload the converted bundle (slug auto-read from .overscore/template.json)
34
+ ```
35
+
36
+ After push, open the listing's **Update** modal, **read** the mock-data attestation, and only then check it and set the visibility (Public / Unlisted / Private). Attestation is a truthful claim that the data is synthetic — never check it on an unconverted bundle.
37
+
38
+ ## What this skill does NOT do
39
+
40
+ - **It does not call any Overscore server-side AI.** All synthetic data is generated here, by you, on the user's own Claude tokens. Never tell the user "Overscore will convert this for you."
41
+ - **It does not modify the original live dashboard.** Conversion always happens on a pulled template copy.
42
+ - **It does not attest or publish for the user.** The user reads and checks the attestation themselves after reviewing the result.
43
+ - **It does not lean on the server strip as the strategy.** The floor is a backstop; keeping real data out of the bundle in the first place is your job.