@amaster.ai/employee-runtime-connector 0.1.0-beta.36 → 0.1.0-beta.38
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/amaster-runtime-daemon.mjs +369 -356
- package/dist/amaster-runtime.mjs +1 -1
- package/package.json +1 -1
|
@@ -1554,19 +1554,230 @@ import { createHash as createHash2 } from "node:crypto";
|
|
|
1554
1554
|
import {
|
|
1555
1555
|
chmodSync as chmodSync2,
|
|
1556
1556
|
copyFileSync,
|
|
1557
|
-
existsSync as
|
|
1557
|
+
existsSync as existsSync3,
|
|
1558
1558
|
lstatSync as lstatSync2,
|
|
1559
|
-
mkdirSync as
|
|
1560
|
-
readFileSync as
|
|
1559
|
+
mkdirSync as mkdirSync3,
|
|
1560
|
+
readFileSync as readFileSync3,
|
|
1561
1561
|
readdirSync as readdirSync2,
|
|
1562
1562
|
rmSync as rmSync2,
|
|
1563
1563
|
statSync as statSync2,
|
|
1564
1564
|
symlinkSync,
|
|
1565
|
-
writeFileSync as
|
|
1565
|
+
writeFileSync as writeFileSync3
|
|
1566
1566
|
} from "node:fs";
|
|
1567
1567
|
import { arch as arch2, platform as platform2 } from "node:os";
|
|
1568
|
-
import { basename as basename2, dirname as
|
|
1568
|
+
import { basename as basename2, dirname as dirname3, isAbsolute as isAbsolute2, join as join4, relative as relative2, resolve as resolve2 } from "node:path";
|
|
1569
1569
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
1570
|
+
|
|
1571
|
+
// src/amaster-runtime-daemon/pi-provider-config.mjs
|
|
1572
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
1573
|
+
import { dirname as dirname2, join as join3 } from "node:path";
|
|
1574
|
+
var AMASTER_API_KEY_ENV_REFERENCE = "${AMASTER_API_KEY}";
|
|
1575
|
+
var AMASTER_BILLING_HEADER_ENV_REFERENCES = Object.freeze({
|
|
1576
|
+
"x-pi-agent-oauth-token": "${AMASTER_PLATFORM_OAUTH_TOKEN}",
|
|
1577
|
+
"x-organization-id": "${AMASTER_PLATFORM_ORGANIZATION_ID}",
|
|
1578
|
+
"x-billing-turn-id": "${AMASTER_BILLING_TURN_ID}"
|
|
1579
|
+
});
|
|
1580
|
+
var MANAGED_PI_PROVIDER_ENV_NAMES = Object.freeze([
|
|
1581
|
+
"AMASTER_MODEL_ACCESS_MODE",
|
|
1582
|
+
"AMASTER_MODEL_CREDENTIAL_REF",
|
|
1583
|
+
"AMASTER_API_KEY",
|
|
1584
|
+
"AMASTER_PROVIDER_BASE_URL",
|
|
1585
|
+
"AMASTER_PROVIDER_DEFAULT_MODEL",
|
|
1586
|
+
"AMASTER_PROVIDER_FLASH_MODEL",
|
|
1587
|
+
"AMASTER_PLATFORM_OAUTH_TOKEN",
|
|
1588
|
+
"AMASTER_PLATFORM_ORGANIZATION_ID",
|
|
1589
|
+
"AMASTER_BILLING_TURN_ID"
|
|
1590
|
+
]);
|
|
1591
|
+
var MANAGED_PI_PROVIDER_PROTECTED_ENV_NAMES = Object.freeze([
|
|
1592
|
+
"AMASTER_MODEL_CREDENTIAL_REF",
|
|
1593
|
+
"AMASTER_API_KEY",
|
|
1594
|
+
"AMASTER_PLATFORM_OAUTH_TOKEN"
|
|
1595
|
+
]);
|
|
1596
|
+
function isRecord(value) {
|
|
1597
|
+
return value && typeof value === "object" && !Array.isArray(value);
|
|
1598
|
+
}
|
|
1599
|
+
function readJsonFile(filePath) {
|
|
1600
|
+
try {
|
|
1601
|
+
const parsed = JSON.parse(readFileSync2(filePath, "utf8"));
|
|
1602
|
+
return asRecord(parsed);
|
|
1603
|
+
} catch {
|
|
1604
|
+
return {};
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
function writeJsonFileAtomic(filePath, value) {
|
|
1608
|
+
mkdirSync2(dirname2(filePath), { recursive: true });
|
|
1609
|
+
const tmpPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
1610
|
+
writeFileSync2(tmpPath, `${JSON.stringify(value, null, 2)}
|
|
1611
|
+
`, { mode: 384 });
|
|
1612
|
+
renameSync(tmpPath, filePath);
|
|
1613
|
+
}
|
|
1614
|
+
function imageGenBaseUrlFromProviderBaseUrl(value) {
|
|
1615
|
+
const input = readString(value);
|
|
1616
|
+
if (!input) return void 0;
|
|
1617
|
+
try {
|
|
1618
|
+
const url = new URL(input);
|
|
1619
|
+
const pathname = url.pathname.replace(/\/+$/, "");
|
|
1620
|
+
if (pathname.toLowerCase().endsWith("/v1")) {
|
|
1621
|
+
url.pathname = pathname.slice(0, -"/v1".length) || "/";
|
|
1622
|
+
}
|
|
1623
|
+
return url.toString();
|
|
1624
|
+
} catch {
|
|
1625
|
+
return input.replace(/\/v1\/?$/, "");
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
function ensureAmasterProviderModel(models, modelId, flash) {
|
|
1629
|
+
const id = readString(modelId);
|
|
1630
|
+
if (!id) return;
|
|
1631
|
+
const existing = Array.isArray(models) ? models : [];
|
|
1632
|
+
const index = existing.findIndex((entry) => asRecord(entry).id === id);
|
|
1633
|
+
if (index >= 0) {
|
|
1634
|
+
existing[index] = {
|
|
1635
|
+
...asRecord(existing[index]),
|
|
1636
|
+
id,
|
|
1637
|
+
input: readStringArray(asRecord(existing[index]).input).length > 0 ? asRecord(existing[index]).input : ["text", "image"],
|
|
1638
|
+
reasoning: asRecord(existing[index]).reasoning ?? true,
|
|
1639
|
+
...flash ? { flash: true } : {}
|
|
1640
|
+
};
|
|
1641
|
+
return;
|
|
1642
|
+
}
|
|
1643
|
+
existing.push({
|
|
1644
|
+
id,
|
|
1645
|
+
input: ["text", "image"],
|
|
1646
|
+
reasoning: true,
|
|
1647
|
+
...flash ? { flash: true } : {}
|
|
1648
|
+
});
|
|
1649
|
+
}
|
|
1650
|
+
function withoutManagedBillingHeaders(value) {
|
|
1651
|
+
const headers = { ...asRecord(value) };
|
|
1652
|
+
for (const name of Object.keys(AMASTER_BILLING_HEADER_ENV_REFERENCES)) {
|
|
1653
|
+
delete headers[name];
|
|
1654
|
+
}
|
|
1655
|
+
return headers;
|
|
1656
|
+
}
|
|
1657
|
+
function syncManagedBillingHeaders(value, executorEnv) {
|
|
1658
|
+
const headers = withoutManagedBillingHeaders(value);
|
|
1659
|
+
if (readString(executorEnv.AMASTER_MODEL_ACCESS_MODE) === "billing_gateway") {
|
|
1660
|
+
Object.assign(headers, AMASTER_BILLING_HEADER_ENV_REFERENCES);
|
|
1661
|
+
}
|
|
1662
|
+
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
1663
|
+
}
|
|
1664
|
+
function managedApiKeyConfigValue(executorEnv, apiKey) {
|
|
1665
|
+
return readString(executorEnv.AMASTER_MODEL_ACCESS_MODE) === "billing_gateway" ? AMASTER_API_KEY_ENV_REFERENCE : apiKey;
|
|
1666
|
+
}
|
|
1667
|
+
function syncAmasterProviderModels(agentDir, executorEnv) {
|
|
1668
|
+
const apiKey = readString(executorEnv.AMASTER_API_KEY);
|
|
1669
|
+
if (!apiKey) return false;
|
|
1670
|
+
const modelsPath = join3(agentDir, "models.json");
|
|
1671
|
+
const config = readJsonFile(modelsPath);
|
|
1672
|
+
const providers = asRecord(config.providers);
|
|
1673
|
+
const amaster = { ...asRecord(providers.amaster) };
|
|
1674
|
+
amaster.apiKey = managedApiKeyConfigValue(executorEnv, apiKey);
|
|
1675
|
+
const baseUrl = readString(executorEnv.AMASTER_PROVIDER_BASE_URL);
|
|
1676
|
+
if (baseUrl) amaster.baseUrl = baseUrl;
|
|
1677
|
+
if (!readString(amaster.api)) amaster.api = "openai-completions";
|
|
1678
|
+
const headers = syncManagedBillingHeaders(amaster.headers, executorEnv);
|
|
1679
|
+
if (headers) amaster.headers = headers;
|
|
1680
|
+
else delete amaster.headers;
|
|
1681
|
+
const models = Array.isArray(amaster.models) ? [...amaster.models] : [];
|
|
1682
|
+
ensureAmasterProviderModel(models, executorEnv.AMASTER_PROVIDER_DEFAULT_MODEL, false);
|
|
1683
|
+
ensureAmasterProviderModel(models, executorEnv.AMASTER_PROVIDER_FLASH_MODEL, true);
|
|
1684
|
+
if (models.length > 0) amaster.models = models;
|
|
1685
|
+
writeJsonFileAtomic(modelsPath, {
|
|
1686
|
+
...config,
|
|
1687
|
+
providers: {
|
|
1688
|
+
...providers,
|
|
1689
|
+
amaster
|
|
1690
|
+
}
|
|
1691
|
+
});
|
|
1692
|
+
return true;
|
|
1693
|
+
}
|
|
1694
|
+
function syncAmasterProviderSettings(agentDir, executorEnv) {
|
|
1695
|
+
const apiKey = readString(executorEnv.AMASTER_API_KEY);
|
|
1696
|
+
if (!apiKey) return false;
|
|
1697
|
+
const settingsPath = join3(agentDir, "settings.json");
|
|
1698
|
+
if (!existsSync2(settingsPath)) return false;
|
|
1699
|
+
const settings = readJsonFile(settingsPath);
|
|
1700
|
+
const baseUrl = readString(executorEnv.AMASTER_PROVIDER_BASE_URL);
|
|
1701
|
+
const defaultModel = readString(executorEnv.AMASTER_PROVIDER_DEFAULT_MODEL);
|
|
1702
|
+
const imageGenBaseUrl = imageGenBaseUrlFromProviderBaseUrl(baseUrl);
|
|
1703
|
+
let changed = false;
|
|
1704
|
+
if (defaultModel) {
|
|
1705
|
+
if (settings.defaultProvider !== "amaster") {
|
|
1706
|
+
settings.defaultProvider = "amaster";
|
|
1707
|
+
changed = true;
|
|
1708
|
+
}
|
|
1709
|
+
if (settings.defaultModel !== defaultModel) {
|
|
1710
|
+
settings.defaultModel = defaultModel;
|
|
1711
|
+
changed = true;
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
const imageGen = settings["pi-image-gen"];
|
|
1715
|
+
if (isRecord(imageGen) && isRecord(imageGen.customProviders) && isRecord(imageGen.customProviders.amaster)) {
|
|
1716
|
+
const customProviders = imageGen.customProviders;
|
|
1717
|
+
const imageGenAmaster = { ...asRecord(customProviders.amaster) };
|
|
1718
|
+
const managedApiKey = managedApiKeyConfigValue(executorEnv, apiKey);
|
|
1719
|
+
if (imageGenAmaster.apiKey !== managedApiKey) {
|
|
1720
|
+
imageGenAmaster.apiKey = managedApiKey;
|
|
1721
|
+
changed = true;
|
|
1722
|
+
}
|
|
1723
|
+
if (imageGenBaseUrl && imageGenAmaster.baseUrl !== imageGenBaseUrl) {
|
|
1724
|
+
imageGenAmaster.baseUrl = imageGenBaseUrl;
|
|
1725
|
+
changed = true;
|
|
1726
|
+
}
|
|
1727
|
+
const imageGenHeaders = syncManagedBillingHeaders(imageGenAmaster.headers, executorEnv);
|
|
1728
|
+
if (JSON.stringify(imageGenHeaders) !== JSON.stringify(imageGenAmaster.headers)) {
|
|
1729
|
+
if (imageGenHeaders) imageGenAmaster.headers = imageGenHeaders;
|
|
1730
|
+
else delete imageGenAmaster.headers;
|
|
1731
|
+
changed = true;
|
|
1732
|
+
}
|
|
1733
|
+
settings["pi-image-gen"] = {
|
|
1734
|
+
...asRecord(imageGen),
|
|
1735
|
+
customProviders: {
|
|
1736
|
+
...customProviders,
|
|
1737
|
+
amaster: imageGenAmaster
|
|
1738
|
+
}
|
|
1739
|
+
};
|
|
1740
|
+
}
|
|
1741
|
+
const webAccess = settings["pi-web-access"];
|
|
1742
|
+
if (isRecord(webAccess) && isRecord(webAccess.providers)) {
|
|
1743
|
+
const webProviders = webAccess.providers;
|
|
1744
|
+
const nextWebProviders = { ...webProviders };
|
|
1745
|
+
for (const [name, rawProvider] of Object.entries(webProviders)) {
|
|
1746
|
+
if (!isRecord(rawProvider)) continue;
|
|
1747
|
+
const providerApiKey = readString(rawProvider.apiKey);
|
|
1748
|
+
const providerBaseUrl = readString(rawProvider.baseUrl);
|
|
1749
|
+
const looksAmasterBacked = name === "amaster" || name === "kimi" || providerApiKey === "${AMASTER_API_KEY}" || providerApiKey === "AMASTER_API_KEY" || providerBaseUrl?.includes("credits.helige") || providerBaseUrl?.includes("credits.amaster");
|
|
1750
|
+
if (!looksAmasterBacked) continue;
|
|
1751
|
+
const nextProvider = {
|
|
1752
|
+
...rawProvider,
|
|
1753
|
+
apiKey: managedApiKeyConfigValue(executorEnv, apiKey),
|
|
1754
|
+
...baseUrl ? { baseUrl } : {}
|
|
1755
|
+
};
|
|
1756
|
+
const webAccessHeaders = syncManagedBillingHeaders(rawProvider.headers, executorEnv);
|
|
1757
|
+
if (webAccessHeaders) nextProvider.headers = webAccessHeaders;
|
|
1758
|
+
else delete nextProvider.headers;
|
|
1759
|
+
if (JSON.stringify(nextProvider) !== JSON.stringify(rawProvider)) {
|
|
1760
|
+
nextWebProviders[name] = nextProvider;
|
|
1761
|
+
changed = true;
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
settings["pi-web-access"] = {
|
|
1765
|
+
...asRecord(webAccess),
|
|
1766
|
+
providers: nextWebProviders
|
|
1767
|
+
};
|
|
1768
|
+
}
|
|
1769
|
+
if (!changed) return false;
|
|
1770
|
+
writeJsonFileAtomic(settingsPath, settings);
|
|
1771
|
+
return true;
|
|
1772
|
+
}
|
|
1773
|
+
function syncAmasterProviderFiles(agentDir, executorEnv) {
|
|
1774
|
+
return {
|
|
1775
|
+
modelsSynced: syncAmasterProviderModels(agentDir, executorEnv),
|
|
1776
|
+
settingsSynced: syncAmasterProviderSettings(agentDir, executorEnv)
|
|
1777
|
+
};
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
// src/amaster-runtime-daemon/pi-managed-mcp-profile.mjs
|
|
1570
1781
|
var piManagedMcpProfileApi = (() => {
|
|
1571
1782
|
const SUPPORTED_SCHEMA_VERSION2 = "amaster.governed-mcp.v1";
|
|
1572
1783
|
const SUPPORTED_SERVER_NAME2 = "amaster";
|
|
@@ -1600,12 +1811,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1600
1811
|
"AMASTER-CLI_CODING_AGENT_SESSION_DIR",
|
|
1601
1812
|
"PI_AGENT_MCP_SERVERS_FILE"
|
|
1602
1813
|
]);
|
|
1603
|
-
const ALLOWED_COMMAND_ENV2 =
|
|
1604
|
-
"AMASTER_API_KEY",
|
|
1605
|
-
"AMASTER_PROVIDER_BASE_URL",
|
|
1606
|
-
"AMASTER_PROVIDER_DEFAULT_MODEL",
|
|
1607
|
-
"AMASTER_PROVIDER_FLASH_MODEL"
|
|
1608
|
-
]);
|
|
1814
|
+
const ALLOWED_COMMAND_ENV2 = new Set(MANAGED_PI_PROVIDER_ENV_NAMES);
|
|
1609
1815
|
const SAFE_INHERITED_ENV2 = /* @__PURE__ */ new Set([
|
|
1610
1816
|
"PATH",
|
|
1611
1817
|
"LANG",
|
|
@@ -1666,13 +1872,13 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1666
1872
|
return rel === "" || !rel.startsWith("..") && !isAbsolute2(rel);
|
|
1667
1873
|
}
|
|
1668
1874
|
function writePrivateFile2(filePath, contents) {
|
|
1669
|
-
|
|
1875
|
+
writeFileSync3(filePath, contents, { mode: 384, flag: "wx" });
|
|
1670
1876
|
chmodSync2(filePath, 384);
|
|
1671
1877
|
const mode = statSync2(filePath).mode & 511;
|
|
1672
1878
|
if (mode !== 384) throw new Error(`pi_managed_mcp_permissions_failed: ${filePath} mode=${mode.toString(8)}`);
|
|
1673
1879
|
}
|
|
1674
1880
|
function copyPrivateFile(source, target) {
|
|
1675
|
-
if (!
|
|
1881
|
+
if (!existsSync3(source)) return false;
|
|
1676
1882
|
const sourceStat = lstatSync2(source);
|
|
1677
1883
|
if (!sourceStat.isFile() || sourceStat.isSymbolicLink()) {
|
|
1678
1884
|
throw new Error(`pi_managed_mcp_source_config_unsafe: ${source}`);
|
|
@@ -1682,7 +1888,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1682
1888
|
return true;
|
|
1683
1889
|
}
|
|
1684
1890
|
function findPiSessionRollout(sessionsRoot, sessionId) {
|
|
1685
|
-
if (!
|
|
1891
|
+
if (!existsSync3(sessionsRoot)) return null;
|
|
1686
1892
|
const matches = [];
|
|
1687
1893
|
const pending = [sessionsRoot];
|
|
1688
1894
|
while (pending.length > 0) {
|
|
@@ -1692,7 +1898,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1692
1898
|
throw new Error("pi_managed_mcp_session_rollout_unsafe: sessions path is not a private directory");
|
|
1693
1899
|
}
|
|
1694
1900
|
for (const entry of readdirSync2(current, { withFileTypes: true })) {
|
|
1695
|
-
const candidate =
|
|
1901
|
+
const candidate = join4(current, entry.name);
|
|
1696
1902
|
if (entry.isSymbolicLink()) throw new Error("pi_managed_mcp_session_rollout_unsafe: symlinks are forbidden");
|
|
1697
1903
|
if (entry.isDirectory()) pending.push(candidate);
|
|
1698
1904
|
else if (entry.isFile() && entry.name.endsWith(`_${sessionId}.jsonl`)) matches.push(candidate);
|
|
@@ -1712,18 +1918,18 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1712
1918
|
nonEmpty2(session.actionRequestId, "nativeSession.actionRequestId");
|
|
1713
1919
|
nonEmpty2(session.invocationId, "nativeSession.invocationId");
|
|
1714
1920
|
const sourceWorkspacePath = nonEmpty2(session.cwd, "nativeSession.cwd");
|
|
1715
|
-
const issueRoot =
|
|
1921
|
+
const issueRoot = dirname3(runDir);
|
|
1716
1922
|
const managedSourceRunDirName = `${sourceRunId}-${createHash2("sha256").update(sourceRunId).digest("hex").slice(0, 8)}`;
|
|
1717
|
-
const sourceRunDirs = readdirSync2(issueRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.isSymbolicLink() && (entry.name === sourceRunId || entry.name === managedSourceRunDirName)).map((entry) =>
|
|
1923
|
+
const sourceRunDirs = readdirSync2(issueRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.isSymbolicLink() && (entry.name === sourceRunId || entry.name === managedSourceRunDirName)).map((entry) => join4(issueRoot, entry.name));
|
|
1718
1924
|
if (sourceRunDirs.length !== 1) {
|
|
1719
1925
|
throw new Error(`pi_managed_mcp_session_rollout_missing: expected one source run directory for ${sourceRunId}, received ${sourceRunDirs.length}`);
|
|
1720
1926
|
}
|
|
1721
|
-
const cacheRoot =
|
|
1722
|
-
const markerPath =
|
|
1723
|
-
if (!
|
|
1927
|
+
const cacheRoot = join4(sourceRunDirs[0], relative2(runDir, executorHome), "session-rollout");
|
|
1928
|
+
const markerPath = join4(cacheRoot, SESSION_ROLLOUT_MARKER2);
|
|
1929
|
+
if (!existsSync3(markerPath) || lstatSync2(markerPath).isSymbolicLink() || !lstatSync2(markerPath).isFile()) {
|
|
1724
1930
|
throw new Error("pi_managed_mcp_session_rollout_missing: source rollout marker is unavailable");
|
|
1725
1931
|
}
|
|
1726
|
-
const marker = JSON.parse(
|
|
1932
|
+
const marker = JSON.parse(readFileSync3(markerPath, "utf8"));
|
|
1727
1933
|
if (marker?.version !== 1 || marker?.companyId !== authority.companyId || marker?.agentId !== authority.agentId || marker?.issueId !== authority.issueId || marker?.sourceRunId !== sourceRunId || marker?.sourceCommandId !== sourceCommandId || marker?.sessionId !== sessionId || marker?.sourceWorkspacePath !== sourceWorkspacePath) {
|
|
1728
1934
|
throw new Error("pi_managed_mcp_session_rollout_authority_mismatch: source rollout does not match the approved continuation");
|
|
1729
1935
|
}
|
|
@@ -1735,8 +1941,8 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1735
1941
|
if (!within3(targetRollout, sessionsRoot)) {
|
|
1736
1942
|
throw new Error("pi_managed_mcp_session_rollout_unsafe: target rollout path is invalid");
|
|
1737
1943
|
}
|
|
1738
|
-
|
|
1739
|
-
writePrivateFile2(targetRollout,
|
|
1944
|
+
mkdirSync3(dirname3(targetRollout), { recursive: true, mode: 448 });
|
|
1945
|
+
writePrivateFile2(targetRollout, readFileSync3(sourceRollout));
|
|
1740
1946
|
return { sessionId, sourceRunId, sourceCommandId, rolloutPath: targetRollout, cacheRoot };
|
|
1741
1947
|
}
|
|
1742
1948
|
function parseVersion(stdout, label, minimum) {
|
|
@@ -1835,10 +2041,10 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1835
2041
|
return { ...env, ...record3(commandEnv) };
|
|
1836
2042
|
}
|
|
1837
2043
|
function projectMcpConfigHasContent(filePath) {
|
|
1838
|
-
if (!
|
|
2044
|
+
if (!existsSync3(filePath)) return false;
|
|
1839
2045
|
let parsed;
|
|
1840
2046
|
try {
|
|
1841
|
-
parsed = JSON.parse(
|
|
2047
|
+
parsed = JSON.parse(readFileSync3(filePath, "utf8"));
|
|
1842
2048
|
} catch {
|
|
1843
2049
|
return true;
|
|
1844
2050
|
}
|
|
@@ -1850,12 +2056,12 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1850
2056
|
const boundary = resolve2(runDir);
|
|
1851
2057
|
if (!within3(cursor, boundary)) throw new Error("pi_managed_mcp_owner_mismatch: cwd is outside the managed run");
|
|
1852
2058
|
while (within3(cursor, boundary)) {
|
|
1853
|
-
for (const relativePath of [".mcp.json",
|
|
1854
|
-
const configPath =
|
|
2059
|
+
for (const relativePath of [".mcp.json", join4(".pi", "mcp.json")]) {
|
|
2060
|
+
const configPath = join4(cursor, relativePath);
|
|
1855
2061
|
if (projectMcpConfigHasContent(configPath)) throw new Error(`pi_managed_mcp_project_override_blocked: ${configPath}`);
|
|
1856
2062
|
}
|
|
1857
2063
|
if (cursor === boundary) break;
|
|
1858
|
-
cursor =
|
|
2064
|
+
cursor = dirname3(cursor);
|
|
1859
2065
|
}
|
|
1860
2066
|
}
|
|
1861
2067
|
function selectManagedBrowserUse(sourceSettings, npmSource) {
|
|
@@ -1863,13 +2069,13 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1863
2069
|
if (plugin.enabled !== true || plugin.package !== MANAGED_BROWSER_USE_PACKAGE) return null;
|
|
1864
2070
|
const packageSpec = Array.isArray(sourceSettings.packages) ? sourceSettings.packages.find((entry) => npmPackageName(entry) === MANAGED_BROWSER_USE_PACKAGE) : null;
|
|
1865
2071
|
if (typeof packageSpec !== "string") return null;
|
|
1866
|
-
const packagePath =
|
|
1867
|
-
if (!
|
|
2072
|
+
const packagePath = join4(npmSource, "node_modules", ...MANAGED_BROWSER_USE_PACKAGE.split("/"), "package.json");
|
|
2073
|
+
if (!existsSync3(packagePath) || lstatSync2(packagePath).isSymbolicLink() || !lstatSync2(packagePath).isFile()) {
|
|
1868
2074
|
throw new Error(`pi_managed_mcp_attestation_failed: enabled ${MANAGED_BROWSER_USE_PACKAGE} package is unavailable`);
|
|
1869
2075
|
}
|
|
1870
2076
|
let packageMetadata;
|
|
1871
2077
|
try {
|
|
1872
|
-
packageMetadata = JSON.parse(
|
|
2078
|
+
packageMetadata = JSON.parse(readFileSync3(packagePath, "utf8"));
|
|
1873
2079
|
} catch {
|
|
1874
2080
|
throw new Error(`pi_managed_mcp_attestation_failed: enabled ${MANAGED_BROWSER_USE_PACKAGE} package metadata is invalid`);
|
|
1875
2081
|
}
|
|
@@ -1904,23 +2110,23 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1904
2110
|
}
|
|
1905
2111
|
function seedPiRuntime(sourceHome, agentDir) {
|
|
1906
2112
|
const source = resolve2(nonEmpty2(sourceHome, "sourcePiHome"));
|
|
1907
|
-
const npmSource =
|
|
1908
|
-
const adapterPackagePath =
|
|
1909
|
-
if (!
|
|
2113
|
+
const npmSource = join4(source, "npm");
|
|
2114
|
+
const adapterPackagePath = join4(npmSource, "node_modules", "pi-mcp-adapter", "package.json");
|
|
2115
|
+
if (!existsSync3(adapterPackagePath) || lstatSync2(adapterPackagePath).isSymbolicLink()) {
|
|
1910
2116
|
throw new Error("pi_managed_mcp_attestation_failed: pi-mcp-adapter package is unavailable");
|
|
1911
2117
|
}
|
|
1912
2118
|
let adapterPackage;
|
|
1913
2119
|
try {
|
|
1914
|
-
adapterPackage = JSON.parse(
|
|
2120
|
+
adapterPackage = JSON.parse(readFileSync3(adapterPackagePath, "utf8"));
|
|
1915
2121
|
} catch {
|
|
1916
2122
|
throw new Error("pi_managed_mcp_attestation_failed: pi-mcp-adapter package metadata is invalid");
|
|
1917
2123
|
}
|
|
1918
2124
|
const adapterVersion = parseVersion(adapterPackage.version, "pi-mcp-adapter", MINIMUM_MCP_ADAPTER_VERSION);
|
|
1919
|
-
const settingsSource =
|
|
2125
|
+
const settingsSource = join4(source, "settings.json");
|
|
1920
2126
|
let sourceSettings = {};
|
|
1921
|
-
if (
|
|
2127
|
+
if (existsSync3(settingsSource)) {
|
|
1922
2128
|
try {
|
|
1923
|
-
sourceSettings = record3(JSON.parse(
|
|
2129
|
+
sourceSettings = record3(JSON.parse(readFileSync3(settingsSource, "utf8")));
|
|
1924
2130
|
} catch {
|
|
1925
2131
|
throw new Error("pi_managed_mcp_attestation_failed: source Pi settings are invalid");
|
|
1926
2132
|
}
|
|
@@ -1937,21 +2143,21 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1937
2143
|
"pi-browser-use": browserUse.config
|
|
1938
2144
|
} : {}
|
|
1939
2145
|
};
|
|
1940
|
-
writePrivateFile2(
|
|
2146
|
+
writePrivateFile2(join4(agentDir, "settings.json"), `${JSON.stringify(settings, null, 2)}
|
|
1941
2147
|
`);
|
|
1942
|
-
copyPrivateFile(
|
|
1943
|
-
const authSource =
|
|
2148
|
+
copyPrivateFile(join4(source, "models.json"), join4(agentDir, "models.json"));
|
|
2149
|
+
const authSource = join4(source, "auth.json");
|
|
1944
2150
|
const protectedValues = [];
|
|
1945
|
-
if (copyPrivateFile(authSource,
|
|
2151
|
+
if (copyPrivateFile(authSource, join4(agentDir, "auth.json"))) {
|
|
1946
2152
|
try {
|
|
1947
|
-
collectAuthSecretStrings2(JSON.parse(
|
|
2153
|
+
collectAuthSecretStrings2(JSON.parse(readFileSync3(authSource, "utf8")), protectedValues);
|
|
1948
2154
|
} catch {
|
|
1949
2155
|
throw new Error("pi_managed_mcp_attestation_failed: source Pi auth is invalid");
|
|
1950
2156
|
}
|
|
1951
2157
|
}
|
|
1952
2158
|
const npmStat = lstatSync2(npmSource);
|
|
1953
2159
|
if (!npmStat.isDirectory() || npmStat.isSymbolicLink()) throw new Error("pi_managed_mcp_source_config_unsafe: Pi npm root");
|
|
1954
|
-
symlinkSync(npmSource,
|
|
2160
|
+
symlinkSync(npmSource, join4(agentDir, "npm"), "dir");
|
|
1955
2161
|
return { adapterVersion, protectedValues };
|
|
1956
2162
|
}
|
|
1957
2163
|
function attestPi(executorCommand, env, configPath, expectedConfig) {
|
|
@@ -1969,7 +2175,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1969
2175
|
${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
1970
2176
|
let effectiveConfig;
|
|
1971
2177
|
try {
|
|
1972
|
-
effectiveConfig = JSON.parse(
|
|
2178
|
+
effectiveConfig = JSON.parse(readFileSync3(configPath, "utf8"));
|
|
1973
2179
|
} catch {
|
|
1974
2180
|
throw new Error("pi_managed_mcp_attestation_failed: managed MCP config is invalid JSON");
|
|
1975
2181
|
}
|
|
@@ -1983,18 +2189,18 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
1983
2189
|
const { gateway, gatewayUrl, sessionToken, headers, runId } = validateAuthority2(input);
|
|
1984
2190
|
const runDir = resolve2(nonEmpty2(input.runDir, "runDir"));
|
|
1985
2191
|
const executorHome = resolve2(nonEmpty2(input.executorHome, "executorHome"));
|
|
1986
|
-
if (!within3(executorHome,
|
|
2192
|
+
if (!within3(executorHome, join4(runDir, "executors"))) throw new Error("pi_managed_mcp_owner_mismatch: executorHome is outside the managed run");
|
|
1987
2193
|
assertNoProjectMcpOverride(nonEmpty2(input.cwd, "cwd"), runDir);
|
|
1988
|
-
const profileRoot =
|
|
1989
|
-
if (
|
|
1990
|
-
const home =
|
|
1991
|
-
const piAgentHome =
|
|
1992
|
-
const piCodingAgentDir =
|
|
1993
|
-
const sessionsRoot =
|
|
1994
|
-
const tmp =
|
|
1995
|
-
for (const directory of [home, piAgentHome, piCodingAgentDir, sessionsRoot, tmp])
|
|
2194
|
+
const profileRoot = join4(executorHome, "managed-mcp");
|
|
2195
|
+
if (existsSync3(profileRoot)) throw new Error(`pi_managed_mcp_profile_exists: ${profileRoot}`);
|
|
2196
|
+
const home = join4(profileRoot, "home");
|
|
2197
|
+
const piAgentHome = join4(profileRoot, "pi-agent-home");
|
|
2198
|
+
const piCodingAgentDir = join4(profileRoot, "pi-coding-agent-dir");
|
|
2199
|
+
const sessionsRoot = join4(piCodingAgentDir, "sessions");
|
|
2200
|
+
const tmp = join4(profileRoot, "tmp");
|
|
2201
|
+
for (const directory of [home, piAgentHome, piCodingAgentDir, sessionsRoot, tmp]) mkdirSync3(directory, { recursive: true, mode: 448 });
|
|
1996
2202
|
try {
|
|
1997
|
-
const markerPath =
|
|
2203
|
+
const markerPath = join4(profileRoot, PROFILE_MARKER2);
|
|
1998
2204
|
const owner = Object.freeze({ commandId: input.commandId, runId });
|
|
1999
2205
|
writePrivateFile2(markerPath, `${JSON.stringify({ version: 1, ...owner, profileRoot })}
|
|
2000
2206
|
`);
|
|
@@ -2009,7 +2215,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2009
2215
|
const sourcePiHome = nonEmpty2(input.baseEnv?.PI_CODING_AGENT_DIR ?? input.baseEnv?.PI_AGENT_HOME, "sourcePiHome");
|
|
2010
2216
|
const seededRuntime = seedPiRuntime(sourcePiHome, piCodingAgentDir);
|
|
2011
2217
|
const restoredNativeSession = restoreManagedPiSessionRollout(input, sessionsRoot, runDir, executorHome, authority);
|
|
2012
|
-
const configPath =
|
|
2218
|
+
const configPath = join4(piCodingAgentDir, "mcp.json");
|
|
2013
2219
|
const config = {
|
|
2014
2220
|
mcpServers: {
|
|
2015
2221
|
[SUPPORTED_SERVER_NAME2]: {
|
|
@@ -2059,7 +2265,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2059
2265
|
protectedValues: [.../* @__PURE__ */ new Set([
|
|
2060
2266
|
sessionToken,
|
|
2061
2267
|
...seededRuntime.protectedValues,
|
|
2062
|
-
...
|
|
2268
|
+
...MANAGED_PI_PROVIDER_PROTECTED_ENV_NAMES.map((name) => input.commandEnv?.[name]).filter((value) => typeof value === "string" && value.length > 0)
|
|
2063
2269
|
])],
|
|
2064
2270
|
attestation: {
|
|
2065
2271
|
...attestationFacts,
|
|
@@ -2081,13 +2287,13 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2081
2287
|
if (!rolloutRelativePath || rolloutRelativePath.startsWith("..") || isAbsolute2(rolloutRelativePath)) {
|
|
2082
2288
|
throw new Error("pi_managed_mcp_session_rollout_unsafe: rollout escaped the managed Pi home");
|
|
2083
2289
|
}
|
|
2084
|
-
const cacheRoot =
|
|
2085
|
-
if (
|
|
2086
|
-
|
|
2087
|
-
const targetRollout =
|
|
2088
|
-
|
|
2089
|
-
writePrivateFile2(targetRollout,
|
|
2090
|
-
writePrivateFile2(
|
|
2290
|
+
const cacheRoot = join4(dirname3(resolve2(profile.profileRoot)), "session-rollout");
|
|
2291
|
+
if (existsSync3(cacheRoot)) rmSync2(cacheRoot, { recursive: true, force: false });
|
|
2292
|
+
mkdirSync3(cacheRoot, { recursive: true, mode: 448 });
|
|
2293
|
+
const targetRollout = join4(cacheRoot, rolloutRelativePath);
|
|
2294
|
+
mkdirSync3(dirname3(targetRollout), { recursive: true, mode: 448 });
|
|
2295
|
+
writePrivateFile2(targetRollout, readFileSync3(sourceRollout));
|
|
2296
|
+
writePrivateFile2(join4(cacheRoot, SESSION_ROLLOUT_MARKER2), `${JSON.stringify({
|
|
2091
2297
|
version: 1,
|
|
2092
2298
|
cacheRoot,
|
|
2093
2299
|
preservedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -2105,19 +2311,19 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2105
2311
|
}
|
|
2106
2312
|
function cleanupManagedPiMcpProfile2(profile, owner) {
|
|
2107
2313
|
const profileRoot = resolve2(nonEmpty2(profile?.profileRoot, "profileRoot"));
|
|
2108
|
-
if (!
|
|
2314
|
+
if (!existsSync3(profileRoot)) return { status: "already_removed", profileRoot };
|
|
2109
2315
|
const rootStat = lstatSync2(profileRoot);
|
|
2110
2316
|
if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) {
|
|
2111
2317
|
throw new Error("pi_managed_mcp_cleanup_owner_mismatch: profile root is not an owned directory");
|
|
2112
2318
|
}
|
|
2113
|
-
const markerPath =
|
|
2114
|
-
const markerStat =
|
|
2319
|
+
const markerPath = join4(profileRoot, PROFILE_MARKER2);
|
|
2320
|
+
const markerStat = existsSync3(markerPath) ? lstatSync2(markerPath) : null;
|
|
2115
2321
|
if (!markerStat?.isFile() || markerStat.isSymbolicLink()) {
|
|
2116
2322
|
throw new Error("pi_managed_mcp_cleanup_owner_mismatch: ownership marker is missing or unsafe");
|
|
2117
2323
|
}
|
|
2118
2324
|
let marker;
|
|
2119
2325
|
try {
|
|
2120
|
-
marker = JSON.parse(
|
|
2326
|
+
marker = JSON.parse(readFileSync3(markerPath, "utf8"));
|
|
2121
2327
|
} catch {
|
|
2122
2328
|
throw new Error("pi_managed_mcp_cleanup_owner_mismatch: ownership marker is invalid");
|
|
2123
2329
|
}
|
|
@@ -2125,12 +2331,12 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2125
2331
|
throw new Error("pi_managed_mcp_cleanup_owner_mismatch: ownership marker does not match command/run");
|
|
2126
2332
|
}
|
|
2127
2333
|
rmSync2(profileRoot, { recursive: true, force: false });
|
|
2128
|
-
if (
|
|
2334
|
+
if (existsSync3(profileRoot)) throw new Error("pi_managed_mcp_cleanup_failed: profile root still exists");
|
|
2129
2335
|
return { status: "removed", profileRoot };
|
|
2130
2336
|
}
|
|
2131
2337
|
function reconcileManagedPiMcpProfiles2(rootPath, options = {}) {
|
|
2132
2338
|
const root = resolve2(rootPath);
|
|
2133
|
-
if (!
|
|
2339
|
+
if (!existsSync3(root)) return { scanned: 0, removed: 0, removedProfiles: 0, removedRollouts: 0, failed: 0, failures: [] };
|
|
2134
2340
|
const profileMarkers = [];
|
|
2135
2341
|
const rolloutMarkers = [];
|
|
2136
2342
|
const pending = [root];
|
|
@@ -2139,7 +2345,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2139
2345
|
const currentStat = lstatSync2(current);
|
|
2140
2346
|
if (!currentStat.isDirectory() || currentStat.isSymbolicLink()) continue;
|
|
2141
2347
|
for (const entry of readdirSync2(current, { withFileTypes: true })) {
|
|
2142
|
-
const fullPath =
|
|
2348
|
+
const fullPath = join4(current, entry.name);
|
|
2143
2349
|
if (entry.isDirectory() && !entry.isSymbolicLink()) pending.push(fullPath);
|
|
2144
2350
|
else if (entry.isFile() && entry.name === PROFILE_MARKER2) profileMarkers.push(fullPath);
|
|
2145
2351
|
else if (entry.isFile() && entry.name === SESSION_ROLLOUT_MARKER2) rolloutMarkers.push(fullPath);
|
|
@@ -2149,9 +2355,9 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2149
2355
|
let removedRollouts = 0;
|
|
2150
2356
|
const failures = [];
|
|
2151
2357
|
for (const markerPath of profileMarkers) {
|
|
2152
|
-
const profileRoot =
|
|
2358
|
+
const profileRoot = dirname3(markerPath);
|
|
2153
2359
|
try {
|
|
2154
|
-
const marker = JSON.parse(
|
|
2360
|
+
const marker = JSON.parse(readFileSync3(markerPath, "utf8"));
|
|
2155
2361
|
if (!within3(profileRoot, root) || marker?.profileRoot !== profileRoot) throw new Error("ownership marker root mismatch");
|
|
2156
2362
|
cleanupManagedPiMcpProfile2({ profileRoot }, { commandId: marker.commandId, runId: marker.runId });
|
|
2157
2363
|
removedProfiles += 1;
|
|
@@ -2162,17 +2368,17 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2162
2368
|
const nowMs = Number.isFinite(options.nowMs) ? options.nowMs : Date.now();
|
|
2163
2369
|
const rolloutTtlMs = Number.isFinite(options.sessionRolloutTtlMs) && options.sessionRolloutTtlMs > 0 ? options.sessionRolloutTtlMs : DEFAULT_SESSION_ROLLOUT_TTL_MS2;
|
|
2164
2370
|
for (const markerPath of rolloutMarkers) {
|
|
2165
|
-
const cacheRoot =
|
|
2371
|
+
const cacheRoot = dirname3(markerPath);
|
|
2166
2372
|
try {
|
|
2167
2373
|
const markerStat = lstatSync2(markerPath);
|
|
2168
2374
|
const cacheStat = lstatSync2(cacheRoot);
|
|
2169
|
-
const marker = JSON.parse(
|
|
2375
|
+
const marker = JSON.parse(readFileSync3(markerPath, "utf8"));
|
|
2170
2376
|
if (!within3(cacheRoot, root) || basename2(cacheRoot) !== "session-rollout" || markerStat.isSymbolicLink() || !markerStat.isFile() || cacheStat.isSymbolicLink() || !cacheStat.isDirectory() || marker?.version !== 1 || typeof marker?.companyId !== "string" || typeof marker?.agentId !== "string" || typeof marker?.sourceRunId !== "string" || typeof marker?.sourceCommandId !== "string" || typeof marker?.sessionId !== "string" || marker?.cacheRoot !== cacheRoot) throw new Error("session rollout ownership marker mismatch");
|
|
2171
2377
|
const preservedAtMs = typeof marker.preservedAt === "string" ? Date.parse(marker.preservedAt) : Number.NaN;
|
|
2172
2378
|
const markerAgeMs = nowMs - (Number.isFinite(preservedAtMs) ? preservedAtMs : markerStat.mtimeMs);
|
|
2173
2379
|
if (markerAgeMs < rolloutTtlMs) continue;
|
|
2174
2380
|
rmSync2(cacheRoot, { recursive: true, force: false });
|
|
2175
|
-
if (
|
|
2381
|
+
if (existsSync3(cacheRoot)) throw new Error("session rollout cache still exists");
|
|
2176
2382
|
removedRollouts += 1;
|
|
2177
2383
|
} catch (error) {
|
|
2178
2384
|
failures.push({ profileRoot: cacheRoot, error: error instanceof Error ? error.message : String(error) });
|
|
@@ -2575,9 +2781,9 @@ function compileCommandPromptWithManifest(input, options = {}) {
|
|
|
2575
2781
|
}
|
|
2576
2782
|
|
|
2577
2783
|
// src/amaster-runtime-daemon/config-state.mjs
|
|
2578
|
-
import { existsSync as
|
|
2784
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "node:fs";
|
|
2579
2785
|
import { homedir as homedir2, hostname } from "node:os";
|
|
2580
|
-
import { dirname as
|
|
2786
|
+
import { dirname as dirname4, join as join5 } from "node:path";
|
|
2581
2787
|
|
|
2582
2788
|
// src/amaster-runtime-daemon/executor-discovery.mjs
|
|
2583
2789
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
@@ -2693,26 +2899,26 @@ function defaultMachineId() {
|
|
|
2693
2899
|
}
|
|
2694
2900
|
function runtimeHome(env) {
|
|
2695
2901
|
return expandHomePath(String(
|
|
2696
|
-
env.AMASTER_RUNTIME_STATE_HOME || env.AMASTER_RUNTIME_HOME ||
|
|
2902
|
+
env.AMASTER_RUNTIME_STATE_HOME || env.AMASTER_RUNTIME_HOME || join5(homedir2(), ".amaster-employee")
|
|
2697
2903
|
));
|
|
2698
2904
|
}
|
|
2699
2905
|
function stateFilePath(env) {
|
|
2700
|
-
return env.AMASTER_DAEMON_STATE_FILE ? expandHomePath(String(env.AMASTER_DAEMON_STATE_FILE)) :
|
|
2906
|
+
return env.AMASTER_DAEMON_STATE_FILE ? expandHomePath(String(env.AMASTER_DAEMON_STATE_FILE)) : join5(runtimeHome(env), "runtime-connector-state.json");
|
|
2701
2907
|
}
|
|
2702
2908
|
function corruptStatePath(path) {
|
|
2703
2909
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/\D/g, "").slice(0, 14);
|
|
2704
2910
|
const base = `${path}.corrupt-${timestamp}Z`;
|
|
2705
2911
|
let candidate = base;
|
|
2706
|
-
for (let suffix = 1;
|
|
2912
|
+
for (let suffix = 1; existsSync4(candidate); suffix += 1) {
|
|
2707
2913
|
candidate = `${base}.${suffix}`;
|
|
2708
2914
|
}
|
|
2709
2915
|
return candidate;
|
|
2710
2916
|
}
|
|
2711
2917
|
function readState(env) {
|
|
2712
2918
|
const path = stateFilePath(env);
|
|
2713
|
-
if (!
|
|
2919
|
+
if (!existsSync4(path)) return {};
|
|
2714
2920
|
try {
|
|
2715
|
-
const state = JSON.parse(
|
|
2921
|
+
const state = JSON.parse(readFileSync4(path, "utf8"));
|
|
2716
2922
|
if (!state || typeof state !== "object" || Array.isArray(state)) {
|
|
2717
2923
|
throw new TypeError("runtime connector state must be a JSON object");
|
|
2718
2924
|
}
|
|
@@ -2720,7 +2926,7 @@ function readState(env) {
|
|
|
2720
2926
|
} catch {
|
|
2721
2927
|
const quarantinePath = corruptStatePath(path);
|
|
2722
2928
|
try {
|
|
2723
|
-
|
|
2929
|
+
renameSync2(path, quarantinePath);
|
|
2724
2930
|
process.stderr.write(`AMaster runtime state was invalid and quarantined at ${quarantinePath}
|
|
2725
2931
|
`);
|
|
2726
2932
|
} catch (error) {
|
|
@@ -2734,15 +2940,15 @@ function readState(env) {
|
|
|
2734
2940
|
}
|
|
2735
2941
|
function writeState(env, state) {
|
|
2736
2942
|
const path = stateFilePath(env);
|
|
2737
|
-
|
|
2943
|
+
mkdirSync4(dirname4(path), { recursive: true });
|
|
2738
2944
|
const temporaryPath = `${path}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
2739
2945
|
try {
|
|
2740
|
-
|
|
2946
|
+
writeFileSync4(temporaryPath, `${JSON.stringify(state, null, 2)}
|
|
2741
2947
|
`, {
|
|
2742
2948
|
flag: "wx",
|
|
2743
2949
|
mode: 384
|
|
2744
2950
|
});
|
|
2745
|
-
|
|
2951
|
+
renameSync2(temporaryPath, path);
|
|
2746
2952
|
} finally {
|
|
2747
2953
|
rmSync3(temporaryPath, { force: true });
|
|
2748
2954
|
}
|
|
@@ -2756,9 +2962,9 @@ function buildConfig(env = process.env, flags = {}) {
|
|
|
2756
2962
|
const authHeader = String(flags.authHeader ?? env.AMASTER_CONNECTOR_AUTH_HEADER ?? "");
|
|
2757
2963
|
const home = runtimeHome(env);
|
|
2758
2964
|
const runtimeWorkspacesRoot = expandHomePath(
|
|
2759
|
-
String(flags.runtimeWorkspacesRoot ?? env.AMASTER_RUNTIME_WORKSPACES_ROOT ??
|
|
2965
|
+
String(flags.runtimeWorkspacesRoot ?? env.AMASTER_RUNTIME_WORKSPACES_ROOT ?? join5(home, "workspaces"))
|
|
2760
2966
|
);
|
|
2761
|
-
|
|
2967
|
+
mkdirSync4(runtimeWorkspacesRoot, { recursive: true });
|
|
2762
2968
|
const workspaceBindings = splitList(
|
|
2763
2969
|
flags.workspaceAllowlist ?? env.AMASTER_WORKSPACE_ALLOWLIST ?? env.AMASTER_WORKSPACE_BINDINGS ?? runtimeWorkspacesRoot
|
|
2764
2970
|
).map(expandHomePath);
|
|
@@ -4000,7 +4206,7 @@ var bestEffortPostJson = bestEffortPostRuntimeConnectorJson;
|
|
|
4000
4206
|
|
|
4001
4207
|
// src/amaster-runtime-daemon/runtime-artifact-upload.mjs
|
|
4002
4208
|
import { createHash as createHash3 } from "node:crypto";
|
|
4003
|
-
import { lstatSync as lstatSync3, readFileSync as
|
|
4209
|
+
import { lstatSync as lstatSync3, readFileSync as readFileSync5, realpathSync } from "node:fs";
|
|
4004
4210
|
import { isAbsolute as isAbsolute3, relative as relative3, resolve as resolve3 } from "node:path";
|
|
4005
4211
|
var SHA256_PATTERN = /^[a-f0-9]{64}$/;
|
|
4006
4212
|
function requiredString(value, name) {
|
|
@@ -4041,7 +4247,7 @@ function prepareRuntimeArtifactUploads(cwd, mcpToolResults) {
|
|
|
4041
4247
|
if (!stat.isFile() || stat.isSymbolicLink() || !pathWithin(realpathSync(sourcePath), root)) {
|
|
4042
4248
|
throw new Error(`Runtime Artifact ${intentId} source is not an owned regular file`);
|
|
4043
4249
|
}
|
|
4044
|
-
const body =
|
|
4250
|
+
const body = readFileSync5(sourcePath);
|
|
4045
4251
|
const actualSha256 = createHash3("sha256").update(body).digest("hex");
|
|
4046
4252
|
if (body.length !== expectedByteSize || actualSha256 !== expectedSha256) {
|
|
4047
4253
|
throw new Error(`Runtime Artifact ${intentId} bytes do not match the governed ownership manifest`);
|
|
@@ -4092,40 +4298,40 @@ function createRuntimeArtifactIngestQueue({ ingest, onError }) {
|
|
|
4092
4298
|
|
|
4093
4299
|
// src/amaster-runtime-daemon/workspace-guard.mjs
|
|
4094
4300
|
import { createHash as createHash4 } from "node:crypto";
|
|
4095
|
-
import { existsSync as
|
|
4096
|
-
import { basename as basename4, join as
|
|
4301
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync5, realpathSync as realpathSync2, statSync as statSync3 } from "node:fs";
|
|
4302
|
+
import { basename as basename4, join as join7, isAbsolute as isAbsolute4, relative as relative4, resolve as resolve4 } from "node:path";
|
|
4097
4303
|
|
|
4098
4304
|
// src/amaster-runtime-daemon/workspace-manifest.mjs
|
|
4099
|
-
import { existsSync as
|
|
4100
|
-
import { basename as basename3, dirname as
|
|
4305
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync5 } from "node:fs";
|
|
4306
|
+
import { basename as basename3, dirname as dirname5, join as join6 } from "node:path";
|
|
4101
4307
|
var WORKSPACE_MANIFEST_FILENAME = ".amaster-runtime.json";
|
|
4102
4308
|
function nowIso() {
|
|
4103
4309
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
4104
4310
|
}
|
|
4105
4311
|
function workspaceManifestPath(workspaceOrCwd) {
|
|
4106
4312
|
if (!workspaceOrCwd) return null;
|
|
4107
|
-
if (typeof workspaceOrCwd === "string") return
|
|
4108
|
-
if (typeof workspaceOrCwd.cwd === "string") return
|
|
4313
|
+
if (typeof workspaceOrCwd === "string") return join6(workspaceOrCwd, WORKSPACE_MANIFEST_FILENAME);
|
|
4314
|
+
if (typeof workspaceOrCwd.cwd === "string") return join6(workspaceOrCwd.cwd, WORKSPACE_MANIFEST_FILENAME);
|
|
4109
4315
|
return null;
|
|
4110
4316
|
}
|
|
4111
4317
|
function readWorkspaceManifest(manifestPath) {
|
|
4112
|
-
if (!manifestPath || !
|
|
4318
|
+
if (!manifestPath || !existsSync5(manifestPath)) return null;
|
|
4113
4319
|
try {
|
|
4114
|
-
const parsed = JSON.parse(
|
|
4320
|
+
const parsed = JSON.parse(readFileSync6(manifestPath, "utf8"));
|
|
4115
4321
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
4116
4322
|
} catch {
|
|
4117
4323
|
return null;
|
|
4118
4324
|
}
|
|
4119
4325
|
}
|
|
4120
4326
|
function writeWorkspaceManifest(manifestPath, manifest) {
|
|
4121
|
-
const tempPath =
|
|
4122
|
-
|
|
4327
|
+
const tempPath = join6(
|
|
4328
|
+
dirname5(manifestPath),
|
|
4123
4329
|
`.${basename3(manifestPath)}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`
|
|
4124
4330
|
);
|
|
4125
4331
|
try {
|
|
4126
|
-
|
|
4332
|
+
writeFileSync5(tempPath, `${JSON.stringify(manifest, null, 2)}
|
|
4127
4333
|
`, { mode: 384 });
|
|
4128
|
-
|
|
4334
|
+
renameSync3(tempPath, manifestPath);
|
|
4129
4335
|
} catch (err) {
|
|
4130
4336
|
rmSync4(tempPath, { force: true });
|
|
4131
4337
|
throw err;
|
|
@@ -4196,7 +4402,7 @@ function resolveWorkspaceCwd(config, command) {
|
|
|
4196
4402
|
if (!allowed) {
|
|
4197
4403
|
throw new Error(`Workspace path is outside AMASTER_WORKSPACE_ALLOWLIST: ${cwd}`);
|
|
4198
4404
|
}
|
|
4199
|
-
if (!
|
|
4405
|
+
if (!existsSync6(cwd) || !statSync3(cwd).isDirectory()) {
|
|
4200
4406
|
throw new Error(`Workspace path does not exist or is not a directory: ${cwd}`);
|
|
4201
4407
|
}
|
|
4202
4408
|
return cwd;
|
|
@@ -4227,7 +4433,7 @@ function workspaceLabel(sourceWorkspacePath, payload) {
|
|
|
4227
4433
|
}
|
|
4228
4434
|
function workspacesRoot(config) {
|
|
4229
4435
|
const root = resolve4(expandHomePath(config.runtimeWorkspacesRoot ?? "~/.amaster-employee/workspaces"));
|
|
4230
|
-
|
|
4436
|
+
mkdirSync5(root, { recursive: true });
|
|
4231
4437
|
return realpathSync2(root);
|
|
4232
4438
|
}
|
|
4233
4439
|
function resolveExecutionWorkspace(config, command, opts = {}) {
|
|
@@ -4240,11 +4446,11 @@ function resolveExecutionWorkspace(config, command, opts = {}) {
|
|
|
4240
4446
|
const workspaceKey = `${safeSegment(workspaceLabel(sourceWorkspacePath, payload), "workspace")}-${shortHash(sourceWorkspacePath)}`;
|
|
4241
4447
|
const issueKey = `${safeSegment(issueLabel(command, payload), "issue")}-${shortHash(issueId, 8)}`;
|
|
4242
4448
|
const runKey = `${safeSegment(runId, "run")}-${shortHash(runId, 8)}`;
|
|
4243
|
-
const runDir =
|
|
4244
|
-
const cwd =
|
|
4245
|
-
const executorHome =
|
|
4246
|
-
|
|
4247
|
-
|
|
4449
|
+
const runDir = join7(root, workspaceKey, issueKey, runKey);
|
|
4450
|
+
const cwd = join7(runDir, "workdir");
|
|
4451
|
+
const executorHome = join7(runDir, "executors", safeSegment(executorKind, "executor"));
|
|
4452
|
+
mkdirSync5(cwd, { recursive: true });
|
|
4453
|
+
mkdirSync5(executorHome, { recursive: true });
|
|
4248
4454
|
const workspace = {
|
|
4249
4455
|
managed: true,
|
|
4250
4456
|
cwd,
|
|
@@ -4266,8 +4472,8 @@ function resolveExecutionWorkspace(config, command, opts = {}) {
|
|
|
4266
4472
|
}
|
|
4267
4473
|
|
|
4268
4474
|
// src/amaster-runtime-daemon/workspace-gc.mjs
|
|
4269
|
-
import { existsSync as
|
|
4270
|
-
import { join as
|
|
4475
|
+
import { existsSync as existsSync7, readdirSync as readdirSync3, statSync as statSync4 } from "node:fs";
|
|
4476
|
+
import { join as join8, resolve as resolve5 } from "node:path";
|
|
4271
4477
|
function readIsoTime(value) {
|
|
4272
4478
|
if (typeof value !== "string" || !value.trim()) return null;
|
|
4273
4479
|
const time = new Date(value).getTime();
|
|
@@ -4290,8 +4496,8 @@ function walkWorkdirs(root) {
|
|
|
4290
4496
|
}
|
|
4291
4497
|
for (const entry of entries) {
|
|
4292
4498
|
if (!entry.isDirectory()) continue;
|
|
4293
|
-
const fullPath =
|
|
4294
|
-
if (entry.name === "workdir" &&
|
|
4499
|
+
const fullPath = join8(current, entry.name);
|
|
4500
|
+
if (entry.name === "workdir" && existsSync7(workspaceManifestPath(fullPath))) {
|
|
4295
4501
|
workdirs.push(fullPath);
|
|
4296
4502
|
continue;
|
|
4297
4503
|
}
|
|
@@ -4322,7 +4528,7 @@ function directorySizeBytes(path) {
|
|
|
4322
4528
|
continue;
|
|
4323
4529
|
}
|
|
4324
4530
|
for (const entry of entries) {
|
|
4325
|
-
stack.push(
|
|
4531
|
+
stack.push(join8(current, entry.name));
|
|
4326
4532
|
}
|
|
4327
4533
|
continue;
|
|
4328
4534
|
}
|
|
@@ -4366,7 +4572,7 @@ function planManagedWorkspaceGcDryRun(input) {
|
|
|
4366
4572
|
candidates: [],
|
|
4367
4573
|
protected: []
|
|
4368
4574
|
};
|
|
4369
|
-
if (!root || !
|
|
4575
|
+
if (!root || !existsSync7(root)) return result2;
|
|
4370
4576
|
for (const workdir of walkWorkdirs(root)) {
|
|
4371
4577
|
const manifest = readWorkspaceManifest(workspaceManifestPath(workdir));
|
|
4372
4578
|
if (!manifest || manifest.managed !== true) continue;
|
|
@@ -4394,8 +4600,8 @@ function planManagedWorkspaceGcDryRun(input) {
|
|
|
4394
4600
|
}
|
|
4395
4601
|
|
|
4396
4602
|
// src/amaster-runtime-daemon/runtime-status-summary.mjs
|
|
4397
|
-
import { existsSync as
|
|
4398
|
-
import { dirname as
|
|
4603
|
+
import { existsSync as existsSync8, readdirSync as readdirSync4, statSync as statSync5 } from "node:fs";
|
|
4604
|
+
import { dirname as dirname6, join as join9, resolve as resolve6 } from "node:path";
|
|
4399
4605
|
function runtimeStatusDirectoryEntries(path) {
|
|
4400
4606
|
try {
|
|
4401
4607
|
return readdirSync4(path, { withFileTypes: true });
|
|
@@ -4418,7 +4624,7 @@ function runtimeStatusDirectorySizeBytes(path) {
|
|
|
4418
4624
|
if (!stat || stat.isSymbolicLink()) continue;
|
|
4419
4625
|
if (stat.isDirectory()) {
|
|
4420
4626
|
for (const entry of runtimeStatusDirectoryEntries(current)) {
|
|
4421
|
-
stack.push(
|
|
4627
|
+
stack.push(join9(current, entry.name));
|
|
4422
4628
|
}
|
|
4423
4629
|
continue;
|
|
4424
4630
|
}
|
|
@@ -4428,15 +4634,15 @@ function runtimeStatusDirectorySizeBytes(path) {
|
|
|
4428
4634
|
}
|
|
4429
4635
|
function walkRuntimeStatusManagedWorkdirs(root) {
|
|
4430
4636
|
const workdirs = [];
|
|
4431
|
-
if (!root || !
|
|
4637
|
+
if (!root || !existsSync8(root)) return workdirs;
|
|
4432
4638
|
const stack = [root];
|
|
4433
4639
|
while (stack.length > 0) {
|
|
4434
4640
|
const current = stack.pop();
|
|
4435
4641
|
if (!current) continue;
|
|
4436
4642
|
for (const entry of runtimeStatusDirectoryEntries(current)) {
|
|
4437
4643
|
if (!entry.isDirectory()) continue;
|
|
4438
|
-
const fullPath =
|
|
4439
|
-
if (entry.name === "workdir" &&
|
|
4644
|
+
const fullPath = join9(current, entry.name);
|
|
4645
|
+
if (entry.name === "workdir" && existsSync8(workspaceManifestPath(fullPath))) {
|
|
4440
4646
|
workdirs.push(fullPath);
|
|
4441
4647
|
continue;
|
|
4442
4648
|
}
|
|
@@ -4477,12 +4683,12 @@ function summarizeRuntimeStatusRecentRun(workdir, manifest) {
|
|
|
4477
4683
|
}
|
|
4478
4684
|
function runtimeStatusOutboxDir(config) {
|
|
4479
4685
|
const statePath = config.AMASTER_DAEMON_STATE_FILE ?? config.daemonStateFile;
|
|
4480
|
-
return
|
|
4686
|
+
return join9(dirname6(stateFilePath({
|
|
4481
4687
|
AMASTER_DAEMON_STATE_FILE: statePath
|
|
4482
4688
|
})), "result-outbox");
|
|
4483
4689
|
}
|
|
4484
4690
|
function countRuntimeStatusJsonEntries(dir) {
|
|
4485
|
-
if (!
|
|
4691
|
+
if (!existsSync8(dir)) return 0;
|
|
4486
4692
|
return runtimeStatusDirectoryEntries(dir).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).length;
|
|
4487
4693
|
}
|
|
4488
4694
|
function summarizeRuntimeLocalState(input) {
|
|
@@ -4514,7 +4720,7 @@ function summarizeRuntimeLocalState(input) {
|
|
|
4514
4720
|
}
|
|
4515
4721
|
}
|
|
4516
4722
|
const pendingOutboxDir = runtimeStatusOutboxDir(config);
|
|
4517
|
-
const invalidOutboxDir =
|
|
4723
|
+
const invalidOutboxDir = join9(pendingOutboxDir, "invalid");
|
|
4518
4724
|
return {
|
|
4519
4725
|
managedWorkspacesRoot: root,
|
|
4520
4726
|
managedWorkdirCount: workdirs.length,
|
|
@@ -4691,16 +4897,16 @@ import { createHash as createHash6 } from "node:crypto";
|
|
|
4691
4897
|
import {
|
|
4692
4898
|
chmodSync as chmodSync4,
|
|
4693
4899
|
copyFileSync as copyFileSync2,
|
|
4694
|
-
existsSync as
|
|
4900
|
+
existsSync as existsSync9,
|
|
4695
4901
|
lstatSync as lstatSync5,
|
|
4696
|
-
mkdirSync as
|
|
4697
|
-
readFileSync as
|
|
4902
|
+
mkdirSync as mkdirSync6,
|
|
4903
|
+
readFileSync as readFileSync7,
|
|
4698
4904
|
readdirSync as readdirSync6,
|
|
4699
4905
|
rmSync as rmSync5,
|
|
4700
4906
|
symlinkSync as symlinkSync2,
|
|
4701
|
-
writeFileSync as
|
|
4907
|
+
writeFileSync as writeFileSync6
|
|
4702
4908
|
} from "node:fs";
|
|
4703
|
-
import { dirname as
|
|
4909
|
+
import { dirname as dirname7, isAbsolute as isAbsolute5, join as join10, relative as relative5, resolve as resolve8 } from "node:path";
|
|
4704
4910
|
var ASSERTION_VERSION = "2026-07-25.v1";
|
|
4705
4911
|
var SHA256 = /^[a-f0-9]{64}$/;
|
|
4706
4912
|
var COPY_ENTRIES = ["SYSTEM.md", "policy", "skills", "agents", "bundles", "extensions"];
|
|
@@ -4725,7 +4931,7 @@ function sha256File(path, label) {
|
|
|
4725
4931
|
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
4726
4932
|
throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
|
|
4727
4933
|
}
|
|
4728
|
-
return createHash6("sha256").update(
|
|
4934
|
+
return createHash6("sha256").update(readFileSync7(path)).digest("hex");
|
|
4729
4935
|
}
|
|
4730
4936
|
function verifyDeclaredFiles(manifest, root, label, ignoredPaths = [], enforceComplete = true) {
|
|
4731
4937
|
if (!Array.isArray(manifest.files) || manifest.files.length === 0) {
|
|
@@ -4748,7 +4954,7 @@ function verifyDeclaredFiles(manifest, root, label, ignoredPaths = [], enforceCo
|
|
|
4748
4954
|
const ignored = ignoredPaths.map((path) => path.split("\\").join("/"));
|
|
4749
4955
|
const visit = (directory) => {
|
|
4750
4956
|
for (const entry of readdirSync6(directory)) {
|
|
4751
|
-
const filePath =
|
|
4957
|
+
const filePath = join10(directory, entry);
|
|
4752
4958
|
const relativePath = relative5(root, filePath).split("\\").join("/");
|
|
4753
4959
|
const stat = lstatSync5(filePath);
|
|
4754
4960
|
if (stat.isSymbolicLink()) {
|
|
@@ -4773,14 +4979,14 @@ function within2(candidate, root) {
|
|
|
4773
4979
|
const rel = relative5(root, candidate);
|
|
4774
4980
|
return rel === "" || !rel.startsWith("..") && !isAbsolute5(rel);
|
|
4775
4981
|
}
|
|
4776
|
-
function
|
|
4777
|
-
if (!
|
|
4982
|
+
function readJsonFile2(path, label, fallback = {}) {
|
|
4983
|
+
if (!existsSync9(path)) return fallback;
|
|
4778
4984
|
const stat = lstatSync5(path);
|
|
4779
4985
|
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
4780
4986
|
throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
|
|
4781
4987
|
}
|
|
4782
4988
|
try {
|
|
4783
|
-
return JSON.parse(
|
|
4989
|
+
return JSON.parse(readFileSync7(path, "utf8"));
|
|
4784
4990
|
} catch {
|
|
4785
4991
|
throw new Error(`pi_trusted_runtime_source_invalid:${label}`);
|
|
4786
4992
|
}
|
|
@@ -4811,21 +5017,21 @@ function copyTreeNoLinks(source, target) {
|
|
|
4811
5017
|
const stat = lstatSync5(source);
|
|
4812
5018
|
if (stat.isSymbolicLink()) throw new Error("pi_trusted_runtime_source_symlink_blocked");
|
|
4813
5019
|
if (stat.isDirectory()) {
|
|
4814
|
-
|
|
5020
|
+
mkdirSync6(target, { recursive: true, mode: 448 });
|
|
4815
5021
|
chmodSync4(target, 448);
|
|
4816
5022
|
for (const entry of readdirSync6(source)) {
|
|
4817
|
-
copyTreeNoLinks(
|
|
5023
|
+
copyTreeNoLinks(join10(source, entry), join10(target, entry));
|
|
4818
5024
|
}
|
|
4819
5025
|
return;
|
|
4820
5026
|
}
|
|
4821
5027
|
if (!stat.isFile()) throw new Error("pi_trusted_runtime_source_type_blocked");
|
|
4822
|
-
|
|
5028
|
+
mkdirSync6(dirname7(target), { recursive: true, mode: 448 });
|
|
4823
5029
|
copyFileSync2(source, target);
|
|
4824
5030
|
chmodSync4(target, 384 | stat.mode & 73);
|
|
4825
5031
|
}
|
|
4826
5032
|
function mergeMcp(seedRoot, overlayRoot, governedConfig) {
|
|
4827
|
-
const seed = record2(
|
|
4828
|
-
const overlay = record2(
|
|
5033
|
+
const seed = record2(readJsonFile2(join10(seedRoot, "mcp.json"), "seed_mcp", { mcpServers: {} }));
|
|
5034
|
+
const overlay = record2(readJsonFile2(join10(overlayRoot, "mcp.json"), "overlay_mcp", { mcpServers: {} }));
|
|
4829
5035
|
assertNoPersistentSecrets(seed, ["seed", "mcp.json"]);
|
|
4830
5036
|
assertNoPersistentSecrets(overlay, ["overlay", "mcp.json"]);
|
|
4831
5037
|
const seedServers = record2(seed.mcpServers);
|
|
@@ -4860,8 +5066,8 @@ function assertEnabledPackagesAvailable(settings, npmRoot) {
|
|
|
4860
5066
|
}
|
|
4861
5067
|
}
|
|
4862
5068
|
for (const name of requiredNames) {
|
|
4863
|
-
const metadataPath =
|
|
4864
|
-
const metadata =
|
|
5069
|
+
const metadataPath = join10(npmRoot, "node_modules", ...name.split("/"), "package.json");
|
|
5070
|
+
const metadata = readJsonFile2(metadataPath, `package:${name}`, null);
|
|
4865
5071
|
if (!metadata || metadata.name !== name) {
|
|
4866
5072
|
throw new Error(`pi_trusted_runtime_package_unavailable:${name}`);
|
|
4867
5073
|
}
|
|
@@ -4880,17 +5086,17 @@ function materializeTrustedPiRuntimeProfile(input) {
|
|
|
4880
5086
|
}
|
|
4881
5087
|
}
|
|
4882
5088
|
for (const entry of COPY_ENTRIES) {
|
|
4883
|
-
const target =
|
|
5089
|
+
const target = join10(agentDir, entry);
|
|
4884
5090
|
rmSync5(target, { recursive: true, force: true });
|
|
4885
5091
|
for (const sourceRoot of [seedRoot, overlayRoot]) {
|
|
4886
|
-
const source =
|
|
4887
|
-
if (
|
|
5092
|
+
const source = join10(sourceRoot, entry);
|
|
5093
|
+
if (existsSync9(source)) copyTreeNoLinks(source, target);
|
|
4888
5094
|
}
|
|
4889
5095
|
}
|
|
4890
5096
|
const mergedJson = {};
|
|
4891
5097
|
for (const entry of JSON_ENTRIES) {
|
|
4892
|
-
const seed =
|
|
4893
|
-
const overlay =
|
|
5098
|
+
const seed = readJsonFile2(join10(seedRoot, entry), `seed_${entry}`, {});
|
|
5099
|
+
const overlay = readJsonFile2(join10(overlayRoot, entry), `overlay_${entry}`, {});
|
|
4894
5100
|
const merged = deepMerge(seed, overlay);
|
|
4895
5101
|
if (entry === "settings.json") {
|
|
4896
5102
|
merged["pi-security"] = {
|
|
@@ -4903,21 +5109,21 @@ function materializeTrustedPiRuntimeProfile(input) {
|
|
|
4903
5109
|
};
|
|
4904
5110
|
}
|
|
4905
5111
|
assertNoPersistentSecrets(merged, [entry]);
|
|
4906
|
-
|
|
5112
|
+
writeFileSync6(join10(agentDir, entry), `${JSON.stringify(merged, null, 2)}
|
|
4907
5113
|
`, {
|
|
4908
5114
|
mode: 384
|
|
4909
5115
|
});
|
|
4910
|
-
chmodSync4(
|
|
5116
|
+
chmodSync4(join10(agentDir, entry), 384);
|
|
4911
5117
|
mergedJson[entry] = merged;
|
|
4912
5118
|
}
|
|
4913
|
-
const governedConfig =
|
|
5119
|
+
const governedConfig = readJsonFile2(input.governedMcpConfigPath, "governed_mcp");
|
|
4914
5120
|
const mcp = mergeMcp(seedRoot, overlayRoot, governedConfig);
|
|
4915
|
-
|
|
5121
|
+
writeFileSync6(input.governedMcpConfigPath, `${JSON.stringify(mcp, null, 2)}
|
|
4916
5122
|
`, { mode: 384 });
|
|
4917
5123
|
chmodSync4(input.governedMcpConfigPath, 384);
|
|
4918
|
-
const npmRoot =
|
|
5124
|
+
const npmRoot = join10(seedRoot, "npm");
|
|
4919
5125
|
assertEnabledPackagesAvailable(mergedJson["settings.json"], npmRoot);
|
|
4920
|
-
const npmTarget =
|
|
5126
|
+
const npmTarget = join10(agentDir, "npm");
|
|
4921
5127
|
rmSync5(npmTarget, { recursive: true, force: true });
|
|
4922
5128
|
const npmStat = lstatSync5(npmRoot);
|
|
4923
5129
|
if (!npmStat.isDirectory() || npmStat.isSymbolicLink()) {
|
|
@@ -4962,13 +5168,13 @@ function readTrustedPiRuntimeAudit(input) {
|
|
|
4962
5168
|
const profileRoot = resolve8(requiredString2(input.profileRoot, "profileRoot"));
|
|
4963
5169
|
const auditFile = resolve8(requiredString2(input.auditFile, "auditFile"));
|
|
4964
5170
|
if (!within2(auditFile, profileRoot)) throw new Error("pi_trusted_runtime_audit_path_escape");
|
|
4965
|
-
if (!
|
|
5171
|
+
if (!existsSync9(auditFile)) throw new Error("pi_trusted_runtime_audit_startup_missing");
|
|
4966
5172
|
const stat = lstatSync5(auditFile);
|
|
4967
5173
|
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
4968
5174
|
throw new Error("pi_trusted_runtime_audit_unsafe");
|
|
4969
5175
|
}
|
|
4970
5176
|
if (stat.size > MAX_AUDIT_BYTES) throw new Error("pi_trusted_runtime_audit_too_large");
|
|
4971
|
-
const lines =
|
|
5177
|
+
const lines = readFileSync7(auditFile, "utf8").split("\n").filter(Boolean);
|
|
4972
5178
|
if (lines.length === 0 || lines.length > MAX_AUDIT_EVENTS) {
|
|
4973
5179
|
throw new Error("pi_trusted_runtime_audit_event_count_invalid");
|
|
4974
5180
|
}
|
|
@@ -5025,11 +5231,11 @@ function readTrustedPiRuntimeLocalDigests(input) {
|
|
|
5025
5231
|
throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
|
|
5026
5232
|
}
|
|
5027
5233
|
}
|
|
5028
|
-
const seedManifestFile =
|
|
5029
|
-
const overlayManifestFile =
|
|
5030
|
-
const seedManifest = JSON.parse(
|
|
5031
|
-
const overlayManifest = JSON.parse(
|
|
5032
|
-
const policyManifest = JSON.parse(
|
|
5234
|
+
const seedManifestFile = join10(seedRoot, "seed-manifest.json");
|
|
5235
|
+
const overlayManifestFile = join10(overlayRoot, "runtime-overlay-manifest.json");
|
|
5236
|
+
const seedManifest = JSON.parse(readFileSync7(seedManifestFile, "utf8"));
|
|
5237
|
+
const overlayManifest = JSON.parse(readFileSync7(overlayManifestFile, "utf8"));
|
|
5238
|
+
const policyManifest = JSON.parse(readFileSync7(policyFile, "utf8"));
|
|
5033
5239
|
verifyDeclaredFiles(seedManifest, seedRoot, "seed", [
|
|
5034
5240
|
"seed-manifest.json",
|
|
5035
5241
|
"npm/package-lock.json",
|
|
@@ -5038,9 +5244,9 @@ function readTrustedPiRuntimeLocalDigests(input) {
|
|
|
5038
5244
|
verifyDeclaredFiles(overlayManifest, overlayRoot, "overlay", ["runtime-overlay-manifest.json"]);
|
|
5039
5245
|
verifyDeclaredFiles(
|
|
5040
5246
|
policyManifest,
|
|
5041
|
-
|
|
5247
|
+
dirname7(policyFile),
|
|
5042
5248
|
"policy",
|
|
5043
|
-
[relative5(
|
|
5249
|
+
[relative5(dirname7(policyFile), policyFile)],
|
|
5044
5250
|
false
|
|
5045
5251
|
);
|
|
5046
5252
|
return {
|
|
@@ -5130,199 +5336,6 @@ function verifyTrustedPiRuntimeAssertion(input) {
|
|
|
5130
5336
|
};
|
|
5131
5337
|
}
|
|
5132
5338
|
|
|
5133
|
-
// src/amaster-runtime-daemon/pi-provider-config.mjs
|
|
5134
|
-
import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync as renameSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
5135
|
-
import { dirname as dirname7, join as join10 } from "node:path";
|
|
5136
|
-
var AMASTER_API_KEY_ENV_REFERENCE = "${AMASTER_API_KEY}";
|
|
5137
|
-
var AMASTER_BILLING_HEADER_ENV_REFERENCES = Object.freeze({
|
|
5138
|
-
"x-pi-agent-oauth-token": "${AMASTER_PLATFORM_OAUTH_TOKEN}",
|
|
5139
|
-
"x-organization-id": "${AMASTER_PLATFORM_ORGANIZATION_ID}",
|
|
5140
|
-
"x-billing-turn-id": "${AMASTER_BILLING_TURN_ID}"
|
|
5141
|
-
});
|
|
5142
|
-
function isRecord(value) {
|
|
5143
|
-
return value && typeof value === "object" && !Array.isArray(value);
|
|
5144
|
-
}
|
|
5145
|
-
function readJsonFile2(filePath) {
|
|
5146
|
-
try {
|
|
5147
|
-
const parsed = JSON.parse(readFileSync7(filePath, "utf8"));
|
|
5148
|
-
return asRecord(parsed);
|
|
5149
|
-
} catch {
|
|
5150
|
-
return {};
|
|
5151
|
-
}
|
|
5152
|
-
}
|
|
5153
|
-
function writeJsonFileAtomic(filePath, value) {
|
|
5154
|
-
mkdirSync6(dirname7(filePath), { recursive: true });
|
|
5155
|
-
const tmpPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
5156
|
-
writeFileSync6(tmpPath, `${JSON.stringify(value, null, 2)}
|
|
5157
|
-
`, { mode: 384 });
|
|
5158
|
-
renameSync3(tmpPath, filePath);
|
|
5159
|
-
}
|
|
5160
|
-
function imageGenBaseUrlFromProviderBaseUrl(value) {
|
|
5161
|
-
const input = readString(value);
|
|
5162
|
-
if (!input) return void 0;
|
|
5163
|
-
try {
|
|
5164
|
-
const url = new URL(input);
|
|
5165
|
-
const pathname = url.pathname.replace(/\/+$/, "");
|
|
5166
|
-
if (pathname.toLowerCase().endsWith("/v1")) {
|
|
5167
|
-
url.pathname = pathname.slice(0, -"/v1".length) || "/";
|
|
5168
|
-
}
|
|
5169
|
-
return url.toString();
|
|
5170
|
-
} catch {
|
|
5171
|
-
return input.replace(/\/v1\/?$/, "");
|
|
5172
|
-
}
|
|
5173
|
-
}
|
|
5174
|
-
function ensureAmasterProviderModel(models, modelId, flash) {
|
|
5175
|
-
const id = readString(modelId);
|
|
5176
|
-
if (!id) return;
|
|
5177
|
-
const existing = Array.isArray(models) ? models : [];
|
|
5178
|
-
const index = existing.findIndex((entry) => asRecord(entry).id === id);
|
|
5179
|
-
if (index >= 0) {
|
|
5180
|
-
existing[index] = {
|
|
5181
|
-
...asRecord(existing[index]),
|
|
5182
|
-
id,
|
|
5183
|
-
input: readStringArray(asRecord(existing[index]).input).length > 0 ? asRecord(existing[index]).input : ["text", "image"],
|
|
5184
|
-
reasoning: asRecord(existing[index]).reasoning ?? true,
|
|
5185
|
-
...flash ? { flash: true } : {}
|
|
5186
|
-
};
|
|
5187
|
-
return;
|
|
5188
|
-
}
|
|
5189
|
-
existing.push({
|
|
5190
|
-
id,
|
|
5191
|
-
input: ["text", "image"],
|
|
5192
|
-
reasoning: true,
|
|
5193
|
-
...flash ? { flash: true } : {}
|
|
5194
|
-
});
|
|
5195
|
-
}
|
|
5196
|
-
function withoutManagedBillingHeaders(value) {
|
|
5197
|
-
const headers = { ...asRecord(value) };
|
|
5198
|
-
for (const name of Object.keys(AMASTER_BILLING_HEADER_ENV_REFERENCES)) {
|
|
5199
|
-
delete headers[name];
|
|
5200
|
-
}
|
|
5201
|
-
return headers;
|
|
5202
|
-
}
|
|
5203
|
-
function syncManagedBillingHeaders(value, executorEnv) {
|
|
5204
|
-
const headers = withoutManagedBillingHeaders(value);
|
|
5205
|
-
if (readString(executorEnv.AMASTER_MODEL_ACCESS_MODE) === "billing_gateway") {
|
|
5206
|
-
Object.assign(headers, AMASTER_BILLING_HEADER_ENV_REFERENCES);
|
|
5207
|
-
}
|
|
5208
|
-
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
5209
|
-
}
|
|
5210
|
-
function managedApiKeyConfigValue(executorEnv, apiKey) {
|
|
5211
|
-
return readString(executorEnv.AMASTER_MODEL_ACCESS_MODE) === "billing_gateway" ? AMASTER_API_KEY_ENV_REFERENCE : apiKey;
|
|
5212
|
-
}
|
|
5213
|
-
function syncAmasterProviderModels(agentDir, executorEnv) {
|
|
5214
|
-
const apiKey = readString(executorEnv.AMASTER_API_KEY);
|
|
5215
|
-
if (!apiKey) return false;
|
|
5216
|
-
const modelsPath = join10(agentDir, "models.json");
|
|
5217
|
-
const config = readJsonFile2(modelsPath);
|
|
5218
|
-
const providers = asRecord(config.providers);
|
|
5219
|
-
const amaster = { ...asRecord(providers.amaster) };
|
|
5220
|
-
amaster.apiKey = managedApiKeyConfigValue(executorEnv, apiKey);
|
|
5221
|
-
const baseUrl = readString(executorEnv.AMASTER_PROVIDER_BASE_URL);
|
|
5222
|
-
if (baseUrl) amaster.baseUrl = baseUrl;
|
|
5223
|
-
if (!readString(amaster.api)) amaster.api = "openai-completions";
|
|
5224
|
-
const headers = syncManagedBillingHeaders(amaster.headers, executorEnv);
|
|
5225
|
-
if (headers) amaster.headers = headers;
|
|
5226
|
-
else delete amaster.headers;
|
|
5227
|
-
const models = Array.isArray(amaster.models) ? [...amaster.models] : [];
|
|
5228
|
-
ensureAmasterProviderModel(models, executorEnv.AMASTER_PROVIDER_DEFAULT_MODEL, false);
|
|
5229
|
-
ensureAmasterProviderModel(models, executorEnv.AMASTER_PROVIDER_FLASH_MODEL, true);
|
|
5230
|
-
if (models.length > 0) amaster.models = models;
|
|
5231
|
-
writeJsonFileAtomic(modelsPath, {
|
|
5232
|
-
...config,
|
|
5233
|
-
providers: {
|
|
5234
|
-
...providers,
|
|
5235
|
-
amaster
|
|
5236
|
-
}
|
|
5237
|
-
});
|
|
5238
|
-
return true;
|
|
5239
|
-
}
|
|
5240
|
-
function syncAmasterProviderSettings(agentDir, executorEnv) {
|
|
5241
|
-
const apiKey = readString(executorEnv.AMASTER_API_KEY);
|
|
5242
|
-
if (!apiKey) return false;
|
|
5243
|
-
const settingsPath = join10(agentDir, "settings.json");
|
|
5244
|
-
if (!existsSync9(settingsPath)) return false;
|
|
5245
|
-
const settings = readJsonFile2(settingsPath);
|
|
5246
|
-
const baseUrl = readString(executorEnv.AMASTER_PROVIDER_BASE_URL);
|
|
5247
|
-
const defaultModel = readString(executorEnv.AMASTER_PROVIDER_DEFAULT_MODEL);
|
|
5248
|
-
const imageGenBaseUrl = imageGenBaseUrlFromProviderBaseUrl(baseUrl);
|
|
5249
|
-
let changed = false;
|
|
5250
|
-
if (defaultModel) {
|
|
5251
|
-
if (settings.defaultProvider !== "amaster") {
|
|
5252
|
-
settings.defaultProvider = "amaster";
|
|
5253
|
-
changed = true;
|
|
5254
|
-
}
|
|
5255
|
-
if (settings.defaultModel !== defaultModel) {
|
|
5256
|
-
settings.defaultModel = defaultModel;
|
|
5257
|
-
changed = true;
|
|
5258
|
-
}
|
|
5259
|
-
}
|
|
5260
|
-
const imageGen = settings["pi-image-gen"];
|
|
5261
|
-
if (isRecord(imageGen) && isRecord(imageGen.customProviders) && isRecord(imageGen.customProviders.amaster)) {
|
|
5262
|
-
const customProviders = imageGen.customProviders;
|
|
5263
|
-
const imageGenAmaster = { ...asRecord(customProviders.amaster) };
|
|
5264
|
-
const managedApiKey = managedApiKeyConfigValue(executorEnv, apiKey);
|
|
5265
|
-
if (imageGenAmaster.apiKey !== managedApiKey) {
|
|
5266
|
-
imageGenAmaster.apiKey = managedApiKey;
|
|
5267
|
-
changed = true;
|
|
5268
|
-
}
|
|
5269
|
-
if (imageGenBaseUrl && imageGenAmaster.baseUrl !== imageGenBaseUrl) {
|
|
5270
|
-
imageGenAmaster.baseUrl = imageGenBaseUrl;
|
|
5271
|
-
changed = true;
|
|
5272
|
-
}
|
|
5273
|
-
const imageGenHeaders = syncManagedBillingHeaders(imageGenAmaster.headers, executorEnv);
|
|
5274
|
-
if (JSON.stringify(imageGenHeaders) !== JSON.stringify(imageGenAmaster.headers)) {
|
|
5275
|
-
if (imageGenHeaders) imageGenAmaster.headers = imageGenHeaders;
|
|
5276
|
-
else delete imageGenAmaster.headers;
|
|
5277
|
-
changed = true;
|
|
5278
|
-
}
|
|
5279
|
-
settings["pi-image-gen"] = {
|
|
5280
|
-
...asRecord(imageGen),
|
|
5281
|
-
customProviders: {
|
|
5282
|
-
...customProviders,
|
|
5283
|
-
amaster: imageGenAmaster
|
|
5284
|
-
}
|
|
5285
|
-
};
|
|
5286
|
-
}
|
|
5287
|
-
const webAccess = settings["pi-web-access"];
|
|
5288
|
-
if (isRecord(webAccess) && isRecord(webAccess.providers)) {
|
|
5289
|
-
const webProviders = webAccess.providers;
|
|
5290
|
-
const nextWebProviders = { ...webProviders };
|
|
5291
|
-
for (const [name, rawProvider] of Object.entries(webProviders)) {
|
|
5292
|
-
if (!isRecord(rawProvider)) continue;
|
|
5293
|
-
const providerApiKey = readString(rawProvider.apiKey);
|
|
5294
|
-
const providerBaseUrl = readString(rawProvider.baseUrl);
|
|
5295
|
-
const looksAmasterBacked = name === "amaster" || name === "kimi" || providerApiKey === "${AMASTER_API_KEY}" || providerApiKey === "AMASTER_API_KEY" || providerBaseUrl?.includes("credits.helige") || providerBaseUrl?.includes("credits.amaster");
|
|
5296
|
-
if (!looksAmasterBacked) continue;
|
|
5297
|
-
const nextProvider = {
|
|
5298
|
-
...rawProvider,
|
|
5299
|
-
apiKey: managedApiKeyConfigValue(executorEnv, apiKey),
|
|
5300
|
-
...baseUrl ? { baseUrl } : {}
|
|
5301
|
-
};
|
|
5302
|
-
const webAccessHeaders = syncManagedBillingHeaders(rawProvider.headers, executorEnv);
|
|
5303
|
-
if (webAccessHeaders) nextProvider.headers = webAccessHeaders;
|
|
5304
|
-
else delete nextProvider.headers;
|
|
5305
|
-
if (JSON.stringify(nextProvider) !== JSON.stringify(rawProvider)) {
|
|
5306
|
-
nextWebProviders[name] = nextProvider;
|
|
5307
|
-
changed = true;
|
|
5308
|
-
}
|
|
5309
|
-
}
|
|
5310
|
-
settings["pi-web-access"] = {
|
|
5311
|
-
...asRecord(webAccess),
|
|
5312
|
-
providers: nextWebProviders
|
|
5313
|
-
};
|
|
5314
|
-
}
|
|
5315
|
-
if (!changed) return false;
|
|
5316
|
-
writeJsonFileAtomic(settingsPath, settings);
|
|
5317
|
-
return true;
|
|
5318
|
-
}
|
|
5319
|
-
function syncAmasterProviderFiles(agentDir, executorEnv) {
|
|
5320
|
-
return {
|
|
5321
|
-
modelsSynced: syncAmasterProviderModels(agentDir, executorEnv),
|
|
5322
|
-
settingsSynced: syncAmasterProviderSettings(agentDir, executorEnv)
|
|
5323
|
-
};
|
|
5324
|
-
}
|
|
5325
|
-
|
|
5326
5339
|
// src/amaster-runtime-daemon/workspace-status.mjs
|
|
5327
5340
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
5328
5341
|
import { createHash as createHash7 } from "node:crypto";
|
|
@@ -5598,7 +5611,7 @@ function readWorkspaceStatus(cwd, opts = {}) {
|
|
|
5598
5611
|
}
|
|
5599
5612
|
|
|
5600
5613
|
// src/amaster-runtime-daemon.mjs
|
|
5601
|
-
var CONNECTOR_VERSION = "0.1.0-beta.
|
|
5614
|
+
var CONNECTOR_VERSION = "0.1.0-beta.38";
|
|
5602
5615
|
var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
|
|
5603
5616
|
var MAX_CHECKPOINT_BYTES = 20 * 1024 * 1024;
|
|
5604
5617
|
var CHECKPOINT_TTL_MS = 24 * 60 * 60 * 1e3;
|
package/dist/amaster-runtime.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { dirname, join, resolve } from "node:path";
|
|
|
5
5
|
import { homedir, hostname } from "node:os";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
|
|
8
|
-
const CONNECTOR_VERSION = "0.1.0-beta.
|
|
8
|
+
const CONNECTOR_VERSION = "0.1.0-beta.38";
|
|
9
9
|
|
|
10
10
|
const CAPABILITIES = [
|
|
11
11
|
"remote_registration",
|