@specific.dev/cli 0.1.129 → 0.1.131

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 (68) hide show
  1. package/dist/admin/404/index.html +1 -1
  2. package/dist/admin/404.html +1 -1
  3. package/dist/admin/__next.!KGRlZmF1bHQp.__PAGE__.txt +1 -1
  4. package/dist/admin/__next.!KGRlZmF1bHQp.txt +1 -1
  5. package/dist/admin/__next._full.txt +1 -1
  6. package/dist/admin/__next._head.txt +1 -1
  7. package/dist/admin/__next._index.txt +1 -1
  8. package/dist/admin/__next._tree.txt +1 -1
  9. package/dist/admin/_not-found/__next._full.txt +1 -1
  10. package/dist/admin/_not-found/__next._head.txt +1 -1
  11. package/dist/admin/_not-found/__next._index.txt +1 -1
  12. package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
  13. package/dist/admin/_not-found/__next._not-found.txt +1 -1
  14. package/dist/admin/_not-found/__next._tree.txt +1 -1
  15. package/dist/admin/_not-found/index.html +1 -1
  16. package/dist/admin/_not-found/index.txt +1 -1
  17. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +1 -1
  18. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +1 -1
  19. package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +1 -1
  20. package/dist/admin/databases/__next._full.txt +1 -1
  21. package/dist/admin/databases/__next._head.txt +1 -1
  22. package/dist/admin/databases/__next._index.txt +1 -1
  23. package/dist/admin/databases/__next._tree.txt +1 -1
  24. package/dist/admin/databases/index.html +1 -1
  25. package/dist/admin/databases/index.txt +1 -1
  26. package/dist/admin/fullscreen/__next._full.txt +1 -1
  27. package/dist/admin/fullscreen/__next._head.txt +1 -1
  28. package/dist/admin/fullscreen/__next._index.txt +1 -1
  29. package/dist/admin/fullscreen/__next._tree.txt +1 -1
  30. package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +1 -1
  31. package/dist/admin/fullscreen/__next.fullscreen.txt +1 -1
  32. package/dist/admin/fullscreen/databases/__next._full.txt +1 -1
  33. package/dist/admin/fullscreen/databases/__next._head.txt +1 -1
  34. package/dist/admin/fullscreen/databases/__next._index.txt +1 -1
  35. package/dist/admin/fullscreen/databases/__next._tree.txt +1 -1
  36. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +1 -1
  37. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +1 -1
  38. package/dist/admin/fullscreen/databases/__next.fullscreen.txt +1 -1
  39. package/dist/admin/fullscreen/databases/index.html +1 -1
  40. package/dist/admin/fullscreen/databases/index.txt +1 -1
  41. package/dist/admin/fullscreen/index.html +1 -1
  42. package/dist/admin/fullscreen/index.txt +1 -1
  43. package/dist/admin/index.html +1 -1
  44. package/dist/admin/index.txt +1 -1
  45. package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.__PAGE__.txt +1 -1
  46. package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.txt +1 -1
  47. package/dist/admin/mail/__next.!KGRlZmF1bHQp.txt +1 -1
  48. package/dist/admin/mail/__next._full.txt +1 -1
  49. package/dist/admin/mail/__next._head.txt +1 -1
  50. package/dist/admin/mail/__next._index.txt +1 -1
  51. package/dist/admin/mail/__next._tree.txt +1 -1
  52. package/dist/admin/mail/index.html +1 -1
  53. package/dist/admin/mail/index.txt +1 -1
  54. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +1 -1
  55. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +1 -1
  56. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +1 -1
  57. package/dist/admin/workflows/__next._full.txt +1 -1
  58. package/dist/admin/workflows/__next._head.txt +1 -1
  59. package/dist/admin/workflows/__next._index.txt +1 -1
  60. package/dist/admin/workflows/__next._tree.txt +1 -1
  61. package/dist/admin/workflows/index.html +1 -1
  62. package/dist/admin/workflows/index.txt +1 -1
  63. package/dist/cli.js +148 -203
  64. package/dist/docs/postgres.md +1 -0
  65. package/package.json +1 -1
  66. /package/dist/admin/_next/static/{wMHOi2gUxRLxCjfghptW7 → q_hKQQIovTI9Xqr5JEBj3}/_buildManifest.js +0 -0
  67. /package/dist/admin/_next/static/{wMHOi2gUxRLxCjfghptW7 → q_hKQQIovTI9Xqr5JEBj3}/_clientMiddlewareManifest.json +0 -0
  68. /package/dist/admin/_next/static/{wMHOi2gUxRLxCjfghptW7 → q_hKQQIovTI9Xqr5JEBj3}/_ssgManifest.js +0 -0
