syntaur 0.13.0 → 0.14.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/.claude-plugin/plugin.json +3 -1
- package/README.md +4 -2
- package/dist/dashboard/server.js +64 -3
- package/dist/dashboard/server.js.map +1 -1
- package/dist/db/leases-db.d.ts +50 -1
- package/dist/db/leases-db.js +123 -1
- package/dist/db/leases-db.js.map +1 -1
- package/dist/index.js +621 -103
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/platforms/claude-code/.claude-plugin/plugin.json +3 -1
- package/platforms/claude-code/skills/extend-resource/SKILL.md +83 -0
- package/platforms/claude-code/skills/list-resources/SKILL.md +74 -0
- package/platforms/codex/skills/extend-resource/SKILL.md +83 -0
- package/platforms/codex/skills/list-resources/SKILL.md +74 -0
- package/skills/extend-resource/SKILL.md +83 -0
- package/skills/list-resources/SKILL.md +74 -0
package/README.md
CHANGED
|
@@ -238,9 +238,11 @@ syntaur lease list # pool overview
|
|
|
238
238
|
syntaur lease --help # full subcommand list
|
|
239
239
|
```
|
|
240
240
|
|
|
241
|
-
|
|
241
|
+
Four skills wrap this for agents: **claim-resource**, **release-resource**, **extend-resource**, and **list-resources** — see [`docs/leases/skills.md`](docs/leases/skills.md).
|
|
242
242
|
|
|
243
|
-
|
|
243
|
+
Admin and cleanup commands (`revoke`, `release-all --for`, `inventory delete`, `inventory update`, `member list`, `history`, plus `claim --wait`) are documented in [`docs/leases/cli-reference.md`](docs/leases/cli-reference.md).
|
|
244
|
+
|
|
245
|
+
**v1 scope:** static inventories (you register members), atomic claim, TTL expiry, dashboard view, optional `claim --wait`, fail-fast by default (capacity-1 inventory works as a named lock). **Not in v1:** automatic provisioning / recycling, an in-process plugin SDK, cross-host coordination, SessionEnd auto-release. Members are recycled by the caller's own scripts between leases for now.
|
|
244
246
|
|
|
245
247
|
---
|
|
246
248
|
|
package/dist/dashboard/server.js
CHANGED
|
@@ -8283,6 +8283,65 @@ function createServersRouter(serversDir2, projectsDir, assignmentsDir2) {
|
|
|
8283
8283
|
import { Router as Router3 } from "express";
|
|
8284
8284
|
import { resolve as resolve13 } from "path";
|
|
8285
8285
|
init_fs();
|
|
8286
|
+
|
|
8287
|
+
// src/utils/transcript.ts
|
|
8288
|
+
import { open } from "fs/promises";
|
|
8289
|
+
var MAX_LINES_SCANNED = 50;
|
|
8290
|
+
async function derivePathFromTranscript(transcriptPath) {
|
|
8291
|
+
if (!transcriptPath) return null;
|
|
8292
|
+
let handle;
|
|
8293
|
+
try {
|
|
8294
|
+
handle = await open(transcriptPath, "r");
|
|
8295
|
+
} catch {
|
|
8296
|
+
return null;
|
|
8297
|
+
}
|
|
8298
|
+
try {
|
|
8299
|
+
const stream = handle.createReadStream({ encoding: "utf-8" });
|
|
8300
|
+
let buffer = "";
|
|
8301
|
+
let scanned = 0;
|
|
8302
|
+
for await (const chunk of stream) {
|
|
8303
|
+
buffer += chunk;
|
|
8304
|
+
let nl = buffer.indexOf("\n");
|
|
8305
|
+
while (nl !== -1) {
|
|
8306
|
+
const line = buffer.slice(0, nl);
|
|
8307
|
+
buffer = buffer.slice(nl + 1);
|
|
8308
|
+
const cwd = extractCwd(line);
|
|
8309
|
+
if (cwd) {
|
|
8310
|
+
stream.destroy();
|
|
8311
|
+
return cwd;
|
|
8312
|
+
}
|
|
8313
|
+
scanned++;
|
|
8314
|
+
if (scanned >= MAX_LINES_SCANNED) {
|
|
8315
|
+
stream.destroy();
|
|
8316
|
+
return null;
|
|
8317
|
+
}
|
|
8318
|
+
nl = buffer.indexOf("\n");
|
|
8319
|
+
}
|
|
8320
|
+
}
|
|
8321
|
+
if (buffer.length > 0) {
|
|
8322
|
+
const cwd = extractCwd(buffer);
|
|
8323
|
+
if (cwd) return cwd;
|
|
8324
|
+
}
|
|
8325
|
+
return null;
|
|
8326
|
+
} finally {
|
|
8327
|
+
await handle.close().catch(() => {
|
|
8328
|
+
});
|
|
8329
|
+
}
|
|
8330
|
+
}
|
|
8331
|
+
function extractCwd(line) {
|
|
8332
|
+
const trimmed = line.trim();
|
|
8333
|
+
if (trimmed.length === 0 || trimmed[0] !== "{") return null;
|
|
8334
|
+
try {
|
|
8335
|
+
const parsed = JSON.parse(trimmed);
|
|
8336
|
+
if (typeof parsed.cwd === "string" && parsed.cwd.length > 0) {
|
|
8337
|
+
return parsed.cwd;
|
|
8338
|
+
}
|
|
8339
|
+
} catch {
|
|
8340
|
+
}
|
|
8341
|
+
return null;
|
|
8342
|
+
}
|
|
8343
|
+
|
|
8344
|
+
// src/dashboard/api-agent-sessions.ts
|
|
8286
8345
|
function createAgentSessionsRouter(projectsDir, broadcast, assignmentsDir2) {
|
|
8287
8346
|
const router = Router3();
|
|
8288
8347
|
router.get("/", async (_req, res) => {
|
|
@@ -8330,6 +8389,8 @@ function createAgentSessionsRouter(projectsDir, broadcast, assignmentsDir2) {
|
|
|
8330
8389
|
return;
|
|
8331
8390
|
}
|
|
8332
8391
|
}
|
|
8392
|
+
const derivedPath = await derivePathFromTranscript(transcriptPath);
|
|
8393
|
+
const recordedPath = derivedPath ?? path ?? "";
|
|
8333
8394
|
const session = {
|
|
8334
8395
|
projectSlug: projectSlug || null,
|
|
8335
8396
|
assignmentSlug: assignmentSlug || null,
|
|
@@ -8337,7 +8398,7 @@ function createAgentSessionsRouter(projectsDir, broadcast, assignmentsDir2) {
|
|
|
8337
8398
|
sessionId,
|
|
8338
8399
|
started: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8339
8400
|
status: "active",
|
|
8340
|
-
path:
|
|
8401
|
+
path: recordedPath,
|
|
8341
8402
|
description: description || null,
|
|
8342
8403
|
transcriptPath: transcriptPath || null
|
|
8343
8404
|
};
|
|
@@ -10340,7 +10401,7 @@ init_fs();
|
|
|
10340
10401
|
init_config2();
|
|
10341
10402
|
import { execFile as execFile2 } from "child_process";
|
|
10342
10403
|
import { promisify as promisify2 } from "util";
|
|
10343
|
-
import { cp, mkdtemp, rm as rm2, readFile as readFile14, writeFile as writeFile4, unlink as unlink3, stat, open, rename as rename5 } from "fs/promises";
|
|
10404
|
+
import { cp, mkdtemp, rm as rm2, readFile as readFile14, writeFile as writeFile4, unlink as unlink3, stat, open as open2, rename as rename5 } from "fs/promises";
|
|
10344
10405
|
import { resolve as resolve19, join as join2 } from "path";
|
|
10345
10406
|
import { tmpdir } from "os";
|
|
10346
10407
|
var exec2 = promisify2(execFile2);
|
|
@@ -10395,7 +10456,7 @@ async function acquireLock() {
|
|
|
10395
10456
|
const lockPath = resolve19(syntaurRoot(), LOCK_FILE_NAME);
|
|
10396
10457
|
await ensureDir(syntaurRoot());
|
|
10397
10458
|
try {
|
|
10398
|
-
const handle = await
|
|
10459
|
+
const handle = await open2(lockPath, "wx");
|
|
10399
10460
|
await handle.write(String(process.pid));
|
|
10400
10461
|
await handle.close();
|
|
10401
10462
|
return lockPath;
|