deepline 0.1.32 → 0.1.33
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/README.md +33 -20
- package/dist/cli/index.js +164 -180
- package/dist/cli/index.mjs +175 -191
- package/dist/index.d.mts +6 -24
- package/dist/index.d.ts +6 -24
- package/dist/index.js +55 -81
- package/dist/index.mjs +56 -82
- package/dist/repo/sdk/src/config.ts +109 -233
- package/dist/repo/sdk/src/types.ts +3 -1
- package/dist/repo/sdk/src/version.ts +2 -2
- package/dist/repo/shared_libs/play-runtime/scheduler-backend.ts +1 -1
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { Command as Command2 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/config.ts
|
|
7
|
-
import {
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
8
8
|
import { homedir } from "os";
|
|
9
9
|
import { dirname, join, resolve } from "path";
|
|
10
10
|
|
|
@@ -44,19 +44,12 @@ var ConfigError = class extends DeeplineError {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
// src/config.ts
|
|
47
|
+
var HOST_URL_ENV = "DEEPLINE_HOST_URL";
|
|
48
|
+
var API_KEY_ENV = "DEEPLINE_API_KEY";
|
|
47
49
|
var PROD_URL = "https://code.deepline.com";
|
|
48
50
|
var DEFAULT_TIMEOUT = 6e4;
|
|
49
51
|
var DEFAULT_MAX_RETRIES = 3;
|
|
50
|
-
var
|
|
51
|
-
function isProdBaseUrl(baseUrl) {
|
|
52
|
-
return baseUrl.trim().replace(/\/$/, "") === PROD_URL;
|
|
53
|
-
}
|
|
54
|
-
function profileNameForBaseUrl(baseUrl) {
|
|
55
|
-
return isProdBaseUrl(baseUrl) ? "prod" : "dev";
|
|
56
|
-
}
|
|
57
|
-
function projectEnvStartDir() {
|
|
58
|
-
return process.env.DEEPLINE_PROJECT_ENV_DIR?.trim() || process.cwd();
|
|
59
|
-
}
|
|
52
|
+
var PROJECT_DEEPLINE_ENV_FILE = ".env.deepline";
|
|
60
53
|
function baseUrlSlug(baseUrl) {
|
|
61
54
|
let url;
|
|
62
55
|
try {
|
|
@@ -65,7 +58,7 @@ function baseUrlSlug(baseUrl) {
|
|
|
65
58
|
return "unknown";
|
|
66
59
|
}
|
|
67
60
|
const host = url.hostname || "unknown";
|
|
68
|
-
const port = url.port ? parseInt(url.port, 10) : null;
|
|
61
|
+
const port = url.port ? Number.parseInt(url.port, 10) : null;
|
|
69
62
|
let slug = host.replace(/[^a-zA-Z0-9]/g, "-");
|
|
70
63
|
if (port && port !== 80 && port !== 443) {
|
|
71
64
|
slug = `${slug}-${port}`;
|
|
@@ -92,79 +85,52 @@ function parseEnvFile(filePath) {
|
|
|
92
85
|
}
|
|
93
86
|
return env;
|
|
94
87
|
}
|
|
95
|
-
function findNearestEnvFile(
|
|
88
|
+
function findNearestEnvFile(name, startDir = process.cwd()) {
|
|
96
89
|
let current = resolve(startDir);
|
|
97
90
|
while (true) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (existsSync(filePath)) return filePath;
|
|
101
|
-
}
|
|
91
|
+
const filePath = join(current, name);
|
|
92
|
+
if (existsSync(filePath)) return filePath;
|
|
102
93
|
const parent = dirname(current);
|
|
103
94
|
if (parent === current) return null;
|
|
104
95
|
current = parent;
|
|
105
96
|
}
|
|
106
97
|
}
|
|
107
|
-
function
|
|
108
|
-
const filePath = findNearestEnvFile(
|
|
98
|
+
function loadProjectDeeplineEnv(startDir = process.cwd()) {
|
|
99
|
+
const filePath = findNearestEnvFile(PROJECT_DEEPLINE_ENV_FILE, startDir);
|
|
109
100
|
return filePath ? parseEnvFile(filePath) : {};
|
|
110
101
|
}
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
function resolveProfileEnvFileNames() {
|
|
115
|
-
const explicitProfile = process.env.DEEPLINE_ENV_PROFILE?.trim() || process.env.DEEPLINE_PROFILE?.trim() || "";
|
|
116
|
-
const names = [];
|
|
117
|
-
if (explicitProfile) names.push(`.env.deepline.${explicitProfile}`);
|
|
118
|
-
const nodeEnv = process.env.NODE_ENV?.trim();
|
|
119
|
-
if (nodeEnv === "production") names.push(".env.deepline.prod");
|
|
120
|
-
else if (nodeEnv === "staging") names.push(".env.deepline.staging");
|
|
121
|
-
names.push(ACTIVE_DEEPLINE_ENV_FILE);
|
|
122
|
-
return names;
|
|
123
|
-
}
|
|
124
|
-
function resolveProjectAppEnvFileNames() {
|
|
125
|
-
const nodeEnv = process.env.NODE_ENV?.trim();
|
|
126
|
-
const names = [];
|
|
127
|
-
if (nodeEnv === "production") names.push(".env.prod");
|
|
128
|
-
if (nodeEnv === "staging") names.push(".env.staging");
|
|
129
|
-
names.push(".env.local", ".env");
|
|
130
|
-
return names;
|
|
131
|
-
}
|
|
132
|
-
function resolveBaseUrlFromEnvValues(env) {
|
|
133
|
-
return env.DEEPLINE_ORIGIN_URL?.trim() || env.DEEPLINE_API_BASE_URL?.trim() || "";
|
|
134
|
-
}
|
|
135
|
-
function loadProjectDeeplineEnv() {
|
|
136
|
-
return findNearestEnv(resolveProfileEnvFileNames(), projectEnvStartDir());
|
|
137
|
-
}
|
|
138
|
-
function loadProjectAppEnv() {
|
|
139
|
-
return findNearestEnv(resolveProjectAppEnvFileNames(), projectEnvStartDir());
|
|
140
|
-
}
|
|
141
|
-
function normalizeWorktreeBaseUrl(baseUrl, worktreeEnv = findNearestWorktreeEnv()) {
|
|
142
|
-
const trimmed = baseUrl.trim().replace(/\/$/, "");
|
|
143
|
-
if (!trimmed) return trimmed;
|
|
102
|
+
function normalizeBaseUrl(baseUrl) {
|
|
103
|
+
const trimmed = baseUrl.trim().replace(/\/+$/, "");
|
|
104
|
+
if (!trimmed) return "";
|
|
144
105
|
try {
|
|
145
106
|
const parsed = new URL(trimmed);
|
|
146
|
-
if (parsed.
|
|
147
|
-
|
|
148
|
-
if (port) return `${parsed.protocol}//localhost:${port}`;
|
|
107
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
108
|
+
return "";
|
|
149
109
|
}
|
|
110
|
+
return parsed.toString().replace(/\/+$/, "");
|
|
150
111
|
} catch {
|
|
112
|
+
return "";
|
|
151
113
|
}
|
|
152
|
-
return trimmed;
|
|
153
114
|
}
|
|
154
|
-
function
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return
|
|
115
|
+
function firstNonEmpty(...values) {
|
|
116
|
+
for (const value of values) {
|
|
117
|
+
const trimmed = value?.trim();
|
|
118
|
+
if (trimmed) return trimmed;
|
|
119
|
+
}
|
|
120
|
+
return "";
|
|
160
121
|
}
|
|
161
|
-
function
|
|
122
|
+
function sdkCliConfigDir(baseUrl) {
|
|
162
123
|
const home = process.env.HOME?.trim() || homedir();
|
|
163
|
-
return join(home, ".local", "deepline", baseUrlSlug(baseUrl || PROD_URL)
|
|
124
|
+
return join(home, ".local", "deepline", baseUrlSlug(baseUrl || PROD_URL));
|
|
125
|
+
}
|
|
126
|
+
function sdkCliEnvFilePath(baseUrl) {
|
|
127
|
+
return join(sdkCliConfigDir(baseUrl), ".env");
|
|
164
128
|
}
|
|
165
129
|
function loadCliEnv(baseUrl = PROD_URL) {
|
|
166
|
-
|
|
167
|
-
|
|
130
|
+
return parseEnvFile(sdkCliEnvFilePath(baseUrl));
|
|
131
|
+
}
|
|
132
|
+
function hostConfigDirPath(baseUrl) {
|
|
133
|
+
return sdkCliConfigDir(baseUrl);
|
|
168
134
|
}
|
|
169
135
|
function hostEnvFilePath(baseUrl) {
|
|
170
136
|
return sdkCliEnvFilePath(baseUrl);
|
|
@@ -175,9 +141,10 @@ function saveHostEnvValues(baseUrl, values) {
|
|
|
175
141
|
if (!existsSync(dir)) {
|
|
176
142
|
mkdirSync(dir, { recursive: true });
|
|
177
143
|
}
|
|
178
|
-
const existing =
|
|
144
|
+
const existing = parseEnvFile(filePath);
|
|
179
145
|
const merged = { ...existing, ...values };
|
|
180
|
-
const
|
|
146
|
+
const allowedKeys = /* @__PURE__ */ new Set([HOST_URL_ENV, API_KEY_ENV]);
|
|
147
|
+
const lines = Object.entries(merged).filter(([key, value]) => allowedKeys.has(key) && value !== "").map(([key, value]) => `${key}=${value}`);
|
|
181
148
|
writeFileSync(filePath, `${lines.join("\n")}
|
|
182
149
|
`, "utf-8");
|
|
183
150
|
}
|
|
@@ -185,31 +152,36 @@ function loadGlobalCliEnv() {
|
|
|
185
152
|
return loadCliEnv(PROD_URL);
|
|
186
153
|
}
|
|
187
154
|
function autoDetectBaseUrl() {
|
|
188
|
-
const
|
|
189
|
-
if (envOrigin) return normalizeWorktreeBaseUrl(envOrigin);
|
|
190
|
-
const envBase = process.env.DEEPLINE_API_BASE_URL?.trim();
|
|
191
|
-
if (envBase) return normalizeWorktreeBaseUrl(envBase);
|
|
192
|
-
const projectDeeplineBaseUrl = resolveBaseUrlFromEnvValues(loadProjectDeeplineEnv());
|
|
193
|
-
if (projectDeeplineBaseUrl) return normalizeWorktreeBaseUrl(projectDeeplineBaseUrl);
|
|
194
|
-
const projectAppBaseUrl = resolveBaseUrlFromEnvValues(loadProjectAppEnv());
|
|
195
|
-
if (projectAppBaseUrl) return normalizeWorktreeBaseUrl(projectAppBaseUrl);
|
|
196
|
-
const worktreeBaseUrl = resolveWorktreeBaseUrl();
|
|
197
|
-
if (worktreeBaseUrl) return worktreeBaseUrl;
|
|
155
|
+
const projectEnv = loadProjectDeeplineEnv();
|
|
198
156
|
const globalEnv = loadGlobalCliEnv();
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
157
|
+
return normalizeBaseUrl(process.env[HOST_URL_ENV] ?? "") || normalizeBaseUrl(projectEnv[HOST_URL_ENV] ?? "") || normalizeBaseUrl(globalEnv[HOST_URL_ENV] ?? "") || PROD_URL;
|
|
158
|
+
}
|
|
159
|
+
function resolveApiKeyForBaseUrl(baseUrl, explicitApiKey) {
|
|
160
|
+
const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
|
|
161
|
+
const projectEnv = loadProjectDeeplineEnv();
|
|
162
|
+
const cliEnv = loadCliEnv(normalizedBaseUrl || baseUrl);
|
|
163
|
+
const projectBaseUrl = normalizeBaseUrl(projectEnv[HOST_URL_ENV] ?? "");
|
|
164
|
+
const projectKeyApplies = projectBaseUrl === normalizedBaseUrl;
|
|
165
|
+
return firstNonEmpty(
|
|
166
|
+
explicitApiKey,
|
|
167
|
+
process.env[API_KEY_ENV],
|
|
168
|
+
projectKeyApplies ? projectEnv[API_KEY_ENV] : "",
|
|
169
|
+
cliEnv[API_KEY_ENV]
|
|
170
|
+
);
|
|
202
171
|
}
|
|
203
172
|
function resolveConfig(options) {
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
173
|
+
const baseUrl = normalizeBaseUrl(
|
|
174
|
+
options?.baseUrl?.trim() || autoDetectBaseUrl()
|
|
175
|
+
);
|
|
176
|
+
if (!baseUrl) {
|
|
177
|
+
throw new ConfigError(
|
|
178
|
+
`Invalid ${HOST_URL_ENV}. Expected an http(s) URL such as https://code.deepline.com.`
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
const apiKey = resolveApiKeyForBaseUrl(baseUrl, options?.apiKey);
|
|
210
182
|
if (!apiKey) {
|
|
211
183
|
throw new ConfigError(
|
|
212
|
-
`No API key found. Set
|
|
184
|
+
`No API key found. Set ${API_KEY_ENV}, add it to .env.deepline, or run: deepline auth register`
|
|
213
185
|
);
|
|
214
186
|
}
|
|
215
187
|
return {
|
|
@@ -219,32 +191,10 @@ function resolveConfig(options) {
|
|
|
219
191
|
maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES
|
|
220
192
|
};
|
|
221
193
|
}
|
|
222
|
-
function mergeEnvFile(filePath, values) {
|
|
223
|
-
const existing = existsSync(filePath) ? parseEnvFile(filePath) : {};
|
|
224
|
-
const merged = { ...existing, ...values };
|
|
225
|
-
const dir = dirname(filePath);
|
|
226
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
227
|
-
const lines = Object.entries(merged).filter(([, value]) => value !== "").map(([key, value]) => `${key}=${value}`);
|
|
228
|
-
writeFileSync(filePath, `${lines.join("\n")}
|
|
229
|
-
`, "utf-8");
|
|
230
|
-
}
|
|
231
|
-
function saveProjectDeeplineEnvValues(baseUrl, values, startDir = projectEnvStartDir()) {
|
|
232
|
-
const root = resolve(startDir);
|
|
233
|
-
const profile = profileNameForBaseUrl(baseUrl);
|
|
234
|
-
const files = [
|
|
235
|
-
join(root, ACTIVE_DEEPLINE_ENV_FILE),
|
|
236
|
-
join(root, `.env.deepline.${profile}`)
|
|
237
|
-
];
|
|
238
|
-
if (profile === "dev") files.push(join(root, ".env"));
|
|
239
|
-
for (const filePath of files) {
|
|
240
|
-
mergeEnvFile(filePath, values);
|
|
241
|
-
}
|
|
242
|
-
return files;
|
|
243
|
-
}
|
|
244
194
|
|
|
245
195
|
// src/version.ts
|
|
246
|
-
var SDK_VERSION = "0.1.
|
|
247
|
-
var SDK_API_CONTRACT = "2026-05-generic-play-input-flags";
|
|
196
|
+
var SDK_VERSION = "0.1.33";
|
|
197
|
+
var SDK_API_CONTRACT = "2026-05-host-env-generic-play-input-flags";
|
|
248
198
|
|
|
249
199
|
// ../shared_libs/play-runtime/coordinator-headers.ts
|
|
250
200
|
var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|
|
@@ -1654,7 +1604,7 @@ async function enforceSdkCompatibility(baseUrl) {
|
|
|
1654
1604
|
}
|
|
1655
1605
|
|
|
1656
1606
|
// src/cli/commands/auth.ts
|
|
1657
|
-
import {
|
|
1607
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, rmSync, writeFileSync as writeFileSync3 } from "fs";
|
|
1658
1608
|
import { hostname } from "os";
|
|
1659
1609
|
import { dirname as dirname3 } from "path";
|
|
1660
1610
|
|
|
@@ -1668,10 +1618,11 @@ import {
|
|
|
1668
1618
|
import { mkdir, writeFile } from "fs/promises";
|
|
1669
1619
|
import { homedir as homedir2 } from "os";
|
|
1670
1620
|
import { dirname as dirname2, join as join2, resolve as resolve2 } from "path";
|
|
1671
|
-
import
|
|
1621
|
+
import * as childProcess from "child_process";
|
|
1672
1622
|
import { parse } from "csv-parse/sync";
|
|
1673
1623
|
import { stringify } from "csv-stringify/sync";
|
|
1674
1624
|
var BROWSER_FOCUS_COOLDOWN_MS = 3e4;
|
|
1625
|
+
var defaultBrowserCommandRunner = childProcess;
|
|
1675
1626
|
function getAuthedHttpClient() {
|
|
1676
1627
|
const config = resolveConfig();
|
|
1677
1628
|
return { config, http: new HttpClient(config) };
|
|
@@ -1740,9 +1691,9 @@ function browserAppNameFromBundleId(bundleId) {
|
|
|
1740
1691
|
};
|
|
1741
1692
|
return names[bundleId.toLowerCase()] ?? "";
|
|
1742
1693
|
}
|
|
1743
|
-
function readDefaultMacBrowserBundleId() {
|
|
1694
|
+
function readDefaultMacBrowserBundleId(runner = defaultBrowserCommandRunner) {
|
|
1744
1695
|
try {
|
|
1745
|
-
const output = execFileSync(
|
|
1696
|
+
const output = runner.execFileSync(
|
|
1746
1697
|
"/usr/bin/defaults",
|
|
1747
1698
|
[
|
|
1748
1699
|
"read",
|
|
@@ -1778,8 +1729,8 @@ function browserStrategyForBundleId(bundleId) {
|
|
|
1778
1729
|
}
|
|
1779
1730
|
return normalized === "com.apple.safari" ? "safari" : "fallback";
|
|
1780
1731
|
}
|
|
1781
|
-
function runAppleScript(script, args) {
|
|
1782
|
-
const result = spawnSync("osascript", ["-", ...args], {
|
|
1732
|
+
function runAppleScript(script, args, runner = defaultBrowserCommandRunner) {
|
|
1733
|
+
const result = runner.spawnSync("osascript", ["-", ...args], {
|
|
1783
1734
|
input: script,
|
|
1784
1735
|
encoding: "utf-8",
|
|
1785
1736
|
stdio: ["pipe", "ignore", "ignore"],
|
|
@@ -1787,7 +1738,7 @@ function runAppleScript(script, args) {
|
|
|
1787
1738
|
});
|
|
1788
1739
|
return result.status === 0;
|
|
1789
1740
|
}
|
|
1790
|
-
function retargetChromiumMacos(appName, targetUrl, allowFocus) {
|
|
1741
|
+
function retargetChromiumMacos(appName, targetUrl, allowFocus, runner = defaultBrowserCommandRunner) {
|
|
1791
1742
|
const host = extractUrlHost(targetUrl);
|
|
1792
1743
|
if (!host) return false;
|
|
1793
1744
|
const escapedAppName = appName.replace(/"/g, '\\"');
|
|
@@ -1819,9 +1770,9 @@ ${newTabBlock} end if
|
|
|
1819
1770
|
end tell
|
|
1820
1771
|
end run
|
|
1821
1772
|
`;
|
|
1822
|
-
return runAppleScript(script, [targetUrl, host]);
|
|
1773
|
+
return runAppleScript(script, [targetUrl, host], runner);
|
|
1823
1774
|
}
|
|
1824
|
-
function retargetSafariMacos(appName, targetUrl, allowFocus) {
|
|
1775
|
+
function retargetSafariMacos(appName, targetUrl, allowFocus, runner = defaultBrowserCommandRunner) {
|
|
1825
1776
|
const host = extractUrlHost(targetUrl);
|
|
1826
1777
|
if (!host) return false;
|
|
1827
1778
|
const escapedAppName = appName.replace(/"/g, '\\"');
|
|
@@ -1853,30 +1804,38 @@ ${newTabBlock} end if
|
|
|
1853
1804
|
end tell
|
|
1854
1805
|
end run
|
|
1855
1806
|
`;
|
|
1856
|
-
return runAppleScript(script, [targetUrl, host]);
|
|
1807
|
+
return runAppleScript(script, [targetUrl, host], runner);
|
|
1857
1808
|
}
|
|
1858
|
-
function openUrlMacos(targetUrl, allowFocus) {
|
|
1859
|
-
const defaultBundleId = readDefaultMacBrowserBundleId();
|
|
1809
|
+
function openUrlMacos(targetUrl, allowFocus, runner = defaultBrowserCommandRunner) {
|
|
1810
|
+
const defaultBundleId = readDefaultMacBrowserBundleId(runner);
|
|
1860
1811
|
const appName = defaultBundleId ? browserAppNameFromBundleId(defaultBundleId) : "";
|
|
1861
1812
|
const strategy = browserStrategyForBundleId(defaultBundleId);
|
|
1862
|
-
if (appName && strategy === "chromium" && retargetChromiumMacos(appName, targetUrl, allowFocus)) {
|
|
1813
|
+
if (appName && strategy === "chromium" && retargetChromiumMacos(appName, targetUrl, allowFocus, runner)) {
|
|
1863
1814
|
return true;
|
|
1864
1815
|
}
|
|
1865
|
-
if (appName && strategy === "safari" && retargetSafariMacos(appName, targetUrl, allowFocus)) {
|
|
1816
|
+
if (appName && strategy === "safari" && retargetSafariMacos(appName, targetUrl, allowFocus, runner)) {
|
|
1866
1817
|
return true;
|
|
1867
1818
|
}
|
|
1868
|
-
if (!allowFocus) {
|
|
1869
|
-
return false;
|
|
1870
|
-
}
|
|
1871
1819
|
try {
|
|
1872
|
-
execFileSync(
|
|
1820
|
+
runner.execFileSync(
|
|
1821
|
+
"open",
|
|
1822
|
+
[...allowFocus ? [] : ["-g"], targetUrl],
|
|
1823
|
+
{ stdio: "ignore" }
|
|
1824
|
+
);
|
|
1873
1825
|
return true;
|
|
1874
1826
|
} catch {
|
|
1875
1827
|
return false;
|
|
1876
1828
|
}
|
|
1877
1829
|
}
|
|
1830
|
+
function browserOpeningDisabled() {
|
|
1831
|
+
const value = String(
|
|
1832
|
+
process.env.DEEPLINE_NO_BROWSER ?? process.env.PLAYGROUND_HEADLESS ?? ""
|
|
1833
|
+
).trim().toLowerCase();
|
|
1834
|
+
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
1835
|
+
}
|
|
1878
1836
|
function openInBrowser(url) {
|
|
1879
1837
|
try {
|
|
1838
|
+
if (browserOpeningDisabled()) return;
|
|
1880
1839
|
const targetUrl = String(url || "").trim();
|
|
1881
1840
|
if (!targetUrl) return;
|
|
1882
1841
|
const allowFocus = claimBrowserFocus();
|
|
@@ -1886,12 +1845,12 @@ function openInBrowser(url) {
|
|
|
1886
1845
|
}
|
|
1887
1846
|
if (!allowFocus) return;
|
|
1888
1847
|
if (process.platform === "win32") {
|
|
1889
|
-
execFileSync("cmd.exe", ["/c", "start", "", targetUrl], {
|
|
1848
|
+
childProcess.execFileSync("cmd.exe", ["/c", "start", "", targetUrl], {
|
|
1890
1849
|
stdio: "ignore"
|
|
1891
1850
|
});
|
|
1892
1851
|
return;
|
|
1893
1852
|
}
|
|
1894
|
-
execFileSync("xdg-open", [targetUrl], { stdio: "ignore" });
|
|
1853
|
+
childProcess.execFileSync("xdg-open", [targetUrl], { stdio: "ignore" });
|
|
1895
1854
|
} catch {
|
|
1896
1855
|
}
|
|
1897
1856
|
}
|
|
@@ -2005,17 +1964,39 @@ var EXIT_SERVER = 2;
|
|
|
2005
1964
|
function envFilePath(baseUrl) {
|
|
2006
1965
|
return hostEnvFilePath(baseUrl);
|
|
2007
1966
|
}
|
|
2008
|
-
function
|
|
2009
|
-
|
|
1967
|
+
function pendingClaimTokenPath(baseUrl) {
|
|
1968
|
+
return `${hostConfigDirPath(baseUrl)}/pending-claim-token`;
|
|
1969
|
+
}
|
|
1970
|
+
function savePendingClaimToken(baseUrl, claimToken) {
|
|
1971
|
+
const filePath = pendingClaimTokenPath(baseUrl);
|
|
2010
1972
|
const dir = dirname3(filePath);
|
|
2011
1973
|
if (!existsSync3(dir)) {
|
|
2012
1974
|
mkdirSync3(dir, { recursive: true });
|
|
2013
1975
|
}
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
1976
|
+
writeFileSync3(filePath, `${claimToken}
|
|
1977
|
+
`, "utf-8");
|
|
1978
|
+
}
|
|
1979
|
+
function readPendingClaimToken(baseUrl) {
|
|
1980
|
+
const filePath = pendingClaimTokenPath(baseUrl);
|
|
1981
|
+
if (!existsSync3(filePath)) return "";
|
|
1982
|
+
try {
|
|
1983
|
+
return readFileSync3(filePath, "utf-8").trim();
|
|
1984
|
+
} catch {
|
|
1985
|
+
return "";
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
function clearPendingClaimToken(baseUrl) {
|
|
1989
|
+
try {
|
|
1990
|
+
rmSync(pendingClaimTokenPath(baseUrl), { force: true });
|
|
1991
|
+
} catch {
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
function saveEnvValues(values, baseUrl) {
|
|
1995
|
+
const filtered = {
|
|
1996
|
+
...values[HOST_URL_ENV] ? { [HOST_URL_ENV]: values[HOST_URL_ENV] } : {},
|
|
1997
|
+
...values[API_KEY_ENV] ? { [API_KEY_ENV]: values[API_KEY_ENV] } : {}
|
|
1998
|
+
};
|
|
1999
|
+
saveHostEnvValues(baseUrl, filtered);
|
|
2019
2000
|
}
|
|
2020
2001
|
async function httpJson(method, url, apiKey, body) {
|
|
2021
2002
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -2121,9 +2102,9 @@ async function handleRegister(args) {
|
|
|
2121
2102
|
const claimUrl = String(data.claim_url || "");
|
|
2122
2103
|
const claimToken = String(data.claim_token || "");
|
|
2123
2104
|
if (claimToken) {
|
|
2105
|
+
savePendingClaimToken(baseUrl, claimToken);
|
|
2124
2106
|
saveEnvValues({
|
|
2125
|
-
|
|
2126
|
-
DEEPLINE_CLAIM_TOKEN: claimToken
|
|
2107
|
+
[HOST_URL_ENV]: baseUrl
|
|
2127
2108
|
}, baseUrl);
|
|
2128
2109
|
}
|
|
2129
2110
|
if (claimUrl) {
|
|
@@ -2147,6 +2128,7 @@ async function handleRegister(args) {
|
|
|
2147
2128
|
{ claim_token: claimToken, reveal: true }
|
|
2148
2129
|
);
|
|
2149
2130
|
if (s === 401 || s === 403) {
|
|
2131
|
+
clearPendingClaimToken(baseUrl);
|
|
2150
2132
|
console.log("Status: unauthorized");
|
|
2151
2133
|
return EXIT_AUTH;
|
|
2152
2134
|
}
|
|
@@ -2163,15 +2145,16 @@ async function handleRegister(args) {
|
|
|
2163
2145
|
const apiKey = String(statusData.api_key || "");
|
|
2164
2146
|
if (apiKey) {
|
|
2165
2147
|
saveEnvValues({
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
DEEPLINE_CLAIM_TOKEN: ""
|
|
2148
|
+
[HOST_URL_ENV]: baseUrl,
|
|
2149
|
+
[API_KEY_ENV]: apiKey
|
|
2169
2150
|
}, baseUrl);
|
|
2151
|
+
clearPendingClaimToken(baseUrl);
|
|
2170
2152
|
printClaimSuccessBanner(statusData);
|
|
2171
2153
|
return EXIT_OK;
|
|
2172
2154
|
}
|
|
2173
2155
|
}
|
|
2174
2156
|
if (state === "expired") {
|
|
2157
|
+
clearPendingClaimToken(baseUrl);
|
|
2175
2158
|
console.log("That approval link expired. Please run: deepline auth register");
|
|
2176
2159
|
return EXIT_AUTH;
|
|
2177
2160
|
}
|
|
@@ -2189,13 +2172,12 @@ async function handleWait(args) {
|
|
|
2189
2172
|
}
|
|
2190
2173
|
}
|
|
2191
2174
|
}
|
|
2192
|
-
const
|
|
2193
|
-
if (env.DEEPLINE_API_KEY?.trim()) {
|
|
2194
|
-
console.log("Already connected.");
|
|
2195
|
-
return EXIT_OK;
|
|
2196
|
-
}
|
|
2197
|
-
const claimToken = env.DEEPLINE_CLAIM_TOKEN?.trim() || "";
|
|
2175
|
+
const claimToken = readPendingClaimToken(baseUrl);
|
|
2198
2176
|
if (!claimToken) {
|
|
2177
|
+
if (resolveApiKeyForBaseUrl(baseUrl)) {
|
|
2178
|
+
console.log("Already connected.");
|
|
2179
|
+
return EXIT_OK;
|
|
2180
|
+
}
|
|
2199
2181
|
console.error("No pending approval. Run: deepline auth register --no-wait");
|
|
2200
2182
|
return EXIT_AUTH;
|
|
2201
2183
|
}
|
|
@@ -2208,6 +2190,7 @@ async function handleWait(args) {
|
|
|
2208
2190
|
{ claim_token: claimToken, reveal: true }
|
|
2209
2191
|
);
|
|
2210
2192
|
if (status === 401 || status === 403) {
|
|
2193
|
+
clearPendingClaimToken(baseUrl);
|
|
2211
2194
|
console.error("Claim is invalid. Run: deepline auth register");
|
|
2212
2195
|
return EXIT_AUTH;
|
|
2213
2196
|
}
|
|
@@ -2224,15 +2207,16 @@ async function handleWait(args) {
|
|
|
2224
2207
|
const apiKey = String(data.api_key || "");
|
|
2225
2208
|
if (apiKey) {
|
|
2226
2209
|
saveEnvValues({
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
DEEPLINE_CLAIM_TOKEN: ""
|
|
2210
|
+
[HOST_URL_ENV]: baseUrl,
|
|
2211
|
+
[API_KEY_ENV]: apiKey
|
|
2230
2212
|
}, baseUrl);
|
|
2213
|
+
clearPendingClaimToken(baseUrl);
|
|
2231
2214
|
printClaimSuccessBanner(data);
|
|
2232
2215
|
return EXIT_OK;
|
|
2233
2216
|
}
|
|
2234
2217
|
}
|
|
2235
2218
|
if (state === "expired") {
|
|
2219
|
+
clearPendingClaimToken(baseUrl);
|
|
2236
2220
|
console.error("That approval link expired. Run: deepline auth register");
|
|
2237
2221
|
return EXIT_AUTH;
|
|
2238
2222
|
}
|
|
@@ -2267,10 +2251,9 @@ async function handleStatus(args) {
|
|
|
2267
2251
|
};
|
|
2268
2252
|
hostLines.push(`Host: ${baseUrl} (unreachable)`);
|
|
2269
2253
|
}
|
|
2270
|
-
const
|
|
2271
|
-
const apiKey = process.env.DEEPLINE_API_KEY?.trim() || env.DEEPLINE_API_KEY || "";
|
|
2254
|
+
const apiKey = resolveApiKeyForBaseUrl(baseUrl);
|
|
2272
2255
|
if (!apiKey) {
|
|
2273
|
-
if (
|
|
2256
|
+
if (readPendingClaimToken(baseUrl)) {
|
|
2274
2257
|
printCommandEnvelope({
|
|
2275
2258
|
...hostStatusPayload ?? { host: baseUrl },
|
|
2276
2259
|
status: "pending",
|
|
@@ -2316,6 +2299,7 @@ async function handleStatus(args) {
|
|
|
2316
2299
|
console.error(`Auth status error (status ${status}).`);
|
|
2317
2300
|
return EXIT_SERVER;
|
|
2318
2301
|
}
|
|
2302
|
+
clearPendingClaimToken(baseUrl);
|
|
2319
2303
|
const payload = {
|
|
2320
2304
|
...hostStatusPayload ?? { host: baseUrl },
|
|
2321
2305
|
status: data.status || "(unknown)",
|
|
@@ -2336,9 +2320,8 @@ async function handleStatus(args) {
|
|
|
2336
2320
|
const apiKeyResp = String(data.api_key || apiKey);
|
|
2337
2321
|
if (apiKeyResp) {
|
|
2338
2322
|
saveEnvValues({
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
DEEPLINE_CLAIM_TOKEN: ""
|
|
2323
|
+
[HOST_URL_ENV]: baseUrl,
|
|
2324
|
+
[API_KEY_ENV]: apiKeyResp
|
|
2342
2325
|
}, baseUrl);
|
|
2343
2326
|
savedApiKeyPath = envFilePath(baseUrl);
|
|
2344
2327
|
}
|
|
@@ -3675,7 +3658,7 @@ Examples:
|
|
|
3675
3658
|
import { createHash as createHash3 } from "crypto";
|
|
3676
3659
|
import {
|
|
3677
3660
|
existsSync as existsSync6,
|
|
3678
|
-
readFileSync as
|
|
3661
|
+
readFileSync as readFileSync5,
|
|
3679
3662
|
readdirSync,
|
|
3680
3663
|
realpathSync,
|
|
3681
3664
|
writeFileSync as writeFileSync5
|
|
@@ -3690,7 +3673,7 @@ import { existsSync as existsSync5 } from "fs";
|
|
|
3690
3673
|
|
|
3691
3674
|
// ../shared_libs/plays/bundling/index.ts
|
|
3692
3675
|
import { createHash } from "crypto";
|
|
3693
|
-
import { existsSync as existsSync4, readFileSync as
|
|
3676
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
3694
3677
|
import { mkdir as mkdir3, readFile, realpath, stat, writeFile as writeFile3 } from "fs/promises";
|
|
3695
3678
|
import { tmpdir } from "os";
|
|
3696
3679
|
import { basename, dirname as dirname5, extname, isAbsolute, join as join3, resolve as resolve5 } from "path";
|
|
@@ -3944,7 +3927,7 @@ function extractDefinedPlayName(sourceCode) {
|
|
|
3944
3927
|
}
|
|
3945
3928
|
function readPackageVersionFromPackageJson(packageJsonPath, packageName) {
|
|
3946
3929
|
try {
|
|
3947
|
-
const packageJson = JSON.parse(
|
|
3930
|
+
const packageJson = JSON.parse(readFileSync4(packageJsonPath, "utf-8"));
|
|
3948
3931
|
if (packageJson.name === packageName && typeof packageJson.version === "string") {
|
|
3949
3932
|
return packageJson.version;
|
|
3950
3933
|
}
|
|
@@ -4239,7 +4222,7 @@ function resolvePackageImport(specifier, fromFile, adapter) {
|
|
|
4239
4222
|
const packageName = getPackageName(specifier);
|
|
4240
4223
|
if (packageName === "deepline" && existsSync4(adapter.sdkPackageJson)) {
|
|
4241
4224
|
const packageJson = JSON.parse(
|
|
4242
|
-
|
|
4225
|
+
readFileSync4(adapter.sdkPackageJson, "utf-8")
|
|
4243
4226
|
);
|
|
4244
4227
|
return {
|
|
4245
4228
|
name: "deepline",
|
|
@@ -5370,7 +5353,7 @@ function materializeRemotePlaySource(input) {
|
|
|
5370
5353
|
}
|
|
5371
5354
|
const outputPath = input.outPath ?? defaultMaterializedPlayPath(input.playName);
|
|
5372
5355
|
if (existsSync6(outputPath)) {
|
|
5373
|
-
const existingSource =
|
|
5356
|
+
const existingSource = readFileSync5(outputPath, "utf-8");
|
|
5374
5357
|
if (existingSource === input.sourceCode) {
|
|
5375
5358
|
return { path: outputPath, status: "unchanged", created: false };
|
|
5376
5359
|
}
|
|
@@ -5441,7 +5424,7 @@ function parsePositiveInteger2(value, flagName) {
|
|
|
5441
5424
|
return parsed;
|
|
5442
5425
|
}
|
|
5443
5426
|
function parseJsonInput(raw) {
|
|
5444
|
-
const source = raw.startsWith("@") ?
|
|
5427
|
+
const source = raw.startsWith("@") ? readFileSync5(resolve8(raw.slice(1)), "utf-8") : raw;
|
|
5445
5428
|
const parsed = JSON.parse(source);
|
|
5446
5429
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
5447
5430
|
throw new Error("--input must be a JSON object.");
|
|
@@ -5593,7 +5576,7 @@ async function stageFileInputArgs(input) {
|
|
|
5593
5576
|
};
|
|
5594
5577
|
}
|
|
5595
5578
|
function stageFile(logicalPath, absolutePath) {
|
|
5596
|
-
const buffer =
|
|
5579
|
+
const buffer = readFileSync5(absolutePath);
|
|
5597
5580
|
return {
|
|
5598
5581
|
logicalPath,
|
|
5599
5582
|
contentBase64: buffer.toString("base64"),
|
|
@@ -5830,10 +5813,6 @@ function openPlayDashboard(input) {
|
|
|
5830
5813
|
}
|
|
5831
5814
|
openInBrowser(input.dashboardUrl);
|
|
5832
5815
|
}
|
|
5833
|
-
function getDashboardUrlFromLiveEvent(event) {
|
|
5834
|
-
const dashboardUrl = getEventPayload(event).dashboardUrl;
|
|
5835
|
-
return typeof dashboardUrl === "string" && dashboardUrl.trim() ? dashboardUrl.trim() : null;
|
|
5836
|
-
}
|
|
5837
5816
|
function printPlayLogLines(input) {
|
|
5838
5817
|
for (const line of input.lines) {
|
|
5839
5818
|
if (input.emitLogs) {
|
|
@@ -5902,7 +5881,7 @@ async function waitForPlayCompletionByStream(input) {
|
|
|
5902
5881
|
billing: false
|
|
5903
5882
|
});
|
|
5904
5883
|
if (TERMINAL_PLAY_STATUSES2.has(finalStatus.status)) {
|
|
5905
|
-
return finalStatus;
|
|
5884
|
+
return input.dashboardUrl ? { ...finalStatus, dashboardUrl: input.dashboardUrl } : finalStatus;
|
|
5906
5885
|
}
|
|
5907
5886
|
}
|
|
5908
5887
|
}
|
|
@@ -5930,6 +5909,10 @@ async function waitForPlayCompletionByStream(input) {
|
|
|
5930
5909
|
}
|
|
5931
5910
|
async function startAndWaitForPlayCompletionByStream(input) {
|
|
5932
5911
|
const startedAt = Date.now();
|
|
5912
|
+
const dashboardUrl = buildPlayDashboardUrl(
|
|
5913
|
+
input.client.baseUrl,
|
|
5914
|
+
input.playName
|
|
5915
|
+
);
|
|
5933
5916
|
const state = {
|
|
5934
5917
|
lastLogIndex: 0,
|
|
5935
5918
|
emittedRunnerStarted: false
|
|
@@ -5960,7 +5943,6 @@ async function startAndWaitForPlayCompletionByStream(input) {
|
|
|
5960
5943
|
}
|
|
5961
5944
|
const workflowId = lastKnownWorkflowId || "pending";
|
|
5962
5945
|
if (workflowId !== "pending" && !emittedDashboardUrl) {
|
|
5963
|
-
const dashboardUrl = getDashboardUrlFromLiveEvent(event) ?? buildPlayDashboardUrl(input.client.baseUrl, input.playName);
|
|
5964
5946
|
openPlayDashboard({
|
|
5965
5947
|
dashboardUrl,
|
|
5966
5948
|
jsonOutput: input.jsonOutput,
|
|
@@ -6009,7 +5991,7 @@ async function startAndWaitForPlayCompletionByStream(input) {
|
|
|
6009
5991
|
firstRunIdMs,
|
|
6010
5992
|
lastPhase
|
|
6011
5993
|
});
|
|
6012
|
-
return finalStatus;
|
|
5994
|
+
return { ...finalStatus, dashboardUrl };
|
|
6013
5995
|
}
|
|
6014
5996
|
}
|
|
6015
5997
|
} catch (error) {
|
|
@@ -6046,6 +6028,7 @@ async function startAndWaitForPlayCompletionByStream(input) {
|
|
|
6046
6028
|
return waitForPlayCompletionByStream({
|
|
6047
6029
|
client: input.client,
|
|
6048
6030
|
workflowId: lastKnownWorkflowId,
|
|
6031
|
+
dashboardUrl,
|
|
6049
6032
|
jsonOutput: input.jsonOutput,
|
|
6050
6033
|
emitLogs: input.emitLogs,
|
|
6051
6034
|
waitTimeoutMs: input.waitTimeoutMs,
|
|
@@ -6080,6 +6063,7 @@ async function startAndWaitForPlayCompletionByStream(input) {
|
|
|
6080
6063
|
return waitForPlayCompletionByStream({
|
|
6081
6064
|
client: input.client,
|
|
6082
6065
|
workflowId: lastKnownWorkflowId,
|
|
6066
|
+
dashboardUrl,
|
|
6083
6067
|
jsonOutput: input.jsonOutput,
|
|
6084
6068
|
emitLogs: input.emitLogs,
|
|
6085
6069
|
waitTimeoutMs: input.waitTimeoutMs,
|
|
@@ -6250,12 +6234,16 @@ function buildRunWarnings(status, rowsInfo) {
|
|
|
6250
6234
|
}
|
|
6251
6235
|
return [];
|
|
6252
6236
|
}
|
|
6253
|
-
function buildRunNextCommands(runId) {
|
|
6254
|
-
|
|
6237
|
+
function buildRunNextCommands(runId, dashboardUrl) {
|
|
6238
|
+
const commands = {
|
|
6255
6239
|
get: `deepline runs get ${runId} --json`,
|
|
6256
6240
|
stop: `deepline runs stop ${runId} --reason "stale lock" --json`,
|
|
6257
6241
|
logs: `deepline runs logs ${runId} --out run.log --json`
|
|
6258
6242
|
};
|
|
6243
|
+
if (dashboardUrl) {
|
|
6244
|
+
commands.open = `Open ${dashboardUrl} to see results.`;
|
|
6245
|
+
}
|
|
6246
|
+
return commands;
|
|
6259
6247
|
}
|
|
6260
6248
|
var RUN_LOG_PREVIEW_LIMIT = 20;
|
|
6261
6249
|
function getRecordField(value, key) {
|
|
@@ -6391,6 +6379,7 @@ function compactPlayStatus(status) {
|
|
|
6391
6379
|
apiVersion: status.apiVersion ?? 1,
|
|
6392
6380
|
...typeof status.name === "string" ? { name: status.name } : {},
|
|
6393
6381
|
...typeof status.playName === "string" ? { playName: status.playName } : {},
|
|
6382
|
+
...status.dashboardUrl ? { dashboardUrl: status.dashboardUrl } : {},
|
|
6394
6383
|
status: status.status,
|
|
6395
6384
|
run: normalizeRunStatusForEnvelope(status),
|
|
6396
6385
|
progress: normalizeProgressForEnvelope(status, rowsInfo),
|
|
@@ -6403,7 +6392,7 @@ function compactPlayStatus(status) {
|
|
|
6403
6392
|
...status.resultView ? { resultView: status.resultView } : {},
|
|
6404
6393
|
...datasetStats ? { dataset_stats: datasetStats } : {},
|
|
6405
6394
|
...billing ? { billing } : {},
|
|
6406
|
-
next: buildRunNextCommands(status.runId)
|
|
6395
|
+
next: buildRunNextCommands(status.runId, status.dashboardUrl)
|
|
6407
6396
|
};
|
|
6408
6397
|
}
|
|
6409
6398
|
function enrichPlayStatusWithDatasetStats(status) {
|
|
@@ -6616,7 +6605,7 @@ async function exportPlayStatusRows(client, status, outPath, options = {}) {
|
|
|
6616
6605
|
return null;
|
|
6617
6606
|
}
|
|
6618
6607
|
const availableRows = collectSerializedDatasetRowsInfos(status);
|
|
6619
|
-
|
|
6608
|
+
const rowsInfo = options.datasetPath ? availableRows.find((info) => info.source === options.datasetPath) ?? null : availableRows.length === 1 ? availableRows[0] : null;
|
|
6620
6609
|
if (!rowsInfo && options.datasetPath) {
|
|
6621
6610
|
const available = availableRows.map((info) => info.source).filter((source) => typeof source === "string");
|
|
6622
6611
|
throw new DeeplineError(
|
|
@@ -6930,7 +6919,7 @@ async function handlePlayCheck(args) {
|
|
|
6930
6919
|
return 1;
|
|
6931
6920
|
}
|
|
6932
6921
|
const absolutePlayPath = resolve8(options.target);
|
|
6933
|
-
const sourceCode =
|
|
6922
|
+
const sourceCode = readFileSync5(absolutePlayPath, "utf-8");
|
|
6934
6923
|
let graph;
|
|
6935
6924
|
try {
|
|
6936
6925
|
graph = await collectBundledPlayGraph(absolutePlayPath);
|
|
@@ -6998,7 +6987,7 @@ async function handleFileBackedRun(options) {
|
|
|
6998
6987
|
const sourceCode = traceCliSync(
|
|
6999
6988
|
"cli.play_file_read_source",
|
|
7000
6989
|
{ targetKind: "file" },
|
|
7001
|
-
() =>
|
|
6990
|
+
() => readFileSync5(absolutePlayPath, "utf-8")
|
|
7002
6991
|
);
|
|
7003
6992
|
const runtimeInput = options.input ? { ...options.input } : {};
|
|
7004
6993
|
let graph;
|
|
@@ -7099,8 +7088,7 @@ async function handleFileBackedRun(options) {
|
|
|
7099
7088
|
{ targetKind: "file", playName },
|
|
7100
7089
|
() => client.startPlayRun(startRequest)
|
|
7101
7090
|
);
|
|
7102
|
-
const
|
|
7103
|
-
const resolvedDashboardUrl = started.dashboardUrl ?? dashboardUrl;
|
|
7091
|
+
const resolvedDashboardUrl = buildPlayDashboardUrl(client.baseUrl, playName);
|
|
7104
7092
|
openPlayDashboard({
|
|
7105
7093
|
dashboardUrl: resolvedDashboardUrl,
|
|
7106
7094
|
jsonOutput: options.jsonOutput,
|
|
@@ -7235,11 +7223,7 @@ async function handleNamedRun(options) {
|
|
|
7235
7223
|
{ targetKind: "name", playName },
|
|
7236
7224
|
() => client.startPlayRun(startRequest)
|
|
7237
7225
|
);
|
|
7238
|
-
const
|
|
7239
|
-
client.baseUrl,
|
|
7240
|
-
playName
|
|
7241
|
-
);
|
|
7242
|
-
const resolvedDashboardUrl = started.dashboardUrl ?? dashboardUrl;
|
|
7226
|
+
const resolvedDashboardUrl = buildPlayDashboardUrl(client.baseUrl, playName);
|
|
7243
7227
|
openPlayDashboard({
|
|
7244
7228
|
dashboardUrl: resolvedDashboardUrl,
|
|
7245
7229
|
jsonOutput: options.jsonOutput,
|
|
@@ -7530,7 +7514,7 @@ async function handlePlayGet(args) {
|
|
|
7530
7514
|
outPath = resolve8(args[++index]);
|
|
7531
7515
|
}
|
|
7532
7516
|
}
|
|
7533
|
-
const playName = isFileTarget(target) ? extractPlayName(
|
|
7517
|
+
const playName = isFileTarget(target) ? extractPlayName(readFileSync5(resolve8(target), "utf-8"), resolve8(target)) : parseReferencedPlayTarget(target).playName;
|
|
7534
7518
|
const detail = isFileTarget(target) ? await client.getPlay(playName) : await assertCanonicalNamedPlayReference(client, target);
|
|
7535
7519
|
const resolvedSource = detail.play.workingRevision?.sourceCode ?? detail.play.liveRevision?.sourceCode ?? detail.play.currentRevision?.sourceCode ?? detail.play.sourceCode ?? "";
|
|
7536
7520
|
const materializedFile = outPath ? materializeRemotePlaySource({
|
|
@@ -9363,8 +9347,8 @@ Examples:
|
|
|
9363
9347
|
}
|
|
9364
9348
|
|
|
9365
9349
|
// src/cli/skills-sync.ts
|
|
9366
|
-
import { spawn as spawn2, spawnSync
|
|
9367
|
-
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as
|
|
9350
|
+
import { spawn as spawn2, spawnSync } from "child_process";
|
|
9351
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync8 } from "fs";
|
|
9368
9352
|
import { homedir as homedir4 } from "os";
|
|
9369
9353
|
import { dirname as dirname10, join as join10 } from "path";
|
|
9370
9354
|
var CHECK_TIMEOUT_MS2 = 3e3;
|
|
@@ -9383,7 +9367,7 @@ function readLocalSkillsVersion(baseUrl) {
|
|
|
9383
9367
|
const path = sdkSkillsVersionPath(baseUrl);
|
|
9384
9368
|
if (!existsSync8(path)) return "";
|
|
9385
9369
|
try {
|
|
9386
|
-
return
|
|
9370
|
+
return readFileSync6(path, "utf-8").trim();
|
|
9387
9371
|
} catch {
|
|
9388
9372
|
return "";
|
|
9389
9373
|
}
|
|
@@ -9455,7 +9439,7 @@ function buildBunxSkillsInstallArgs(baseUrl) {
|
|
|
9455
9439
|
];
|
|
9456
9440
|
}
|
|
9457
9441
|
function hasCommand(command) {
|
|
9458
|
-
const result =
|
|
9442
|
+
const result = spawnSync(command, ["--version"], {
|
|
9459
9443
|
stdio: "ignore",
|
|
9460
9444
|
shell: process.platform === "win32"
|
|
9461
9445
|
});
|