package/dist/cli.js CHANGED
@@ -367494,6 +367494,29 @@ function closeDebugLog() {
367494
367494
  logStream = null;
367495
367495
  }
367496
367496
  }
367497
+ async function readApiError(response, operation, requestDescriptor) {
367498
+ const rawBody = await response.text().catch(() => "");
367499
+ writeLog("api:error", `Request was: ${requestDescriptor}`);
367500
+ writeLog("api:error", `Response: ${response.status} ${response.statusText}`);
367501
+ if (rawBody) {
367502
+ writeLog("api:error", `Response body: ${rawBody}`);
367503
+ }
367504
+ if (rawBody) {
367505
+ try {
367506
+ const parsed = JSON.parse(rawBody);
367507
+ if (parsed && typeof parsed === "object" && typeof parsed.error === "string" && typeof parsed.code === "string") {
367508
+ const apiErr = parsed;
367509
+ return new Error(`${operation}: ${apiErr.error} (${apiErr.code})`);
367510
+ }
367511
+ } catch {
367512
+ }
367513
+ }
367514
+ const snippet = rawBody.trim().slice(0, 200);
367515
+ const suffix = snippet ? ` \u2014 ${snippet}` : "";
367516
+ return new Error(
367517
+ `${operation}: HTTP ${response.status} ${response.statusText}${suffix}`
367518
+ );
367519
+ }
367497
367520
  var ApiClient = class {
367498
367521
  baseUrl;
367499
367522
  staticToken;
@@ -367536,25 +367559,11 @@ var ApiClient = class {
367536
367559
  });
367537
367560
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
367538
367561
  if (!response.ok) {
367539
- let errorBody;
367540
- try {
367541
- const error = await response.json();
367542
- errorBody = JSON.stringify(error);
367543
- writeLog("api:error", `API error: ${error.error} (${error.code})`);
367544
- writeLog("api:error", `Request was: POST ${this.baseUrl}/deployments`);
367545
- writeLog("api:error", `Request body was: ${JSON.stringify(requestBody)}`);
367546
- writeLog("api:error", `Response body: ${errorBody}`);
367547
- throw new Error(
367548
- `Failed to create deployment: ${error.error} (${error.code})`
367549
- );
367550
- } catch (e) {
367551
- if (e instanceof Error && e.message.startsWith("Failed to create")) {
367552
- throw e;
367553
- }
367554
- errorBody = await response.text();
367555
- writeLog("api:error", `Failed to parse error response: ${errorBody}`);
367556
- throw new Error(`Failed to create deployment: ${response.statusText}`);
367557
- }
367562
+ throw await readApiError(
367563
+ response,
367564
+ "Failed to create deployment",
367565
+ `POST ${this.baseUrl}/deployments body=${JSON.stringify(requestBody)}`
367566
+ );
367558
367567
  }
367559
367568
  return response.json();
367560
367569
  }
@@ -367572,24 +367581,11 @@ var ApiClient = class {
367572
367581
  });
