@specific.dev/cli 0.1.50 → 0.1.51
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.__PAGE__.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._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/__next.databases.__PAGE__.txt +1 -1
- package/dist/admin/databases/__next.databases.txt +1 -1
- package/dist/admin/databases/index.html +1 -1
- package/dist/admin/databases/index.txt +1 -1
- package/dist/admin/index.html +1 -1
- package/dist/admin/index.txt +1 -1
- package/dist/cli.js +124 -95
- package/dist/docs/builds.md +42 -0
- package/dist/docs/services.md +34 -0
- package/dist/postinstall.js +1 -1
- package/package.json +2 -2
- /package/dist/admin/_next/static/{o2Qo92jA0gWbtB1ZWKQFF → h5UEt0QGdPmIwztzVl3eF}/_buildManifest.js +0 -0
- /package/dist/admin/_next/static/{o2Qo92jA0gWbtB1ZWKQFF → h5UEt0QGdPmIwztzVl3eF}/_clientMiddlewareManifest.json +0 -0
- /package/dist/admin/_next/static/{o2Qo92jA0gWbtB1ZWKQFF → h5UEt0QGdPmIwztzVl3eF}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -637,19 +637,19 @@ var init_open = __esm({
|
|
|
637
637
|
}
|
|
638
638
|
const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
|
|
639
639
|
if (options2.wait) {
|
|
640
|
-
return new Promise((
|
|
640
|
+
return new Promise((resolve10, reject) => {
|
|
641
641
|
subprocess.once("error", reject);
|
|
642
642
|
subprocess.once("close", (exitCode) => {
|
|
643
643
|
if (!options2.allowNonzeroExitCode && exitCode !== 0) {
|
|
644
644
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
645
645
|
return;
|
|
646
646
|
}
|
|
647
|
-
|
|
647
|
+
resolve10(subprocess);
|
|
648
648
|
});
|
|
649
649
|
});
|
|
650
650
|
}
|
|
651
651
|
if (isFallbackAttempt) {
|
|
652
|
-
return new Promise((
|
|
652
|
+
return new Promise((resolve10, reject) => {
|
|
653
653
|
subprocess.once("error", reject);
|
|
654
654
|
subprocess.once("spawn", () => {
|
|
655
655
|
subprocess.once("close", (exitCode) => {
|
|
@@ -659,17 +659,17 @@ var init_open = __esm({
|
|
|
659
659
|
return;
|
|
660
660
|
}
|
|
661
661
|
subprocess.unref();
|
|
662
|
-
|
|
662
|
+
resolve10(subprocess);
|
|
663
663
|
});
|
|
664
664
|
});
|
|
665
665
|
});
|
|
666
666
|
}
|
|
667
667
|
subprocess.unref();
|
|
668
|
-
return new Promise((
|
|
668
|
+
return new Promise((resolve10, reject) => {
|
|
669
669
|
subprocess.once("error", reject);
|
|
670
670
|
subprocess.once("spawn", () => {
|
|
671
671
|
subprocess.off("error", reject);
|
|
672
|
-
|
|
672
|
+
resolve10(subprocess);
|
|
673
673
|
});
|
|
674
674
|
});
|
|
675
675
|
};
|
|
@@ -183682,7 +183682,7 @@ async function pollUntilToken(deviceAuth, isCancelled) {
|
|
|
183682
183682
|
return null;
|
|
183683
183683
|
}
|
|
183684
183684
|
function sleep(ms) {
|
|
183685
|
-
return new Promise((
|
|
183685
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
183686
183686
|
}
|
|
183687
183687
|
|
|
183688
183688
|
// src/lib/auth/login.tsx
|
|
@@ -183699,7 +183699,7 @@ function LoginUI({
|
|
|
183699
183699
|
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, isReauthentication && /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "Session expired. Please log in again."), /* @__PURE__ */ React.createElement(Text, { bold: true }, "Log in to Specific"), state.phase === "waiting-for-browser" ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, "Your authentication code:", " ", /* @__PURE__ */ React.createElement(Text, { color: "cyan", bold: true }, state.userCode))), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "blue" }, /* @__PURE__ */ React.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React.createElement(Text, null, " Waiting for authentication in browser...")), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "If the browser didn't open, visit: ", state.verificationUri)) : /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "blue" }, /* @__PURE__ */ React.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React.createElement(Text, null, " Initiating login...")));
|
|
183700
183700
|
}
|
|
183701
183701
|
function performLogin(options2 = {}) {
|
|
183702
|
-
return new Promise((
|
|
183702
|
+
return new Promise((resolve10) => {
|
|
183703
183703
|
let currentState = { phase: "initiating" };
|
|
183704
183704
|
let flowHandle;
|
|
183705
183705
|
const instance = render(
|
|
@@ -183739,14 +183739,14 @@ function performLogin(options2 = {}) {
|
|
|
183739
183739
|
process.off("SIGINT", handleExit);
|
|
183740
183740
|
process.off("SIGTERM", handleExit);
|
|
183741
183741
|
instance.unmount();
|
|
183742
|
-
|
|
183742
|
+
resolve10({ success: true, userEmail: newState.email });
|
|
183743
183743
|
}, 100);
|
|
183744
183744
|
} else if (newState.phase === "error") {
|
|
183745
183745
|
setTimeout(() => {
|
|
183746
183746
|
process.off("SIGINT", handleExit);
|
|
183747
183747
|
process.off("SIGTERM", handleExit);
|
|
183748
183748
|
instance.unmount();
|
|
183749
|
-
|
|
183749
|
+
resolve10({ success: false, error: new Error(newState.message) });
|
|
183750
183750
|
}, 100);
|
|
183751
183751
|
}
|
|
183752
183752
|
}
|
|
@@ -183873,7 +183873,7 @@ function trackEvent(event, properties) {
|
|
|
183873
183873
|
event,
|
|
183874
183874
|
properties: {
|
|
183875
183875
|
...properties,
|
|
183876
|
-
cli_version: "0.1.
|
|
183876
|
+
cli_version: "0.1.51",
|
|
183877
183877
|
platform: process.platform,
|
|
183878
183878
|
node_version: process.version,
|
|
183879
183879
|
project_id: getProjectId(),
|
|
@@ -184529,6 +184529,9 @@ function parseBuilds(buildData) {
|
|
|
184529
184529
|
if (fieldObj.context) {
|
|
184530
184530
|
build.context = String(fieldObj.context);
|
|
184531
184531
|
}
|
|
184532
|
+
if (fieldObj.root) {
|
|
184533
|
+
build.root = String(fieldObj.root);
|
|
184534
|
+
}
|
|
184532
184535
|
if (dev) {
|
|
184533
184536
|
build.dev = dev;
|
|
184534
184537
|
}
|
|
@@ -184616,6 +184619,9 @@ function parseServices(serviceData) {
|
|
|
184616
184619
|
if (fieldObj.command) {
|
|
184617
184620
|
service.command = String(fieldObj.command);
|
|
184618
184621
|
}
|
|
184622
|
+
if (fieldObj.root) {
|
|
184623
|
+
service.root = String(fieldObj.root);
|
|
184624
|
+
}
|
|
184619
184625
|
const endpoints = parseEndpoints(fieldObj);
|
|
184620
184626
|
if (fieldObj.expose !== void 0) {
|
|
184621
184627
|
service.expose = {};
|
|
@@ -185055,10 +185061,10 @@ async function downloadFile(url, destPath, onProgress) {
|
|
|
185055
185061
|
});
|
|
185056
185062
|
}
|
|
185057
185063
|
}
|
|
185058
|
-
await new Promise((
|
|
185064
|
+
await new Promise((resolve10, reject) => {
|
|
185059
185065
|
fileStream.end((err) => {
|
|
185060
185066
|
if (err) reject(err);
|
|
185061
|
-
else
|
|
185067
|
+
else resolve10();
|
|
185062
185068
|
});
|
|
185063
185069
|
});
|
|
185064
185070
|
fs11.renameSync(partPath, destPath);
|
|
@@ -185241,7 +185247,7 @@ var drizzleGatewayBinary = {
|
|
|
185241
185247
|
// src/lib/bin/definitions/reshape.ts
|
|
185242
185248
|
var reshapeBinary = {
|
|
185243
185249
|
name: "reshape",
|
|
185244
|
-
versions: ["0.9.
|
|
185250
|
+
versions: ["0.9.1"],
|
|
185245
185251
|
// GitHub release assets
|
|
185246
185252
|
urlTemplate: "https://github.com/fabianlindfors/reshape/releases/download/v{version}/reshape-{arch}",
|
|
185247
185253
|
platformMapping: {
|
|
@@ -185265,13 +185271,13 @@ async function runReshapeCheck(migrationsDir) {
|
|
|
185265
185271
|
try {
|
|
185266
185272
|
const binary = await ensureBinary(reshapeBinary);
|
|
185267
185273
|
const reshapePath = binary.executables["reshape"];
|
|
185268
|
-
return new Promise((
|
|
185274
|
+
return new Promise((resolve10) => {
|
|
185269
185275
|
execFile7(reshapePath, ["check", "--dirs", migrationsDir], (err, _stdout, stderr) => {
|
|
185270
185276
|
if (err) {
|
|
185271
185277
|
const errorMsg = stderr.trim() || err.message;
|
|
185272
|
-
|
|
185278
|
+
resolve10({ success: false, error: errorMsg });
|
|
185273
185279
|
} else {
|
|
185274
|
-
|
|
185280
|
+
resolve10({ success: true });
|
|
185275
185281
|
}
|
|
185276
185282
|
});
|
|
185277
185283
|
});
|
|
@@ -186228,7 +186234,7 @@ var NodeFsHandler = class {
|
|
|
186228
186234
|
this._addToNodeFs(path26, initialAdd, wh, depth + 1);
|
|
186229
186235
|
}
|
|
186230
186236
|
}).on(EV.ERROR, this._boundHandleError);
|
|
186231
|
-
return new Promise((
|
|
186237
|
+
return new Promise((resolve10, reject) => {
|
|
186232
186238
|
if (!stream)
|
|
186233
186239
|
return reject();
|
|
186234
186240
|
stream.once(STR_END, () => {
|
|
@@ -186237,7 +186243,7 @@ var NodeFsHandler = class {
|
|
|
186237
186243
|
return;
|
|
186238
186244
|
}
|
|
186239
186245
|
const wasThrottled = throttler ? throttler.clear() : false;
|
|
186240
|
-
|
|
186246
|
+
resolve10(void 0);
|
|
186241
186247
|
previous.getChildren().filter((item) => {
|
|
186242
186248
|
return item !== directory && !current.has(item);
|
|
186243
186249
|
}).forEach((item) => {
|
|
@@ -187301,7 +187307,7 @@ async function startStorage(storage, port, dataDir) {
|
|
|
187301
187307
|
};
|
|
187302
187308
|
}
|
|
187303
187309
|
async function runCommand(command, args, env2) {
|
|
187304
|
-
return new Promise((
|
|
187310
|
+
return new Promise((resolve10, reject) => {
|
|
187305
187311
|
const proc = spawn(command, args, {
|
|
187306
187312
|
stdio: ["ignore", "pipe", "pipe"],
|
|
187307
187313
|
env: env2
|
|
@@ -187312,7 +187318,7 @@ async function runCommand(command, args, env2) {
|
|
|
187312
187318
|
});
|
|
187313
187319
|
proc.on("close", (code) => {
|
|
187314
187320
|
if (code === 0) {
|
|
187315
|
-
|
|
187321
|
+
resolve10();
|
|
187316
187322
|
} else {
|
|
187317
187323
|
reject(new Error(`Command failed with code ${code}: ${stderr}`));
|
|
187318
187324
|
}
|
|
@@ -187321,7 +187327,7 @@ async function runCommand(command, args, env2) {
|
|
|
187321
187327
|
});
|
|
187322
187328
|
}
|
|
187323
187329
|
async function createPostgresDatabase(postgresPath, dataDir, dbName, env2) {
|
|
187324
|
-
return new Promise((
|
|
187330
|
+
return new Promise((resolve10, reject) => {
|
|
187325
187331
|
const proc = spawn(
|
|
187326
187332
|
postgresPath,
|
|
187327
187333
|
["--single", "-D", dataDir, "postgres"],
|
|
@@ -187335,7 +187341,7 @@ async function createPostgresDatabase(postgresPath, dataDir, dbName, env2) {
|
|
|
187335
187341
|
stderr += data.toString();
|
|
187336
187342
|
});
|
|
187337
187343
|
proc.on("close", (code) => {
|
|
187338
|
-
|
|
187344
|
+
resolve10();
|
|
187339
187345
|
});
|
|
187340
187346
|
proc.on("error", reject);
|
|
187341
187347
|
proc.stdin?.write(`CREATE DATABASE "${dbName}";
|
|
@@ -187355,33 +187361,33 @@ async function waitForTcpPort(host, port, timeoutMs = 3e4) {
|
|
|
187355
187361
|
throw new Error(`Port ${port} did not become available within timeout`);
|
|
187356
187362
|
}
|
|
187357
187363
|
function checkTcpPort(host, port) {
|
|
187358
|
-
return new Promise((
|
|
187364
|
+
return new Promise((resolve10) => {
|
|
187359
187365
|
const socket = new net.Socket();
|
|
187360
187366
|
socket.setTimeout(1e3);
|
|
187361
187367
|
socket.on("connect", () => {
|
|
187362
187368
|
socket.destroy();
|
|
187363
|
-
|
|
187369
|
+
resolve10(true);
|
|
187364
187370
|
});
|
|
187365
187371
|
socket.on("timeout", () => {
|
|
187366
187372
|
socket.destroy();
|
|
187367
|
-
|
|
187373
|
+
resolve10(false);
|
|
187368
187374
|
});
|
|
187369
187375
|
socket.on("error", () => {
|
|
187370
187376
|
socket.destroy();
|
|
187371
|
-
|
|
187377
|
+
resolve10(false);
|
|
187372
187378
|
});
|
|
187373
187379
|
socket.connect(port, host);
|
|
187374
187380
|
});
|
|
187375
187381
|
}
|
|
187376
187382
|
async function stopProcess(proc) {
|
|
187377
|
-
return new Promise((
|
|
187383
|
+
return new Promise((resolve10) => {
|
|
187378
187384
|
if (proc.killed || proc.exitCode !== null) {
|
|
187379
|
-
|
|
187385
|
+
resolve10();
|
|
187380
187386
|
return;
|
|
187381
187387
|
}
|
|
187382
187388
|
proc.once("exit", () => {
|
|
187383
187389
|
clearTimeout(forceKillTimeout);
|
|
187384
|
-
|
|
187390
|
+
resolve10();
|
|
187385
187391
|
});
|
|
187386
187392
|
proc.kill("SIGTERM");
|
|
187387
187393
|
const forceKillTimeout = setTimeout(() => {
|
|
@@ -187392,7 +187398,7 @@ async function stopProcess(proc) {
|
|
|
187392
187398
|
});
|
|
187393
187399
|
}
|
|
187394
187400
|
function sleep2(ms) {
|
|
187395
|
-
return new Promise((
|
|
187401
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
187396
187402
|
}
|
|
187397
187403
|
|
|
187398
187404
|
// src/lib/dev/service-runner.ts
|
|
@@ -187746,7 +187752,7 @@ function resolveEnvForExec(env2, resources, secrets, configs) {
|
|
|
187746
187752
|
}
|
|
187747
187753
|
|
|
187748
187754
|
// src/lib/dev/service-runner.ts
|
|
187749
|
-
function startService(service, resources, secrets, configs, endpointPorts, serviceEndpoints, onLog, publicUrls) {
|
|
187755
|
+
function startService(service, resources, secrets, configs, endpointPorts, serviceEndpoints, onLog, publicUrls, cwd) {
|
|
187750
187756
|
const command = service.dev?.command ?? service.command;
|
|
187751
187757
|
if (!command) {
|
|
187752
187758
|
throw new Error(`Service "${service.name}" has no command`);
|
|
@@ -187768,7 +187774,7 @@ function startService(service, resources, secrets, configs, endpointPorts, servi
|
|
|
187768
187774
|
);
|
|
187769
187775
|
const child = spawn2(command, {
|
|
187770
187776
|
shell: true,
|
|
187771
|
-
cwd: process.cwd(),
|
|
187777
|
+
cwd: cwd || process.cwd(),
|
|
187772
187778
|
env: {
|
|
187773
187779
|
...process.env,
|
|
187774
187780
|
...resolvedEnv
|
|
@@ -187796,14 +187802,14 @@ function startService(service, resources, secrets, configs, endpointPorts, servi
|
|
|
187796
187802
|
ports: endpointPorts,
|
|
187797
187803
|
process: child,
|
|
187798
187804
|
async stop() {
|
|
187799
|
-
return new Promise((
|
|
187805
|
+
return new Promise((resolve10) => {
|
|
187800
187806
|
if (child.killed || child.exitCode !== null) {
|
|
187801
|
-
|
|
187807
|
+
resolve10();
|
|
187802
187808
|
return;
|
|
187803
187809
|
}
|
|
187804
187810
|
child.once("exit", () => {
|
|
187805
187811
|
clearTimeout(forceKillTimeout);
|
|
187806
|
-
|
|
187812
|
+
resolve10();
|
|
187807
187813
|
});
|
|
187808
187814
|
child.kill("SIGTERM");
|
|
187809
187815
|
const forceKillTimeout = setTimeout(() => {
|
|
@@ -187884,7 +187890,7 @@ var InstanceStateManager = class {
|
|
|
187884
187890
|
}
|
|
187885
187891
|
continue;
|
|
187886
187892
|
}
|
|
187887
|
-
await new Promise((
|
|
187893
|
+
await new Promise((resolve10) => setTimeout(resolve10, 100));
|
|
187888
187894
|
} else {
|
|
187889
187895
|
throw e;
|
|
187890
187896
|
}
|
|
@@ -188167,7 +188173,7 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
|
|
|
188167
188173
|
handleRequest
|
|
188168
188174
|
);
|
|
188169
188175
|
httpsServer.on("upgrade", handleUpgrade);
|
|
188170
|
-
return new Promise((
|
|
188176
|
+
return new Promise((resolve10, reject) => {
|
|
188171
188177
|
let httpStarted = false;
|
|
188172
188178
|
let httpsStarted = false;
|
|
188173
188179
|
let failed = false;
|
|
@@ -188178,7 +188184,7 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
|
|
|
188178
188184
|
"proxy",
|
|
188179
188185
|
`HTTP/HTTPS proxy started on ports ${HTTP_PORT}/${HTTPS_PORT}`
|
|
188180
188186
|
);
|
|
188181
|
-
|
|
188187
|
+
resolve10({
|
|
188182
188188
|
httpPort: HTTP_PORT,
|
|
188183
188189
|
httpsPort: HTTPS_PORT,
|
|
188184
188190
|
updateServices,
|
|
@@ -188190,13 +188196,13 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
|
|
|
188190
188196
|
writeLog("proxy", "Certificate updated");
|
|
188191
188197
|
},
|
|
188192
188198
|
async stop() {
|
|
188193
|
-
return new Promise((
|
|
188199
|
+
return new Promise((resolve11) => {
|
|
188194
188200
|
let closed = 0;
|
|
188195
188201
|
const onClose = () => {
|
|
188196
188202
|
closed++;
|
|
188197
188203
|
if (closed === 2) {
|
|
188198
188204
|
clearTimeout(forceCloseTimeout);
|
|
188199
|
-
|
|
188205
|
+
resolve11();
|
|
188200
188206
|
}
|
|
188201
188207
|
};
|
|
188202
188208
|
httpServer.close(onClose);
|
|
@@ -188204,7 +188210,7 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
|
|
|
188204
188210
|
const forceCloseTimeout = setTimeout(() => {
|
|
188205
188211
|
httpServer.closeAllConnections?.();
|
|
188206
188212
|
httpsServer.closeAllConnections?.();
|
|
188207
|
-
|
|
188213
|
+
resolve11();
|
|
188208
188214
|
}, 2e3);
|
|
188209
188215
|
});
|
|
188210
188216
|
}
|
|
@@ -188367,7 +188373,7 @@ function serveFileContent(res, filePath, contentType, statusCode = 200) {
|
|
|
188367
188373
|
}
|
|
188368
188374
|
}
|
|
188369
188375
|
async function startAdminServer(getState) {
|
|
188370
|
-
return new Promise((
|
|
188376
|
+
return new Promise((resolve10, reject) => {
|
|
188371
188377
|
const server = http.createServer((req, res) => {
|
|
188372
188378
|
const url = new URL(req.url || "/", "http://localhost");
|
|
188373
188379
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
@@ -188399,7 +188405,7 @@ async function startAdminServer(getState) {
|
|
|
188399
188405
|
}
|
|
188400
188406
|
const port = addr.port;
|
|
188401
188407
|
writeLog("admin", `Admin API server started on port ${port}`);
|
|
188402
|
-
|
|
188408
|
+
resolve10({
|
|
188403
188409
|
port,
|
|
188404
188410
|
stop: () => new Promise((res, rej) => {
|
|
188405
188411
|
server.close((err) => err ? rej(err) : res());
|
|
@@ -188560,33 +188566,33 @@ async function waitForTcpPort2(host, port, timeoutMs = 3e4) {
|
|
|
188560
188566
|
throw new Error(`Electric port ${port} did not become available within timeout`);
|
|
188561
188567
|
}
|
|
188562
188568
|
function checkTcpPort2(host, port) {
|
|
188563
|
-
return new Promise((
|
|
188569
|
+
return new Promise((resolve10) => {
|
|
188564
188570
|
const socket = new net2.Socket();
|
|
188565
188571
|
socket.setTimeout(1e3);
|
|
188566
188572
|
socket.on("connect", () => {
|
|
188567
188573
|
socket.destroy();
|
|
188568
|
-
|
|
188574
|
+
resolve10(true);
|
|
188569
188575
|
});
|
|
188570
188576
|
socket.on("timeout", () => {
|
|
188571
188577
|
socket.destroy();
|
|
188572
|
-
|
|
188578
|
+
resolve10(false);
|
|
188573
188579
|
});
|
|
188574
188580
|
socket.on("error", () => {
|
|
188575
188581
|
socket.destroy();
|
|
188576
|
-
|
|
188582
|
+
resolve10(false);
|
|
188577
188583
|
});
|
|
188578
188584
|
socket.connect(port, host);
|
|
188579
188585
|
});
|
|
188580
188586
|
}
|
|
188581
188587
|
async function stopProcess2(proc) {
|
|
188582
|
-
return new Promise((
|
|
188588
|
+
return new Promise((resolve10) => {
|
|
188583
188589
|
if (proc.killed || proc.exitCode !== null) {
|
|
188584
|
-
|
|
188590
|
+
resolve10();
|
|
188585
188591
|
return;
|
|
188586
188592
|
}
|
|
188587
188593
|
proc.once("exit", () => {
|
|
188588
188594
|
clearTimeout(forceKillTimeout);
|
|
188589
|
-
|
|
188595
|
+
resolve10();
|
|
188590
188596
|
});
|
|
188591
188597
|
proc.kill("SIGTERM");
|
|
188592
188598
|
const forceKillTimeout = setTimeout(() => {
|
|
@@ -188597,7 +188603,7 @@ async function stopProcess2(proc) {
|
|
|
188597
188603
|
});
|
|
188598
188604
|
}
|
|
188599
188605
|
function sleep3(ms) {
|
|
188600
|
-
return new Promise((
|
|
188606
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
188601
188607
|
}
|
|
188602
188608
|
|
|
188603
188609
|
// src/lib/dev/drizzle-gateway-manager.ts
|
|
@@ -188681,33 +188687,33 @@ async function waitForTcpPort3(host, port, timeoutMs = 3e4) {
|
|
|
188681
188687
|
);
|
|
188682
188688
|
}
|
|
188683
188689
|
function checkTcpPort3(host, port) {
|
|
188684
|
-
return new Promise((
|
|
188690
|
+
return new Promise((resolve10) => {
|
|
188685
188691
|
const socket = new net3.Socket();
|
|
188686
188692
|
socket.setTimeout(1e3);
|
|
188687
188693
|
socket.on("connect", () => {
|
|
188688
188694
|
socket.destroy();
|
|
188689
|
-
|
|
188695
|
+
resolve10(true);
|
|
188690
188696
|
});
|
|
188691
188697
|
socket.on("timeout", () => {
|
|
188692
188698
|
socket.destroy();
|
|
188693
|
-
|
|
188699
|
+
resolve10(false);
|
|
188694
188700
|
});
|
|
188695
188701
|
socket.on("error", () => {
|
|
188696
188702
|
socket.destroy();
|
|
188697
|
-
|
|
188703
|
+
resolve10(false);
|
|
188698
188704
|
});
|
|
188699
188705
|
socket.connect(port, host);
|
|
188700
188706
|
});
|
|
188701
188707
|
}
|
|
188702
188708
|
async function stopProcess3(proc) {
|
|
188703
|
-
return new Promise((
|
|
188709
|
+
return new Promise((resolve10) => {
|
|
188704
188710
|
if (proc.killed || proc.exitCode !== null) {
|
|
188705
|
-
|
|
188711
|
+
resolve10();
|
|
188706
188712
|
return;
|
|
188707
188713
|
}
|
|
188708
188714
|
proc.once("exit", () => {
|
|
188709
188715
|
clearTimeout(forceKillTimeout);
|
|
188710
|
-
|
|
188716
|
+
resolve10();
|
|
188711
188717
|
});
|
|
188712
188718
|
proc.kill("SIGTERM");
|
|
188713
188719
|
const forceKillTimeout = setTimeout(() => {
|
|
@@ -188718,7 +188724,7 @@ async function stopProcess3(proc) {
|
|
|
188718
188724
|
});
|
|
188719
188725
|
}
|
|
188720
188726
|
function sleep4(ms) {
|
|
188721
|
-
return new Promise((
|
|
188727
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
188722
188728
|
}
|
|
188723
188729
|
|
|
188724
188730
|
// src/lib/dev/sync-detector.ts
|
|
@@ -189335,7 +189341,7 @@ var ProxyRegistryManager = class {
|
|
|
189335
189341
|
* This catches cases where the owner process is alive but the proxy has crashed.
|
|
189336
189342
|
*/
|
|
189337
189343
|
isProxyListening(port, timeoutMs = 1e3) {
|
|
189338
|
-
return new Promise((
|
|
189344
|
+
return new Promise((resolve10) => {
|
|
189339
189345
|
const socket = new net4.Socket();
|
|
189340
189346
|
let resolved = false;
|
|
189341
189347
|
const cleanup = () => {
|
|
@@ -189347,15 +189353,15 @@ var ProxyRegistryManager = class {
|
|
|
189347
189353
|
socket.setTimeout(timeoutMs);
|
|
189348
189354
|
socket.on("connect", () => {
|
|
189349
189355
|
cleanup();
|
|
189350
|
-
|
|
189356
|
+
resolve10(true);
|
|
189351
189357
|
});
|
|
189352
189358
|
socket.on("timeout", () => {
|
|
189353
189359
|
cleanup();
|
|
189354
|
-
|
|
189360
|
+
resolve10(false);
|
|
189355
189361
|
});
|
|
189356
189362
|
socket.on("error", () => {
|
|
189357
189363
|
cleanup();
|
|
189358
|
-
|
|
189364
|
+
resolve10(false);
|
|
189359
189365
|
});
|
|
189360
189366
|
socket.connect(port, "127.0.0.1");
|
|
189361
189367
|
});
|
|
@@ -189406,7 +189412,7 @@ var ProxyRegistryManager = class {
|
|
|
189406
189412
|
}
|
|
189407
189413
|
continue;
|
|
189408
189414
|
}
|
|
189409
|
-
await new Promise((
|
|
189415
|
+
await new Promise((resolve10) => setTimeout(resolve10, 100));
|
|
189410
189416
|
} else {
|
|
189411
189417
|
throw e;
|
|
189412
189418
|
}
|
|
@@ -189890,7 +189896,7 @@ function DevUI({ instanceKey, tunnelEnabled }) {
|
|
|
189890
189896
|
...tunnelsRef.current.map((tunnel) => tunnel.stop())
|
|
189891
189897
|
]);
|
|
189892
189898
|
if (tunnelsRef.current.length > 0) {
|
|
189893
|
-
await new Promise((
|
|
189899
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1500));
|
|
189894
189900
|
}
|
|
189895
189901
|
electricInstancesRef.current = [];
|
|
189896
189902
|
reshapeWatchersRef.current = [];
|
|
@@ -190400,6 +190406,14 @@ Add them to the config block in specific.local`);
|
|
|
190400
190406
|
}
|
|
190401
190407
|
}
|
|
190402
190408
|
const services2 = [];
|
|
190409
|
+
function resolveServiceCwd(service) {
|
|
190410
|
+
if (service.root) return path18.resolve(process.cwd(), service.root);
|
|
190411
|
+
if (service.build) {
|
|
190412
|
+
const build = config2.builds.find((b) => b.name === service.build.name);
|
|
190413
|
+
if (build?.root) return path18.resolve(process.cwd(), build.root);
|
|
190414
|
+
}
|
|
190415
|
+
return process.cwd();
|
|
190416
|
+
}
|
|
190403
190417
|
for (const service of config2.services) {
|
|
190404
190418
|
if (cancelled) break;
|
|
190405
190419
|
if (service.serve) {
|
|
@@ -190423,7 +190437,8 @@ Add them to the config block in specific.local`);
|
|
|
190423
190437
|
endpointPorts,
|
|
190424
190438
|
serviceEndpoints,
|
|
190425
190439
|
(line) => addLog(line, colorMap),
|
|
190426
|
-
publicUrls
|
|
190440
|
+
publicUrls,
|
|
190441
|
+
resolveServiceCwd(service)
|
|
190427
190442
|
);
|
|
190428
190443
|
services2.push(running);
|
|
190429
190444
|
startedServices.push(running);
|
|
@@ -190468,7 +190483,9 @@ Add them to the config block in specific.local`);
|
|
|
190468
190483
|
configs,
|
|
190469
190484
|
endpointPorts,
|
|
190470
190485
|
serviceEndpoints,
|
|
190471
|
-
(line) => addLog(line, colorMap)
|
|
190486
|
+
(line) => addLog(line, colorMap),
|
|
190487
|
+
void 0,
|
|
190488
|
+
resolveServiceCwd(service)
|
|
190472
190489
|
);
|
|
190473
190490
|
newServices.push(running);
|
|
190474
190491
|
} catch (err) {
|
|
@@ -190978,7 +190995,7 @@ import * as path21 from "path";
|
|
|
190978
190995
|
// src/lib/deploy/build-tester.ts
|
|
190979
190996
|
import { spawn as spawn5 } from "child_process";
|
|
190980
190997
|
import { existsSync as existsSync20 } from "fs";
|
|
190981
|
-
import { join as join21 } from "path";
|
|
190998
|
+
import { join as join21, resolve as resolve7 } from "path";
|
|
190982
190999
|
function getDependencyInstallCommand(build, projectDir) {
|
|
190983
191000
|
switch (build.base) {
|
|
190984
191001
|
case "node":
|
|
@@ -190988,9 +191005,10 @@ function getDependencyInstallCommand(build, projectDir) {
|
|
|
190988
191005
|
return "yarn install --frozen-lockfile";
|
|
190989
191006
|
} else if (existsSync20(join21(projectDir, "package-lock.json"))) {
|
|
190990
191007
|
return "npm ci";
|
|
190991
|
-
} else {
|
|
191008
|
+
} else if (existsSync20(join21(projectDir, "package.json"))) {
|
|
190992
191009
|
return "npm install";
|
|
190993
191010
|
}
|
|
191011
|
+
return null;
|
|
190994
191012
|
case "python":
|
|
190995
191013
|
if (existsSync20(join21(projectDir, "poetry.lock"))) {
|
|
190996
191014
|
return "poetry install --no-interaction";
|
|
@@ -191014,7 +191032,7 @@ function getDependencyInstallCommand(build, projectDir) {
|
|
|
191014
191032
|
}
|
|
191015
191033
|
}
|
|
191016
191034
|
function runCommand2(command, projectDir, buildName) {
|
|
191017
|
-
return new Promise((
|
|
191035
|
+
return new Promise((resolve10) => {
|
|
191018
191036
|
const stdout = [];
|
|
191019
191037
|
const stderr = [];
|
|
191020
191038
|
writeLog("build-test", `[${buildName}] Running: ${command}`);
|
|
@@ -191044,7 +191062,7 @@ function runCommand2(command, projectDir, buildName) {
|
|
|
191044
191062
|
});
|
|
191045
191063
|
child.on("error", (err) => {
|
|
191046
191064
|
writeLog("build-test:error", `[${buildName}] Failed to start: ${err.message}`);
|
|
191047
|
-
|
|
191065
|
+
resolve10({
|
|
191048
191066
|
success: false,
|
|
191049
191067
|
output: `Failed to start command: ${err.message}`
|
|
191050
191068
|
});
|
|
@@ -191053,10 +191071,10 @@ function runCommand2(command, projectDir, buildName) {
|
|
|
191053
191071
|
const output = [...stdout, ...stderr].join("");
|
|
191054
191072
|
if (code === 0) {
|
|
191055
191073
|
writeLog("build-test", `[${buildName}] Command succeeded (exit code 0)`);
|
|
191056
|
-
|
|
191074
|
+
resolve10({ success: true, output });
|
|
191057
191075
|
} else {
|
|
191058
191076
|
writeLog("build-test:error", `[${buildName}] Command failed with exit code ${code}`);
|
|
191059
|
-
|
|
191077
|
+
resolve10({
|
|
191060
191078
|
success: false,
|
|
191061
191079
|
output: output || `Exit code: ${code}`
|
|
191062
191080
|
});
|
|
@@ -191067,7 +191085,7 @@ function runCommand2(command, projectDir, buildName) {
|
|
|
191067
191085
|
async function testBuild(build, projectDir) {
|
|
191068
191086
|
const startTime = Date.now();
|
|
191069
191087
|
const outputs = [];
|
|
191070
|
-
const workDir = projectDir;
|
|
191088
|
+
const workDir = build.root ? resolve7(projectDir, build.root) : projectDir;
|
|
191071
191089
|
writeLog("build-test", `Starting test for build "${build.name}" (base: ${build.base}, workDir: ${workDir})`);
|
|
191072
191090
|
const depsCommand = getDependencyInstallCommand(build, workDir);
|
|
191073
191091
|
if (depsCommand) {
|
|
@@ -192328,8 +192346,17 @@ async function execCommand(serviceName, command, instanceKey = "default") {
|
|
|
192328
192346
|
};
|
|
192329
192347
|
process.on("SIGINT", () => handleSignal("SIGINT"));
|
|
192330
192348
|
process.on("SIGTERM", () => handleSignal("SIGTERM"));
|
|
192349
|
+
let effectiveCwd = process.cwd();
|
|
192350
|
+
if (service.root) {
|
|
192351
|
+
effectiveCwd = path22.resolve(process.cwd(), service.root);
|
|
192352
|
+
} else if (service.build) {
|
|
192353
|
+
const build = config.builds.find((b) => b.name === service.build.name);
|
|
192354
|
+
if (build?.root) {
|
|
192355
|
+
effectiveCwd = path22.resolve(process.cwd(), build.root);
|
|
192356
|
+
}
|
|
192357
|
+
}
|
|
192331
192358
|
child = spawn6(command[0], command.slice(1), {
|
|
192332
|
-
cwd:
|
|
192359
|
+
cwd: effectiveCwd,
|
|
192333
192360
|
env: {
|
|
192334
192361
|
...process.env,
|
|
192335
192362
|
...resolvedEnv
|
|
@@ -192744,20 +192771,22 @@ function CleanUI({ instanceKey }) {
|
|
|
192744
192771
|
}
|
|
192745
192772
|
} else {
|
|
192746
192773
|
const keysDir = path25.join(specificDir, "keys");
|
|
192747
|
-
if (fs27.existsSync(keysDir)) {
|
|
192748
|
-
|
|
192749
|
-
|
|
192750
|
-
|
|
192751
|
-
|
|
192752
|
-
|
|
192753
|
-
|
|
192754
|
-
|
|
192755
|
-
|
|
192756
|
-
|
|
192757
|
-
|
|
192758
|
-
|
|
192759
|
-
|
|
192760
|
-
|
|
192774
|
+
if (!fs27.existsSync(keysDir)) {
|
|
192775
|
+
setState({ status: "nothing" });
|
|
192776
|
+
return;
|
|
192777
|
+
}
|
|
192778
|
+
const keys = fs27.readdirSync(keysDir).filter(
|
|
192779
|
+
(f) => fs27.statSync(path25.join(keysDir, f)).isDirectory()
|
|
192780
|
+
);
|
|
192781
|
+
for (const key of keys) {
|
|
192782
|
+
const stateManager2 = new InstanceStateManager(projectRoot, key);
|
|
192783
|
+
const existingInstances2 = await stateManager2.getExistingInstances();
|
|
192784
|
+
if (existingInstances2) {
|
|
192785
|
+
setState({
|
|
192786
|
+
status: "error",
|
|
192787
|
+
error: `Cannot clean while 'specific dev' is running for key "${key}" (PID ${existingInstances2.owner.pid}). Please stop it first.`
|
|
192788
|
+
});
|
|
192789
|
+
return;
|
|
192761
192790
|
}
|
|
192762
192791
|
}
|
|
192763
192792
|
const stateManager = new InstanceStateManager(projectRoot);
|
|
@@ -192771,7 +192800,7 @@ function CleanUI({ instanceKey }) {
|
|
|
192771
192800
|
}
|
|
192772
192801
|
setState({ status: "cleaning" });
|
|
192773
192802
|
try {
|
|
192774
|
-
fs27.rmSync(
|
|
192803
|
+
fs27.rmSync(keysDir, { recursive: true, force: true });
|
|
192775
192804
|
setState({ status: "success" });
|
|
192776
192805
|
} catch (err) {
|
|
192777
192806
|
setState({
|
|
@@ -192787,16 +192816,16 @@ function CleanUI({ instanceKey }) {
|
|
|
192787
192816
|
return /* @__PURE__ */ React8.createElement(Box8, null, /* @__PURE__ */ React8.createElement(Text8, { color: "blue" }, /* @__PURE__ */ React8.createElement(Spinner6, { type: "dots" })), /* @__PURE__ */ React8.createElement(Text8, null, " Checking for running instances..."));
|
|
192788
192817
|
}
|
|
192789
192818
|
if (state.status === "cleaning") {
|
|
192790
|
-
return /* @__PURE__ */ React8.createElement(Box8, null, /* @__PURE__ */ React8.createElement(Text8, { color: "blue" }, /* @__PURE__ */ React8.createElement(Spinner6, { type: "dots" })), /* @__PURE__ */ React8.createElement(Text8, null, "
|
|
192819
|
+
return /* @__PURE__ */ React8.createElement(Box8, null, /* @__PURE__ */ React8.createElement(Text8, { color: "blue" }, /* @__PURE__ */ React8.createElement(Spinner6, { type: "dots" })), /* @__PURE__ */ React8.createElement(Text8, null, " Cleaning app data..."));
|
|
192791
192820
|
}
|
|
192792
192821
|
if (state.status === "error") {
|
|
192793
192822
|
return /* @__PURE__ */ React8.createElement(Text8, { color: "red" }, "Error: ", state.error);
|
|
192794
192823
|
}
|
|
192795
192824
|
if (state.status === "nothing") {
|
|
192796
|
-
const target2 = instanceKey ? `key "${instanceKey}"` : "
|
|
192825
|
+
const target2 = instanceKey ? `key "${instanceKey}"` : "app data";
|
|
192797
192826
|
return /* @__PURE__ */ React8.createElement(Text8, { color: "yellow" }, "Nothing to clean (", target2, " does not exist)");
|
|
192798
192827
|
}
|
|
192799
|
-
const target = instanceKey ? `key "${instanceKey}"` : "
|
|
192828
|
+
const target = instanceKey ? `key "${instanceKey}"` : "app data";
|
|
192800
192829
|
return /* @__PURE__ */ React8.createElement(Text8, { color: "green" }, "Cleaned ", target);
|
|
192801
192830
|
}
|
|
192802
192831
|
function cleanCommand(instanceKey) {
|
|
@@ -192934,7 +192963,7 @@ function betaCommand() {
|
|
|
192934
192963
|
var program = new Command();
|
|
192935
192964
|
var env = "production";
|
|
192936
192965
|
var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
|
|
192937
|
-
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.
|
|
192966
|
+
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.51").enablePositionalOptions();
|
|
192938
192967
|
program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").action((options2) => initCommand(options2));
|
|
192939
192968
|
program.command("docs [topic]").description("Fetch LLM-optimized documentation").action(docsCommand);
|
|
192940
192969
|
program.command("check").description("Validate specific.hcl configuration").action(checkCommand);
|