@specific.dev/cli 0.1.122 → 0.1.123
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/admin/404/index.html +1 -1
- package/dist/admin/404.html +1 -1
- package/dist/admin/__next.!KGRlZmF1bHQp.__PAGE__.txt +1 -1
- package/dist/admin/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/__next._full.txt +1 -1
- package/dist/admin/__next._head.txt +1 -1
- package/dist/admin/__next._index.txt +1 -1
- package/dist/admin/__next._tree.txt +1 -1
- package/dist/admin/_not-found/__next._full.txt +1 -1
- package/dist/admin/_not-found/__next._head.txt +1 -1
- package/dist/admin/_not-found/__next._index.txt +1 -1
- package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/dist/admin/_not-found/__next._not-found.txt +1 -1
- package/dist/admin/_not-found/__next._tree.txt +1 -1
- package/dist/admin/_not-found/index.html +1 -1
- package/dist/admin/_not-found/index.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/databases/__next._full.txt +1 -1
- package/dist/admin/databases/__next._head.txt +1 -1
- package/dist/admin/databases/__next._index.txt +1 -1
- package/dist/admin/databases/__next._tree.txt +1 -1
- package/dist/admin/databases/index.html +1 -1
- package/dist/admin/databases/index.txt +1 -1
- package/dist/admin/fullscreen/__next._full.txt +1 -1
- package/dist/admin/fullscreen/__next._head.txt +1 -1
- package/dist/admin/fullscreen/__next._index.txt +1 -1
- package/dist/admin/fullscreen/__next._tree.txt +1 -1
- package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +1 -1
- package/dist/admin/fullscreen/__next.fullscreen.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._full.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._head.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._index.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._tree.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.txt +1 -1
- package/dist/admin/fullscreen/databases/index.html +1 -1
- package/dist/admin/fullscreen/databases/index.txt +1 -1
- package/dist/admin/fullscreen/index.html +1 -1
- package/dist/admin/fullscreen/index.txt +1 -1
- package/dist/admin/index.html +1 -1
- package/dist/admin/index.txt +1 -1
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.__PAGE__.txt +1 -1
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.txt +1 -1
- package/dist/admin/mail/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/mail/__next._full.txt +1 -1
- package/dist/admin/mail/__next._head.txt +1 -1
- package/dist/admin/mail/__next._index.txt +1 -1
- package/dist/admin/mail/__next._tree.txt +1 -1
- package/dist/admin/mail/index.html +1 -1
- package/dist/admin/mail/index.txt +1 -1
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +1 -1
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +1 -1
- package/dist/admin/workflows/__next._full.txt +1 -1
- package/dist/admin/workflows/__next._head.txt +1 -1
- package/dist/admin/workflows/__next._index.txt +1 -1
- package/dist/admin/workflows/__next._tree.txt +1 -1
- package/dist/admin/workflows/index.html +1 -1
- package/dist/admin/workflows/index.txt +1 -1
- package/dist/cli.js +98 -6
- package/package.json +1 -1
- /package/dist/admin/_next/static/{eboxHGqEe6h17B0pFV0xY → iKEnJVRd6gOzhr5N6iD4r}/_buildManifest.js +0 -0
- /package/dist/admin/_next/static/{eboxHGqEe6h17B0pFV0xY → iKEnJVRd6gOzhr5N6iD4r}/_clientMiddlewareManifest.json +0 -0
- /package/dist/admin/_next/static/{eboxHGqEe6h17B0pFV0xY → iKEnJVRd6gOzhr5N6iD4r}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -367814,6 +367814,58 @@ var ApiClient = class {
|
|
|
367814
367814
|
}
|
|
367815
367815
|
return response.json();
|
|
367816
367816
|
}
|
|
367817
|
+
async createPreviewEnvironment(projectId) {
|
|
367818
|
+
const url = `${this.baseUrl}/environments/preview`;
|
|
367819
|
+
writeLog("api", `POST ${url}`);
|
|
367820
|
+
const response = await fetch(url, {
|
|
367821
|
+
method: "POST",
|
|
367822
|
+
headers: {
|
|
367823
|
+
"Content-Type": "application/json",
|
|
367824
|
+
...await this.authHeaders()
|
|
367825
|
+
},
|
|
367826
|
+
body: JSON.stringify({ projectId })
|
|
367827
|
+
});
|
|
367828
|
+
writeLog("api", `Response: ${response.status} ${response.statusText}`);
|
|
367829
|
+
if (!response.ok) {
|
|
367830
|
+
try {
|
|
367831
|
+
const error = await response.json();
|
|
367832
|
+
throw new Error(
|
|
367833
|
+
`Failed to create preview environment: ${error.error} (${error.code})`
|
|
367834
|
+
);
|
|
367835
|
+
} catch (e) {
|
|
367836
|
+
if (e instanceof Error && e.message.startsWith("Failed to create preview")) {
|
|
367837
|
+
throw e;
|
|
367838
|
+
}
|
|
367839
|
+
throw new Error(`Failed to create preview environment: ${response.statusText}`);
|
|
367840
|
+
}
|
|
367841
|
+
}
|
|
367842
|
+
return response.json();
|
|
367843
|
+
}
|
|
367844
|
+
async deletePreviewEnvironment(environmentId) {
|
|
367845
|
+
const url = `${this.baseUrl}/environments/${environmentId}`;
|
|
367846
|
+
writeLog("api", `DELETE ${url}`);
|
|
367847
|
+
const response = await fetch(url, {
|
|
367848
|
+
method: "DELETE",
|
|
367849
|
+
headers: await this.authHeaders()
|
|
367850
|
+
});
|
|
367851
|
+
writeLog("api", `Response: ${response.status} ${response.statusText}`);
|
|
367852
|
+
if (!response.ok) {
|
|
367853
|
+
if (response.status === 404) {
|
|
367854
|
+
return;
|
|
367855
|
+
}
|
|
367856
|
+
try {
|
|
367857
|
+
const error = await response.json();
|
|
367858
|
+
throw new Error(
|
|
367859
|
+
`Failed to delete preview environment: ${error.error} (${error.code})`
|
|
367860
|
+
);
|
|
367861
|
+
} catch (e) {
|
|
367862
|
+
if (e instanceof Error && e.message.startsWith("Failed to delete preview")) {
|
|
367863
|
+
throw e;
|
|
367864
|
+
}
|
|
367865
|
+
throw new Error(`Failed to delete preview environment: ${response.statusText}`);
|
|
367866
|
+
}
|
|
367867
|
+
}
|
|
367868
|
+
}
|
|
367817
367869
|
async getMe(signal) {
|
|
367818
367870
|
const url = `${this.baseUrl}/users/me`;
|
|
367819
367871
|
writeLog("api", `GET ${url}`);
|
|
@@ -367891,6 +367943,13 @@ var SpecificClient = class {
|
|
|
367891
367943
|
async submitConfigs(deploymentId, configs) {
|
|
367892
367944
|
await this.client.submitConfigs(deploymentId, configs);
|
|
367893
367945
|
}
|
|
367946
|
+
// --- Preview Environments ---
|
|
367947
|
+
async createPreviewEnvironment(projectId) {
|
|
367948
|
+
return this.client.createPreviewEnvironment(projectId);
|
|
367949
|
+
}
|
|
367950
|
+
async deletePreviewEnvironment(environmentId) {
|
|
367951
|
+
return this.client.deletePreviewEnvironment(environmentId);
|
|
367952
|
+
}
|
|
367894
367953
|
};
|
|
367895
367954
|
function toDeployment(response) {
|
|
367896
367955
|
return {
|
|
@@ -372770,6 +372829,7 @@ import * as fs3 from "fs";
|
|
|
372770
372829
|
import * as path3 from "path";
|
|
372771
372830
|
var PROJECT_ID_FILE = ".specific/project_id";
|
|
372772
372831
|
var ENVIRONMENT_ID_FILE = ".specific/environment_id";
|
|
372832
|
+
var PREVIEW_ENVIRONMENT_ID_FILE = ".specific/preview_environment_id";
|
|
372773
372833
|
var ProjectNotLinkedError = class extends Error {
|
|
372774
372834
|
constructor() {
|
|
372775
372835
|
super(
|
|
@@ -372826,6 +372886,21 @@ function writeEnvironmentId(environmentId, projectDir = process.cwd()) {
|
|
|
372826
372886
|
}
|
|
372827
372887
|
fs3.writeFileSync(path3.join(specificDir, "environment_id"), environmentId + "\n");
|
|
372828
372888
|
}
|
|
372889
|
+
function readPreviewEnvironmentId(projectDir = process.cwd()) {
|
|
372890
|
+
const filePath = path3.join(projectDir, PREVIEW_ENVIRONMENT_ID_FILE);
|
|
372891
|
+
if (!fs3.existsSync(filePath)) {
|
|
372892
|
+
return null;
|
|
372893
|
+
}
|
|
372894
|
+
const id = fs3.readFileSync(filePath, "utf-8").trim();
|
|
372895
|
+
return id || null;
|
|
372896
|
+
}
|
|
372897
|
+
function writePreviewEnvironmentId(environmentId, projectDir = process.cwd()) {
|
|
372898
|
+
const specificDir = path3.join(projectDir, ".specific");
|
|
372899
|
+
if (!fs3.existsSync(specificDir)) {
|
|
372900
|
+
fs3.mkdirSync(specificDir, { recursive: true });
|
|
372901
|
+
}
|
|
372902
|
+
fs3.writeFileSync(path3.join(specificDir, "preview_environment_id"), environmentId + "\n");
|
|
372903
|
+
}
|
|
372829
372904
|
|
|
372830
372905
|
// src/lib/auth/credentials.ts
|
|
372831
372906
|
import * as fs19 from "fs";
|
|
@@ -373266,7 +373341,7 @@ function trackEvent(event, properties) {
|
|
|
373266
373341
|
event,
|
|
373267
373342
|
properties: {
|
|
373268
373343
|
...properties,
|
|
373269
|
-
cli_version: "0.1.
|
|
373344
|
+
cli_version: "0.1.123",
|
|
373270
373345
|
platform: process.platform,
|
|
373271
373346
|
node_version: process.version,
|
|
373272
373347
|
project_id: getProjectId()
|
|
@@ -376181,6 +376256,21 @@ async function runDeployPipeline(options2) {
|
|
|
376181
376256
|
} else if (!hasProjectId(projectDir)) {
|
|
376182
376257
|
writeProjectId(projectId);
|
|
376183
376258
|
}
|
|
376259
|
+
if (options2.preview) {
|
|
376260
|
+
const previousPreviewId = readPreviewEnvironmentId(projectDir);
|
|
376261
|
+
if (previousPreviewId) {
|
|
376262
|
+
console.log("Cleaning up previous preview environment...");
|
|
376263
|
+
try {
|
|
376264
|
+
await client2.deletePreviewEnvironment(previousPreviewId);
|
|
376265
|
+
} catch {
|
|
376266
|
+
}
|
|
376267
|
+
}
|
|
376268
|
+
console.log("Creating preview environment...");
|
|
376269
|
+
const preview = await client2.createPreviewEnvironment(projectId);
|
|
376270
|
+
writePreviewEnvironmentId(preview.id, projectDir);
|
|
376271
|
+
console.log(`Preview environment "${preview.name}" created (expires: ${new Date(preview.expiresAt).toLocaleString()})`);
|
|
376272
|
+
options2.env = preview.name;
|
|
376273
|
+
}
|
|
376184
376274
|
let environmentName;
|
|
376185
376275
|
if (options2.env) {
|
|
376186
376276
|
environmentName = options2.env;
|
|
@@ -376402,14 +376492,15 @@ async function deployCommand(options2) {
|
|
|
376402
376492
|
console.error(formatConfigError(err, hcl, configPath));
|
|
376403
376493
|
process.exit(1);
|
|
376404
376494
|
}
|
|
376405
|
-
const hasNonInteractiveFlags = options2.project || options2.secret?.length || options2.config?.length;
|
|
376495
|
+
const hasNonInteractiveFlags = options2.project || options2.secret?.length || options2.config?.length || options2.preview;
|
|
376406
376496
|
if (!isInteractive() || hasNonInteractiveFlags) {
|
|
376407
376497
|
await runDeployPipeline({
|
|
376408
376498
|
config,
|
|
376409
376499
|
projectId: options2.project,
|
|
376410
376500
|
env: options2.env,
|
|
376411
376501
|
secrets: options2.secret,
|
|
376412
|
-
configs: options2.config
|
|
376502
|
+
configs: options2.config,
|
|
376503
|
+
preview: options2.preview
|
|
376413
376504
|
});
|
|
376414
376505
|
return;
|
|
376415
376506
|
}
|
|
@@ -377278,7 +377369,7 @@ function compareVersions(a, b) {
|
|
|
377278
377369
|
return 0;
|
|
377279
377370
|
}
|
|
377280
377371
|
async function checkForUpdate() {
|
|
377281
|
-
const currentVersion = "0.1.
|
|
377372
|
+
const currentVersion = "0.1.123";
|
|
377282
377373
|
const response = await fetch(`${BINARIES_BASE_URL}/latest?t=${Date.now()}`);
|
|
377283
377374
|
if (!response.ok) {
|
|
377284
377375
|
throw new Error(`Failed to check for updates: HTTP ${response.status}`);
|
|
@@ -377548,7 +377639,7 @@ async function projectListCommand() {
|
|
|
377548
377639
|
var program = new Command();
|
|
377549
377640
|
var env = "production";
|
|
377550
377641
|
var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
|
|
377551
|
-
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.
|
|
377642
|
+
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.123").enablePositionalOptions();
|
|
377552
377643
|
program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").addHelpText("after", `
|
|
377553
377644
|
Examples:
|
|
377554
377645
|
$ specific init
|
|
@@ -377569,11 +377660,12 @@ Examples:
|
|
|
377569
377660
|
const key = options2.key ?? getDefaultKey();
|
|
377570
377661
|
devCommand(key, options2.tunnel ?? false);
|
|
377571
377662
|
});
|
|
377572
|
-
program.command("deploy").description("Deploy to Specific infrastructure").option("--project <id>", "Project ID to deploy to (overrides .projectid file)").option("--env <name>", "Target environment (auto-selected if only one exists)").option("--secret <key=value...>", "Secret values (repeatable)").option("--config <key=value...>", "Config values (repeatable)").addHelpText("after", `
|
|
377663
|
+
program.command("deploy").description("Deploy to Specific infrastructure").option("--project <id>", "Project ID to deploy to (overrides .projectid file)").option("--env <name>", "Target environment (auto-selected if only one exists)").option("--secret <key=value...>", "Secret values (repeatable)").option("--config <key=value...>", "Config values (repeatable)").option("--preview", "Deploy to an ephemeral preview environment").addHelpText("after", `
|
|
377573
377664
|
Examples:
|
|
377574
377665
|
$ specific deploy
|
|
377575
377666
|
$ specific deploy --env staging
|
|
377576
377667
|
$ specific deploy --project proj_123
|
|
377668
|
+
$ specific deploy --preview
|
|
377577
377669
|
$ specific deploy --secret db_url=postgres://... --config domain=app.com`).action((options2) => {
|
|
377578
377670
|
deployCommand(options2);
|
|
377579
377671
|
});
|
package/package.json
CHANGED
/package/dist/admin/_next/static/{eboxHGqEe6h17B0pFV0xY → iKEnJVRd6gOzhr5N6iD4r}/_buildManifest.js
RENAMED
|
File without changes
|
|
File without changes
|
/package/dist/admin/_next/static/{eboxHGqEe6h17B0pFV0xY → iKEnJVRd6gOzhr5N6iD4r}/_ssgManifest.js
RENAMED
|
File without changes
|