367573
367582
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
367574
367583
  if (!response.ok) {
367575
- let errorBody;
367576
- try {
367577
- const error = await response.json();
367578
- errorBody = JSON.stringify(error);
367579
- writeLog("api:error", `API error: ${error.error} (${error.code})`);
367580
- writeLog("api:error", `Request was: POST ${url} (${tarball.length} bytes)`);
367581
- writeLog("api:error", `Response body: ${errorBody}`);
367582
- throw new Error(
367583
- `Failed to upload tarball: ${error.error} (${error.code})`
367584
- );
367585
- } catch (e) {
367586
- if (e instanceof Error && e.message.startsWith("Failed to upload")) {
367587
- throw e;
367588
- }
367589
- errorBody = await response.text();
367590
- writeLog("api:error", `Failed to parse error response: ${errorBody}`);
367591
- throw new Error(`Failed to upload tarball: ${response.statusText}`);
367592
- }
367584
+ throw await readApiError(
367585
+ response,
367586
+ "Failed to upload tarball",
367587
+ `POST ${url} (${tarball.length} bytes)`
367588
+ );
367593
367589
  }
367594
367590
  return response.json();
367595
367591
  }
@@ -367601,24 +367597,11 @@ var ApiClient = class {
367601
367597
  });
367602
367598
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
367603
367599
  if (!response.ok) {
367604
- let errorBody;
367605
- try {
367606
- const error = await response.json();
367607
- errorBody = JSON.stringify(error);
367608
- writeLog("api:error", `API error: ${error.error} (${error.code})`);
367609
- writeLog("api:error", `Request was: GET ${url}`);
367610
- writeLog("api:error", `Response body: ${errorBody}`);
367611
- throw new Error(
367612
- `Failed to get deployment: ${error.error} (${error.code})`
367613
- );
367614
- } catch (e) {
367615
- if (e instanceof Error && e.message.startsWith("Failed to get")) {
367616
- throw e;
367617
- }
367618
- errorBody = await response.text();
367619
- writeLog("api:error", `Failed to parse error response: ${errorBody}`);
367620
- throw new Error(`Failed to get deployment: ${response.statusText}`);
367621
- }
367600
+ throw await readApiError(
367601
+ response,
367602
+ "Failed to get deployment",
367603
+ `GET ${url}`
367604
+ );
367622
367605
  }
367623
367606
  return response.json();
367624
367607
  }
@@ -367631,24 +367614,11 @@ var ApiClient = class {
367631
367614
  });
367632
367615
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
367633
367616
  if (!response.ok) {
367634
- let errorBody;
367635
- try {
367636
- const error = await response.json();
367637
- errorBody = JSON.stringify(error);
367638
- writeLog("api:error", `API error: ${error.error} (${error.code})`);
367639
- writeLog("api:error", `Request was: POST ${url}`);
367640
- writeLog("api:error", `Response body: ${errorBody}`);
367641
- throw new Error(
367642
- `Failed to start deployment: ${error.error} (${error.code})`
367643
- );
367644
- } catch (e) {
367645
- if (e instanceof Error && e.message.startsWith("Failed to start")) {
367646
- throw e;
367647
- }
367648
- errorBody = await response.text();
367649
- writeLog("api:error", `Failed to parse error response: ${errorBody}`);
367650
- throw new Error(`Failed to start deployment: ${response.statusText}`);
367651
- }
367617
+ throw await readApiError(
367618
+ response,
367619
+ "Failed to start deployment",
367620
+ `POST ${url}`
367621
+ );
367652
367622
  }
367653
367623
  return response.json();
367654
367624
  }
@@ -367666,25 +367636,11 @@ var ApiClient = class {
367666
367636
  });
