@specific.dev/cli 0.1.119 → 0.1.120
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 +236 -22
- package/package.json +1 -1
- /package/dist/admin/_next/static/{Jq_9GUFfnF8eZkPZMF_EC → wSllkH7WRyJEpQx0UpLjo}/_buildManifest.js +0 -0
- /package/dist/admin/_next/static/{Jq_9GUFfnF8eZkPZMF_EC → wSllkH7WRyJEpQx0UpLjo}/_clientMiddlewareManifest.json +0 -0
- /package/dist/admin/_next/static/{Jq_9GUFfnF8eZkPZMF_EC → wSllkH7WRyJEpQx0UpLjo}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -372759,6 +372759,7 @@ import * as crypto3 from "crypto";
|
|
|
372759
372759
|
import * as fs3 from "fs";
|
|
372760
372760
|
import * as path3 from "path";
|
|
372761
372761
|
var PROJECT_ID_FILE = ".specific/project_id";
|
|
372762
|
+
var ENVIRONMENT_ID_FILE = ".specific/environment_id";
|
|
372762
372763
|
var ProjectNotLinkedError = class extends Error {
|
|
372763
372764
|
constructor() {
|
|
372764
372765
|
super(
|
|
@@ -372793,6 +372794,28 @@ function writeProjectId(projectId, projectDir = process.cwd()) {
|
|
|
372793
372794
|
}
|
|
372794
372795
|
fs3.writeFileSync(path3.join(specificDir, "project_id"), projectId + "\n");
|
|
372795
372796
|
}
|
|
372797
|
+
function readEnvironmentId(projectDir = process.cwd()) {
|
|
372798
|
+
const envIdPath = path3.join(projectDir, ENVIRONMENT_ID_FILE);
|
|
372799
|
+
if (!fs3.existsSync(envIdPath)) {
|
|
372800
|
+
throw new Error(`${ENVIRONMENT_ID_FILE} does not exist`);
|
|
372801
|
+
}
|
|
372802
|
+
const envId = fs3.readFileSync(envIdPath, "utf-8").trim();
|
|
372803
|
+
if (!envId) {
|
|
372804
|
+
throw new Error(`${ENVIRONMENT_ID_FILE} is empty`);
|
|
372805
|
+
}
|
|
372806
|
+
return envId;
|
|
372807
|
+
}
|
|
372808
|
+
function hasEnvironmentId(projectDir = process.cwd()) {
|
|
372809
|
+
const envIdPath = path3.join(projectDir, ENVIRONMENT_ID_FILE);
|
|
372810
|
+
return fs3.existsSync(envIdPath);
|
|
372811
|
+
}
|
|
372812
|
+
function writeEnvironmentId(environmentId, projectDir = process.cwd()) {
|
|
372813
|
+
const specificDir = path3.join(projectDir, ".specific");
|
|
372814
|
+
if (!fs3.existsSync(specificDir)) {
|
|
372815
|
+
fs3.mkdirSync(specificDir, { recursive: true });
|
|
372816
|
+
}
|
|
372817
|
+
fs3.writeFileSync(path3.join(specificDir, "environment_id"), environmentId + "\n");
|
|
372818
|
+
}
|
|
372796
372819
|
|
|
372797
372820
|
// src/lib/auth/credentials.ts
|
|
372798
372821
|
import * as fs19 from "fs";
|
|
@@ -373233,7 +373256,7 @@ function trackEvent(event, properties) {
|
|
|
373233
373256
|
event,
|
|
373234
373257
|
properties: {
|
|
373235
373258
|
...properties,
|
|
373236
|
-
cli_version: "0.1.
|
|
373259
|
+
cli_version: "0.1.120",
|
|
373237
373260
|
platform: process.platform,
|
|
373238
373261
|
node_version: process.version,
|
|
373239
373262
|
project_id: getProjectId()
|
|
@@ -375208,6 +375231,28 @@ function NameInput({ onSubmit, onCancel }) {
|
|
|
375208
375231
|
});
|
|
375209
375232
|
return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React7.createElement(Text7, { bold: true }, "Create new project"), /* @__PURE__ */ React7.createElement(Text7, null, "Enter project name:"), /* @__PURE__ */ React7.createElement(Box7, null, /* @__PURE__ */ React7.createElement(Text7, { color: "cyan" }, "> "), /* @__PURE__ */ React7.createElement(Text7, null, value), /* @__PURE__ */ React7.createElement(Text7, { color: "gray" }, "|")), /* @__PURE__ */ React7.createElement(Text7, { dimColor: true }, "Press Enter to create, Esc to go back"));
|
|
375210
375233
|
}
|
|
375234
|
+
function EnvironmentSelector({
|
|
375235
|
+
environments,
|
|
375236
|
+
selectedIndex,
|
|
375237
|
+
onSelect,
|
|
375238
|
+
onUp,
|
|
375239
|
+
onDown
|
|
375240
|
+
}) {
|
|
375241
|
+
useInput4((input, key) => {
|
|
375242
|
+
if (key.return) {
|
|
375243
|
+
const env2 = environments[selectedIndex];
|
|
375244
|
+
if (env2) onSelect(env2);
|
|
375245
|
+
} else if (key.upArrow) {
|
|
375246
|
+
onUp();
|
|
375247
|
+
} else if (key.downArrow) {
|
|
375248
|
+
onDown();
|
|
375249
|
+
}
|
|
375250
|
+
});
|
|
375251
|
+
return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React7.createElement(Text7, { bold: true }, "Select an environment to deploy to:"), /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column" }, environments.map((env2, index) => {
|
|
375252
|
+
const isSelected = index === selectedIndex;
|
|
375253
|
+
return /* @__PURE__ */ React7.createElement(Text7, { key: env2.id }, isSelected ? /* @__PURE__ */ React7.createElement(Text7, { color: "cyan" }, " ", "> ") : /* @__PURE__ */ React7.createElement(Text7, null, " "), /* @__PURE__ */ React7.createElement(Text7, null, env2.name));
|
|
375254
|
+
})), /* @__PURE__ */ React7.createElement(Text7, { dimColor: true }, "Use arrow keys to navigate, Enter to select"));
|
|
375255
|
+
}
|
|
375211
375256
|
function getMissingSecrets(pendingActions) {
|
|
375212
375257
|
if (!pendingActions) return [];
|
|
375213
375258
|
const secretAction = pendingActions.find((a) => a.type === "missing_secrets");
|
|
@@ -375244,7 +375289,7 @@ function formatErrorCode(code) {
|
|
|
375244
375289
|
function StructuredError({ error }) {
|
|
375245
375290
|
return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text7, { color: "red", bold: true }, formatErrorCode(error.code), ": ", error.message), error.resource && /* @__PURE__ */ React7.createElement(Text7, { dimColor: true }, "Resource: ", error.resource), error.output && /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React7.createElement(Text7, { bold: true }, "Output:"), /* @__PURE__ */ React7.createElement(Text7, null, error.output)));
|
|
375246
375291
|
}
|
|
375247
|
-
function DeployUI({
|
|
375292
|
+
function DeployUI({ envFlag, config }) {
|
|
375248
375293
|
const { exit } = useApp3();
|
|
375249
375294
|
const [state, setState] = useState6({ phase: "checking-auth" });
|
|
375250
375295
|
const clientRef = React7.useRef(null);
|
|
@@ -375254,10 +375299,7 @@ function DeployUI({ environment, config }) {
|
|
|
375254
375299
|
if (hasProjectId(projectDir)) {
|
|
375255
375300
|
const projectId = readProjectId(projectDir);
|
|
375256
375301
|
if (isLoggedIn()) {
|
|
375257
|
-
setState({
|
|
375258
|
-
phase: "creating-tarball",
|
|
375259
|
-
projectId
|
|
375260
|
-
});
|
|
375302
|
+
setState({ phase: "loading-environments", projectId });
|
|
375261
375303
|
} else {
|
|
375262
375304
|
setState({ phase: "logging-in", projectId });
|
|
375263
375305
|
}
|
|
@@ -375312,7 +375354,7 @@ function DeployUI({ environment, config }) {
|
|
|
375312
375354
|
const successResponse = response;
|
|
375313
375355
|
await saveCredentialsFromToken(successResponse);
|
|
375314
375356
|
setState(
|
|
375315
|
-
(s) => s.projectId ? { phase: "
|
|
375357
|
+
(s) => s.projectId ? { phase: "loading-environments", projectId: s.projectId } : { phase: "loading-projects" }
|
|
375316
375358
|
);
|
|
375317
375359
|
}
|
|
375318
375360
|
};
|
|
@@ -375371,8 +375413,9 @@ function DeployUI({ environment, config }) {
|
|
|
375371
375413
|
const proj = project;
|
|
375372
375414
|
writeProjectId(proj.id);
|
|
375373
375415
|
setState({
|
|
375374
|
-
phase: "
|
|
375375
|
-
projectId: proj.id
|
|
375416
|
+
phase: "loading-environments",
|
|
375417
|
+
projectId: proj.id,
|
|
375418
|
+
environments: proj.environments
|
|
375376
375419
|
});
|
|
375377
375420
|
}
|
|
375378
375421
|
},
|
|
@@ -375395,8 +375438,9 @@ function DeployUI({ environment, config }) {
|
|
|
375395
375438
|
if (cancelled) return;
|
|
375396
375439
|
writeProjectId(project.id);
|
|
375397
375440
|
setState({
|
|
375398
|
-
phase: "
|
|
375399
|
-
projectId: project.id
|
|
375441
|
+
phase: "loading-environments",
|
|
375442
|
+
projectId: project.id,
|
|
375443
|
+
environments: project.environments
|
|
375400
375444
|
});
|
|
375401
375445
|
} catch (err) {
|
|
375402
375446
|
if (cancelled) return;
|
|
@@ -375411,6 +375455,101 @@ function DeployUI({ environment, config }) {
|
|
|
375411
375455
|
cancelled = true;
|
|
375412
375456
|
};
|
|
375413
375457
|
}, [state.phase, state.newProjectName]);
|
|
375458
|
+
useEffect6(() => {
|
|
375459
|
+
if (state.phase !== "loading-environments" || !state.projectId) return;
|
|
375460
|
+
let cancelled = false;
|
|
375461
|
+
async function loadEnvironments() {
|
|
375462
|
+
try {
|
|
375463
|
+
let environments = state.environments;
|
|
375464
|
+
if (!environments) {
|
|
375465
|
+
const token = await getValidAccessToken();
|
|
375466
|
+
const client2 = new SpecificClient({ accessToken: token });
|
|
375467
|
+
const projects2 = await client2.listProjects();
|
|
375468
|
+
const project = projects2.find((p) => p.id === state.projectId);
|
|
375469
|
+
environments = project?.environments ?? [];
|
|
375470
|
+
}
|
|
375471
|
+
if (cancelled) return;
|
|
375472
|
+
if (environments.length === 0) {
|
|
375473
|
+
setState((s) => ({
|
|
375474
|
+
...s,
|
|
375475
|
+
phase: "error",
|
|
375476
|
+
error: "No environments found for this project"
|
|
375477
|
+
}));
|
|
375478
|
+
return;
|
|
375479
|
+
}
|
|
375480
|
+
if (envFlag) {
|
|
375481
|
+
const match = environments.find((e) => e.name === envFlag);
|
|
375482
|
+
if (!match) {
|
|
375483
|
+
setState((s) => ({
|
|
375484
|
+
...s,
|
|
375485
|
+
phase: "error",
|
|
375486
|
+
error: `Environment "${envFlag}" not found. Available: ${environments.map((e) => e.name).join(", ")}`
|
|
375487
|
+
}));
|
|
375488
|
+
return;
|
|
375489
|
+
}
|
|
375490
|
+
writeEnvironmentId(match.id);
|
|
375491
|
+
setState((s) => ({
|
|
375492
|
+
...s,
|
|
375493
|
+
phase: "creating-tarball",
|
|
375494
|
+
environmentName: match.name,
|
|
375495
|
+
environments
|
|
375496
|
+
}));
|
|
375497
|
+
return;
|
|
375498
|
+
}
|
|
375499
|
+
const projectDir = process.cwd();
|
|
375500
|
+
if (hasEnvironmentId(projectDir)) {
|
|
375501
|
+
const savedEnvId = readEnvironmentId(projectDir);
|
|
375502
|
+
const match = environments.find((e) => e.id === savedEnvId);
|
|
375503
|
+
if (match) {
|
|
375504
|
+
setState((s) => ({
|
|
375505
|
+
...s,
|
|
375506
|
+
phase: "creating-tarball",
|
|
375507
|
+
environmentName: match.name,
|
|
375508
|
+
environments
|
|
375509
|
+
}));
|
|
375510
|
+
return;
|
|
375511
|
+
}
|
|
375512
|
+
}
|
|
375513
|
+
if (environments.length === 1) {
|
|
375514
|
+
writeEnvironmentId(environments[0].id);
|
|
375515
|
+
setState((s) => ({
|
|
375516
|
+
...s,
|
|
375517
|
+
phase: "creating-tarball",
|
|
375518
|
+
environmentName: environments[0].name,
|
|
375519
|
+
environments
|
|
375520
|
+
}));
|
|
375521
|
+
return;
|
|
375522
|
+
}
|
|
375523
|
+
setState((s) => ({
|
|
375524
|
+
...s,
|
|
375525
|
+
phase: "selecting-environment",
|
|
375526
|
+
environments,
|
|
375527
|
+
environmentSelectedIndex: 0
|
|
375528
|
+
}));
|
|
375529
|
+
} catch (err) {
|
|
375530
|
+
if (cancelled) return;
|
|
375531
|
+
setState({
|
|
375532
|
+
phase: "error",
|
|
375533
|
+
error: err instanceof Error ? err.message : String(err)
|
|
375534
|
+
});
|
|
375535
|
+
}
|
|
375536
|
+
}
|
|
375537
|
+
loadEnvironments();
|
|
375538
|
+
return () => {
|
|
375539
|
+
cancelled = true;
|
|
375540
|
+
};
|
|
375541
|
+
}, [state.phase, state.projectId]);
|
|
375542
|
+
const handleEnvironmentSelect = useCallback3(
|
|
375543
|
+
(env2) => {
|
|
375544
|
+
writeEnvironmentId(env2.id);
|
|
375545
|
+
setState((s) => ({
|
|
375546
|
+
...s,
|
|
375547
|
+
phase: "creating-tarball",
|
|
375548
|
+
environmentName: env2.name
|
|
375549
|
+
}));
|
|
375550
|
+
},
|
|
375551
|
+
[]
|
|
375552
|
+
);
|
|
375414
375553
|
const handleSecretSubmit = useCallback3((value) => {
|
|
375415
375554
|
setState((s) => {
|
|
375416
375555
|
if (!s.missingSecrets || s.currentSecretIndex === void 0) return s;
|
|
@@ -375555,12 +375694,13 @@ function DeployUI({ environment, config }) {
|
|
|
375555
375694
|
}
|
|
375556
375695
|
})();
|
|
375557
375696
|
}, [state]);
|
|
375697
|
+
const environment = state.environmentName || "prod";
|
|
375558
375698
|
useEffect6(() => {
|
|
375559
|
-
if (state.phase !== "creating-tarball" || !state.projectId) return;
|
|
375699
|
+
if (state.phase !== "creating-tarball" || !state.projectId || !state.environmentName) return;
|
|
375560
375700
|
let cancelled = false;
|
|
375561
375701
|
async function runDeploy() {
|
|
375562
375702
|
const projectDir = process.cwd();
|
|
375563
|
-
writeLog("deploy", `Starting deployment to "${
|
|
375703
|
+
writeLog("deploy", `Starting deployment to "${state.environmentName}"`);
|
|
375564
375704
|
writeLog("deploy", `Project directory: ${projectDir}`);
|
|
375565
375705
|
const client2 = new SpecificClient({ tokenProvider: getValidAccessToken });
|
|
375566
375706
|
clientRef.current = client2;
|
|
@@ -375592,7 +375732,7 @@ function DeployUI({ environment, config }) {
|
|
|
375592
375732
|
try {
|
|
375593
375733
|
writeLog("deploy", `Creating deployment for project ${state.projectId}`);
|
|
375594
375734
|
const gitInfo = getGitInfo(projectDir);
|
|
375595
|
-
deployment2 = await client2.createDeployment(state.projectId,
|
|
375735
|
+
deployment2 = await client2.createDeployment(state.projectId, state.environmentName, {
|
|
375596
375736
|
triggeredBy: "cli",
|
|
375597
375737
|
...gitInfo && {
|
|
375598
375738
|
gitCommitSha: gitInfo.commitSha,
|
|
@@ -375634,7 +375774,7 @@ function DeployUI({ environment, config }) {
|
|
|
375634
375774
|
return () => {
|
|
375635
375775
|
cancelled = true;
|
|
375636
375776
|
};
|
|
375637
|
-
}, [state.projectId,
|
|
375777
|
+
}, [state.projectId, state.environmentName, config.builds]);
|
|
375638
375778
|
useEffect6(() => {
|
|
375639
375779
|
if (state.phase !== "pending" || !state.deployment) return;
|
|
375640
375780
|
let pollInterval;
|
|
@@ -375902,6 +376042,30 @@ function DeployUI({ environment, config }) {
|
|
|
375902
376042
|
if (phase === "creating-project") {
|
|
375903
376043
|
return /* @__PURE__ */ React7.createElement(Box7, null, /* @__PURE__ */ React7.createElement(Text7, { color: "blue" }, /* @__PURE__ */ React7.createElement(Spinner4, { type: "dots" })), /* @__PURE__ */ React7.createElement(Text7, null, " Creating project..."));
|
|
375904
376044
|
}
|
|
376045
|
+
if (phase === "loading-environments") {
|
|
376046
|
+
return /* @__PURE__ */ React7.createElement(Box7, null, /* @__PURE__ */ React7.createElement(Text7, { color: "blue" }, /* @__PURE__ */ React7.createElement(Spinner4, { type: "dots" })), /* @__PURE__ */ React7.createElement(Text7, null, " Loading environments..."));
|
|
376047
|
+
}
|
|
376048
|
+
if (phase === "selecting-environment" && state.environments && state.environmentSelectedIndex !== void 0) {
|
|
376049
|
+
return /* @__PURE__ */ React7.createElement(
|
|
376050
|
+
EnvironmentSelector,
|
|
376051
|
+
{
|
|
376052
|
+
environments: state.environments,
|
|
376053
|
+
selectedIndex: state.environmentSelectedIndex,
|
|
376054
|
+
onSelect: handleEnvironmentSelect,
|
|
376055
|
+
onUp: () => setState((s) => ({
|
|
376056
|
+
...s,
|
|
376057
|
+
environmentSelectedIndex: Math.max(0, (s.environmentSelectedIndex ?? 0) - 1)
|
|
376058
|
+
})),
|
|
376059
|
+
onDown: () => setState((s) => ({
|
|
376060
|
+
...s,
|
|
376061
|
+
environmentSelectedIndex: Math.min(
|
|
376062
|
+
(s.environments?.length ?? 1) - 1,
|
|
376063
|
+
(s.environmentSelectedIndex ?? 0) + 1
|
|
376064
|
+
)
|
|
376065
|
+
}))
|
|
376066
|
+
}
|
|
376067
|
+
);
|
|
376068
|
+
}
|
|
375905
376069
|
const currentSecret = missingSecrets && currentSecretIndex !== void 0 ? missingSecrets[currentSecretIndex] : void 0;
|
|
375906
376070
|
const currentConfig = missingConfigs && currentConfigIndex !== void 0 ? missingConfigs[currentConfigIndex] : void 0;
|
|
375907
376071
|
const getDisplayPhase = () => {
|
|
@@ -376007,6 +376171,52 @@ async function runDeployPipeline(options2) {
|
|
|
376007
376171
|
} else if (!hasProjectId(projectDir)) {
|
|
376008
376172
|
writeProjectId(projectId);
|
|
376009
376173
|
}
|
|
376174
|
+
let environmentName;
|
|
376175
|
+
if (options2.env) {
|
|
376176
|
+
environmentName = options2.env;
|
|
376177
|
+
} else if (hasEnvironmentId(projectDir)) {
|
|
376178
|
+
const savedEnvId = readEnvironmentId(projectDir);
|
|
376179
|
+
const projects = await client2.listProjects();
|
|
376180
|
+
const project = projects.find((p) => p.id === projectId);
|
|
376181
|
+
const env2 = project?.environments.find((e) => e.id === savedEnvId);
|
|
376182
|
+
if (env2) {
|
|
376183
|
+
environmentName = env2.name;
|
|
376184
|
+
} else {
|
|
376185
|
+
const environments = project?.environments ?? [];
|
|
376186
|
+
if (environments.length === 1) {
|
|
376187
|
+
environmentName = environments[0].name;
|
|
376188
|
+
writeEnvironmentId(environments[0].id);
|
|
376189
|
+
} else if (environments.length === 0) {
|
|
376190
|
+
console.error("Error: No environments found for this project");
|
|
376191
|
+
process.exit(1);
|
|
376192
|
+
} else {
|
|
376193
|
+
console.error(
|
|
376194
|
+
`Error: Multiple environments available. Specify one with --env.
|
|
376195
|
+
Available: ${environments.map((e) => e.name).join(", ")}
|
|
376196
|
+
Example: specific deploy --env ${environments[0].name}`
|
|
376197
|
+
);
|
|
376198
|
+
process.exit(1);
|
|
376199
|
+
}
|
|
376200
|
+
}
|
|
376201
|
+
} else {
|
|
376202
|
+
const projects = await client2.listProjects();
|
|
376203
|
+
const project = projects.find((p) => p.id === projectId);
|
|
376204
|
+
const environments = project?.environments ?? [];
|
|
376205
|
+
if (environments.length === 1) {
|
|
376206
|
+
environmentName = environments[0].name;
|
|
376207
|
+
writeEnvironmentId(environments[0].id);
|
|
376208
|
+
} else if (environments.length === 0) {
|
|
376209
|
+
console.error("Error: No environments found for this project");
|
|
376210
|
+
process.exit(1);
|
|
376211
|
+
} else {
|
|
376212
|
+
console.error(
|
|
376213
|
+
`Error: Multiple environments available. Specify one with --env.
|
|
376214
|
+
Available: ${environments.map((e) => e.name).join(", ")}
|
|
376215
|
+
Example: specific deploy --env ${environments[0].name}`
|
|
376216
|
+
);
|
|
376217
|
+
process.exit(1);
|
|
376218
|
+
}
|
|
376219
|
+
}
|
|
376010
376220
|
const parsedSecrets = {};
|
|
376011
376221
|
if (options2.secrets) {
|
|
376012
376222
|
for (const s of options2.secrets) {
|
|
@@ -376040,7 +376250,7 @@ async function runDeployPipeline(options2) {
|
|
|
376040
376250
|
let deployment;
|
|
376041
376251
|
try {
|
|
376042
376252
|
const gitInfo = getGitInfo(projectDir);
|
|
376043
|
-
deployment = await client2.createDeployment(projectId,
|
|
376253
|
+
deployment = await client2.createDeployment(projectId, environmentName, {
|
|
376044
376254
|
triggeredBy: "cli",
|
|
376045
376255
|
...gitInfo && {
|
|
376046
376256
|
gitCommitSha: gitInfo.commitSha,
|
|
@@ -376187,6 +376397,7 @@ async function deployCommand(options2) {
|
|
|
376187
376397
|
await runDeployPipeline({
|
|
376188
376398
|
config,
|
|
376189
376399
|
projectId: options2.project,
|
|
376400
|
+
env: options2.env,
|
|
376190
376401
|
secrets: options2.secret,
|
|
376191
376402
|
configs: options2.config
|
|
376192
376403
|
});
|
|
@@ -376196,7 +376407,7 @@ async function deployCommand(options2) {
|
|
|
376196
376407
|
/* @__PURE__ */ React7.createElement(
|
|
376197
376408
|
DeployUI,
|
|
376198
376409
|
{
|
|
376199
|
-
|
|
376410
|
+
envFlag: options2.env,
|
|
376200
376411
|
config
|
|
376201
376412
|
}
|
|
376202
376413
|
)
|
|
@@ -377057,7 +377268,7 @@ function compareVersions(a, b) {
|
|
|
377057
377268
|
return 0;
|
|
377058
377269
|
}
|
|
377059
377270
|
async function checkForUpdate() {
|
|
377060
|
-
const currentVersion = "0.1.
|
|
377271
|
+
const currentVersion = "0.1.120";
|
|
377061
377272
|
const response = await fetch(`${BINARIES_BASE_URL}/latest?t=${Date.now()}`);
|
|
377062
377273
|
if (!response.ok) {
|
|
377063
377274
|
throw new Error(`Failed to check for updates: HTTP ${response.status}`);
|
|
@@ -377306,12 +377517,14 @@ async function projectListCommand() {
|
|
|
377306
377517
|
if (!grouped.has(orgName)) {
|
|
377307
377518
|
grouped.set(orgName, []);
|
|
377308
377519
|
}
|
|
377309
|
-
grouped.get(orgName).push({ id: project.id, name: project.name });
|
|
377520
|
+
grouped.get(orgName).push({ id: project.id, name: project.name, environments: project.environments });
|
|
377310
377521
|
}
|
|
377311
377522
|
for (const [orgName, orgProjects] of grouped) {
|
|
377312
377523
|
console.log(`${orgName}:`);
|
|
377313
377524
|
for (const project of orgProjects) {
|
|
377314
|
-
|
|
377525
|
+
const envNames = project.environments.map((e) => e.name).join(", ");
|
|
377526
|
+
const envSuffix = envNames ? ` \u2014 ${envNames}` : "";
|
|
377527
|
+
console.log(` ${project.name} (${project.id})${envSuffix}`);
|
|
377315
377528
|
}
|
|
377316
377529
|
}
|
|
377317
377530
|
} catch (error) {
|
|
@@ -377325,7 +377538,7 @@ async function projectListCommand() {
|
|
|
377325
377538
|
var program = new Command();
|
|
377326
377539
|
var env = "production";
|
|
377327
377540
|
var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
|
|
377328
|
-
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.
|
|
377541
|
+
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.120").enablePositionalOptions();
|
|
377329
377542
|
program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").addHelpText("after", `
|
|
377330
377543
|
Examples:
|
|
377331
377544
|
$ specific init
|
|
@@ -377346,9 +377559,10 @@ Examples:
|
|
|
377346
377559
|
const key = options2.key ?? getDefaultKey();
|
|
377347
377560
|
devCommand(key, options2.tunnel ?? false);
|
|
377348
377561
|
});
|
|
377349
|
-
program.command("deploy").description("Deploy to Specific infrastructure").option("--project <id>", "Project ID to deploy to (overrides .projectid file)").option("--secret <key=value...>", "Secret values (repeatable)").option("--config <key=value...>", "Config values (repeatable)").addHelpText("after", `
|
|
377562
|
+
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", `
|
|
377350
377563
|
Examples:
|
|
377351
377564
|
$ specific deploy
|
|
377565
|
+
$ specific deploy --env staging
|
|
377352
377566
|
$ specific deploy --project proj_123
|
|
377353
377567
|
$ specific deploy --secret db_url=postgres://... --config domain=app.com`).action((options2) => {
|
|
377354
377568
|
deployCommand(options2);
|
package/package.json
CHANGED
/package/dist/admin/_next/static/{Jq_9GUFfnF8eZkPZMF_EC → wSllkH7WRyJEpQx0UpLjo}/_buildManifest.js
RENAMED
|
File without changes
|
|
File without changes
|
/package/dist/admin/_next/static/{Jq_9GUFfnF8eZkPZMF_EC → wSllkH7WRyJEpQx0UpLjo}/_ssgManifest.js
RENAMED
|
File without changes
|