@schoolai/shipyard 3.32.0 → 3.33.0-rc.20260923.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/capability-detector-worker.js +8 -8
- package/dist/{chunk-PVN4AJAH.js → chunk-3PJULQHI.js} +2 -2
- package/dist/{chunk-NFVZCZPA.js → chunk-4WJOA7HF.js} +2 -2
- package/dist/{chunk-RBXWUYDC.js → chunk-DQQOVPVK.js} +2 -2
- package/dist/{chunk-ZDJEJI62.js → chunk-ELZLWLTO.js} +2 -2
- package/dist/{chunk-42SK2S4V.js → chunk-FYT3ETTP.js} +2 -2
- package/dist/{chunk-SGFCXJJJ.js → chunk-JYAI3JHY.js} +2 -2
- package/dist/{chunk-7IS6KGWY.js → chunk-M6XAVFHJ.js} +3 -3
- package/dist/{chunk-FARMJBC7.js → chunk-MV7VSD2T.js} +2 -2
- package/dist/{chunk-FARMJBC7.js.map → chunk-MV7VSD2T.js.map} +1 -1
- package/dist/{chunk-RR6V6SNM.js → chunk-VHPNDDB5.js} +100 -17
- package/dist/chunk-VHPNDDB5.js.map +1 -0
- package/dist/{chunk-5TF227G7.js → chunk-WKJAGQU7.js} +3 -3
- package/dist/{chunk-UIBOKFSG.js → chunk-XPOXRIHH.js} +9 -47
- package/dist/chunk-XPOXRIHH.js.map +1 -0
- package/dist/{chunk-MAA2DPW5.js → chunk-ZXYFMJAS.js} +3 -3
- package/dist/cursor-runner.js +3 -3
- package/dist/electron-utility.js +2 -2
- package/dist/{git-repo-M634UEX7.js → git-repo-K45YAY55.js} +3 -3
- package/dist/index.js +4 -4
- package/dist/{login-6YTDDUP4.js → login-SOAGMUHR.js} +3 -3
- package/dist/{mcp-servers-LTYMM2F2.js → mcp-servers-GHDSX3UE.js} +3 -3
- package/dist/{plan-backfill-52OBXJRO.js → plan-backfill-W4FLMVC6.js} +5 -5
- package/dist/{serve-JVTSDF4E.js → serve-SDRQ7JYB.js} +120 -83
- package/dist/{serve-JVTSDF4E.js.map → serve-SDRQ7JYB.js.map} +1 -1
- package/dist/{skills-BX2NZKPN.js → skills-RO2BW4XO.js} +3 -3
- package/dist/{start-TYBSF7PZ.js → start-DHYV7OQM.js} +6 -6
- package/package.json +2 -3
- package/dist/chunk-RR6V6SNM.js.map +0 -1
- package/dist/chunk-UIBOKFSG.js.map +0 -1
- /package/dist/{chunk-PVN4AJAH.js.map → chunk-3PJULQHI.js.map} +0 -0
- /package/dist/{chunk-NFVZCZPA.js.map → chunk-4WJOA7HF.js.map} +0 -0
- /package/dist/{chunk-RBXWUYDC.js.map → chunk-DQQOVPVK.js.map} +0 -0
- /package/dist/{chunk-ZDJEJI62.js.map → chunk-ELZLWLTO.js.map} +0 -0
- /package/dist/{chunk-42SK2S4V.js.map → chunk-FYT3ETTP.js.map} +0 -0
- /package/dist/{chunk-SGFCXJJJ.js.map → chunk-JYAI3JHY.js.map} +0 -0
- /package/dist/{chunk-7IS6KGWY.js.map → chunk-M6XAVFHJ.js.map} +0 -0
- /package/dist/{chunk-5TF227G7.js.map → chunk-WKJAGQU7.js.map} +0 -0
- /package/dist/{chunk-MAA2DPW5.js.map → chunk-ZXYFMJAS.js.map} +0 -0
- /package/dist/{git-repo-M634UEX7.js.map → git-repo-K45YAY55.js.map} +0 -0
- /package/dist/{login-6YTDDUP4.js.map → login-SOAGMUHR.js.map} +0 -0
- /package/dist/{mcp-servers-LTYMM2F2.js.map → mcp-servers-GHDSX3UE.js.map} +0 -0
- /package/dist/{plan-backfill-52OBXJRO.js.map → plan-backfill-W4FLMVC6.js.map} +0 -0
- /package/dist/{skills-BX2NZKPN.js.map → skills-RO2BW4XO.js.map} +0 -0
- /package/dist/{start-TYBSF7PZ.js.map → start-DHYV7OQM.js.map} +0 -0
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
_resolveBucketForTesting,
|
|
4
4
|
detectSkills,
|
|
5
5
|
scopeEnvironmentsToActiveRepo
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-ELZLWLTO.js";
|
|
7
|
+
import "./chunk-MV7VSD2T.js";
|
|
8
8
|
import "./chunk-EHQITHQX.js";
|
|
9
9
|
import "./chunk-2H7UOFLK.js";
|
|
10
10
|
export {
|
|
@@ -12,4 +12,4 @@ export {
|
|
|
12
12
|
detectSkills,
|
|
13
13
|
scopeEnvironmentsToActiveRepo
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=skills-
|
|
15
|
+
//# sourceMappingURL=skills-RO2BW4XO.js.map
|
|
@@ -3,18 +3,18 @@ import {
|
|
|
3
3
|
createMetricsCollector,
|
|
4
4
|
decideAction,
|
|
5
5
|
makeInitialAttemptState
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4WJOA7HF.js";
|
|
7
7
|
import {
|
|
8
8
|
ensureAuthenticated,
|
|
9
9
|
getSignalingUrl
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-JYAI3JHY.js";
|
|
11
11
|
import {
|
|
12
12
|
print
|
|
13
13
|
} from "./chunk-MM3M2KAC.js";
|
|
14
14
|
import {
|
|
15
15
|
loadAuthToken
|
|
16
16
|
} from "./chunk-XPYW5WQS.js";
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-ZXYFMJAS.js";
|
|
18
18
|
import {
|
|
19
19
|
CRASH_STDERR_DIRNAME,
|
|
20
20
|
EXIT_RECORD_BASENAME,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
import "./chunk-EIWGZUA2.js";
|
|
26
26
|
import "./chunk-Y6AAH7LO.js";
|
|
27
27
|
import "./chunk-ZFKJAYAN.js";
|
|
28
|
-
import "./chunk-
|
|
28
|
+
import "./chunk-MV7VSD2T.js";
|
|
29
29
|
import "./chunk-EHQITHQX.js";
|
|
30
30
|
import {
|
|
31
31
|
logger
|
|
@@ -515,7 +515,7 @@ async function runDaemonChild() {
|
|
|
515
515
|
env.SHIPYARD_USER_ID = authResult.userId;
|
|
516
516
|
env.SHIPYARD_USER_DISPLAY_NAME = authResult.displayName;
|
|
517
517
|
env.SHIPYARD_SIGNALING_URL = authResult.signalingUrl;
|
|
518
|
-
const { serve } = await import("./serve-
|
|
518
|
+
const { serve } = await import("./serve-SDRQ7JYB.js");
|
|
519
519
|
return serve({ isDev: env.SHIPYARD_DEV, autoOpenBrowser: !authResult.deviceFlowRan });
|
|
520
520
|
}
|
|
521
521
|
async function runSupervisor() {
|
|
@@ -606,4 +606,4 @@ async function createSupervisorMetrics(env) {
|
|
|
606
606
|
export {
|
|
607
607
|
startCommand
|
|
608
608
|
};
|
|
609
|
-
//# sourceMappingURL=start-
|
|
609
|
+
//# sourceMappingURL=start-DHYV7OQM.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schoolai/shipyard",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.33.0-rc.20260923.1",
|
|
4
4
|
"description": "Shipyard daemon - collaborative coding agents with Loro CRDT sync",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@cursor/sdk": "1.0.23",
|
|
25
25
|
"@linear/sdk": "82.1.0",
|
|
26
26
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
27
|
-
"@openai/codex": "0.
|
|
27
|
+
"@openai/codex": "0.155.1",
|
|
28
28
|
"@parcel/watcher": "^2.5.6",
|
|
29
29
|
"@typescript/native-preview": "latest",
|
|
30
30
|
"@vscode/ripgrep": "^1.18.0",
|
|
@@ -39,7 +39,6 @@
|
|
|
39
39
|
"open": "^11.0.0",
|
|
40
40
|
"pino": "^10.3.1",
|
|
41
41
|
"pino-roll": "^4.0.0",
|
|
42
|
-
"proper-lockfile": "4.1.2",
|
|
43
42
|
"pyright": "^1.1.410",
|
|
44
43
|
"toml": "^4.1.1",
|
|
45
44
|
"typescript": "^6.0.3",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/fs-utils.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, rename, unlink, writeFile } from 'node:fs/promises';\nimport { dirname, join, parse } from 'node:path';\n\nexport function isEnoent(err: unknown): boolean {\n return typeof err === 'object' && err !== null && 'code' in err && err.code === 'ENOENT';\n}\n\nexport function isEexist(err: unknown): boolean {\n return typeof err === 'object' && err !== null && 'code' in err && err.code === 'EEXIST';\n}\n\n/**\n * Detect JSON parse errors or Zod validation failures that indicate\n * a corrupt store file. Shared across all file-backed stores.\n */\nexport function isCorruptionError(err: unknown): boolean {\n if (err instanceof SyntaxError) return true;\n if (typeof err === 'object' && err !== null && 'name' in err && err.name === 'ZodError')\n return true;\n return false;\n}\n\n/**\n * Write `contents` to `filePath` atomically by writing to a unique tmp\n * path, then `rename`-ing into place.\n *\n * The tmp path includes `pid` + `randomUUID()` so concurrent writers\n * (different daemon processes, parallel test workers) cannot truncate\n * each other's in-flight tmp file. A shared `${filePath}.tmp` is unsafe:\n * if writer A's `open(w)` truncates a tmp that writer B already wrote\n * but hasn't yet renamed, the next `rename(tmp, filePath)` slides a\n * partial 0-byte (or `{`) into the canonical path — exactly the\n * corruption we observed in `rate-limits.json`.\n *\n * `rename` within one filesystem is atomic per POSIX, so a reader either\n * sees the prior canonical file or the fully-written new one. fsync is\n * intentionally NOT called — power-loss durability is not the failure\n * mode we're fixing, and forcing fsync on every store write would slow\n * the daemon meaningfully without addressing the actual race.\n *\n * Pass `mode` to set permissions on the tmp file (used by credentials-\n * vault to preserve `0o600`). Callers are responsible for `mkdir`-ing\n * the parent dir.\n */\nexport async function atomicWriteFile(\n filePath: string,\n contents: string,\n options?: { mode?: number }\n): Promise<void> {\n const tmpPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;\n await writeFile(tmpPath, contents, { encoding: 'utf-8', mode: options?.mode });\n await rename(tmpPath, filePath);\n}\n\ninterface LockRecord {\n pid: number;\n startedAt: number;\n /**\n * Unique per acquisition — guards against a pid+startedAt collision (17\n * daemons can start within the same millisecond) unlinking a live peer's lock.\n */\n id: string;\n}\n\nexport interface WithFileLockOptions {\n /** Max time to wait to acquire before throwing. Default 5000ms. */\n timeoutMs?: number;\n /** Age past which a held lock is considered abandoned. Default 5000ms. */\n staleMs?: number;\n /** Injected in tests; defaults to `Date.now`. */\n now?: () => number;\n /** Injected in tests; defaults to a `process.kill(pid, 0)` liveness probe. */\n isProcessAlive?: (pid: number) => boolean;\n /** Injected in tests; defaults to a real `setTimeout` delay. */\n sleep?: (ms: number) => Promise<void>;\n}\n\nconst LOCK_ACQUIRE_TIMEOUT_MS = 5_000;\n/**\n * Stale-takeover age must be well ABOVE the acquire timeout so a live holder\n * whose critical section runs longer than a waiter's timeout is never declared\n * stale and stolen (which would run two `fn`s concurrently). A crashed holder\n * is still reclaimed immediately via the PID-liveness check; this age is only\n * the backstop for PID reuse.\n */\nconst LOCK_STALE_MS = 30_000;\nconst LOCK_BACKOFF_BASE_MS = 5;\nconst LOCK_BACKOFF_CAP_MS = 50;\n\n/**\n * Pure predicate: is an existing lock safe to steal? Stale when the owner PID\n * is no longer alive, or it has been held longer than `staleMs` (a backstop\n * against a crashed owner whose PID was later reused). Mirrors\n * `self-update-lock.ts:isStaleLock`; duplicated here because `fs-utils` is a\n * lower layer and must not import from `services/` (that would be a cycle).\n */\nexport function isLockStale(\n lock: { pid: number; startedAt: number },\n nowMs: number,\n staleMs: number,\n isProcessAlive: (pid: number) => boolean\n): boolean {\n if (nowMs - lock.startedAt > staleMs) return true;\n if (!isProcessAlive(lock.pid)) return true;\n return false;\n}\n\n/**\n * Run `fn` while holding a cross-process advisory lock at `lockPath`.\n *\n * Cross-process safe via O_EXCL (`wx`) create — exactly one process wins the\n * create; losers inspect the existing lock and either wait (live owner) or\n * steal it (stale owner). Throws if the lock cannot be acquired within\n * `timeoutMs`: callers MUST treat a throw as \"did not run\". For credential /\n * record writes, failing the write (and retrying later) is strictly safer than\n * proceeding unlocked and clobbering another daemon's concurrent write.\n *\n * The lock is released in a `finally`, and only if we still own it — guarding\n * against unlinking a successor's lock when our `fn` overran `staleMs` and a\n * peer stole the lock mid-flight.\n */\nexport async function withFileLock<T>(\n lockPath: string,\n fn: () => Promise<T>,\n options?: WithFileLockOptions\n): Promise<T> {\n const settings = resolveLockSettings(options);\n const owner: LockRecord = { pid: process.pid, startedAt: settings.now(), id: randomUUID() };\n\n await mkdir(dirname(lockPath), { recursive: true });\n await acquireFileLock(lockPath, owner, settings);\n\n try {\n return await fn();\n } finally {\n await releaseLockIfOwner(lockPath, owner);\n }\n}\n\ninterface LockSettings {\n timeoutMs: number;\n staleMs: number;\n now: () => number;\n isProcessAlive: (pid: number) => boolean;\n sleep: (ms: number) => Promise<void>;\n}\n\nfunction resolveLockSettings(options?: WithFileLockOptions): LockSettings {\n return {\n timeoutMs: options?.timeoutMs ?? LOCK_ACQUIRE_TIMEOUT_MS,\n staleMs: options?.staleMs ?? LOCK_STALE_MS,\n now: options?.now ?? Date.now,\n isProcessAlive: options?.isProcessAlive ?? defaultIsProcessAlive,\n sleep: options?.sleep ?? defaultSleep,\n };\n}\n\n/**\n * Throw rather than return on timeout: a write that cannot take the lock must\n * NOT silently proceed unlocked, which would reintroduce the whole-file clobber.\n */\nasync function acquireFileLock(\n lockPath: string,\n owner: LockRecord,\n settings: LockSettings\n): Promise<void> {\n const deadline = settings.now() + settings.timeoutMs;\n let attempt = 0;\n\n while (true) {\n try {\n await writeFile(lockPath, JSON.stringify(owner), { flag: 'wx', mode: 0o600 });\n return;\n } catch (err) {\n if (!isEexist(err)) throw err;\n if (\n await tryStealStaleLock(lockPath, settings.now(), settings.staleMs, settings.isProcessAlive)\n )\n continue;\n if (settings.now() >= deadline) {\n throw new Error(\n `withFileLock: timed out acquiring ${lockPath} after ${settings.timeoutMs}ms`\n );\n }\n attempt += 1;\n await settings.sleep(backoffDelay(attempt));\n }\n }\n}\n\nfunction defaultSleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction defaultIsProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n /** EPERM => the process exists but we lack permission to signal it. */\n return typeof err === 'object' && err !== null && 'code' in err && err.code === 'EPERM';\n }\n}\n\nfunction backoffDelay(attempt: number): number {\n const base = Math.min(LOCK_BACKOFF_BASE_MS * 2 ** (attempt - 1), LOCK_BACKOFF_CAP_MS);\n return base + Math.random() * LOCK_BACKOFF_BASE_MS;\n}\n\nfunction parseLockRecord(raw: string): LockRecord | null {\n let value: unknown;\n try {\n value = JSON.parse(raw);\n } catch {\n return null;\n }\n if (typeof value !== 'object' || value === null) return null;\n const pid = Reflect.get(value, 'pid');\n const startedAt = Reflect.get(value, 'startedAt');\n const id = Reflect.get(value, 'id');\n if (typeof pid === 'number' && typeof startedAt === 'number' && typeof id === 'string') {\n return { pid, startedAt, id };\n }\n return null;\n}\n\nasync function tryStealStaleLock(\n lockPath: string,\n nowMs: number,\n staleMs: number,\n isProcessAlive: (pid: number) => boolean\n): Promise<boolean> {\n let existing: LockRecord | null;\n try {\n existing = parseLockRecord(await readFile(lockPath, 'utf-8'));\n } catch (err) {\n if (isEnoent(err)) return true;\n return false;\n }\n if (!existing) {\n await unlinkIfExists(lockPath);\n return true;\n }\n if (!isLockStale(existing, nowMs, staleMs, isProcessAlive)) return false;\n await unlinkMatching(lockPath, existing);\n return true;\n}\n\nasync function unlinkMatching(lockPath: string, expected: LockRecord): Promise<void> {\n try {\n const current = parseLockRecord(await readFile(lockPath, 'utf-8'));\n if (current && current.id !== expected.id) {\n return;\n }\n } catch (err) {\n if (isEnoent(err)) return;\n }\n await unlinkIfExists(lockPath);\n}\n\nasync function releaseLockIfOwner(lockPath: string, owner: LockRecord): Promise<void> {\n try {\n const current = parseLockRecord(await readFile(lockPath, 'utf-8'));\n if (current && current.id !== owner.id) {\n return;\n }\n } catch (err) {\n if (isEnoent(err)) return;\n }\n await unlinkIfExists(lockPath);\n}\n\nasync function unlinkIfExists(path: string): Promise<void> {\n try {\n await unlink(path);\n } catch (err) {\n if (!isEnoent(err)) throw err;\n }\n}\n\n/**\n * Walk up the directory tree from `startDir` to find the project root.\n *\n * Looks for `.git` (directory or file — worktrees use a `.git` file) or\n * `pnpm-workspace.yaml` as root markers.\n *\n * Returns a discriminated result so callers can distinguish \"marker found\"\n * (genuinely scoped, even if the marker is in startDir itself) from\n * \"no marker anywhere\" (genuinely unscoped). The bare-string return shape\n * conflated these, since both cases produced `startDir` — breaking the\n * unscoped detection in `serve.ts` whenever the daemon was launched from\n * a project's own root directory.\n *\n * In dev: `startDir` is typically `apps/daemon/` (pnpm runs from package dir),\n * so this walks up to find the monorepo root. In prod install: `startDir` is\n * the user's project directory where the daemon is launched, and `.git` is\n * found immediately. Called once at daemon startup — the result is used as\n * the workspace root for file-io, LSP, and file watching.\n */\nexport function findProjectRoot(startDir: string): { root: string; foundMarker: boolean } {\n let dir = startDir;\n while (true) {\n if (existsSync(join(dir, 'pnpm-workspace.yaml')) || existsSync(join(dir, '.git'))) {\n return { root: dir, foundMarker: true };\n }\n const parent = dirname(dir);\n if (parent === dir || parent === parse(dir).root) {\n return { root: startDir, foundMarker: false };\n }\n dir = parent;\n }\n}\n"],"mappings":"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","names":[]}
|