@rivus/agent-kit-collab 0.0.0 → 0.3.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/LICENSE +21 -0
- package/README.md +149 -0
- package/dist/acquire-process-lock-A0oYDN9m.js +311 -0
- package/dist/lanes.d.ts +120 -0
- package/dist/lanes.js +323 -0
- package/dist/lease.d.ts +265 -0
- package/dist/lease.js +670 -0
- package/dist/process-lock.d.ts +58 -0
- package/dist/process-lock.js +2 -0
- package/package.json +66 -6
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Result } from "@rivus/agent-kit/catalog";
|
|
2
|
+
import { Platform } from "@rivus/agent-kit/platform";
|
|
3
|
+
//#region src/process-lock/application/ports.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The part of Platform a process lock uses. With `sqlite` the lock is an exclusive SQLite lock; without it, a lock
|
|
6
|
+
* file. `process` supplies the identity recorded for diagnostics and, for lock files, judged for liveness; it throws
|
|
7
|
+
* on win32, which the lock does not support.
|
|
8
|
+
*/
|
|
9
|
+
type ProcessLockPlatform = Pick<Platform, "fs" | "process" | "clock" | "sqlite">;
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/process-lock/application/holder.d.ts
|
|
12
|
+
/** Who holds or held a process lock, as recorded when it was acquired; it may be stale. */
|
|
13
|
+
interface ProcessLockHolder {
|
|
14
|
+
readonly host: string;
|
|
15
|
+
readonly bootId: string;
|
|
16
|
+
readonly pid: number;
|
|
17
|
+
readonly startTime: number;
|
|
18
|
+
/** Wall-clock milliseconds. */
|
|
19
|
+
readonly acquiredAt: number;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/process-lock/application/acquire-process-lock.d.ts
|
|
23
|
+
interface ProcessLockOptions {
|
|
24
|
+
/** Keep trying while another process holds the lock, instead of returning `ProcessLockHeld` at once. */
|
|
25
|
+
readonly wait?: boolean;
|
|
26
|
+
/** How often a waiting call tries again, in milliseconds; 50 by default. */
|
|
27
|
+
readonly retryMs?: number;
|
|
28
|
+
/** Aborting stops waiting and rejects with `signal.reason`; a lock taken after the abort is released first. */
|
|
29
|
+
readonly signal?: AbortSignal;
|
|
30
|
+
}
|
|
31
|
+
/** A held process lock. Releasing it is the caller's job; the lock also ends when the process exits. */
|
|
32
|
+
interface ProcessLock {
|
|
33
|
+
readonly path: string;
|
|
34
|
+
/** `sqlite` when the platform has SQLite; `file` is the weaker fallback (see `acquireProcessLock`). */
|
|
35
|
+
readonly mechanism: "sqlite" | "file";
|
|
36
|
+
readonly holder: ProcessLockHolder;
|
|
37
|
+
/** Releases the lock; later calls do nothing. */
|
|
38
|
+
release(): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
/** Another process, or another acquisition in this one, holds the lock. */
|
|
41
|
+
interface ProcessLockHeld {
|
|
42
|
+
readonly _tag: "ProcessLockHeld";
|
|
43
|
+
readonly path: string;
|
|
44
|
+
/** What the holder recorded for diagnostics; it may be stale, and is absent when nothing readable was recorded. */
|
|
45
|
+
readonly holder: ProcessLockHolder | undefined;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A single-instance lock on `path`, which must be in an existing local directory (not NFS). With `platform.sqlite`,
|
|
49
|
+
* `path` is a SQLite database held with `locking_mode=EXCLUSIVE`: the kernel releases it when the process exits or
|
|
50
|
+
* crashes, at once, and nothing is ever reclaimed. The holder's identity goes into `<path>.holder` for diagnostics
|
|
51
|
+
* only. Without SQLite, `path` is a lock file that holds the identity itself; a lock file whose holder died is
|
|
52
|
+
* reclaimed on the next attempt, which needs the holder on this host (see `tryFileLock` for the remaining gaps).
|
|
53
|
+
*
|
|
54
|
+
* Supports darwin and linux, where the platform can identify processes.
|
|
55
|
+
*/
|
|
56
|
+
export declare function acquireProcessLock(platform: ProcessLockPlatform, path: string, options?: ProcessLockOptions): Promise<Result<ProcessLock, ProcessLockHeld>>;
|
|
57
|
+
//#endregion
|
|
58
|
+
export type { ProcessLock, ProcessLockHeld, ProcessLockHolder, ProcessLockOptions, ProcessLockPlatform };
|
package/package.json
CHANGED
|
@@ -1,16 +1,76 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rivus/agent-kit-collab",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Collaboration primitives between coding agents: fenced leases, single-instance process locks and keyed scheduling lanes.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/PerfectPan/agent-kit.git",
|
|
9
9
|
"directory": "packages/agent-kit-collab"
|
|
10
10
|
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"exports": {
|
|
14
|
+
"./lease": {
|
|
15
|
+
"types": "./dist/lease.d.ts",
|
|
16
|
+
"default": "./dist/lease.js"
|
|
17
|
+
},
|
|
18
|
+
"./lanes": {
|
|
19
|
+
"types": "./dist/lanes.d.ts",
|
|
20
|
+
"default": "./dist/lanes.js"
|
|
21
|
+
},
|
|
22
|
+
"./process-lock": {
|
|
23
|
+
"types": "./dist/process-lock.d.ts",
|
|
24
|
+
"default": "./dist/process-lock.js"
|
|
25
|
+
},
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=22.13"
|
|
33
|
+
},
|
|
11
34
|
"publishConfig": {
|
|
12
|
-
"access": "public"
|
|
13
|
-
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"zod": "^4.6.5"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@arethetypeswrong/cli": "0.18.5",
|
|
42
|
+
"@effect/vitest": "4.0.1",
|
|
43
|
+
"@perfectpan/lint-config": "github:PerfectPan/lint-config#v0.3.2",
|
|
44
|
+
"@rivus/agent-kit": "0.3.0",
|
|
45
|
+
"@size-limit/preset-small-lib": "14.1.0",
|
|
46
|
+
"@types/node": "24.19.1",
|
|
47
|
+
"effect": "4.0.1",
|
|
48
|
+
"oxc-parser": "0.153.0",
|
|
49
|
+
"oxfmt": "0.71.0",
|
|
50
|
+
"oxlint": "1.86.0",
|
|
51
|
+
"oxlint-tsgolint": "7.0.2003",
|
|
52
|
+
"publint": "0.3.25",
|
|
53
|
+
"size-limit": "14.1.0",
|
|
54
|
+
"tsdown": "0.23.0",
|
|
55
|
+
"typescript": "7.0.2",
|
|
56
|
+
"vitest": "5.0.3"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"@rivus/agent-kit": "^0.3.0",
|
|
60
|
+
"effect": "4.0.1"
|
|
61
|
+
},
|
|
62
|
+
"peerDependenciesMeta": {
|
|
63
|
+
"effect": {
|
|
64
|
+
"optional": true
|
|
65
|
+
}
|
|
14
66
|
},
|
|
15
|
-
"
|
|
16
|
-
|
|
67
|
+
"scripts": {
|
|
68
|
+
"build": "tsdown",
|
|
69
|
+
"check:package": "publint --strict --pack npm && attw --pack . --profile esm-only && size-limit 2>&1 && node scripts/check-dist.ts",
|
|
70
|
+
"lint": "oxlint",
|
|
71
|
+
"typecheck": "tsc -p src/tsconfig.json && tsc -p test/tsconfig.json && tsc -p tsconfig.json",
|
|
72
|
+
"test": "vitest run",
|
|
73
|
+
"format": "oxfmt -c node_modules/@perfectpan/lint-config/oxfmt.json . '!CHANGELOG.*'",
|
|
74
|
+
"format:check": "oxfmt -c node_modules/@perfectpan/lint-config/oxfmt.json --check . '!CHANGELOG.*'"
|
|
75
|
+
}
|
|
76
|
+
}
|