@overscore/cli 0.8.0 → 0.8.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 +51 -31
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -711,6 +711,49 @@ async function analysisApiRequest(cfg, method, urlPath, body) {
711
711
  }
712
712
  return data;
713
713
  }
714
+ /**
715
+ * Fetch hub-managed rule files (company-context, sql-style) for a project
716
+ * and write them into the target analysis folder, overwriting whatever's
717
+ * there. Best-effort and non-fatal — if the hub is unreachable, the existing
718
+ * files (template defaults or bundle contents) stay in place.
719
+ *
720
+ * Called from both `analysis new` (after the template walker) and `analysis
721
+ * pull` (after the bundle extraction) so hub overrides always reflect the
722
+ * latest state regardless of how the analysis was created.
723
+ */
724
+ async function syncHubManagedRules(targetDir, baseUrl, projectSlug, apiKey) {
725
+ const authHeader = { Authorization: `Bearer ${apiKey}` };
726
+ const rulesDir = path.join(targetDir, ".claude", "rules");
727
+ fs.mkdirSync(rulesDir, { recursive: true });
728
+ // Company context — null means "no company context set yet"; leave any
729
+ // existing file alone in that case.
730
+ try {
731
+ const ctxRes = await fetch(`${baseUrl}/api/projects/${projectSlug}/context`, { headers: authHeader });
732
+ if (ctxRes.ok) {
733
+ const ctxData = (await ctxRes.json());
734
+ if (ctxData.context_md) {
735
+ fs.writeFileSync(path.join(rulesDir, "company-context.md"), ctxData.context_md);
736
+ }
737
+ }
738
+ }
739
+ catch {
740
+ // Non-fatal
741
+ }
742
+ // SQL style override — null means "use the CLI default"; leave the
743
+ // template/bundle file alone in that case.
744
+ try {
745
+ const sqlRes = await fetch(`${baseUrl}/api/projects/${projectSlug}/sql-style`, { headers: authHeader });
746
+ if (sqlRes.ok) {
747
+ const sqlData = (await sqlRes.json());
748
+ if (sqlData.sql_style_md) {
749
+ fs.writeFileSync(path.join(rulesDir, "sql-style.md"), sqlData.sql_style_md);
750
+ }
751
+ }
752
+ }
753
+ catch {
754
+ // Non-fatal
755
+ }
756
+ }
714
757
  /**
715
758
  * Recursively copies a template directory to a target directory, substituting
716
759
  * `{{KEY}}` placeholders in text files. Mirrors directory structure.
@@ -793,38 +836,10 @@ async function analysisNew(title) {
793
836
  PROJECT_SLUG: data.project_slug,
794
837
  DATE: today,
795
838
  });
796
- // Pull project's company-context.md and any project-level rule overrides
797
- // (best-effort, non-fatal — the template defaults are still in place if
798
- // the network is down or the hub is unreachable).
839
+ // Pull hub-managed rules (company context + sql style override). Best-effort
840
+ // and non-fatal — template defaults stay in place if the hub is unreachable.
799
841
  const baseUrl = cfg.apiUrl.replace(/\/api$/, "");
800
- const authHeader = { Authorization: `Bearer ${cfg.apiKey}` };
801
- // Company context
802
- try {
803
- const ctxRes = await fetch(`${baseUrl}/api/projects/${data.project_slug}/context`, { headers: authHeader });
804
- if (ctxRes.ok) {
805
- const ctxData = (await ctxRes.json());
806
- if (ctxData.context_md) {
807
- fs.writeFileSync(path.join(targetDir, ".claude", "rules", "company-context.md"), ctxData.context_md);
808
- }
809
- }
810
- }
811
- catch {
812
- // Non-fatal
813
- }
814
- // SQL style override — if the project has a custom version, replace the
815
- // template default. If null/missing, the template default stays in place.
816
- try {
817
- const sqlRes = await fetch(`${baseUrl}/api/projects/${data.project_slug}/sql-style`, { headers: authHeader });
818
- if (sqlRes.ok) {
819
- const sqlData = (await sqlRes.json());
820
- if (sqlData.sql_style_md) {
821
- fs.writeFileSync(path.join(targetDir, ".claude", "rules", "sql-style.md"), sqlData.sql_style_md);
822
- }
823
- }
824
- }
825
- catch {
826
- // Non-fatal
827
- }
842
+ await syncHubManagedRules(targetDir, baseUrl, data.project_slug, cfg.apiKey);
828
843
  console.log(` Analysis created: ${data.title}
829
844
  Slug: ${data.slug}
830
845
  Project: ${data.project_slug}
@@ -965,6 +980,11 @@ async function analysisPull(slug) {
965
980
  // Non-fatal
966
981
  }
967
982
  }
983
+ // Refresh hub-managed rule files after restoring from the bundle. The
984
+ // bundle contains whatever was set at publish time; this overwrites them
985
+ // with the latest hub state so company context and SQL style stay in
986
+ // sync across pulls. Best-effort and non-fatal.
987
+ await syncHubManagedRules(targetDir, baseUrl, projectSlug, cfg.apiKey);
968
988
  console.log(`
969
989
  Pulled "${analysisTitle}"
970
990
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@overscore/cli",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "CLI for deploying Overscore dashboards and publishing analyses",
5
5
  "bin": {
6
6
  "overscore": "dist/index.js"