@overscore/cli 0.8.1 → 0.9.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.
Files changed (2) hide show
  1. package/dist/index.js +82 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -287,6 +287,8 @@ async function deploy() {
287
287
  // Non-fatal
288
288
  }
289
289
  }
290
+ // Pull latest platform rules so the local project stays up to date
291
+ await syncPlatformRules(process.cwd(), baseUrl, apiKey);
290
292
  }
291
293
  async function queryList() {
292
294
  const { dashboardSlug } = loadEnv();
@@ -543,6 +545,26 @@ VITE_OVERSCORE_API_URL=https://overscore.dev/api
543
545
  catch {
544
546
  // Non-fatal — the version from the source zip is fine
545
547
  }
548
+ // Pull dashboard context from Hub (may be newer than the source zip)
549
+ try {
550
+ const dashCtxRes = await fetch(`${baseUrl}/api/dashboards/${dashboardSlug}/context`, {
551
+ headers: { Authorization: `Bearer ${apiKey}` },
552
+ });
553
+ if (dashCtxRes.ok) {
554
+ const dashCtxData = (await dashCtxRes.json());
555
+ if (dashCtxData.context_md) {
556
+ const rulesDir = path.join(targetDir, ".claude", "rules");
557
+ fs.mkdirSync(rulesDir, { recursive: true });
558
+ fs.writeFileSync(path.join(rulesDir, "dashboard-context.md"), dashCtxData.context_md);
559
+ console.log(" Updated dashboard context from Hub.");
560
+ }
561
+ }
562
+ }
563
+ catch {
564
+ // Non-fatal
565
+ }
566
+ // Pull latest platform rules
567
+ await syncPlatformRules(targetDir, baseUrl, apiKey);
546
568
  console.log(`
547
569
  Pulled v${version}${commitMsg ? ` — "${commitMsg}"` : ""}
548
570
 
@@ -673,17 +695,38 @@ async function loadAnalysisConfig() {
673
695
  };
674
696
  }
675
697
  }
676
- // (3) Interactive
698
+ // (3) Interactive — only ask for the API key, resolve project automatically
677
699
  console.log("\n No Overscore config found. Let's set one up.\n");
678
700
  const apiKey = await prompt("API key (from the Hub):");
679
701
  if (!apiKey || !apiKey.startsWith("os_")) {
680
702
  console.error("\n Error: API key should start with os_\n");
681
703
  process.exit(1);
682
704
  }
683
- const projectSlug = await prompt("Project slug:");
705
+ // Look up the project slug from the key
706
+ let projectSlug = null;
707
+ try {
708
+ const res = await fetch(`${HUB_URL}/api/auth/key-info`, {
709
+ method: "POST",
710
+ headers: { "Content-Type": "application/json" },
711
+ body: JSON.stringify({ key: apiKey }),
712
+ });
713
+ if (res.ok) {
714
+ const data = (await res.json());
715
+ projectSlug = data.project_slug || null;
716
+ if (projectSlug) {
717
+ console.log(`\n Detected project: ${projectSlug}`);
718
+ }
719
+ }
720
+ }
721
+ catch {
722
+ // Fall back to manual entry
723
+ }
684
724
  if (!projectSlug) {
685
- console.error("\n Error: Project slug is required\n");
686
- process.exit(1);
725
+ projectSlug = await prompt("Project slug:");
726
+ if (!projectSlug) {
727
+ console.error("\n Error: Project slug is required\n");
728
+ process.exit(1);
729
+ }
687
730
  }
688
731
  // Save for next time
689
732
  fs.mkdirSync(configDir, { recursive: true });
@@ -754,6 +797,41 @@ async function syncHubManagedRules(targetDir, baseUrl, projectSlug, apiKey) {
754
797
  // Non-fatal
755
798
  }
756
799
  }
800
+ /**
801
+ * Fetch the latest platform-owned Claude Code rules from the Hub and write
802
+ * them into the project's .claude/ directory. This keeps rules like
803
+ * data-fetching.md, query-performance.md, and skills up to date even in
804
+ * projects that were scaffolded months ago.
805
+ *
806
+ * Called from `deploy` (before uploading) and `pull` (after extracting).
807
+ * User-owned files (company-context.md, dashboard-context.md) are NOT
808
+ * touched — those sync via separate mechanisms.
809
+ */
810
+ async function syncPlatformRules(targetDir, baseUrl, apiKey) {
811
+ try {
812
+ const res = await fetch(`${baseUrl}/api/platform-rules`, {
813
+ headers: { Authorization: `Bearer ${apiKey}` },
814
+ });
815
+ if (!res.ok)
816
+ return;
817
+ const data = (await res.json());
818
+ if (!data.files)
819
+ return;
820
+ let count = 0;
821
+ for (const [relPath, content] of Object.entries(data.files)) {
822
+ const fullPath = path.join(targetDir, ".claude", relPath);
823
+ fs.mkdirSync(path.dirname(fullPath), { recursive: true });
824
+ fs.writeFileSync(fullPath, content);
825
+ count++;
826
+ }
827
+ if (count > 0) {
828
+ console.log(` Platform rules synced (${count} files).`);
829
+ }
830
+ }
831
+ catch {
832
+ // Non-fatal — existing rules stay in place
833
+ }
834
+ }
757
835
  /**
758
836
  * Recursively copies a template directory to a target directory, substituting
759
837
  * `{{KEY}}` placeholders in text files. Mirrors directory structure.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@overscore/cli",
3
- "version": "0.8.1",
3
+ "version": "0.9.1",
4
4
  "description": "CLI for deploying Overscore dashboards and publishing analyses",
5
5
  "bin": {
6
6
  "overscore": "dist/index.js"