vibe64 0.1.26 → 0.1.28

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.
Files changed (111) hide show
  1. package/dist/assets/{VRadioGroup-D6WRdUau.js → VRadioGroup-BuRMvs7d.js} +1 -1
  2. package/dist/assets/{VTabs-BGX5dGoS.js → VTabs-CQq9CAuT.js} +1 -1
  3. package/dist/assets/{VTextarea-CD6H_mtJ.js → VTextarea-Duvzvmjq.js} +1 -1
  4. package/dist/assets/{Vibe64AsyncModuleState-Cel3OePx.js → Vibe64AsyncModuleState-DuuzlJDp.js} +1 -1
  5. package/dist/assets/{Vibe64AuthSettingsButton-CMMeacsl.js → Vibe64AuthSettingsButton-CKOCL-kl.js} +1 -1
  6. package/dist/assets/{Vibe64DashboardShell-C2UhX2ke.js → Vibe64DashboardShell-DMT8aOp1.js} +1 -1
  7. package/dist/assets/{Vibe64DatabaseWorkspace-C43TE5-O.js → Vibe64DatabaseWorkspace-CqH0zfFZ.js} +1 -1
  8. package/dist/assets/{Vibe64OutputControls-BmzH2ASf.js → Vibe64OutputControls-DDILWOYb.js} +1 -1
  9. package/dist/assets/{Vibe64RepositoryWorkspace-CT9tkvHh.js → Vibe64RepositoryWorkspace-D11BZHtF.js} +1 -1
  10. package/dist/assets/Vibe64SessionFiles-BSoB7Xrs.js +1 -0
  11. package/dist/assets/{Vibe64SessionFiles-CH5PCxwg.css → Vibe64SessionFiles-DVux69YS.css} +1 -1
  12. package/dist/assets/{Vibe64SubsystemsView-DNx-pZp8.js → Vibe64SubsystemsView-tLlxmK3M.js} +1 -1
  13. package/dist/assets/{Vibe64SystemWorldView-UdNJZbqX.js → Vibe64SystemWorldView-8og8TPyL.js} +1 -1
  14. package/dist/assets/{_sessionId_-DZTmI19N.js → _sessionId_-Dts6gv4W.js} +1 -1
  15. package/dist/assets/{_sessionTool_-CugJWIK4.js → _sessionTool_-bHJUlHCW.js} +1 -1
  16. package/dist/assets/_slug_-B3fqw8Sl.js +12 -0
  17. package/dist/assets/_slug_-DfHqx2_b.css +1 -0
  18. package/dist/assets/{dashboard-D4NXqPY1.js → dashboard-CcD6GIaB.js} +1 -1
  19. package/dist/assets/{definitions-CyUCoqu-.js → definitions-ChGXm26a.js} +1 -1
  20. package/dist/assets/{error-kYKTA8fu.js → error-CStS-Kbt.js} +1 -1
  21. package/dist/assets/{index-hy7AAm-B.js → index-B262pg9q.js} +1 -1
  22. package/dist/assets/{index-DX6Rm6jZ.js → index-B_grpOta.js} +1 -1
  23. package/dist/assets/{index-Cpt19GIW.js → index-BtHA_DX9.js} +1 -1
  24. package/dist/assets/{index-SBc6H2In.js → index-C4KnwA0g.js} +4 -4
  25. package/dist/assets/{index-DeRx59Iq.js → index-CC7BFJAg.js} +1 -1
  26. package/dist/assets/{index-6Kv-7k0S.js → index-CKFrWxnr.js} +1 -1
  27. package/dist/assets/{index-BDe3NnFP.js → index-CPG-_bMW.js} +1 -1
  28. package/dist/assets/{index-CuEZOpKL.js → index-CV9pOpbQ.js} +1 -1
  29. package/dist/assets/{index-D4p1hWbM.js → index-DIQxSy1c.js} +1 -1
  30. package/dist/assets/{index-D5vnCntG.js → index-DVaJ8fEr.js} +1 -1
  31. package/dist/assets/{index-BGu7hfTb.js → index-DtGqjUin.js} +1 -1
  32. package/dist/assets/{index-Cca4WXur.js → index-YQALXwL4.js} +1 -1
  33. package/dist/assets/{placement-Nw6LF6xp.js → placement-Cyt3SnRe.js} +1 -1
  34. package/dist/assets/{studioGateApi-B2eiydiA.js → studioGateApi-BwBnOYBp.js} +1 -1
  35. package/dist/assets/{useArchivedVibe64Sessions-LeGda1Y9.js → useArchivedVibe64Sessions-_FKt1-qN.js} +1 -1
  36. package/dist/assets/{useVibe64ConversationLog-BPyKYbvH.js → useVibe64ConversationLog-BjnpqM9K.js} +1 -1
  37. package/dist/assets/{useVibe64ProjectScope-n5T5l2pY.js → useVibe64ProjectScope-DcDkjbLT.js} +1 -1
  38. package/dist/assets/{useVibe64SessionData-BToODuTg.js → useVibe64SessionData-BHLSmuPm.js} +1 -1
  39. package/dist/assets/{useVibe64SessionSelection-D1wXIWTm.js → useVibe64SessionSelection-G6KQKJxb.js} +1 -1
  40. package/dist/assets/{vibe64RepositoryRealtime-Xo7aIksE.js → vibe64RepositoryRealtime-C2WPn5do.js} +1 -1
  41. package/dist/assets/{vibe64SessionInfo-Dy_4bL3a.js → vibe64SessionInfo-8kuxgD5r.js} +1 -1
  42. package/dist/assets/{vibe64SessionPanelModel-5UED-6V-.js → vibe64SessionPanelModel-DDaXjAJ_.js} +1 -1
  43. package/dist/assets/{vibe64SessionRequestConfig-B7Llggdb.js → vibe64SessionRequestConfig-uGWcyQY6.js} +1 -1
  44. package/dist/assets/{vibe64SessionToolDefinitions-C4maKOfp.js → vibe64SessionToolDefinitions-D5CgOIqa.js} +1 -1
  45. package/dist/assets/{vueRefOrGetterValue-_KqAOFjr.js → vueRefOrGetterValue-CV9c3oBd.js} +1 -1
  46. package/dist/index.html +1 -1
  47. package/node_modules/@jskit-ai/connector-google-calendar/package.json +3 -3
  48. package/node_modules/@jskit-ai/connector-google-calendar/patterns/calendar-cli/example/package.json +4 -4
  49. package/node_modules/@jskit-ai/connectors-catalog/package.json +3 -3
  50. package/node_modules/@jskit-ai/connectors-catalog/test/dbt-semantic-layer.test.js +3 -0
  51. package/node_modules/@jskit-ai/connectors-catalog/test/google-ads.test.js +3 -0
  52. package/node_modules/@jskit-ai/connectors-catalog/test/salesforce.test.js +3 -0
  53. package/node_modules/@jskit-ai/connectors-catalog/test/xero.test.js +3 -0
  54. package/node_modules/@jskit-ai/connectors-core/package.json +4 -4
  55. package/node_modules/@jskit-ai/http-web/package.json +6 -6
  56. package/node_modules/@jskit-ai/kernel/package.json +1 -1
  57. package/node_modules/@jskit-ai/kernel/server/runtime/fastifyBootstrap.js +50 -10
  58. package/node_modules/@jskit-ai/kernel/server/runtime/fastifyBootstrap.test.js +38 -0
  59. package/node_modules/@jskit-ai/kernel/shared/support/normalize.js +8 -0
  60. package/node_modules/@jskit-ai/kernel/shared/support/normalize.test.js +10 -0
  61. package/node_modules/@jskit-ai/payments-core/package.json +1 -1
  62. package/node_modules/@jskit-ai/realtime/package.json +3 -3
  63. package/node_modules/@jskit-ai/realtime/patterns/realtime-application/example/package.json +2 -2
  64. package/node_modules/@jskit-ai/resource-core/package.json +2 -2
  65. package/node_modules/@jskit-ai/resource-crud-core/package.json +3 -3
  66. package/node_modules/@jskit-ai/shell-web/package.json +2 -2
  67. package/node_modules/@jskit-ai/uploads-runtime/package.json +2 -2
  68. package/node_modules/@local/current-app/package.json +1 -1
  69. package/node_modules/@local/main/package.json +2 -2
  70. package/node_modules/@local/studio-health/package.json +1 -1
  71. package/node_modules/@local/vibe64-accounts/package.json +3 -3
  72. package/node_modules/@local/vibe64-core/package.json +1 -1
  73. package/node_modules/@local/vibe64-database-tools/package.json +3 -3
  74. package/node_modules/@local/vibe64-project/package.json +1 -1
  75. package/node_modules/@local/vibe64-runtime/src/server/codexAppServerProvider.js +34 -0
  76. package/node_modules/@local/vibe64-sessions/package.json +1 -1
  77. package/node_modules/@local/vibe64-sessions/src/server/sessionRenewal.js +4 -1
  78. package/node_modules/@local/vibe64-source-editor/package.json +5 -5
  79. package/node_modules/@local/vibe64-system-graph/package.json +3 -3
  80. package/node_modules/@local/vibe64-terminals/package.json +2 -2
  81. package/node_modules/@local/vibe64-terminals/src/server/agent/providers/codexSessionAgentProvider.js +6 -0
  82. package/node_modules/@local/vibe64-terminals/src/server/agent/sessionAgentManager.js +16 -0
  83. package/node_modules/@local/vibe64-terminals/src/server/codexTerminal.js +180 -64
  84. package/node_modules/@local/vibe64-terminals/src/server/registerRoutes.js +12 -0
  85. package/node_modules/@local/vibe64-terminals/src/server/service.js +57 -16
  86. package/node_modules/@local/vibe64-terminals/src/server/sessionPromptHints.js +9 -1
  87. package/node_modules/@local/vibe64-terminals/src/server/sessionSaveCommitMessage.js +1 -1
  88. package/package.json +15 -15
  89. package/packages/current-app/package.json +1 -1
  90. package/packages/main/package.json +2 -2
  91. package/packages/studio-health/package.json +1 -1
  92. package/packages/vibe64-accounts/package.json +3 -3
  93. package/packages/vibe64-core/package.json +1 -1
  94. package/packages/vibe64-database-tools/package.json +3 -3
  95. package/packages/vibe64-project/package.json +1 -1
  96. package/packages/vibe64-runtime/src/server/codexAppServerProvider.js +34 -0
  97. package/packages/vibe64-sessions/package.json +1 -1
  98. package/packages/vibe64-sessions/src/server/sessionRenewal.js +4 -1
  99. package/packages/vibe64-source-editor/package.json +5 -5
  100. package/packages/vibe64-system-graph/package.json +3 -3
  101. package/packages/vibe64-terminals/package.json +2 -2
  102. package/packages/vibe64-terminals/src/server/agent/providers/codexSessionAgentProvider.js +6 -0
  103. package/packages/vibe64-terminals/src/server/agent/sessionAgentManager.js +16 -0
  104. package/packages/vibe64-terminals/src/server/codexTerminal.js +180 -64
  105. package/packages/vibe64-terminals/src/server/registerRoutes.js +12 -0
  106. package/packages/vibe64-terminals/src/server/service.js +57 -16
  107. package/packages/vibe64-terminals/src/server/sessionPromptHints.js +9 -1
  108. package/packages/vibe64-terminals/src/server/sessionSaveCommitMessage.js +1 -1
  109. package/dist/assets/Vibe64SessionFiles-BS5MW7Qz.js +0 -1
  110. package/dist/assets/_slug_-BzRzebKA.js +0 -12
  111. package/dist/assets/_slug_-Q7ibe3SE.css +0 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/connector-google-calendar",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "description": "Google Calendar account configuration and event operations for JSKIT connectors.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -11,7 +11,7 @@