367667
367637
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
367668
367638
  if (!response.ok) {
367669
- let errorBody;
367670
- try {
367671
- const error = await response.json();
367672
- errorBody = JSON.stringify(error);
367673
- writeLog("api:error", `API error: ${error.error} (${error.code})`);
367674
- writeLog("api:error", `Request was: PUT ${url}`);
367675
- writeLog("api:error", `Secret keys: ${secretKeys.join(", ")}`);
367676
- writeLog("api:error", `Response body: ${errorBody}`);
367677
- throw new Error(
367678
- `Failed to submit secrets: ${error.error} (${error.code})`
367679
- );
367680
- } catch (e) {
367681
- if (e instanceof Error && e.message.startsWith("Failed to submit secrets")) {
367682
- throw e;
367683
- }
367684
- errorBody = await response.text();
367685
- writeLog("api:error", `Failed to parse error response: ${errorBody}`);
367686
- throw new Error(`Failed to submit secrets: ${response.statusText}`);
367687
- }
367639
+ throw await readApiError(
367640
+ response,
367641
+ "Failed to submit secrets",
367642
+ `PUT ${url} keys=${secretKeys.join(",")}`
367643
+ );
367688
367644
  }
367689
367645
  return response.json();
367690
367646
  }
@@ -367702,25 +367658,11 @@ var ApiClient = class {
367702
367658
  });
367703
367659
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
367704
367660
  if (!response.ok) {
367705
- let errorBody;
367706
- try {
367707
- const error = await response.json();
367708
- errorBody = JSON.stringify(error);
367709
- writeLog("api:error", `API error: ${error.error} (${error.code})`);
367710
- writeLog("api:error", `Request was: PUT ${url}`);
367711
- writeLog("api:error", `Config keys: ${configKeys.join(", ")}`);
367712
- writeLog("api:error", `Response body: ${errorBody}`);
367713
- throw new Error(
367714
- `Failed to submit configs: ${error.error} (${error.code})`
367715
- );
367716
- } catch (e) {
367717
- if (e instanceof Error && e.message.startsWith("Failed to submit configs")) {
367718
- throw e;
367719
- }
367720
- errorBody = await response.text();
367721
- writeLog("api:error", `Failed to parse error response: ${errorBody}`);
367722
- throw new Error(`Failed to submit configs: ${response.statusText}`);
367723
- }
367661
+ throw await readApiError(
367662
+ response,
367663
+ "Failed to submit configs",
367664
+ `PUT ${url} keys=${configKeys.join(",")}`
367665
+ );
367724
367666
  }
367725
367667
  return response.json();
367726
367668
  }
@@ -367732,22 +367674,27 @@ var ApiClient = class {
367732
367674
  });
367733
367675
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
367734
367676
  if (!response.ok) {
367735
- let errorBody;
367736
- try {
367737
- const error = await response.json();
367738
- errorBody = JSON.stringify(error);
367739
- writeLog("api:error", `API error: ${error.error} (${error.code})`);
367740
- writeLog("api:error", `Request was: GET ${url}`);
367741
- writeLog("api:error", `Response body: ${errorBody}`);
367742
- throw new Error(`Failed to list projects: ${error.error} (${error.code})`);
367743
- } catch (e) {
367744
- if (e instanceof Error && e.message.startsWith("Failed to list")) {
367745
- throw e;
367746
- }
367747
- errorBody = await response.text();
367748
- writeLog("api:error", `Failed to parse error response: ${errorBody}`);
367749
- throw new Error(`Failed to list projects: ${response.statusText}`);
367750
- }
367677
+ throw await readApiError(
367678
+ response,
367679
+ "Failed to list projects",
367680
+ `GET ${url}`
367681
+ );
367682
+ }
367683
+ return response.json();
367684
+ }
367685
+ async getProjectStatus(projectId) {
367686
+ const url = `${this.baseUrl}/projects/${projectId}/status`;
367687
+ writeLog("api", `GET ${url}`);
367688
+ const response = await fetch(url, {
367689
+ headers: await this.authHeaders()
367690
+ });
367691
+ writeLog("api", `Response: ${response.status} ${response.statusText}`);
367692
+ if (!response.ok) {
367693
+ throw await readApiError(
367694
+ response,
367695
+ "Failed to get project status",
367696
+ `GET ${url}`
367697
+ );
367751
367698
  }
367752
367699
  return response.json();
367753
367700
  }
