@ory/argus 1.0.0 → 1.0.1
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/build-info.json +4 -4
- package/dist/runtime.d.ts +5 -0
- package/dist/runtime.js +78 -1
- package/package.json +1 -1
package/dist/build-info.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"repo": "ory-agent-plugins",
|
|
3
|
-
"commit": "
|
|
4
|
-
"commitShort": "
|
|
3
|
+
"commit": "f803b3fe7be2cd6918652a082a7a4a3eb4ddab53",
|
|
4
|
+
"commitShort": "f803b3f",
|
|
5
5
|
"branch": "main",
|
|
6
|
-
"commitDate": "2026-08-
|
|
6
|
+
"commitDate": "2026-08-30T11:50:10-07:00",
|
|
7
7
|
"dirty": false,
|
|
8
|
-
"builtAt": "2026-08-
|
|
8
|
+
"builtAt": "2026-08-30T18:53:36.809Z"
|
|
9
9
|
}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -345,6 +345,11 @@ export interface PreparedRuntime {
|
|
|
345
345
|
/** Store directories GC'd after rewiring — reported by `install`. */
|
|
346
346
|
prunedStores: string[];
|
|
347
347
|
}
|
|
348
|
+
/** Serialize installs because npm mutates and prunes the shared prefix in place. */
|
|
349
|
+
export declare function withRuntimeInstallLock<T>(action: () => T, options?: {
|
|
350
|
+
timeoutMs?: number;
|
|
351
|
+
pollMs?: number;
|
|
352
|
+
}): T;
|
|
348
353
|
/**
|
|
349
354
|
* One call per plugin install: resolve the runtime, write the shims, record
|
|
350
355
|
* the wiring, and GC stores nothing references any more.
|
package/dist/runtime.js
CHANGED
|
@@ -104,12 +104,14 @@ exports.removeRuntimeWiring = removeRuntimeWiring;
|
|
|
104
104
|
exports.pruneRuntimeStores = pruneRuntimeStores;
|
|
105
105
|
exports.resolveRuntimeForInstall = resolveRuntimeForInstall;
|
|
106
106
|
exports.requireHookCommand = requireHookCommand;
|
|
107
|
+
exports.withRuntimeInstallLock = withRuntimeInstallLock;
|
|
107
108
|
exports.wireRuntime = wireRuntime;
|
|
108
109
|
exports.checkRuntimeHealth = checkRuntimeHealth;
|
|
109
110
|
exports.describeRuntimeHealth = describeRuntimeHealth;
|
|
110
111
|
const fs = __importStar(require("node:fs"));
|
|
111
112
|
const path = __importStar(require("node:path"));
|
|
112
113
|
const node_child_process_1 = require("node:child_process");
|
|
114
|
+
const node_crypto_1 = require("node:crypto");
|
|
113
115
|
const config_js_1 = require("./config.js");
|
|
114
116
|
// ─── Paths ─────────────────────────────────────────────────────────
|
|
115
117
|
/** Root of the runtime store: `<dataDir>/runtime`. */
|
|
@@ -120,6 +122,9 @@ function getRuntimeRoot() {
|
|
|
120
122
|
function getRuntimeStoreDir(version) {
|
|
121
123
|
return path.join(getRuntimeRoot(), version);
|
|
122
124
|
}
|
|
125
|
+
function getRuntimeInstallLockPath() {
|
|
126
|
+
return path.join(getRuntimeRoot(), ".install.lock");
|
|
127
|
+
}
|
|
123
128
|
/** Directory holding the generated entry shims: `<dataDir>/bin`. */
|
|
124
129
|
function getShimDir() {
|
|
125
130
|
return path.join((0, config_js_1.getDataDir)(), "bin");
|
|
@@ -222,7 +227,16 @@ function materializeRuntime(opts) {
|
|
|
222
227
|
const storeDir = getRuntimeStoreDir(version);
|
|
223
228
|
fs.mkdirSync(storeDir, { recursive: true });
|
|
224
229
|
const extras = opts.extraPackages ?? [`${exports.MCP_SERVER_PACKAGE}@${version}`];
|
|
225
|
-
|
|
230
|
+
// npm --no-save prunes packages omitted from a later install into the same
|
|
231
|
+
// prefix. Reinstall every runtime already wired to this shared store so
|
|
232
|
+
// adding one harness cannot remove another harness's package.
|
|
233
|
+
const retained = Object.values(readRuntimeManifest().harnesses)
|
|
234
|
+
.filter((wiring) => wiring.storeDir &&
|
|
235
|
+
path.resolve(wiring.storeDir) === path.resolve(storeDir))
|
|
236
|
+
.map((wiring) => `${wiring.packageName}@${wiring.version}`);
|
|
237
|
+
const specs = [
|
|
238
|
+
...new Set([`${packageName}@${version}`, ...retained, ...extras]),
|
|
239
|
+
];
|
|
226
240
|
const installer = opts.installer ?? exports.defaultNpmInstaller;
|
|
227
241
|
const result = installer({ prefix: storeDir, specs });
|
|
228
242
|
if (!result.ok) {
|
|
@@ -648,6 +662,66 @@ function requireHookCommand(runtime) {
|
|
|
648
662
|
}
|
|
649
663
|
return runtime.hookCommand;
|
|
650
664
|
}
|
|
665
|
+
const RUNTIME_LOCK_TIMEOUT_MS = 5 * 60_000;
|
|
666
|
+
const RUNTIME_LOCK_POLL_MS = 50;
|
|
667
|
+
/** Serialize installs because npm mutates and prunes the shared prefix in place. */
|
|
668
|
+
function withRuntimeInstallLock(action, options = {}) {
|
|
669
|
+
const root = getRuntimeRoot();
|
|
670
|
+
const lockPath = getRuntimeInstallLockPath();
|
|
671
|
+
const deadline = Date.now() + (options.timeoutMs ?? RUNTIME_LOCK_TIMEOUT_MS);
|
|
672
|
+
fs.mkdirSync(root, { recursive: true });
|
|
673
|
+
let fd;
|
|
674
|
+
const token = `${process.pid}:${(0, node_crypto_1.randomUUID)()}`;
|
|
675
|
+
for (;;) {
|
|
676
|
+
try {
|
|
677
|
+
fd = fs.openSync(lockPath, "wx", 0o600);
|
|
678
|
+
fs.writeSync(fd, token);
|
|
679
|
+
break;
|
|
680
|
+
}
|
|
681
|
+
catch (err) {
|
|
682
|
+
if (err.code !== "EEXIST")
|
|
683
|
+
throw err;
|
|
684
|
+
if (Date.now() > deadline) {
|
|
685
|
+
throw new Error(`Timed out waiting for the Ory runtime install lock at ${lockPath}. ` +
|
|
686
|
+
"Remove it only if no other plugin install is running.");
|
|
687
|
+
}
|
|
688
|
+
sleepRuntimeLock(options.pollMs ?? RUNTIME_LOCK_POLL_MS);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
try {
|
|
692
|
+
return action();
|
|
693
|
+
}
|
|
694
|
+
finally {
|
|
695
|
+
try {
|
|
696
|
+
fs.closeSync(fd);
|
|
697
|
+
}
|
|
698
|
+
catch {
|
|
699
|
+
/* best-effort */
|
|
700
|
+
}
|
|
701
|
+
try {
|
|
702
|
+
if (fs.readFileSync(lockPath, "utf8") === token)
|
|
703
|
+
fs.unlinkSync(lockPath);
|
|
704
|
+
}
|
|
705
|
+
catch {
|
|
706
|
+
/* best-effort */
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
let runtimeLockSleepBuffer;
|
|
711
|
+
function sleepRuntimeLock(ms) {
|
|
712
|
+
if (runtimeLockSleepBuffer === undefined) {
|
|
713
|
+
try {
|
|
714
|
+
runtimeLockSleepBuffer = new Int32Array(new SharedArrayBuffer(4));
|
|
715
|
+
}
|
|
716
|
+
catch {
|
|
717
|
+
runtimeLockSleepBuffer = null;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
if (!runtimeLockSleepBuffer) {
|
|
721
|
+
throw new Error("This runtime cannot wait for another Ory plugin install to finish.");
|
|
722
|
+
}
|
|
723
|
+
Atomics.wait(runtimeLockSleepBuffer, 0, 0, ms);
|
|
724
|
+
}
|
|
651
725
|
/**
|
|
652
726
|
* One call per plugin install: resolve the runtime, write the shims, record
|
|
653
727
|
* the wiring, and GC stores nothing references any more.
|
|
@@ -656,6 +730,9 @@ function requireHookCommand(runtime) {
|
|
|
656
730
|
* harness is about to use is never a GC candidate.
|
|
657
731
|
*/
|
|
658
732
|
function wireRuntime(opts) {
|
|
733
|
+
return withRuntimeInstallLock(() => wireRuntimeUnlocked(opts));
|
|
734
|
+
}
|
|
735
|
+
function wireRuntimeUnlocked(opts) {
|
|
659
736
|
const target = resolveRuntimeForInstall({
|
|
660
737
|
packageName: opts.packageName,
|
|
661
738
|
packageRoot: opts.packageRoot,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ory/argus",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Ory Argus: the core API for building authentication, authorization, and audit into AI agent harness plugins, extensions, and custom integrations",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://ory.com",
|