11
11
  "./server": "./src/server/provider.js"
12
12
  },
13
13
  "dependencies": {
14
- "@jskit-ai/connectors-core": "0.1.1",
14
+ "@jskit-ai/connectors-core": "0.1.4",
15
15
  "json-rest-schema": "^1.0.17"
16
16
  },
17
17
  "jskit": {
@@ -30,6 +30,6 @@
30
30
  }
31
31
  },
32
32
  "peerDependencies": {
33
- "@jskit-ai/kernel": "0.1.184"
33
+ "@jskit-ai/kernel": "0.1.187"
34
34
  }
35
35
  }
@@ -7,10 +7,10 @@
7
7
  "db:migrate:status": "knex --knexfile ./knexfile.js migrate:list"
8
8
  },
9
9
  "dependencies": {
10
- "@jskit-ai/connectors-core": "0.1.1",
11
- "@jskit-ai/connector-google-calendar": "0.1.1",
12
- "@jskit-ai/database-runtime": "0.1.184",
13
- "@jskit-ai/database-runtime-mysql": "0.1.182",
10
+ "@jskit-ai/connectors-core": "0.1.4",
11
+ "@jskit-ai/connector-google-calendar": "0.1.4",
12
+ "@jskit-ai/database-runtime": "0.1.187",
13
+ "@jskit-ai/database-runtime-mysql": "0.1.185",
14
14
  "knex": "^3.1.0"
15
15
  }