@@ -367769,25 +367716,11 @@ var ApiClient = class {
367769
367716
  });
367770
367717
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
367771
367718
  if (!response.ok) {
367772
- let errorBody;
367773
- try {
367774
- const error = await response.json();
367775
- errorBody = JSON.stringify(error);
367776
- writeLog("api:error", `API error: ${error.error} (${error.code})`);
367777
- writeLog("api:error", `Request was: POST ${url}`);
367778
- writeLog("api:error", `Request body was: ${JSON.stringify(requestBody)}`);
367779
- writeLog("api:error", `Response body: ${errorBody}`);
367780
- throw new Error(
367781
- `Failed to create project: ${error.error} (${error.code})`
367782
- );
367783
- } catch (e) {
367784
- if (e instanceof Error && e.message.startsWith("Failed to create project")) {
367785
- throw e;
367786
- }
367787
- errorBody = await response.text();
367788
- writeLog("api:error", `Failed to parse error response: ${errorBody}`);
367789
- throw new Error(`Failed to create project: ${response.statusText}`);
367790
- }
367719
+ throw await readApiError(
367720
+ response,
367721
+ "Failed to create project",
367722
+ `POST ${url} body=${JSON.stringify(requestBody)}`
367723
+ );
367791
367724
  }
367792
367725
  return response.json();
367793
367726
  }
@@ -367799,20 +367732,11 @@ var ApiClient = class {
367799
367732
  });
367800
367733
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
367801
367734
  if (!response.ok) {
367802
- let errorBody;
367803
- try {
367804
- const error = await response.json();
367805
- errorBody = JSON.stringify(error);
367806
- writeLog("api:error", `API error: ${error.error} (${error.code})`);
367807
- throw new Error(`Failed to list organizations: ${error.error} (${error.code})`);
367808
- } catch (e) {
367809
- if (e instanceof Error && e.message.startsWith("Failed to list organizations")) {
367810
- throw e;
367811
- }
367812
- errorBody = await response.text();
367813
- writeLog("api:error", `Failed to parse error response: ${errorBody}`);
367814
- throw new Error(`Failed to list organizations: ${response.statusText}`);
367815
- }
367735
+ throw await readApiError(
367736
+ response,
367737
+ "Failed to list organizations",
367738
+ `GET ${url}`
367739
+ );
367816
367740
  }
367817
367741
  return response.json();
367818
367742
  }
@@ -367829,17 +367753,11 @@ var ApiClient = class {
367829
367753
  });
367830
367754
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
367831
367755
  if (!response.ok) {
367832
- try {
367833
- const error = await response.json();
367834
- throw new Error(
367835
- `Failed to create preview environment: ${error.error} (${error.code})`
367836
- );
367837
- } catch (e) {
367838
- if (e instanceof Error && e.message.startsWith("Failed to create preview")) {
367839
- throw e;
367840
- }
367841
- throw new Error(`Failed to create preview environment: ${response.statusText}`);
367842
- }
367756
+ throw await readApiError(
367757
+ response,
367758
+ "Failed to create preview environment",
367759
+ `POST ${url}`
367760
+ );
367843
367761
  }
367844
367762
  return response.json();
367845
367763
  }
@@ -367855,17 +367773,11 @@ var ApiClient = class {
367855
367773
  if (response.status === 404) {
367856
367774
  return;
367857
367775
  }
367858
- try {
367859
- const error = await response.json();
367860
- throw new Error(
367861
- `Failed to delete preview environment: ${error.error} (${error.code})`
367862
- );
367863
- } catch (e) {
367864
- if (e instanceof Error && e.message.startsWith("Failed to delete preview")) {
367865
- throw e;
367866
- }
367867
- throw new Error(`Failed to delete preview environment: ${response.statusText}`);
367868
- }
367776
+ throw await readApiError(
367777
+ response,
367778
+ "Failed to delete preview environment",
367779
+ `DELETE ${url}`
367780
+ );
367869
367781
  }
367870
367782
  }
