@kubb/studio 5.2.4 → 5.2.6
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.cjs +49 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.js +51 -9
- package/dist/index.js.map +1 -1
- package/dist/protocol.cjs +8 -0
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.ts +584 -2
- package/dist/protocol.js +7 -1
- package/dist/protocol.js.map +1 -1
- package/package.json +4 -4
- package/dist/index-V3fjg2mj.d.ts +0 -569
package/dist/index.cjs
CHANGED
|
@@ -564,12 +564,14 @@ async function disconnect({ sessionId, token, studioUrl, slug }) {
|
|
|
564
564
|
});
|
|
565
565
|
console.log((0, node_util.styleText)("green", `[${tag}] Disconnected from Studio`));
|
|
566
566
|
} catch (error) {
|
|
567
|
+
const statusCode = error?.statusCode;
|
|
568
|
+
if (statusCode !== void 0 && statusCode >= 400 && statusCode < 500) return;
|
|
567
569
|
console.warn((0, node_util.styleText)("yellow", `[${tag}] Failed to notify Studio of disconnection: ${getErrorMessage(error)}`));
|
|
568
570
|
}
|
|
569
571
|
}
|
|
570
572
|
//#endregion
|
|
571
573
|
//#region package.json
|
|
572
|
-
var version = "5.2.
|
|
574
|
+
var version = "5.2.6";
|
|
573
575
|
//#endregion
|
|
574
576
|
//#region src/hooks.ts
|
|
575
577
|
/**
|
|
@@ -1522,6 +1524,9 @@ const CONNECT_TIMEOUT_MS = 5e3;
|
|
|
1522
1524
|
*/
|
|
1523
1525
|
const eventSeqCounters = /* @__PURE__ */ new WeakMap();
|
|
1524
1526
|
const require$1 = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
1527
|
+
function relativeStoragePath(root, filePath) {
|
|
1528
|
+
return ((0, node_path.isAbsolute)(filePath) ? (0, node_path.relative)((0, node_path.resolve)(root), filePath) : filePath).replaceAll("\\", "/");
|
|
1529
|
+
}
|
|
1525
1530
|
async function resolvePeerDependencies(names) {
|
|
1526
1531
|
const uniqueNames = [...new Set(names.map(toPackageName))];
|
|
1527
1532
|
const peerDependencies = {};
|
|
@@ -1576,9 +1581,10 @@ function sendAgentMessage(ws$3, message) {
|
|
|
1576
1581
|
* Sends a single `kubb:error` payload to Studio, stamped from the same per-socket counter the event stream
|
|
1577
1582
|
* uses so Studio can still order it against the generation events around it.
|
|
1578
1583
|
*/
|
|
1579
|
-
function sendErrorMessage(ws$4, error) {
|
|
1584
|
+
function sendErrorMessage(ws$4, error, jobId) {
|
|
1580
1585
|
sendAgentMessage(ws$4, {
|
|
1581
1586
|
type: "agent:data",
|
|
1587
|
+
jobId,
|
|
1582
1588
|
payload: {
|
|
1583
1589
|
type: "kubb:error",
|
|
1584
1590
|
data: [{
|
|
@@ -1593,7 +1599,7 @@ function sendErrorMessage(ws$4, error) {
|
|
|
1593
1599
|
/**
|
|
1594
1600
|
* Forwards selected Kubb lifecycle events to Studio as data messages for the active session.
|
|
1595
1601
|
*/
|
|
1596
|
-
function setupEventsStream(ws$5, hooks) {
|
|
1602
|
+
function setupEventsStream(ws$5, hooks, jobId) {
|
|
1597
1603
|
const unhooks = [];
|
|
1598
1604
|
/**
|
|
1599
1605
|
* Registers a listener and keeps its remover, so one generation's listeners come off the session
|
|
@@ -1605,6 +1611,7 @@ function setupEventsStream(ws$5, hooks) {
|
|
|
1605
1611
|
function sendDataMessage(payload) {
|
|
1606
1612
|
sendAgentMessage(ws$5, {
|
|
1607
1613
|
type: "agent:data",
|
|
1614
|
+
jobId,
|
|
1608
1615
|
payload: {
|
|
1609
1616
|
...payload,
|
|
1610
1617
|
timestamp: Date.now(),
|
|
@@ -1703,7 +1710,7 @@ function setupEventsStream(ws$5, hooks) {
|
|
|
1703
1710
|
limit: FILE_READ_CONCURRENCY,
|
|
1704
1711
|
run: async (path) => {
|
|
1705
1712
|
const content = await storage.readItem(path);
|
|
1706
|
-
if (content !== null) files[path] = content;
|
|
1713
|
+
if (content !== null) files[relativeStoragePath(config.root, path)] = content;
|
|
1707
1714
|
}
|
|
1708
1715
|
});
|
|
1709
1716
|
sendDataMessage({
|
|
@@ -1791,6 +1798,12 @@ function setupEventsStream(ws$5, hooks) {
|
|
|
1791
1798
|
//#endregion
|
|
1792
1799
|
//#region src/StudioSession.ts
|
|
1793
1800
|
/**
|
|
1801
|
+
* How long the `agent:connect` handshake may go unacknowledged before `studio:ready` is given up
|
|
1802
|
+
* on for this open. A Studio that predates the ack never sends one, so this only ever produces a
|
|
1803
|
+
* warning, not a reconnect.
|
|
1804
|
+
*/
|
|
1805
|
+
const READY_TIMEOUT_MS = 1e4;
|
|
1806
|
+
/**
|
|
1794
1807
|
* Fills in a host's options: the hosted Studio URL, the current working directory, and every
|
|
1795
1808
|
* permission off unless granted. Idempotent, so a reconnect can pass an already-resolved bag
|
|
1796
1809
|
* back in.
|
|
@@ -1858,9 +1871,11 @@ var StudioSession = class {
|
|
|
1858
1871
|
#session;
|
|
1859
1872
|
#ws;
|
|
1860
1873
|
#studioVersion;
|
|
1874
|
+
#activeJobId = null;
|
|
1861
1875
|
#disposed = false;
|
|
1862
1876
|
#isGenerating = false;
|
|
1863
1877
|
#heartbeatTimer;
|
|
1878
|
+
#readyTimer;
|
|
1864
1879
|
#lastPongAt = Date.now();
|
|
1865
1880
|
constructor(options) {
|
|
1866
1881
|
this.#options = applyStudioDefaults(options);
|
|
@@ -1904,7 +1919,7 @@ var StudioSession = class {
|
|
|
1904
1919
|
signal?.addEventListener("abort", this.#onAbort, { once: true });
|
|
1905
1920
|
this.#unhooks.push(() => signal?.removeEventListener("abort", this.#onAbort));
|
|
1906
1921
|
this.#heartbeatTimer = setInterval(() => this.#sendHeartbeat(), heartbeatInterval);
|
|
1907
|
-
this.#unhooks.push(this.#hooks.hook("kubb:error", ({ error }) => sendErrorMessage(ws, error)));
|
|
1922
|
+
this.#unhooks.push(this.#hooks.hook("kubb:error", ({ error }) => sendErrorMessage(ws, error, this.#activeJobId ?? "connection")));
|
|
1908
1923
|
} catch (error) {
|
|
1909
1924
|
await this.#hooks.callHook("studio:error", { error: toError(error) });
|
|
1910
1925
|
if (error instanceof InvalidAgentTokenError) throw error;
|
|
@@ -1994,10 +2009,24 @@ var StudioSession = class {
|
|
|
1994
2009
|
});
|
|
1995
2010
|
try {
|
|
1996
2011
|
await this.#sendConnectedPayload();
|
|
2012
|
+
this.#waitForReady();
|
|
1997
2013
|
} catch (error) {
|
|
1998
2014
|
await this.#warn(`Failed to send the connect payload: ${getErrorMessage(error)}`);
|
|
1999
2015
|
}
|
|
2000
2016
|
}
|
|
2017
|
+
/**
|
|
2018
|
+
* Arms the timeout for Studio's `studio:ready` acknowledgement. Re-armed on every open, since a
|
|
2019
|
+
* command sent while the agent is not attached is lost either way (see `#sendConnectedPayload`),
|
|
2020
|
+
* so each reconnect needs its own fresh wait.
|
|
2021
|
+
*/
|
|
2022
|
+
#waitForReady() {
|
|
2023
|
+
if (this.#disposed) return;
|
|
2024
|
+
clearTimeout(this.#readyTimer);
|
|
2025
|
+
this.#readyTimer = setTimeout(() => {
|
|
2026
|
+
this.#readyTimer = void 0;
|
|
2027
|
+
Promise.resolve(this.#warn(`Kubb Studio did not confirm the connection was ready within ${READY_TIMEOUT_MS}ms`)).catch(() => {});
|
|
2028
|
+
}, READY_TIMEOUT_MS);
|
|
2029
|
+
}
|
|
2001
2030
|
#onOpen = () => void this.#handleOpen().catch(() => {});
|
|
2002
2031
|
#onAbort = () => void this.#end({
|
|
2003
2032
|
reason: "shutdown",
|
|
@@ -2017,6 +2046,8 @@ var StudioSession = class {
|
|
|
2017
2046
|
dispose(reason = "cleanup") {
|
|
2018
2047
|
clearInterval(this.#heartbeatTimer);
|
|
2019
2048
|
this.#heartbeatTimer = void 0;
|
|
2049
|
+
clearTimeout(this.#readyTimer);
|
|
2050
|
+
this.#readyTimer = void 0;
|
|
2020
2051
|
try {
|
|
2021
2052
|
this.#ws?.close(1e3, reason);
|
|
2022
2053
|
} catch {}
|
|
@@ -2051,6 +2082,12 @@ var StudioSession = class {
|
|
|
2051
2082
|
this.#lastPongAt = Date.now();
|
|
2052
2083
|
return;
|
|
2053
2084
|
}
|
|
2085
|
+
if (require_protocol.isStudioReadyMessage(data)) {
|
|
2086
|
+
clearTimeout(this.#readyTimer);
|
|
2087
|
+
this.#readyTimer = void 0;
|
|
2088
|
+
await this.#hooks.callHook("studio:ready", {});
|
|
2089
|
+
return;
|
|
2090
|
+
}
|
|
2054
2091
|
if (require_protocol.isDisconnectMessage(data)) {
|
|
2055
2092
|
await this.#handleDisconnect(data.reason);
|
|
2056
2093
|
return;
|
|
@@ -2103,6 +2140,7 @@ var StudioSession = class {
|
|
|
2103
2140
|
return;
|
|
2104
2141
|
}
|
|
2105
2142
|
this.#isGenerating = true;
|
|
2143
|
+
this.#activeJobId = data.jobId;
|
|
2106
2144
|
try {
|
|
2107
2145
|
const config = await loadConfig();
|
|
2108
2146
|
const patch = data.payload;
|
|
@@ -2115,7 +2153,7 @@ var StudioSession = class {
|
|
|
2115
2153
|
await this.#warn(`Ignored the spec from Studio; set ${remedy} to generate from it`);
|
|
2116
2154
|
}
|
|
2117
2155
|
const resolvedPlugins = plugins ?? config.plugins;
|
|
2118
|
-
const detach = [setupHookListener(this.#hooks, root), setupEventsStream(ws, this.#hooks)];
|
|
2156
|
+
const detach = [setupHookListener(this.#hooks, root), setupEventsStream(ws, this.#hooks, data.jobId)];
|
|
2119
2157
|
try {
|
|
2120
2158
|
await generate({
|
|
2121
2159
|
config: {
|
|
@@ -2143,6 +2181,7 @@ var StudioSession = class {
|
|
|
2143
2181
|
});
|
|
2144
2182
|
} finally {
|
|
2145
2183
|
this.#isGenerating = false;
|
|
2184
|
+
this.#activeJobId = null;
|
|
2146
2185
|
}
|
|
2147
2186
|
}
|
|
2148
2187
|
async #handleSave(ws, data, command) {
|
|
@@ -2151,6 +2190,7 @@ var StudioSession = class {
|
|
|
2151
2190
|
await this.#warn("Ignored save: the message carried no edits");
|
|
2152
2191
|
sendAgentMessage(ws, {
|
|
2153
2192
|
type: "agent:save",
|
|
2193
|
+
jobId: data.jobId,
|
|
2154
2194
|
payload: {
|
|
2155
2195
|
outcomes: [],
|
|
2156
2196
|
changed: false
|
|
@@ -2161,6 +2201,7 @@ var StudioSession = class {
|
|
|
2161
2201
|
const edits = data.edits;
|
|
2162
2202
|
const refuse = (reason) => sendAgentMessage(ws, {
|
|
2163
2203
|
type: "agent:save",
|
|
2204
|
+
jobId: data.jobId,
|
|
2164
2205
|
payload: {
|
|
2165
2206
|
outcomes: edits.map((edit) => ({
|
|
2166
2207
|
edit,
|
|
@@ -2184,6 +2225,7 @@ var StudioSession = class {
|
|
|
2184
2225
|
if (changed) await (0, node_fs_promises.writeFile)(configFile, patched, "utf-8");
|
|
2185
2226
|
sendAgentMessage(ws, {
|
|
2186
2227
|
type: "agent:save",
|
|
2228
|
+
jobId: data.jobId,
|
|
2187
2229
|
payload: {
|
|
2188
2230
|
outcomes,
|
|
2189
2231
|
changed,
|
|
@@ -2409,6 +2451,7 @@ exports.InvalidAgentTokenError = InvalidAgentTokenError;
|
|
|
2409
2451
|
exports.PairingCanceledError = PairingCanceledError;
|
|
2410
2452
|
exports.createClient = createClient;
|
|
2411
2453
|
exports.createFileStorage = createFileStorage;
|
|
2454
|
+
exports.createJobId = require_protocol.createJobId;
|
|
2412
2455
|
exports.defaultStudioUrl = defaultStudioUrl;
|
|
2413
2456
|
exports.pollForPairingToken = pollForPairingToken;
|
|
2414
2457
|
exports.runConnection = runConnection;
|