16
16
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/connectors-catalog",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "description": "Provider definitions and focused API operations for JSKIT connectors.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -123,14 +123,14 @@
123
123
  "@aws-sdk/client-redshift-data": "3.1128.0",
124
124
  "@aws-sdk/client-s3": "3.1128.0",
125
125
  "@aws-sdk/s3-request-presigner": "3.1128.0",
126
- "@jskit-ai/connectors-core": "0.1.1",
126
+ "@jskit-ai/connectors-core": "0.1.4",
127
127
  "@modelcontextprotocol/sdk": "1.30.0",
128
128
  "@smithy/fetch-http-handler": "5.8.0",
129
129
  "json-rest-schema": "^1.0.17",
130
130
  "jose": "^6.1.3"
131
131
  },
132
132
  "peerDependencies": {
133
- "@jskit-ai/kernel": "0.1.184"
133
+ "@jskit-ai/kernel": "0.1.187"
134
134
  },
135
135
  "jskit": {
136
136
  "kind": "runtime",
@@ -163,6 +163,9 @@ test("dbt changing environment, host or token reference requires verification fo
163
163
  });
164
164
 
165
165
  test("dbt abort and timeout interrupt requests without replay or automatic page traversal", async (t) => {
166
+ // The fake transport has no socket to keep Node 22 alive for an unrefed timeout.
167
+ const keepAlive = setTimeout(() => {}, 1000);
168
+ t.after(() => clearTimeout(keepAlive));
166
169
  const f = await fixture(t); await f.service.connectApiKey(input); const before = f.requests.length;
167
170
  const controller = new AbortController(); controller.abort();
168
171
  await assert.rejects(f.service.invoke({ ...input, operation: "metrics.list", signal: controller.signal }), { code: "connector_cancelled" });
@@ -241,6 +241,9 @@ test("Google Ads rejects declined or insufficient consent and keeps managed assi
241
241
  });
242
242
 
243
243
  test("Google Ads refresh scope reduction, API cancellation and timeout do not replay requests", async (t) => {
244
+ // The fake transport has no socket to keep Node 22 alive for an unrefed timeout.
245
+ const keepAlive = setTimeout(() => {}, 1000);
246
+ t.after(() => clearTimeout(keepAlive));
244
247
  const f = await fixture(t); await f.connect(); f.state.stall = "api";
245
248
  const timed = createConnectionService({ ...f.options, providers: [{ ...provider, requestTimeoutMs: 20 }] });
246
249
  await assert.rejects(f.invoke(undefined, timed), { code: "connector_provider_timeout" });
@@ -235,6 +235,9 @@ test("Salesforce host policy, cancelled/denied consent and managed references ca
235
235
  });
236
236
 
237
237
  test("Salesforce cancellation and timeout interrupt requests and a revoked refresh becomes reconnect-required", async (t) => {
238
+ // The fake transport has no socket to keep Node 22 alive for an unrefed timeout.
239
+ const keepAlive = setTimeout(() => {}, 1000);
240
+ t.after(() => clearTimeout(keepAlive));
238
241
  const f = await fixture(t); await f.connect(); f.state.stall = "api";
239
242
  const timed = createConnectionService({ ...f.options, providers: [{ ...provider, requestTimeoutMs: 30 }] });
240
243
  await assert.rejects(timed.invoke({ ...input, operation: "limits.read" }), { code: "connector_provider_timeout" });
@@ -248,6 +248,9 @@ test("Xero errors are redacted, never retried and require reconnect after authen
248
248
  });
249
249
 
250
250
  test("Xero interruption and timeout stop before the accounting call and keep the connection usable", async (t) => {
251
+ // The fake transport has no socket to keep Node 22 alive for an unrefed timeout.
252
+ const keepAlive = setTimeout(() => {}, 1000);
253
+ t.after(() => clearTimeout(keepAlive));
251
254
  const f = await fixture(t); await f.connect(); f.state.stall = true;
252
255
  const service = createConnectionService({ ...f.options, providers: [{ ...xeroProvider, requestTimeoutMs: 35 }] });
253
256
  const count = f.requests.length;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/connectors-core",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "description": "Portable integration configuration and server-side account connection runtime.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -53,9 +53,9 @@
53
53
  }
54
54
  },
55
55
  "peerDependencies": {
56
- "@jskit-ai/database-runtime": "0.1.184",
57
- "@jskit-ai/http-runtime": "0.1.182",
58
- "@jskit-ai/kernel": "0.1.184"
56
+ "@jskit-ai/database-runtime": "0.1.187",
57
+ "@jskit-ai/http-runtime": "0.1.185",
58
+ "@jskit-ai/kernel": "0.1.187"
59
59
  },
60
60
  "peerDependenciesMeta": {
61
61
  "@jskit-ai/database-runtime": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/http-web",
3
- "version": "0.1.29",
3
+ "version": "0.1.32",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -44,14 +44,14 @@
44
44
  "./client/support/contractGuards": "./src/client/support/contractGuards.js"
45
45
  },
46
46
  "dependencies": {
47
- "@jskit-ai/resource-crud-core": "0.1.126",
47
+ "@jskit-ai/resource-crud-core": "0.1.129",
48
48
  "@mdi/js": "^7.4.47"
49
49
  },
50
50
  "peerDependencies": {
51
- "@jskit-ai/http-runtime": "0.1.182",
52
- "@jskit-ai/kernel": "0.1.184",
53
- "@jskit-ai/realtime": "0.1.181",
54
- "@jskit-ai/shell-web": "0.1.188",
51
+ "@jskit-ai/http-runtime": "0.1.185",
52
+ "@jskit-ai/kernel": "0.1.187",
53
+ "@jskit-ai/realtime": "0.1.184",
54
+ "@jskit-ai/shell-web": "0.1.191",
55
55
  "@tanstack/vue-query": "^5.90.5",
56
56
  "vue": "^3.5.13",
57
57
  "vue-router": "^5.0.4",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/kernel",
3
- "version": "0.1.184",
3
+ "version": "0.1.187",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "json-rest-schema": "^1.0.17"
@@ -1,5 +1,5 @@
1
1
  import { ActionRuntimeError } from "../../shared/actions/actionDefinitions.js";
2
- import { normalizeOpaqueId } from "../../shared/support/normalize.js";
2
+ import { normalizeOpaqueId, normalizeTransactionOutcome } from "../../shared/support/normalize.js";
3
3
  import { resolveDefaultSurfaceId } from "../support/appConfig.js";
4
4
 
5
5
  const JSON_API_CONTENT_TYPE = "application/vnd.api+json";
@@ -255,7 +255,9 @@ function resolveRequestRouteTransport(request) {
255
255
 
256
256
  function applyRouteTransportErrorResponse(reply, request, error, {
257
257
  statusCode = 500,
258
- normalizedErrorCode = ""
258
+ normalizedErrorCode = "",
259
+ message = error?.message,
260
+ exposeDetails = true
259
261
  } = {}) {
260
262
  const transport = resolveRequestRouteTransport(request);
261
263
  const errorSerializer = transport && typeof transport.error === "function" ? transport.error : null;
@@ -267,7 +269,9 @@ function applyRouteTransportErrorResponse(reply, request, error, {
267
269
  request,
268
270
  reply,
269
271
  statusCode,
270
- code: normalizedErrorCode
272
+ code: normalizedErrorCode,
273
+ message,
274
+ exposeDetails
271
275
  });
272
276
 
273
277
  if (payload && typeof payload.then === "function") {
@@ -282,6 +286,36 @@ function applyRouteTransportErrorResponse(reply, request, error, {
282
286
  return true;
283
287
  }
284
288
 
289
+ function resolveApiErrorStatus(error, code) {
290
+ // JSON REST's public error codes need HTTP classification even without status hints.
291
+ switch (code) {
292
+ case "REST_API_VALIDATION":
293
+ return 422;
294
+ case "REST_API_RESOURCE":
295
+ switch (error?.subtype) {
296
+ case "not_found": return 404;
297
+ case "forbidden": return 403;
298
+ case "conflict": return 409;
299
+ default: return 400;
300
+ }
301
+ case "REST_API_VERSION_CONFLICT":
302
+ return 409;
303
+ case "REST_API_PRECONDITION_FAILED":
304
+ return 412;
305
+ case "REST_API_FIELDSET_INVALID":
306
+ case "REST_API_INCLUDE_INVALID":
307
+ return 400;
308
+ case "REST_API_PAYLOAD":
309
+ return error?.statusCode === 413 ? 413 : 400;
310
+ case "REST_API_TEMPORAL_DATA_INVALID":
311
+ return 500;
312
+ default: {
313
+ const status = Number(error?.statusCode || error?.status);
314
+ return Number.isInteger(status) && status >= 400 && status <= 599 ? status : 500;
315
+ }
316
+ }
317
+ }
318
+
285
319
  function registerApiErrorHandler(
286
320
  app,
287
321
  {
@@ -308,10 +342,10 @@ function registerApiErrorHandler(
308
342
 
309
343
  app.setErrorHandler((error, request, reply) => {
310
344
  const normalizedErrorCode = String(error?.code || "").trim();
345
+ const transactionOutcome = normalizeTransactionOutcome(error?.transactionOutcome);
346
+ const outcomeFields = transactionOutcome ? { transactionOutcome } : {};
311
347
  const isCsrfErrorCode = normalizedErrorCode.startsWith("FST_CSRF_");
312
- const statusFromError = Number(error?.statusCode || error?.status);
313
- const statusCode =
314
- Number.isInteger(statusFromError) && statusFromError >= 400 && statusFromError <= 599 ? statusFromError : 500;
348
+ const statusCode = resolveApiErrorStatus(error, normalizedErrorCode);
315
349
 
316
350
  if (Array.isArray(error?.validation)) {
317
351
  const fieldErrors = resolveValidationFieldErrors(error);
@@ -325,6 +359,7 @@ function registerApiErrorHandler(
325
359
  reply.code(400).send({
326
360
  error: "Validation failed.",
327
361
  code: validationErrorCode,
362
+ ...outcomeFields,
328
363
  fieldErrors,
329
364
  details: {
330
365
  fieldErrors
@@ -336,7 +371,8 @@ function registerApiErrorHandler(
336
371
  if (isAppError(error) || error instanceof ActionRuntimeError) {
337
372
  if (applyRouteTransportErrorResponse(reply, request, error, {
338
373
  statusCode: error.status,
339
- normalizedErrorCode: normalizedErrorCode || "app_error"
374
+ normalizedErrorCode: normalizedErrorCode || "app_error",
375
+ exposeDetails: shouldExposeAppErrorDetails(normalizedErrorCode)
340
376
  })) {
341
377
  return;
342
378
  }
@@ -349,7 +385,8 @@ function registerApiErrorHandler(
349
385
  const appErrorCode = normalizedErrorCode || "app_error";
350
386
  const payload = {
351
387
  error: error.message,
352
- code: appErrorCode
388
+ code: appErrorCode,
389
+ ...outcomeFields
353
390
  };
354
391
  if (error.details && shouldExposeAppErrorDetails(appErrorCode)) {
355
392
  payload.details = error.details;
@@ -385,7 +422,8 @@ function registerApiErrorHandler(
385
422
  normalizedErrorCode || (statusCode >= 500 ? "internal_server_error" : "request_failed");
386
423
  const payload = {
387
424
  error: message,
388
- code: fallbackErrorCode
425
+ code: fallbackErrorCode,
426
+ ...outcomeFields
389
427
  };
390
428
  if (isCsrfErrorCode) {
391
429
  payload.details = {
@@ -394,7 +432,9 @@ function registerApiErrorHandler(
394
432
  }
395
433
  if (applyRouteTransportErrorResponse(reply, request, error, {
396
434
  statusCode,
397
- normalizedErrorCode: fallbackErrorCode
435
+ normalizedErrorCode: fallbackErrorCode,
436
+ message,
437
+ exposeDetails: statusCode < 500
398
438
  })) {
399
439
  return;
400
440
  }
@@ -155,6 +155,44 @@ test("registerApiErrorHandler includes internal_server_error code for unhandled
155
155
  assert.equal(reply.payload.error, "Internal server error.");
156
156
  });
157
157
 
158
+ test("registerApiErrorHandler exposes only allowlisted transaction outcomes", () => {
159
+ const fastify = createFastifyStub();
160
+ registerApiErrorHandler(fastify, { isAppError });
161
+ for (const transactionOutcome of ["none", "pending", "committed", "rolledBack", "unknown"]) {
162
+ const error = Object.assign(new Error("Private SQL failure"), {
163
+ transactionOutcome,
164
+ cause: { password: "private" },
165
+ cleanupErrors: [{ message: "private cleanup" }]
166
+ });
167
+ const reply = createReplyStub();
168
+ fastify.errorHandler(error, {}, reply);
169
+ assert.equal(reply.statusCode, 500);
170
+ assert.deepEqual(reply.payload, {
171
+ error: "Internal server error.",
172
+ code: "internal_server_error",
173
+ transactionOutcome
174
+ });
175
+ }
176
+ for (const transactionOutcome of [undefined, "success", { secret: "private" }]) {
177
+ const reply = createReplyStub();
178
+ fastify.errorHandler(Object.assign(new Error("private"), { transactionOutcome }), {}, reply);
179
+ assert.equal(Object.hasOwn(reply.payload, "transactionOutcome"), false);
180
+ }
181
+ });
182
+
183
+ test("AppError and validation payloads retain transaction outcomes", () => {
184
+ const fastify = createFastifyStub();
185
+ registerApiErrorHandler(fastify, { isAppError });
186
+ for (const error of [
187
+ Object.assign(new AppError(409, "Conflict."), { transactionOutcome: "rolledBack" }),
188
+ { validation: [{ instancePath: "/title", message: "Required" }], transactionOutcome: "none" }
189
+ ]) {
190
+ const reply = createReplyStub();
191
+ fastify.errorHandler(error, {}, reply);
192
+ assert.equal(reply.payload.transactionOutcome, error.transactionOutcome);
193
+ }
194
+ });
195
+
158
196
  test("registerApiErrorHandler keeps known error code for non-app errors", () => {
159
197
  const fastify = createFastifyStub();
160
198
  registerApiErrorHandler(fastify, { isAppError });
@@ -1,3 +1,9 @@
1
+ const TRANSACTION_OUTCOMES = Object.freeze(["none", "pending", "committed", "rolledBack", "unknown"]);
2
+
3
+ function normalizeTransactionOutcome(value) {
4
+ return TRANSACTION_OUTCOMES.includes(value) ? value : "";
5
+ }
6
+
1
7
  function normalizeText(value, { fallback = "" } = {}) {
2
8
  const normalized = String(value || "").trim();
3
9
  return normalized || fallback;
@@ -351,6 +357,8 @@ function ensureNonEmptyText(value, label = "value") {
351
357
  }
352
358
 
353
359
  export {
360
+ TRANSACTION_OUTCOMES,
361
+ normalizeTransactionOutcome,
354
362
  normalizeText,
355
363
  hasValue,
356
364
  normalizeBoolean,
@@ -17,9 +17,19 @@ import {
17
17
  normalizeOneOf,
18
18
  normalizeQueryToken,
19
19
  normalizeText,
20
+ normalizeTransactionOutcome,
20
21
  normalizeUniqueTextList
21
22
  } from "./normalize.js";
22
23
 
24
+ test("normalizeTransactionOutcome accepts only the documented literal outcomes", () => {
25
+ for (const value of ["none", "pending", "committed", "rolledBack", "unknown"]) {
26
+ assert.equal(normalizeTransactionOutcome(value), value);
27
+ }
28
+ for (const value of [undefined, null, false, 0, "", "rolledback", " committed ", { toString: () => "committed" }]) {
29
+ assert.equal(normalizeTransactionOutcome(value), "");
30
+ }
31
+ });
32
+
23
33
  test("hasValue returns false for nullish and blank text, true otherwise", () => {
24
34
  assert.equal(hasValue(null), false);
25
35
  assert.equal(hasValue(undefined), false);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/payments-core",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "description": "Application-owned payment configuration, subscription access and transactional usage credits.",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/realtime",
3
- "version": "0.1.181",
3
+ "version": "0.1.184",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -20,8 +20,8 @@
20
20
  "socket.io-client": "^4.8.3"
21
21
  },
22
22
  "peerDependencies": {
23
- "@jskit-ai/kernel": "0.1.184",
24
- "@jskit-ai/shell-web": "0.1.188",
23
+ "@jskit-ai/kernel": "0.1.187",
24
+ "@jskit-ai/shell-web": "0.1.191",
25
25
  "vue": "^3.5.13"
26
26
  },
27
27
  "description": "Thin, generic realtime runtime wrappers for socket.io server and client.",
@@ -2,7 +2,7 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@jskit-ai/realtime": "0.1.181",
6
- "@jskit-ai/shell-web": "0.1.188"
5
+ "@jskit-ai/realtime": "0.1.184",
6
+ "@jskit-ai/shell-web": "0.1.191"
7
7
  }
8
8
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/resource-core",
3
- "version": "0.1.126",
3
+ "version": "0.1.129",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -27,6 +27,6 @@
27
27
  }
28
28
  },
29
29
  "peerDependencies": {
30
- "@jskit-ai/kernel": "0.1.184"
30
+ "@jskit-ai/kernel": "0.1.187"
31
31
  }
32
32
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/resource-crud-core",
3
- "version": "0.1.126",
3
+ "version": "0.1.129",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -13,7 +13,7 @@
13
13
  "./shared/crudResource": "./src/shared/crudResource.js"
14
14
  },
15
15
  "dependencies": {
16
- "@jskit-ai/resource-core": "0.1.126"
16
+ "@jskit-ai/resource-core": "0.1.129"
17
17
  },
18
18
  "description": "Shared CRUD resource, field, lookup, filter, and namespace contracts.",
19
19
  "jskit": {
@@ -34,6 +34,6 @@
34
34
  }
35
35
  },
36
36
  "peerDependencies": {
37
- "@jskit-ai/kernel": "0.1.184"
37
+ "@jskit-ai/kernel": "0.1.187"
38
38
  }
39
39
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/shell-web",
3
- "version": "0.1.188",
3
+ "version": "0.1.191",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -31,7 +31,7 @@
31
31
  "@mdi/js": "^7.4.47"
32
32
  },
33
33
  "peerDependencies": {
34
- "@jskit-ai/kernel": "0.1.184",
34
+ "@jskit-ai/kernel": "0.1.187",
35
35
  "pinia": "^3.0.4",
36
36
  "vue": "^3.5.13",
37
37
  "vue-router": "^5.0.4",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/uploads-runtime",
3
- "version": "0.1.159",
3
+ "version": "0.1.162",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -77,6 +77,6 @@
77
77
  }
78
78
  },
79
79
  "peerDependencies": {
80
- "@jskit-ai/kernel": "0.1.184"
80
+ "@jskit-ai/kernel": "0.1.187"
81
81
  }
82
82
  }
@@ -48,7 +48,7 @@
48
48
  }
49
49
  },
50
50
  "dependencies": {
51
- "@jskit-ai/kernel": "0.1.184",
51
+ "@jskit-ai/kernel": "0.1.187",
52
52
  "@local/vibe64-core": "0.1.0",
53
53
  "@local/vibe64-genesis": "0.1.0",
54
54
  "@local/vibe64-project": "0.1.0",
@@ -28,7 +28,7 @@
28
28
  }
29
29
  },
30
30
  "dependencies": {
31
- "@jskit-ai/kernel": "0.1.184",
32
- "@jskit-ai/realtime": "0.1.181"
31
+ "@jskit-ai/kernel": "0.1.187",
32
+ "@jskit-ai/realtime": "0.1.184"
33
33
  }
34
34
  }
@@ -49,7 +49,7 @@
49
49
  }
50
50
  },
51
51
  "dependencies": {
52
- "@jskit-ai/kernel": "0.1.184",
52
+ "@jskit-ai/kernel": "0.1.187",
53
53
  "@local/vibe64-accounts": "0.1.0",
54
54
  "@local/vibe64-core": "0.1.0",
55
55
  "@local/vibe64-execution": "0.1.0",
@@ -61,9 +61,9 @@
61
61
  }
62
62
  },
63
63
  "dependencies": {
64
- "@jskit-ai/http-web": "0.1.29",
65
- "@jskit-ai/kernel": "0.1.184",
66
- "@jskit-ai/realtime": "0.1.181",
64
+ "@jskit-ai/http-web": "0.1.32",
65
+ "@jskit-ai/kernel": "0.1.187",
66
+ "@jskit-ai/realtime": "0.1.184",
67
67
  "@mdi/js": "^7.4.47",
68
68
  "@local/studio-terminal-core": "0.1.0",
69
69
  "@local/vibe64-core": "0.1.0",
@@ -98,7 +98,7 @@
98
98
  }
99
99
  },
100
100
  "dependencies": {
101
- "@jskit-ai/kernel": "0.1.184",
101
+ "@jskit-ai/kernel": "0.1.187",
102
102
  "@local/vibe64-execution": "0.1.0"
103
103
  }
104
104
  }
@@ -67,9 +67,9 @@
67
67
  "@codemirror/language": "^6.12.4",
68
68
  "@codemirror/state": "^6.7.0",
69
69
  "@codemirror/view": "^6.43.4",
70
- "@jskit-ai/http-web": "0.1.29",
71
- "@jskit-ai/kernel": "0.1.184",
72
- "@jskit-ai/shell-web": "0.1.188",
70
+ "@jskit-ai/http-web": "0.1.32",
71
+ "@jskit-ai/kernel": "0.1.187",
72
+ "@jskit-ai/shell-web": "0.1.191",
73
73
  "@local/vibe64-core": "0.1.0",
74
74
  "@local/vibe64-execution": "0.1.0",
75
75
  "@local/vibe64-project": "0.1.0",
@@ -57,7 +57,7 @@
57
57
  }
58
58
  },
59
59
  "dependencies": {
60
- "@jskit-ai/kernel": "0.1.184",
60
+ "@jskit-ai/kernel": "0.1.187",
61
61
  "@local/vibe64-core": "0.1.0",
62
62
  "@local/vibe64-execution": "0.1.0",
63
63
  "@local/vibe64-genesis": "0.1.0",
@@ -1480,6 +1480,19 @@ async function stopCodexAppServerRuntime(options = {}) {
1480
1480
  stopped: false
1481
1481
  };
1482
1482
  }
1483
+ const expectedAccount = normalizeAgentText(options.expectedAccountIdentitySignature);
1484
+ if (expectedAccount) {
1485
+ // A replacement runtime is installed only after the previous process has
1486
+ // drained under this same lock. Never stop that replacement for stale
1487
+ // ephemeral-thread cleanup.
1488
+ if (!codexAppServerProcessMetadataIsIdentifiable(existing, runtimeDir) ||
1489
+ !/^sha256:[a-f0-9]{64}$/u.test(existing.accountIdentitySignature)) {
1490
+ return { processExitVerified: false, runtimeDirRemoved: false, stopped: false };
1491
+ }
1492
+ if (existing.accountIdentitySignature !== expectedAccount) {
1493
+ return { ownershipSuperseded: true, processExitVerified: false, runtimeDirRemoved: false, stopped: false };
1494
+ }
1495
+ }
1483
1496
  processStop = await stopCodexAppServerProcess(runtimeDir, options);
1484
1497
  if (processStop.processExitVerified === true && preserveProcessExitProof) {
1485
1498
  const metadata = await readCodexAppServerMetadata(runtimeDir);
@@ -3650,6 +3663,25 @@ class CodexAppServerAgentProvider {
3650
3663
  };
3651
3664
  }
3652
3665
 
3666
+ async readGoal(threadId = "") {
3667
+ const client = await this.activeClient();
3668
+ return this.runRequest(
3669
+ () => client.request("thread/goal/get", { threadId: normalizeAgentText(threadId) }),
3670
+ "codex-app-server-goal-read"
3671
+ );
3672
+ }
3673
+
3674
+ async setGoalStatus(threadId = "", status = "") {
3675
+ if (!["active", "paused"].includes(status)) {
3676
+ throw new TypeError("Invalid Codex goal status.");
3677
+ }
3678
+ const client = await this.activeClient();
3679
+ return this.runRequest(
3680
+ () => client.request("thread/goal/set", { threadId: normalizeAgentText(threadId), status }),
3681
+ "codex-app-server-goal-status"
3682
+ );
3683
+ }
3684
+
3653
3685
  async readThread(threadId = "") {
3654
3686
  const client = await this.activeClient();
3655
3687
  const response = await this.runRequest(
@@ -3994,12 +4026,14 @@ class CodexAppServerAgentProvider {
3994
4026
  }
3995
4027
 
3996
4028
  async stopRuntime({
4029
+ expectedAccountIdentitySignature = "",
3997
4030
  preserveProcessExitProof = false
3998
4031
  } = {}) {
3999
4032
  this.close();
4000
4033
  const runtime = this.runtime || {};
4001
4034
  const result = await stopCodexAppServerRuntime({
4002
4035
  ...this.options,
4036
+ expectedAccountIdentitySignature,
4003
4037
  preserveProcessExitProof,
4004
4038
  runtimeDir: runtime.runtimeDir || this.options.runtimeDir
4005
4039
  });
@@ -50,7 +50,7 @@
50
50
  }
51
51
  },
52
52
  "dependencies": {
53
- "@jskit-ai/kernel": "0.1.184",
53
+ "@jskit-ai/kernel": "0.1.187",
54
54
  "@local/vibe64-core": "0.1.0",
55
55
  "@local/vibe64-execution": "0.1.0",
56
56
  "@local/vibe64-project": "0.1.0",