367871
367783
  async getMe(signal) {
@@ -367877,22 +367789,11 @@ var ApiClient = class {
367877
367789
  });
367878
367790
  writeLog("api", `Response: ${response.status} ${response.statusText}`);
367879
367791
  if (!response.ok) {
367880
- let errorBody;
367881
- try {
367882
- const error = await response.json();
367883
- errorBody = JSON.stringify(error);
367884
- writeLog("api:error", `API error: ${error.error} (${error.code})`);
367885
- writeLog("api:error", `Request was: GET ${url}`);
367886
- writeLog("api:error", `Response body: ${errorBody}`);
367887
- throw new Error(`Failed to get user: ${error.error} (${error.code})`);
367888
- } catch (e) {
367889
- if (e instanceof Error && e.message.startsWith("Failed to get user")) {
367890
- throw e;
367891
- }
367892
- errorBody = await response.text();
367893
- writeLog("api:error", `Failed to parse error response: ${errorBody}`);
367894
- throw new Error(`Failed to get user: ${response.statusText}`);
367895
- }
367792
+ throw await readApiError(
367793
+ response,
367794
+ "Failed to get user",
367795
+ `GET ${url}`
367796
+ );
367896
367797
  }
367897
367798
  return response.json();
367898
367799
  }
@@ -367911,6 +367812,9 @@ var SpecificClient = class {
367911
367812
  const response = await this.client.listProjects();
367912
367813
  return response.projects;
367913
367814
  }
367815
+ async getProjectStatus(projectId) {
367816
+ return await this.client.getProjectStatus(projectId);
367817
+ }
367914
367818
  async createProject(name, organizationId) {
367915
367819
  return await this.client.createProject(name, organizationId);
367916
367820
  }
@@ -368089,7 +367993,7 @@ async function createProjectTarball(projectDir, context = ".") {
368089
367993
  }
368090
367994
  async function createTarball(config, projectDir) {
368091
367995
  const builds = config.builds || [];
368092
- const contexts = builds.map((b) => b.context || ".").filter(Boolean);
367996
+ const contexts = [".", ...builds.map((b) => b.context || ".")].filter(Boolean);
368093
367997
  const widestContext = findWidestContext(projectDir, contexts);
368094
367998
  return await createProjectTarball(projectDir, widestContext);
368095
367999
  }
@@ -369788,7 +369692,7 @@ async function saveLocalConfig(name, value) {
369788
369692
  }
369789
369693
  function appendSearchPathToUrl(baseUrl, searchPath) {
369790
369694
  const url = new URL(baseUrl);
369791
- url.searchParams.set("options", `-c search_path=${searchPath}`);
369695
+ url.searchParams.set("options", `-c search_path=${searchPath},public`);
369792
369696
  return url.toString();
369793
369697
  }
