@schoolai/shipyard 3.3.1-rc.20260428.2 → 3.3.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/index.js +2 -2
- package/dist/{serve-6UUDZZYJ.js → serve-K7MIPIVY.js} +99 -55
- package/dist/{serve-6UUDZZYJ.js.map → serve-K7MIPIVY.js.map} +1 -1
- package/dist/{start-3CVST3BN.js → start-OWA2D3PI.js} +2 -2
- package/package.json +1 -1
- /package/dist/{start-3CVST3BN.js.map → start-OWA2D3PI.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -111,7 +111,7 @@ async function handleSubcommand() {
|
|
|
111
111
|
return true;
|
|
112
112
|
}
|
|
113
113
|
if (subcommand === "start") {
|
|
114
|
-
const { startCommand } = await import("./start-
|
|
114
|
+
const { startCommand } = await import("./start-OWA2D3PI.js");
|
|
115
115
|
await startCommand();
|
|
116
116
|
return true;
|
|
117
117
|
}
|
|
@@ -128,7 +128,7 @@ async function main() {
|
|
|
128
128
|
const args = parseCliArgs();
|
|
129
129
|
if (args.serve) {
|
|
130
130
|
await loadAuthFromConfig(env);
|
|
131
|
-
const { serve } = await import("./serve-
|
|
131
|
+
const { serve } = await import("./serve-K7MIPIVY.js");
|
|
132
132
|
return serve({ isDev: env.SHIPYARD_DEV });
|
|
133
133
|
}
|
|
134
134
|
logger.error("Use `shipyard start` to run the daemon. Use --help for usage.");
|
|
@@ -43328,15 +43328,23 @@ function buildSetTaskCwdHandler(deps) {
|
|
|
43328
43328
|
};
|
|
43329
43329
|
}
|
|
43330
43330
|
function buildEnvironmentChangedHandler(deps) {
|
|
43331
|
-
const { daemon } = deps;
|
|
43331
|
+
const { daemon, refreshCapabilities } = deps;
|
|
43332
43332
|
let debounceTimer = null;
|
|
43333
43333
|
return {
|
|
43334
43334
|
onEnvironmentChanged: (cwd) => {
|
|
43335
|
+
if (daemon.preWarmManager.cwd === cwd) {
|
|
43336
|
+
if (debounceTimer) {
|
|
43337
|
+
clearTimeout(debounceTimer);
|
|
43338
|
+
debounceTimer = null;
|
|
43339
|
+
}
|
|
43340
|
+
return;
|
|
43341
|
+
}
|
|
43335
43342
|
daemon.taskManager.setWorkspaceRoot(cwd);
|
|
43336
43343
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
43337
43344
|
debounceTimer = setTimeout(() => {
|
|
43338
43345
|
daemon.preWarmManager.kill();
|
|
43339
43346
|
daemon.preWarmManager.start(cwd);
|
|
43347
|
+
refreshCapabilities();
|
|
43340
43348
|
}, 200);
|
|
43341
43349
|
}
|
|
43342
43350
|
};
|
|
@@ -45766,26 +45774,30 @@ function wireControlChannel(rawChannel, daemon, logAdapter, deps) {
|
|
|
45766
45774
|
const resourceUnsubs = /* @__PURE__ */ new Map();
|
|
45767
45775
|
const commentCrud = wireCommentCrud(daemon, () => controlHandler, logAdapter);
|
|
45768
45776
|
const todoHandlers = buildTodoHandlers(daemon, logAdapter);
|
|
45777
|
+
let capRefreshGeneration = 0;
|
|
45778
|
+
const refreshCapabilitiesAndPush = (failureEvent) => {
|
|
45779
|
+
const gen = ++capRefreshGeneration;
|
|
45780
|
+
daemon.userSettingsStore.getSettings().then(
|
|
45781
|
+
(userSettings) => detectCapabilities(
|
|
45782
|
+
deps?.tokenStore,
|
|
45783
|
+
userSettings.preferredAnthropicAuth ?? void 0,
|
|
45784
|
+
daemon.capabilities?.anthropicAuth
|
|
45785
|
+
)
|
|
45786
|
+
).then((fresh) => {
|
|
45787
|
+
if (gen !== capRefreshGeneration) return;
|
|
45788
|
+
daemon.capabilities = fresh;
|
|
45789
|
+
sendCapabilities(controlHandler);
|
|
45790
|
+
}).catch((err) => {
|
|
45791
|
+
logAdapter({
|
|
45792
|
+
event: failureEvent,
|
|
45793
|
+
error: err instanceof Error ? err.message : String(err)
|
|
45794
|
+
});
|
|
45795
|
+
});
|
|
45796
|
+
};
|
|
45769
45797
|
const worktreeRunner = new WorktreeMachineRunner({
|
|
45770
45798
|
io: defaultWorktreeIO,
|
|
45771
45799
|
sendControl: (msg) => controlHandler.sendControl(msg),
|
|
45772
|
-
refreshCapabilities: () =>
|
|
45773
|
-
daemon.userSettingsStore.getSettings().then(
|
|
45774
|
-
(userSettings) => detectCapabilities(
|
|
45775
|
-
deps?.tokenStore,
|
|
45776
|
-
userSettings.preferredAnthropicAuth ?? void 0,
|
|
45777
|
-
daemon.capabilities?.anthropicAuth
|
|
45778
|
-
)
|
|
45779
|
-
).then((fresh) => {
|
|
45780
|
-
daemon.capabilities = fresh;
|
|
45781
|
-
sendCapabilities(controlHandler);
|
|
45782
|
-
}).catch((err) => {
|
|
45783
|
-
logAdapter({
|
|
45784
|
-
event: "capability_refresh_after_worktree_failed",
|
|
45785
|
-
error: err instanceof Error ? err.message : String(err)
|
|
45786
|
-
});
|
|
45787
|
-
});
|
|
45788
|
-
},
|
|
45800
|
+
refreshCapabilities: () => refreshCapabilitiesAndPush("capability_refresh_after_worktree_failed"),
|
|
45789
45801
|
log: logAdapter
|
|
45790
45802
|
});
|
|
45791
45803
|
const lazyInfraDeps = {
|
|
@@ -45797,6 +45809,7 @@ function wireControlChannel(rawChannel, daemon, logAdapter, deps) {
|
|
|
45797
45809
|
tokenStore: deps?.tokenStore,
|
|
45798
45810
|
logAdapter,
|
|
45799
45811
|
sendCapabilities,
|
|
45812
|
+
refreshCapabilities: () => refreshCapabilitiesAndPush("capability_refresh_after_env_changed_failed"),
|
|
45800
45813
|
worktreeRunner
|
|
45801
45814
|
};
|
|
45802
45815
|
const worktreeHandlers = buildWorktreeHandlers(lazyInfraDeps);
|
|
@@ -48200,9 +48213,10 @@ function handleFileIOChannel(initialCwd, send, log, deps) {
|
|
|
48200
48213
|
respondError(requestId, "Path is not a directory");
|
|
48201
48214
|
return;
|
|
48202
48215
|
}
|
|
48216
|
+
respond({ type: "set_cwd_ack", requestId, canonical });
|
|
48217
|
+
if (canonical === cwd) return;
|
|
48203
48218
|
cwd = canonical;
|
|
48204
48219
|
log({ event: "file_io_cwd_changed", cwd: canonical });
|
|
48205
|
-
respond({ type: "set_cwd_ack", requestId, canonical });
|
|
48206
48220
|
for (const listener of cwdChangeListeners) {
|
|
48207
48221
|
listener(canonical);
|
|
48208
48222
|
}
|
|
@@ -49076,7 +49090,7 @@ function createPtyManager() {
|
|
|
49076
49090
|
}
|
|
49077
49091
|
log.info({ shell, cwd: options.cwd, cols, rows }, "Spawning PTY");
|
|
49078
49092
|
try {
|
|
49079
|
-
process2 = pty.spawn(shell, [
|
|
49093
|
+
process2 = pty.spawn(shell, [], {
|
|
49080
49094
|
name: "xterm-256color",
|
|
49081
49095
|
cols,
|
|
49082
49096
|
rows,
|
|
@@ -49196,10 +49210,8 @@ function createPtyManager() {
|
|
|
49196
49210
|
|
|
49197
49211
|
// src/services/terminal-handler.ts
|
|
49198
49212
|
var MAX_PTYS_DEFAULT = 20;
|
|
49199
|
-
var CWD_TIMEOUT_MS = 5e3;
|
|
49200
49213
|
function handleTerminalChannel(taskId, terminalId, cwd, send, log, deps) {
|
|
49201
49214
|
const maxPtys = deps.maxPtys ?? MAX_PTYS_DEFAULT;
|
|
49202
|
-
let cwdTimer = null;
|
|
49203
49215
|
let disposed = false;
|
|
49204
49216
|
function sendControl(msg) {
|
|
49205
49217
|
if (disposed) return;
|
|
@@ -49277,6 +49289,7 @@ function handleTerminalChannel(taskId, terminalId, cwd, send, log, deps) {
|
|
|
49277
49289
|
});
|
|
49278
49290
|
pty2.setExitSink((exitCode3) => {
|
|
49279
49291
|
sendControl({ type: "exited", exitCode: exitCode3 });
|
|
49292
|
+
log({ event: "terminal_exited", taskId, terminalId, exitCode: exitCode3 });
|
|
49280
49293
|
});
|
|
49281
49294
|
log({ event: "terminal_reattached", taskId, terminalId, pid: pty2.pid });
|
|
49282
49295
|
}
|
|
@@ -49292,25 +49305,7 @@ function handleTerminalChannel(taskId, terminalId, cwd, send, log, deps) {
|
|
|
49292
49305
|
}
|
|
49293
49306
|
return spawnPty(spawnCwd);
|
|
49294
49307
|
}
|
|
49295
|
-
let ptyRef =
|
|
49296
|
-
let cwdReceived = false;
|
|
49297
|
-
function cancelCwdTimer() {
|
|
49298
|
-
if (cwdTimer) {
|
|
49299
|
-
clearTimeout(cwdTimer);
|
|
49300
|
-
cwdTimer = null;
|
|
49301
|
-
}
|
|
49302
|
-
}
|
|
49303
|
-
function forceSpawn() {
|
|
49304
|
-
cwdReceived = true;
|
|
49305
|
-
cancelCwdTimer();
|
|
49306
|
-
ptyRef = ensurePty(cwd);
|
|
49307
|
-
}
|
|
49308
|
-
cwdTimer = setTimeout(() => {
|
|
49309
|
-
cwdTimer = null;
|
|
49310
|
-
if (!cwdReceived && !disposed) {
|
|
49311
|
-
ptyRef = ensurePty(cwd);
|
|
49312
|
-
}
|
|
49313
|
-
}, CWD_TIMEOUT_MS);
|
|
49308
|
+
let ptyRef = ensurePty(cwd);
|
|
49314
49309
|
function handleControl(payload) {
|
|
49315
49310
|
const parsed = TerminalControlMessageSchema.safeParse(JSON.parse(payload));
|
|
49316
49311
|
if (!parsed.success) {
|
|
@@ -49320,8 +49315,6 @@ function handleTerminalChannel(taskId, terminalId, cwd, send, log, deps) {
|
|
|
49320
49315
|
const msg = parsed.data;
|
|
49321
49316
|
switch (msg.type) {
|
|
49322
49317
|
case "cwd":
|
|
49323
|
-
cwdReceived = true;
|
|
49324
|
-
cancelCwdTimer();
|
|
49325
49318
|
if (!ptyRef) ptyRef = ensurePty(msg.path);
|
|
49326
49319
|
return;
|
|
49327
49320
|
case "resize":
|
|
@@ -49344,15 +49337,11 @@ function handleTerminalChannel(taskId, terminalId, cwd, send, log, deps) {
|
|
|
49344
49337
|
}
|
|
49345
49338
|
return;
|
|
49346
49339
|
}
|
|
49347
|
-
if (!ptyRef)
|
|
49340
|
+
if (!ptyRef) ptyRef = ensurePty(cwd);
|
|
49348
49341
|
if (ptyRef?.alive) ptyRef.write(data);
|
|
49349
49342
|
}
|
|
49350
49343
|
function dispose() {
|
|
49351
49344
|
disposed = true;
|
|
49352
|
-
if (cwdTimer) {
|
|
49353
|
-
clearTimeout(cwdTimer);
|
|
49354
|
-
cwdTimer = null;
|
|
49355
|
-
}
|
|
49356
49345
|
if (ptyRef) {
|
|
49357
49346
|
ptyRef.setDataSink(null);
|
|
49358
49347
|
ptyRef.setExitSink(null);
|
|
@@ -100457,6 +100446,26 @@ function buildJsonlConversationStore(dataDir) {
|
|
|
100457
100446
|
});
|
|
100458
100447
|
return [...fresh];
|
|
100459
100448
|
}
|
|
100449
|
+
async function refreshCacheAfterAppend(channelId, appended) {
|
|
100450
|
+
const hit = readCache.get(channelId);
|
|
100451
|
+
if (!hit) return;
|
|
100452
|
+
try {
|
|
100453
|
+
const s2 = await stat13(channelPath(channelId));
|
|
100454
|
+
hit.messages.push(appended);
|
|
100455
|
+
hit.size = s2.size;
|
|
100456
|
+
hit.mtimeMs = s2.mtimeMs;
|
|
100457
|
+
} catch (err) {
|
|
100458
|
+
if (isEnoent(err)) {
|
|
100459
|
+
readCache.delete(channelId);
|
|
100460
|
+
return;
|
|
100461
|
+
}
|
|
100462
|
+
logPerf({
|
|
100463
|
+
event: "perf_jsonl_cache_refresh_stat_failed",
|
|
100464
|
+
channelId,
|
|
100465
|
+
error: err instanceof Error ? err.message : String(err)
|
|
100466
|
+
});
|
|
100467
|
+
}
|
|
100468
|
+
}
|
|
100460
100469
|
function contentFingerprint(message) {
|
|
100461
100470
|
const texts = message.content.filter((b2) => b2.type === "text").map((b2) => b2.type === "text" ? b2.text : "").join("\0");
|
|
100462
100471
|
return `${message.participantId}${texts}`;
|
|
@@ -100594,7 +100603,7 @@ function buildJsonlConversationStore(dataDir) {
|
|
|
100594
100603
|
const prev = channelQueues.get(message.channelId) ?? Promise.resolve();
|
|
100595
100604
|
const next = prev.then(async () => {
|
|
100596
100605
|
await ensureDir();
|
|
100597
|
-
const existing = await
|
|
100606
|
+
const existing = await readLinesCached(message.channelId);
|
|
100598
100607
|
const currentSeq = seqCounters.get(message.channelId);
|
|
100599
100608
|
const decision = classifyDedupResult(
|
|
100600
100609
|
existing,
|
|
@@ -100616,7 +100625,11 @@ function buildJsonlConversationStore(dataDir) {
|
|
|
100616
100625
|
const line = JSON.stringify(rest);
|
|
100617
100626
|
await appendFile2(channelPath(message.channelId), `${line}
|
|
100618
100627
|
`, "utf-8");
|
|
100619
|
-
|
|
100628
|
+
await refreshCacheAfterAppend(message.channelId, {
|
|
100629
|
+
...rest,
|
|
100630
|
+
channelId: message.channelId,
|
|
100631
|
+
seqNo: decision.seqNo
|
|
100632
|
+
});
|
|
100620
100633
|
resolveResult({ seqNo: decision.seqNo, isDuplicate: false, dedupKey: null });
|
|
100621
100634
|
}).catch((err) => {
|
|
100622
100635
|
readCache.delete(message.channelId);
|
|
@@ -103654,6 +103667,13 @@ var Thread = class {
|
|
|
103654
103667
|
#sendControlMessage;
|
|
103655
103668
|
#streamDeltaSinks = /* @__PURE__ */ new Set();
|
|
103656
103669
|
#latestSettings = {};
|
|
103670
|
+
/**
|
|
103671
|
+
* Last values pushed to the live subprocess. Reset to undefined whenever
|
|
103672
|
+
* a fresh subprocess is attached (settings get applied via spawn options
|
|
103673
|
+
* instead). Lets `#applySettingsToSubprocess` skip per-flush IPC roundtrips
|
|
103674
|
+
* when nothing has changed since the previous flush.
|
|
103675
|
+
*/
|
|
103676
|
+
#appliedToSubprocess = {};
|
|
103657
103677
|
#agentParticipantId = PENDING_AGENT_PARTICIPANT_ID;
|
|
103658
103678
|
#ownSessionId = null;
|
|
103659
103679
|
/** Fork retry state */
|
|
@@ -103720,6 +103740,7 @@ var Thread = class {
|
|
|
103720
103740
|
if (config2.onCwdChanged) {
|
|
103721
103741
|
this.#subprocess.setOnCwdChanged(config2.onCwdChanged);
|
|
103722
103742
|
}
|
|
103743
|
+
this.#seedAppliedFromSpawnSettings();
|
|
103723
103744
|
}
|
|
103724
103745
|
const warmState = "warm_idle";
|
|
103725
103746
|
const coldState = "cold_idle";
|
|
@@ -103954,6 +103975,7 @@ var Thread = class {
|
|
|
103954
103975
|
this.#subprocess?.setOnCwdChanged(null);
|
|
103955
103976
|
this.#subprocess?.close();
|
|
103956
103977
|
this.#subprocess = null;
|
|
103978
|
+
this.#appliedToSubprocess = {};
|
|
103957
103979
|
}
|
|
103958
103980
|
setControlChannelSend(send) {
|
|
103959
103981
|
this.#sendControlMessage = send;
|
|
@@ -104138,6 +104160,7 @@ ${conversationReplay}` : conversationReplay;
|
|
|
104138
104160
|
this.#config.mode,
|
|
104139
104161
|
this.#config.onCwdChanged
|
|
104140
104162
|
);
|
|
104163
|
+
this.#seedAppliedFromSpawnSettings();
|
|
104141
104164
|
};
|
|
104142
104165
|
doSpawn().catch((err) => {
|
|
104143
104166
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -104149,6 +104172,20 @@ ${conversationReplay}` : conversationReplay;
|
|
|
104149
104172
|
this.#manager.notifySpawnFailed(msg, this.#lastSpawnInitialContent ?? void 0);
|
|
104150
104173
|
});
|
|
104151
104174
|
}
|
|
104175
|
+
/**
|
|
104176
|
+
* Subprocess spawn applies the latest settings via spawn options. Mirror
|
|
104177
|
+
* those into `#appliedToSubprocess` so the first flush after spawn doesn't
|
|
104178
|
+
* re-issue equivalent IPC roundtrips.
|
|
104179
|
+
*/
|
|
104180
|
+
#seedAppliedFromSpawnSettings() {
|
|
104181
|
+
const s2 = this.#latestSettings;
|
|
104182
|
+
this.#appliedToSubprocess = {
|
|
104183
|
+
permissionMode: s2.permissionMode,
|
|
104184
|
+
model: s2.model,
|
|
104185
|
+
reasoningEffort: s2.reasoningEffort,
|
|
104186
|
+
fastMode: s2.fastMode
|
|
104187
|
+
};
|
|
104188
|
+
}
|
|
104152
104189
|
/**
|
|
104153
104190
|
* Flush #latestSettings to the running subprocess after spawn. Each setting
|
|
104154
104191
|
* is awaited independently and errors are logged but don't abort the flush —
|
|
@@ -104163,23 +104200,28 @@ ${conversationReplay}` : conversationReplay;
|
|
|
104163
104200
|
if (!this.#subprocess) return;
|
|
104164
104201
|
const subprocess = this.#subprocess;
|
|
104165
104202
|
const settings = this.#latestSettings;
|
|
104203
|
+
const applied = this.#appliedToSubprocess;
|
|
104166
104204
|
const permissionMode = settings.permissionMode;
|
|
104167
|
-
if (permissionMode !== void 0) {
|
|
104205
|
+
if (permissionMode !== void 0 && permissionMode !== applied.permissionMode) {
|
|
104168
104206
|
await this.#tryFlush("permission_mode", () => subprocess.setPermissionMode(permissionMode));
|
|
104207
|
+
applied.permissionMode = permissionMode;
|
|
104169
104208
|
}
|
|
104170
104209
|
const model = settings.model;
|
|
104171
|
-
if (model !== void 0) {
|
|
104210
|
+
if (model !== void 0 && model !== applied.model) {
|
|
104172
104211
|
await this.#tryFlush("model", () => subprocess.setModel(model));
|
|
104212
|
+
applied.model = model;
|
|
104173
104213
|
}
|
|
104174
|
-
if (settings.reasoningEffort !== void 0) {
|
|
104214
|
+
if (settings.reasoningEffort !== void 0 && settings.reasoningEffort !== applied.reasoningEffort) {
|
|
104175
104215
|
const patch = translateEffortToFlagSettings(settings.reasoningEffort);
|
|
104176
104216
|
if (patch !== null) {
|
|
104177
104217
|
await this.#tryFlush("effort", () => subprocess.applyFlagSettings(patch));
|
|
104178
104218
|
}
|
|
104219
|
+
applied.reasoningEffort = settings.reasoningEffort;
|
|
104179
104220
|
}
|
|
104180
|
-
if (settings.fastMode !== void 0) {
|
|
104221
|
+
if (settings.fastMode !== void 0 && settings.fastMode !== applied.fastMode) {
|
|
104181
104222
|
const fastMode = settings.fastMode;
|
|
104182
104223
|
await this.#tryFlush("fast_mode", () => subprocess.applyFlagSettings({ fastMode }));
|
|
104224
|
+
applied.fastMode = fastMode;
|
|
104183
104225
|
}
|
|
104184
104226
|
}
|
|
104185
104227
|
async #tryFlush(kind, fn) {
|
|
@@ -104235,10 +104277,12 @@ ${conversationReplay}` : conversationReplay;
|
|
|
104235
104277
|
this.#subprocess?.setOnCwdChanged(null);
|
|
104236
104278
|
this.#subprocess?.close();
|
|
104237
104279
|
this.#subprocess = null;
|
|
104280
|
+
this.#appliedToSubprocess = {};
|
|
104238
104281
|
}
|
|
104239
104282
|
#handleForceKill() {
|
|
104240
104283
|
this.#subprocess?.forceKill();
|
|
104241
104284
|
this.#subprocess = null;
|
|
104285
|
+
this.#appliedToSubprocess = {};
|
|
104242
104286
|
}
|
|
104243
104287
|
/** ------------------------------------------------------------------ */
|
|
104244
104288
|
/** SDK error retry logic */
|
|
@@ -117850,4 +117894,4 @@ export {
|
|
|
117850
117894
|
decideWorkspaceScope,
|
|
117851
117895
|
serve
|
|
117852
117896
|
};
|
|
117853
|
-
//# sourceMappingURL=serve-
|
|
117897
|
+
//# sourceMappingURL=serve-K7MIPIVY.js.map
|