loadout-ai 0.9.2 → 0.9.4
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/CHANGELOG.md +25 -0
- package/README.md +160 -242
- package/catalog/discovered.json +28808 -27462
- package/dist/src/core/coordination/lock.js +25 -3
- package/dist/src/core/reporting/cli-guide.js +4 -2
- package/docs/DISCOVERED.md +248 -248
- package/docs/REFERENCE.md +6 -2
- package/docs/USER_TEST_GUIDE.md +4 -3
- package/docs/assets/loadout-social-preview.png +0 -0
- package/docs/assets/loadout-unified-workflow-v2.webp +0 -0
- package/docs/superpowers/plans/2026-09-07-public-surface-demo-release.md +181 -0
- package/docs/superpowers/plans/2026-09-07-readme-and-unified-hero.md +380 -0
- package/docs/superpowers/specs/2026-09-07-readme-and-unified-hero-design.md +135 -0
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ import { join } from "node:path";
|
|
|
4
4
|
const LOCK_FILE = "coordination.lock";
|
|
5
5
|
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
6
6
|
const MALFORMED_LOCK_STALE_MS = 30_000;
|
|
7
|
+
const localLockTails = new Map();
|
|
7
8
|
export class CoordinationLockTimeoutError extends Error {
|
|
8
9
|
constructor(timeoutMs) {
|
|
9
10
|
super(`Timed out waiting ${timeoutMs}ms for the coordination lock`);
|
|
@@ -64,9 +65,25 @@ async function releaseOwnedLock(path, token) {
|
|
|
64
65
|
function wait(delayMs) {
|
|
65
66
|
return new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
66
67
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
async function withLocalLock(path, operation) {
|
|
69
|
+
const previous = localLockTails.get(path) ?? Promise.resolve();
|
|
70
|
+
let release = () => undefined;
|
|
71
|
+
const current = new Promise((resolve) => {
|
|
72
|
+
release = resolve;
|
|
73
|
+
});
|
|
74
|
+
const tail = previous.then(() => current);
|
|
75
|
+
localLockTails.set(path, tail);
|
|
76
|
+
await previous;
|
|
77
|
+
try {
|
|
78
|
+
return await operation();
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
release();
|
|
82
|
+
if (localLockTails.get(path) === tail)
|
|
83
|
+
localLockTails.delete(path);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async function withFileLock(path, operation, timeoutMs) {
|
|
70
87
|
const deadline = Date.now() + timeoutMs;
|
|
71
88
|
const token = randomUUID();
|
|
72
89
|
const owner = {
|
|
@@ -138,3 +155,8 @@ export async function withCoordinationLock(coordinationDir, operation, timeoutMs
|
|
|
138
155
|
await releaseOwnedLock(path, token);
|
|
139
156
|
}
|
|
140
157
|
}
|
|
158
|
+
/** Serialize coordination mutations within this process and across processes. */
|
|
159
|
+
export async function withCoordinationLock(coordinationDir, operation, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
160
|
+
const path = join(coordinationDir, LOCK_FILE);
|
|
161
|
+
return withLocalLock(path, () => withFileLock(path, operation, timeoutMs));
|
|
162
|
+
}
|
|
@@ -5,8 +5,10 @@ Loadout — manage the skills, tools, and MCP servers your AI agents use.
|
|
|
5
5
|
FIRST TIME
|
|
6
6
|
|
|
7
7
|
loadout doctor which agents you have, and whether they are healthy
|
|
8
|
-
loadout setup --mode stable
|
|
9
|
-
|
|
8
|
+
loadout setup --mode stable --details
|
|
9
|
+
preview 30 reviewed skills and findings
|
|
10
|
+
loadout setup --mode stable --yes --approve-risk
|
|
11
|
+
install only after reviewing those findings
|
|
10
12
|
|
|
11
13
|
IN A PROJECT
|
|
12
14
|
|