369794
369698
  var MissingSecretError = class extends Error {
@@ -373789,7 +373693,7 @@ function trackEvent(event, properties) {
373789
373693
  event,
373790
373694
  properties: {
373791
373695
  ...properties,
373792
- cli_version: "0.1.129",
373696
+ cli_version: "0.1.131",
373793
373697
  platform: process.platform,
373794
373698
  node_version: process.version,
373795
373699
  project_id: getProjectId()
@@ -377895,7 +377799,7 @@ function compareVersions(a, b) {
377895
377799
  return 0;
377896
377800
  }
377897
377801
  async function checkForUpdate() {
377898
- const currentVersion = "0.1.129";
377802
+ const currentVersion = "0.1.131";
377899
377803
  const response = await fetch(`${BINARIES_BASE_URL}/latest?t=${Date.now()}`);
377900
377804
  if (!response.ok) {
377901
377805
  throw new Error(`Failed to check for updates: HTTP ${response.status}`);
@@ -378161,11 +378065,49 @@ async function projectListCommand() {
378161
378065
  }
378162
378066
  }
378163
378067
 
378068
+ // src/commands/status.tsx
378069
+ async function statusCommand() {
378070
+ try {
378071
+ const projectId = readProjectId();
378072
+ const token = await getValidAccessToken();
378073
+ const client2 = new SpecificClient({ accessToken: token });
378074
+ const status = await client2.getProjectStatus(projectId);
378075
+ console.log(`${status.name} (${status.id})`);
378076
+ if (status.environments.length === 0) {
378077
+ console.log("");
378078
+ console.log("No environments found.");
378079
+ return;
378080
+ }
378081
+ for (const env2 of status.environments) {
378082
+ console.log("");
378083
+ console.log(`Environment: ${env2.name} (${env2.id})`);
378084
+ console.log(` Status: ${env2.status}`);
378085
+ if (env2.activeDeployment) {
378086
+ console.log(
378087
+ ` Active deployment: ${env2.activeDeployment.id} (${env2.activeDeployment.state})`
378088
+ );
378089
+ } else {
378090
+ console.log(` Active deployment: none`);
378091
+ }
378092
+ if (env2.inProgressDeployments.length > 0) {
378093
+ console.log(` In progress:`);
378094
+ for (const d of env2.inProgressDeployments) {
378095
+ console.log(` - ${d.id} (${d.state})`);
378096
+ }
378097
+ }
378098
+ }
378099
+ } catch (error) {
378100
+ const message = error instanceof Error ? error.message : "Unknown error occurred";
378101
+ console.error(`Failed to get status: ${message}`);
378102
+ process.exit(1);
378103
+ }
378104
+ }
378105
+
378164
378106
  // src/cli-program.tsx
378165
378107
  var program = new Command();
378166
378108
  var env = "production";
378167
378109
  var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
378168
- program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.129").enablePositionalOptions();
378110
+ program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.131").enablePositionalOptions();
378169
378111
  program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").addHelpText("after", `
378170
378112
  Examples:
378171
378113
  $ specific init
@@ -378239,6 +378181,9 @@ Examples:
378239
378181
  $ specific project list`).action(() => {
378240
378182
  projectListCommand();
378241
378183
  });
378184
+ program.command("status").description("Show project, environments, and deployment status").addHelpText("after", `
378185
+ Examples:
378186
+ $ specific status`).action(statusCommand);
378242
378187
  program.command("beta").description("Manage beta feature flags").action(betaCommand);
378243
378188
  program.command("update").description("Update Specific CLI to the latest version").action(updateCommand);
378244
378189
  program.command("login").description("Log in to Specific").option("--device-code <code>", "Complete login using a device code from a previous non-interactive login").action((options2) => loginCommand(options2));
@@ -43,6 +43,7 @@ The following PostgreSQL extensions are available in both development and produc
43
43
  - **pgvector** (`vector`) - Vector similarity search. Enable with `CREATE EXTENSION vector;` in a migration. See https://github.com/pgvector/pgvector for full documentation.
44
44
  - **pg_search** (`pg_search`) - Full-text search with BM25 ranking, powered by ParadeDB. Enable with `CREATE EXTENSION pg_search;` in a migration. See https://docs.paradedb.com/documentation/getting-started/quickstart for full documentation.
45
45
  - **PostGIS** (`postgis`) - Geospatial queries and indexing over geometry and geography types. Enable with `CREATE EXTENSION postgis;` in a migration. See https://postgis.net/documentation/ for full documentation.
46
+ - **pg_trgm** (`pg_trgm`) - Trigram-based fuzzy text matching and `gin_trgm_ops` / `gist_trgm_ops` indexes for `LIKE`/`ILIKE`/similarity queries. Enable with `CREATE EXTENSION pg_trgm;` in a migration. See https://www.postgresql.org/docs/current/pgtrgm.html for full documentation.
46
47
 
47
48
  ## Querying the database
48
49
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specific.dev/cli",
3
- "version": "0.1.129",
3
+ "version": "0.1.131",
4
4
  "description": "CLI for Specific infrastructure-as-code",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",