@camstack/agent 1.0.8 → 1.1.0
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/{chunk-U6SD2QE6.mjs → chunk-PFQZTXGW.mjs} +87 -16
- package/dist/chunk-PFQZTXGW.mjs.map +1 -0
- package/dist/cli.js +81 -14
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +81 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +3 -2
- package/dist/chunk-U6SD2QE6.mjs.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -369,6 +369,29 @@ async function applyDeployedBundle(input) {
|
|
|
369
369
|
return { addonDir: liveDir };
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
+
// src/fetch-bundle-from-hub.ts
|
|
373
|
+
var import_node_crypto2 = require("crypto");
|
|
374
|
+
var import_undici = require("undici");
|
|
375
|
+
async function fetchBundleFromHub(opts) {
|
|
376
|
+
const authHeader = { Authorization: `Bearer ${opts.token}` };
|
|
377
|
+
const res = opts.fetchImpl ? await opts.fetchImpl(opts.url, { headers: authHeader }) : await (0, import_undici.fetch)(opts.url, {
|
|
378
|
+
headers: authHeader,
|
|
379
|
+
dispatcher: new import_undici.Agent({ connect: { rejectUnauthorized: false } })
|
|
380
|
+
});
|
|
381
|
+
if (!res.ok) {
|
|
382
|
+
throw new Error(`bundle fetch failed: HTTP ${res.status}`);
|
|
383
|
+
}
|
|
384
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
385
|
+
if (buffer.length !== opts.bytes) {
|
|
386
|
+
throw new Error(`bundle bytes mismatch: expected ${opts.bytes}, got ${buffer.length}`);
|
|
387
|
+
}
|
|
388
|
+
const sha = (0, import_node_crypto2.createHash)("sha256").update(buffer).digest("hex");
|
|
389
|
+
if (sha !== opts.sha256) {
|
|
390
|
+
throw new Error(`bundle sha256 mismatch: expected ${opts.sha256}, got ${sha}`);
|
|
391
|
+
}
|
|
392
|
+
return buffer;
|
|
393
|
+
}
|
|
394
|
+
|
|
372
395
|
// src/agent-service.ts
|
|
373
396
|
var deploySwapLogger = {
|
|
374
397
|
info: (msg) => console.log(`[Agent] ${msg}`),
|
|
@@ -402,6 +425,28 @@ async function withTimeout(p, ms, fallback) {
|
|
|
402
425
|
}
|
|
403
426
|
}
|
|
404
427
|
var METRICS_SNAPSHOT_TIMEOUT_MS = 2e3;
|
|
428
|
+
function resolveDeployAction(seam) {
|
|
429
|
+
return async (params) => {
|
|
430
|
+
const { addonId, source, bundle } = params;
|
|
431
|
+
if (source && (0, import_system.isAddonDeploySource)(source)) {
|
|
432
|
+
if (source.kind === "npm") {
|
|
433
|
+
await seam.installFromNpm(addonId, source.version);
|
|
434
|
+
return { success: true, addonId };
|
|
435
|
+
}
|
|
436
|
+
const buf2 = await seam.fetchBundle(source);
|
|
437
|
+
const { addonDir: addonDir2 } = await seam.applyBundle(buf2);
|
|
438
|
+
seam.onApplied(addonDir2);
|
|
439
|
+
return { success: true, addonId, path: addonDir2 };
|
|
440
|
+
}
|
|
441
|
+
if (bundle === void 0) {
|
|
442
|
+
throw new Error("$agent.deploy: no source descriptor and no legacy bundle provided");
|
|
443
|
+
}
|
|
444
|
+
const buf = typeof bundle === "string" ? Buffer.from(bundle, "base64") : bundle;
|
|
445
|
+
const { addonDir } = await seam.applyBundle(buf);
|
|
446
|
+
seam.onApplied(addonDir);
|
|
447
|
+
return { success: true, addonId, path: addonDir };
|
|
448
|
+
};
|
|
449
|
+
}
|
|
405
450
|
function readHubAddressFromConfig(configPath) {
|
|
406
451
|
if (!configPath) return null;
|
|
407
452
|
try {
|
|
@@ -574,8 +619,7 @@ function createAgentService(deps) {
|
|
|
574
619
|
deploy: {
|
|
575
620
|
handler: async (ctx) => {
|
|
576
621
|
const { params } = ctx;
|
|
577
|
-
const { addonId, bundle } = params;
|
|
578
|
-
const bufferData = typeof bundle === "string" ? Buffer.from(bundle, "base64") : bundle;
|
|
622
|
+
const { addonId, source, bundle } = params;
|
|
579
623
|
const { execFile } = await import("child_process");
|
|
580
624
|
const { promisify } = await import("util");
|
|
581
625
|
const execFileAsync = promisify(execFile);
|
|
@@ -593,17 +637,37 @@ function createAgentService(deps) {
|
|
|
593
637
|
}
|
|
594
638
|
}
|
|
595
639
|
};
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
640
|
+
const seam = {
|
|
641
|
+
installFromNpm: (pkg, v) => {
|
|
642
|
+
if (!deps.installFromNpm) {
|
|
643
|
+
throw new Error("npm deploy source unsupported on this agent");
|
|
644
|
+
}
|
|
645
|
+
return deps.installFromNpm(pkg, v);
|
|
646
|
+
},
|
|
647
|
+
applyBundle: (buf) => applyDeployedBundle({
|
|
648
|
+
addonsDir: deps.addonsDir,
|
|
649
|
+
addonId,
|
|
650
|
+
bundle: buf,
|
|
651
|
+
extract,
|
|
652
|
+
logger: deploySwapLogger
|
|
653
|
+
}),
|
|
654
|
+
fetchBundle: (s) => fetchBundleFromHub(s),
|
|
655
|
+
// Evict every addon DECLARATION id this package contributes
|
|
656
|
+
// from `loadedAddons` so the follow-up `$agent.reload` actually
|
|
657
|
+
// re-instantiates it. `loadDeployedAddons` skips any addon
|
|
658
|
+
// still present in `loadedAddons`; without this eviction a
|
|
659
|
+
// redeploy would leave the agent pinned to the pre-update
|
|
660
|
+
// version. The `deploy` param `addonId` is the PACKAGE name
|
|
661
|
+
// (used only as the on-disk dir), whereas `loadedAddons` is
|
|
662
|
+
// keyed by the addon DECLARATION id — they differ for scoped
|
|
663
|
+
// packages, so we read the extracted manifest to bridge them.
|
|
664
|
+
onApplied: (addonDir) => {
|
|
665
|
+
for (const declId of readDeployedAddonIds(addonDir)) {
|
|
666
|
+
deps.loadedAddons.delete(declId);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
return resolveDeployAction(seam)({ addonId, source, bundle });
|
|
607
671
|
}
|
|
608
672
|
},
|
|
609
673
|
/**
|
|
@@ -1070,7 +1134,10 @@ async function startAgent(configPath) {
|
|
|
1070
1134
|
subtree.registerNode(params);
|
|
1071
1135
|
triggerUpwardRegistration();
|
|
1072
1136
|
},
|
|
1073
|
-
expectedClusterSecretHash: config.secret ? (0, import_system3.hashClusterSecret)(config.secret) : void 0
|
|
1137
|
+
expectedClusterSecretHash: config.secret ? (0, import_system3.hashClusterSecret)(config.secret) : void 0,
|
|
1138
|
+
installFromNpm: async (pkg, version) => {
|
|
1139
|
+
await installer.install(pkg, version);
|
|
1140
|
+
}
|
|
1074
1141
|
});
|
|
1075
1142
|
broker.createService(agentServiceSchema);
|
|
1076
1143
|
const agentTcpPort = (0, import_system3.deriveAgentListenPort)(broker.nodeID);
|