@kvell007/embed-labs-cli 0.1.0-alpha.13 → 0.1.0-alpha.14
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/index.js +95 -12
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createHash } from "node:crypto";
|
|
2
|
+
import { createHash, createHmac, randomBytes } from "node:crypto";
|
|
3
3
|
import { constants } from "node:fs";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
5
|
import { access, cp, mkdir, mkdtemp, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -1386,6 +1386,7 @@ async function cloudDownloadArtifact(artifactId, outputPath) {
|
|
|
1386
1386
|
const token = await cloudAuthToken();
|
|
1387
1387
|
if (token) {
|
|
1388
1388
|
headers.authorization = `Bearer ${token}`;
|
|
1389
|
+
addCloudRequestSignature(headers, "GET", `/v1/artifacts/${encodeURIComponent(artifactId)}/download`, "", token);
|
|
1389
1390
|
}
|
|
1390
1391
|
const response = await fetch(`${serviceBaseUrl(DEFAULT_CLOUD_API_URL)}/v1/artifacts/${encodeURIComponent(artifactId)}/download`, {
|
|
1391
1392
|
headers: Object.keys(headers).length > 0 ? headers : undefined
|
|
@@ -1421,17 +1422,19 @@ async function cloudDownloadArtifact(artifactId, outputPath) {
|
|
|
1421
1422
|
async function cloudRequest(method, path, body) {
|
|
1422
1423
|
try {
|
|
1423
1424
|
const headers = {};
|
|
1424
|
-
|
|
1425
|
+
const bodyText = body === undefined ? "" : JSON.stringify(body);
|
|
1426
|
+
if (bodyText) {
|
|
1425
1427
|
headers["content-type"] = "application/json";
|
|
1426
1428
|
}
|
|
1427
1429
|
const token = await cloudAuthToken();
|
|
1428
1430
|
if (token) {
|
|
1429
1431
|
headers.authorization = `Bearer ${token}`;
|
|
1432
|
+
addCloudRequestSignature(headers, method, path, bodyText, token);
|
|
1430
1433
|
}
|
|
1431
1434
|
const response = await fetch(`${serviceBaseUrl(DEFAULT_CLOUD_API_URL)}${path}`, {
|
|
1432
1435
|
method,
|
|
1433
1436
|
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
|
1434
|
-
body: body === undefined ? undefined :
|
|
1437
|
+
body: body === undefined ? undefined : bodyText
|
|
1435
1438
|
});
|
|
1436
1439
|
return await response.json();
|
|
1437
1440
|
}
|
|
@@ -1441,6 +1444,39 @@ async function cloudRequest(method, path, body) {
|
|
|
1441
1444
|
});
|
|
1442
1445
|
}
|
|
1443
1446
|
}
|
|
1447
|
+
function addCloudRequestSignature(headers, method, pathWithQuery, bodyText, token) {
|
|
1448
|
+
if (process.env.EMBED_CLOUD_API_SIGNING === "0") {
|
|
1449
|
+
return;
|
|
1450
|
+
}
|
|
1451
|
+
const timestamp = String(Math.floor(Date.now() / 1000));
|
|
1452
|
+
const nonce = randomBytes(16).toString("hex");
|
|
1453
|
+
const bodySha256 = createHash("sha256").update(bodyText).digest("hex");
|
|
1454
|
+
const keyId = createHash("sha256").update(token).digest("hex").slice(0, 16);
|
|
1455
|
+
const canonical = cloudRequestCanonicalString(method, pathWithQuery, timestamp, nonce, bodySha256);
|
|
1456
|
+
headers["x-embed-key-id"] = keyId;
|
|
1457
|
+
headers["x-embed-timestamp"] = timestamp;
|
|
1458
|
+
headers["x-embed-nonce"] = nonce;
|
|
1459
|
+
headers["x-embed-body-sha256"] = bodySha256;
|
|
1460
|
+
headers["x-embed-signature"] = createHmac("sha256", token).update(canonical).digest("hex");
|
|
1461
|
+
}
|
|
1462
|
+
function cloudRequestCanonicalString(method, pathWithQuery, timestamp, nonce, bodySha256) {
|
|
1463
|
+
return [
|
|
1464
|
+
method.toUpperCase(),
|
|
1465
|
+
normalizeCloudPathForSignature(pathWithQuery),
|
|
1466
|
+
timestamp,
|
|
1467
|
+
nonce,
|
|
1468
|
+
bodySha256
|
|
1469
|
+
].join("\n");
|
|
1470
|
+
}
|
|
1471
|
+
function normalizeCloudPathForSignature(pathWithQuery) {
|
|
1472
|
+
try {
|
|
1473
|
+
const parsed = new URL(pathWithQuery, "http://embed.local");
|
|
1474
|
+
return `${parsed.pathname}${parsed.search}`;
|
|
1475
|
+
}
|
|
1476
|
+
catch {
|
|
1477
|
+
return pathWithQuery.startsWith("/") ? pathWithQuery : `/${pathWithQuery}`;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1444
1480
|
async function pluginList(parsed) {
|
|
1445
1481
|
const releaseDir = stringFlag(parsed, "release-dir");
|
|
1446
1482
|
const manifest = releaseDir ? await readPluginReleaseManifest(releaseDir) : undefined;
|
|
@@ -1850,6 +1886,7 @@ async function cleanupLegacyCodexPluginRemnants(targetRoot) {
|
|
|
1850
1886
|
const removedPaths = [];
|
|
1851
1887
|
const removedConfigTables = [];
|
|
1852
1888
|
const warnings = [];
|
|
1889
|
+
const stoppedProcesses = await stopLegacyCodexPluginProcesses(warnings);
|
|
1853
1890
|
const legacyPaths = [
|
|
1854
1891
|
join(targetRoot, "dbt-agent"),
|
|
1855
1892
|
join(targetRoot, "development-board-toolchain"),
|
|
@@ -1859,7 +1896,7 @@ async function cleanupLegacyCodexPluginRemnants(targetRoot) {
|
|
|
1859
1896
|
];
|
|
1860
1897
|
legacyPaths.push(...await discoverLegacyCodexCachePaths(targetRoot));
|
|
1861
1898
|
if (resolve(targetRoot) === resolve(defaultCodexPluginRoot())) {
|
|
1862
|
-
legacyPaths.push(join(defaultCodexHome(), ".tmp", "plugins"), join(defaultCodexHome(), ".tmp", "plugins.sha"));
|
|
1899
|
+
legacyPaths.push(join(defaultCodexHome(), ".tmp", "plugins"), join(defaultCodexHome(), ".tmp", "plugins.sha"), join(defaultCodexHome(), "memories", "skills", "dbt-agent-live-board-ops"), join(defaultCodexHome(), "memories", "skills", "dbt-agent-platform-plugin-maintenance"));
|
|
1863
1900
|
}
|
|
1864
1901
|
for (const candidate of legacyPaths) {
|
|
1865
1902
|
try {
|
|
@@ -1888,14 +1925,51 @@ async function cleanupLegacyCodexPluginRemnants(targetRoot) {
|
|
|
1888
1925
|
warnings.push(`Could not update ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1889
1926
|
}
|
|
1890
1927
|
}
|
|
1891
|
-
const removedHistoryEntries = await
|
|
1928
|
+
const removedHistoryEntries = await cleanupLegacyCodexTextState(warnings);
|
|
1892
1929
|
return {
|
|
1893
1930
|
legacy_removed_paths: Array.from(new Set(removedPaths)),
|
|
1894
1931
|
legacy_removed_config_tables: removedConfigTables,
|
|
1895
1932
|
legacy_removed_history_entries: removedHistoryEntries,
|
|
1933
|
+
legacy_stopped_processes: stoppedProcesses,
|
|
1896
1934
|
...(warnings.length > 0 ? { warnings } : {})
|
|
1897
1935
|
};
|
|
1898
1936
|
}
|
|
1937
|
+
async function stopLegacyCodexPluginProcesses(warnings) {
|
|
1938
|
+
if (process.platform === "win32")
|
|
1939
|
+
return 0;
|
|
1940
|
+
try {
|
|
1941
|
+
const ps = await runLocalProcess("ps", ["-axo", "pid=,command="]);
|
|
1942
|
+
if (ps.code !== 0)
|
|
1943
|
+
return 0;
|
|
1944
|
+
let stopped = 0;
|
|
1945
|
+
for (const line of ps.stdout.split("\n")) {
|
|
1946
|
+
const match = /^\s*(\d+)\s+(.+)$/.exec(line);
|
|
1947
|
+
if (!match)
|
|
1948
|
+
continue;
|
|
1949
|
+
const pid = Number(match[1]);
|
|
1950
|
+
const command = match[2] || "";
|
|
1951
|
+
if (!isLegacyCodexPluginProcess(command))
|
|
1952
|
+
continue;
|
|
1953
|
+
try {
|
|
1954
|
+
process.kill(pid, "SIGTERM");
|
|
1955
|
+
stopped += 1;
|
|
1956
|
+
}
|
|
1957
|
+
catch (error) {
|
|
1958
|
+
warnings.push(`Could not stop legacy Codex plugin process ${pid}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
return stopped;
|
|
1962
|
+
}
|
|
1963
|
+
catch (error) {
|
|
1964
|
+
warnings.push(`Could not scan legacy Codex plugin processes: ${error instanceof Error ? error.message : String(error)}`);
|
|
1965
|
+
return 0;
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
function isLegacyCodexPluginProcess(command) {
|
|
1969
|
+
const trimmed = command.trim();
|
|
1970
|
+
return /^\/.*\/dbt-agent-mcp-bridge(?:\s|$)/.test(trimmed)
|
|
1971
|
+
|| /^dbt-agent-mcp-bridge(?:\s|$)/.test(trimmed);
|
|
1972
|
+
}
|
|
1899
1973
|
async function discoverLegacyCodexCachePaths(targetRoot) {
|
|
1900
1974
|
const paths = [];
|
|
1901
1975
|
const cacheRoot = join(targetRoot, "cache");
|
|
@@ -1913,12 +1987,18 @@ async function discoverLegacyCodexCachePaths(targetRoot) {
|
|
|
1913
1987
|
}
|
|
1914
1988
|
return paths;
|
|
1915
1989
|
}
|
|
1916
|
-
async function
|
|
1917
|
-
|
|
1990
|
+
async function cleanupLegacyCodexTextState(warnings) {
|
|
1991
|
+
let removed = 0;
|
|
1992
|
+
removed += await cleanupLegacyCodexTextFile(join(defaultCodexHome(), "history.jsonl"), warnings);
|
|
1993
|
+
removed += await cleanupLegacyCodexTextFile(join(defaultCodexHome(), "session_index.jsonl"), warnings);
|
|
1994
|
+
removed += await cleanupLegacyCodexTextFile(join(defaultCodexHome(), "rules", "default.rules"), warnings);
|
|
1995
|
+
return removed;
|
|
1996
|
+
}
|
|
1997
|
+
async function cleanupLegacyCodexTextFile(filePath, warnings) {
|
|
1918
1998
|
try {
|
|
1919
|
-
if (!await pathExists(
|
|
1999
|
+
if (!await pathExists(filePath))
|
|
1920
2000
|
return 0;
|
|
1921
|
-
const current = await readFile(
|
|
2001
|
+
const current = await readFile(filePath, "utf8");
|
|
1922
2002
|
const lines = current.split("\n");
|
|
1923
2003
|
let removed = 0;
|
|
1924
2004
|
const kept = lines.filter((line) => {
|
|
@@ -1931,12 +2011,12 @@ async function cleanupLegacyCodexHistoryMentions(warnings) {
|
|
|
1931
2011
|
return true;
|
|
1932
2012
|
});
|
|
1933
2013
|
if (removed > 0) {
|
|
1934
|
-
await writeFile(
|
|
2014
|
+
await writeFile(filePath, kept.join("\n"), "utf8");
|
|
1935
2015
|
}
|
|
1936
2016
|
return removed;
|
|
1937
2017
|
}
|
|
1938
2018
|
catch (error) {
|
|
1939
|
-
warnings.push(`Could not clean Codex legacy
|
|
2019
|
+
warnings.push(`Could not clean Codex legacy text state ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1940
2020
|
return 0;
|
|
1941
2021
|
}
|
|
1942
2022
|
}
|
|
@@ -1985,7 +2065,10 @@ function legacyCodexCleanupWarning(cleanup) {
|
|
|
1985
2065
|
parts.push(`removed ${cleanup.legacy_removed_config_tables.length} legacy Codex config table(s)`);
|
|
1986
2066
|
}
|
|
1987
2067
|
if (cleanup.legacy_removed_history_entries) {
|
|
1988
|
-
parts.push(`removed ${cleanup.legacy_removed_history_entries} legacy Codex
|
|
2068
|
+
parts.push(`removed ${cleanup.legacy_removed_history_entries} legacy Codex text-state mention(s)`);
|
|
2069
|
+
}
|
|
2070
|
+
if (cleanup.legacy_stopped_processes) {
|
|
2071
|
+
parts.push(`stopped ${cleanup.legacy_stopped_processes} legacy Codex plugin process(es)`);
|
|
1989
2072
|
}
|
|
1990
2073
|
if (cleanup.warnings?.length) {
|
|
1991
2074
|
parts.push(`cleanup warning(s): ${cleanup.warnings.join("; ")}`);
|