@sentry/junior 0.164.0 → 0.166.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.
Files changed (74) hide show
  1. package/dist/{agent-hooks-WTBPNRTC.js → agent-hooks-ZIPK2HUF.js} +9 -9
  2. package/dist/api/schema/workspace.d.ts +10 -4
  3. package/dist/api/schema.js +1 -1
  4. package/dist/api.js +52 -27
  5. package/dist/app.js +59 -60
  6. package/dist/{catalog-runtime-CZ2SQINY.js → catalog-runtime-GEZAHBUP.js} +5 -5
  7. package/dist/chat/pi/transcript.d.ts +10 -10
  8. package/dist/chat/repository-instructions.d.ts +12 -1
  9. package/dist/chat/sandbox/sandbox.d.ts +1 -1
  10. package/dist/chat/sandbox/snapshot/resolve.d.ts +16 -0
  11. package/dist/chat/sandbox/snapshot/runtime.d.ts +2 -0
  12. package/dist/chat/services/conversation-memory.d.ts +7 -0
  13. package/dist/chat/workspaces/store.d.ts +10 -3
  14. package/dist/chat/workspaces/types.d.ts +8 -1
  15. package/dist/chat/workspaces/validation.d.ts +0 -1
  16. package/dist/{chunk-HHW6ZVIZ.js → chunk-22RO7IDD.js} +109 -21
  17. package/dist/{chunk-FKDY7NTC.js → chunk-2KV4BAAN.js} +12 -12
  18. package/dist/{chunk-Y2B6AXZQ.js → chunk-2ZKFLHVP.js} +6 -6
  19. package/dist/{chunk-ZUTAGCPH.js → chunk-3EZ5V7XQ.js} +9 -9
  20. package/dist/{chunk-3L23VTY7.js → chunk-43KLUCAM.js} +17 -17
  21. package/dist/{chunk-PU45BSBS.js → chunk-4CMORAHL.js} +9 -5
  22. package/dist/chunk-4DARCEZH.js +274 -0
  23. package/dist/{chunk-6ENAACWN.js → chunk-4MDEQNSW.js} +9 -5
  24. package/dist/{chunk-ZSNABC2E.js → chunk-65SNO3WK.js} +9 -7
  25. package/dist/{chunk-WJUKESU2.js → chunk-ABNRESX6.js} +1 -1
  26. package/dist/{chunk-FX4PX3SA.js → chunk-AEKBVJMV.js} +2 -2
  27. package/dist/{chunk-26JYGL2L.js → chunk-BKP3PVKR.js} +1 -1
  28. package/dist/{chunk-XAIRI54J.js → chunk-C3USHSIJ.js} +1 -1
  29. package/dist/{chunk-RYYEHWIL.js → chunk-CDBTQQQ4.js} +1 -1
  30. package/dist/{chunk-2K25MRZK.js → chunk-DTQAMME2.js} +5 -5
  31. package/dist/{chunk-BXBZDV3C.js → chunk-EKBVHDZO.js} +1 -1
  32. package/dist/{chunk-6BXV63YX.js → chunk-FEYQVP64.js} +5 -5
  33. package/dist/{chunk-H36GJVJV.js → chunk-FFE3BMAT.js} +7 -7
  34. package/dist/{chunk-LPLVNMVN.js → chunk-JDTCQDRU.js} +3 -3
  35. package/dist/{chunk-VHSEMJTS.js → chunk-JUFZR2LD.js} +1 -1
  36. package/dist/{chunk-RBV4JHCP.js → chunk-KQ5YZGDV.js} +1 -1
  37. package/dist/{chunk-4GTOFUQF.js → chunk-LGSGPWYH.js} +1 -1
  38. package/dist/{chunk-NLTQRYNP.js → chunk-MDW5YPXW.js} +2 -2
  39. package/dist/{chunk-5FWQ73UZ.js → chunk-OCOGPNHA.js} +1 -1
  40. package/dist/{chunk-JW23XD4I.js → chunk-OYN45QUQ.js} +6 -6
  41. package/dist/{chunk-VV2DN24T.js → chunk-P6UQMGM2.js} +1 -1
  42. package/dist/{chunk-RJHZNPDH.js → chunk-Q2IPCX7J.js} +45 -282
  43. package/dist/{chunk-7WKWMMYQ.js → chunk-SLWGX3G5.js} +93 -85
  44. package/dist/{chunk-CGCNFEAU.js → chunk-U2UCDSDF.js} +4 -4
  45. package/dist/{chunk-RULIISEI.js → chunk-VNPG55CU.js} +1 -1
  46. package/dist/{chunk-YHCTPDXS.js → chunk-WX42YNDQ.js} +67 -24
  47. package/dist/{chunk-5GLGQHO3.js → chunk-YTIKGCPC.js} +2 -1
  48. package/dist/{chunk-NAGI2XH3.js → chunk-ZKJO4K6M.js} +4 -4
  49. package/dist/cli/chat.js +30 -29
  50. package/dist/cli/check.js +6 -6
  51. package/dist/cli/plugins.js +12 -12
  52. package/dist/cli/snapshot-create.js +12 -10
  53. package/dist/cli/upgrade.js +7 -7
  54. package/dist/db/schema/workspaces.d.ts +68 -17
  55. package/dist/db/schema.d.ts +68 -17
  56. package/dist/{db-32KRFS6L.js → db-TGZBS2CP.js} +7 -7
  57. package/dist/instrumentation.js +4 -4
  58. package/dist/nitro.js +2 -2
  59. package/dist/{oauth-callback-server-CGZP2Z6U.js → oauth-callback-server-Z54WUF5H.js} +22 -22
  60. package/dist/{runner-S5N4Q2XL.js → runner-PVFHKKK6.js} +12 -12
  61. package/dist/{skills-KYPSHSQR.js → skills-BYRH3QWD.js} +6 -6
  62. package/dist/spawn-RIPWK7EP.js +37 -0
  63. package/dist/{validation-SZBE7JNF.js → validation-VZIE4RHA.js} +6 -6
  64. package/dist/version.js +1 -1
  65. package/dist/{work-GCZKHEZX.js → work-JTHAOPDQ.js} +17 -17
  66. package/dist/worker-APEVP56Y.js +24 -0
  67. package/migrations/0030_drop_workspace_repo_primary.sql +2 -0
  68. package/migrations/0031_wild_phantom_reporter.sql +4 -0
  69. package/migrations/meta/0030_snapshot.json +2799 -0
  70. package/migrations/meta/0031_snapshot.json +2823 -0
  71. package/migrations/meta/_journal.json +15 -1
  72. package/package.json +6 -5
  73. package/dist/spawn-EGOB3CLV.js +0 -37
  74. package/dist/worker-6MY5Q4A2.js +0 -24
@@ -3,15 +3,15 @@ import {
3
3
  } from "./chunk-FA6POGLH.js";
4
4
  import {
5
5
  getTurnRequestDeadline
6
- } from "./chunk-RYYEHWIL.js";
6
+ } from "./chunk-CDBTQQQ4.js";
7
7
  import {
8
8
  buildSentryConversationUrl,
9
9
  deleteWebAuthorization
10
- } from "./chunk-5FWQ73UZ.js";
10
+ } from "./chunk-OCOGPNHA.js";
11
11
  import {
12
12
  ensureConversationWake,
13
13
  requestConversationWork
14
- } from "./chunk-NAGI2XH3.js";
14
+ } from "./chunk-ZKJO4K6M.js";
15
15
  import {
16
16
  buildDeliveredTurnStatePatch,
17
17
  finalizeFailedTurnReplyWithEvent,
@@ -24,7 +24,7 @@ import {
24
24
  requireTurnFailureEventId,
25
25
  resolveTurnSessionRouting,
26
26
  scheduleSessionCompletedPluginTasks
27
- } from "./chunk-ZUTAGCPH.js";
27
+ } from "./chunk-3EZ5V7XQ.js";
28
28
  import {
29
29
  ConversationTurnLifecycleService,
30
30
  coerceThreadConversationState,
@@ -33,7 +33,7 @@ import {
33
33
  getPersistedSandboxState,
34
34
  getPersistedThreadState,
35
35
  persistThreadStateById
36
- } from "./chunk-2K25MRZK.js";
36
+ } from "./chunk-DTQAMME2.js";
37
37
  import {
38
38
  getVercelConversationWorkQueue
39
39
  } from "./chunk-WR76IVA5.js";
@@ -47,7 +47,7 @@ import {
47
47
  lookupSlackUserProfile,
48
48
  resolvePluginOAuthAccount,
49
49
  runAgentWithTimeout
50
- } from "./chunk-H36GJVJV.js";
50
+ } from "./chunk-FFE3BMAT.js";
51
51
  import {
52
52
  RetryableDeliveryError
53
53
  } from "./chunk-RF6J3DIO.js";
@@ -63,13 +63,13 @@ import {
63
63
  removeReactionFromMessage,
64
64
  resolveBaseUrl,
65
65
  truncateStatusText
66
- } from "./chunk-JW23XD4I.js";
66
+ } from "./chunk-OYN45QUQ.js";
67
67
  import {
68
68
  parseSlackThreadId,
69
69
  readSlackRawMessageContext,
70
70
  resolveSlackChannelIdFromMessage,
71
71
  resolveSlackChannelIdFromThreadId
72
- } from "./chunk-WJUKESU2.js";
72
+ } from "./chunk-ABNRESX6.js";
73
73
  import {
74
74
  CooperativeTurnYieldError,
75
75
  TurnSliceLimitExceededError,
@@ -96,7 +96,7 @@ import {
96
96
  recordTurnSummary,
97
97
  saveTurnCheckpoint,
98
98
  turnHasReply
99
- } from "./chunk-HHW6ZVIZ.js";
99
+ } from "./chunk-22RO7IDD.js";
100
100
  import {
101
101
  SlackActionError,
102
102
  getDashboardConversationLink,
@@ -105,18 +105,18 @@ import {
105
105
  getSlackClient,
106
106
  isDmChannel,
107
107
  normalizeSlackConversationId
108
- } from "./chunk-YHCTPDXS.js";
108
+ } from "./chunk-WX42YNDQ.js";
109
109
  import {
110
110
  getConversationEventStore,
111
111
  getSqlExecutor,
112
112
  requireSlackDestination,
113
113
  upsertIdentity,
114
114
  upsertLinkedIdentity
115
- } from "./chunk-LPLVNMVN.js";
115
+ } from "./chunk-JDTCQDRU.js";
116
116
  import {
117
117
  acquireActiveLock,
118
118
  getStateAdapter
119
- } from "./chunk-BXBZDV3C.js";
119
+ } from "./chunk-EKBVHDZO.js";
120
120
  import {
121
121
  botConfig,
122
122
  escapeXml,
@@ -124,18 +124,18 @@ import {
124
124
  getRuntimeMetadata,
125
125
  normalizeSlackEmojiName,
126
126
  standardModelId
127
- } from "./chunk-FX4PX3SA.js";
127
+ } from "./chunk-AEKBVJMV.js";
128
128
  import {
129
129
  discoverSkills
130
- } from "./chunk-NLTQRYNP.js";
130
+ } from "./chunk-MDW5YPXW.js";
131
131
  import {
132
132
  pluginCatalogRuntime
133
- } from "./chunk-RULIISEI.js";
133
+ } from "./chunk-VNPG55CU.js";
134
134
  import {
135
135
  buildOAuthTokenRequest,
136
136
  hasRequiredOAuthScope,
137
137
  parseOAuthTokenResponse
138
- } from "./chunk-VV2DN24T.js";
138
+ } from "./chunk-P6UQMGM2.js";
139
139
  import {
140
140
  createSlackResumeActor,
141
141
  isUserActor,
@@ -151,7 +151,7 @@ import {
151
151
  setTags,
152
152
  toOptionalString,
153
153
  withLogContext
154
- } from "./chunk-VHSEMJTS.js";
154
+ } from "./chunk-JUFZR2LD.js";
155
155
  import {
156
156
  homeDir
157
157
  } from "./chunk-H4HBKISO.js";
@@ -721,20 +721,24 @@ var revokePersonalTokenResponseSchema = z6.object({ revoked: z6.literal(true) })
721
721
  import { z as z7 } from "zod";
722
722
  var workspaceRepoInputSchema = z7.object({
723
723
  provider: z7.string(),
724
- repo: z7.string(),
725
- isPrimary: z7.boolean().optional()
724
+ repo: z7.string()
726
725
  }).strict();
727
726
  var workspaceRepoSchema = z7.object({
728
727
  provider: z7.string(),
729
728
  repo: z7.string(),
730
- checkoutPath: z7.string(),
731
- isPrimary: z7.boolean()
729
+ checkoutPath: z7.string()
730
+ }).strict();
731
+ var workspaceSnapshotSchema = z7.object({
732
+ id: z7.string(),
733
+ generatedAt: z7.iso.datetime(),
734
+ buildDurationMs: z7.number().int().nonnegative()
732
735
  }).strict();
733
736
  var workspaceSchema = z7.object({
734
737
  id: z7.string().uuid(),
735
738
  name: z7.string(),
736
739
  setupScript: z7.string(),
737
- repos: z7.array(workspaceRepoSchema)
740
+ repos: z7.array(workspaceRepoSchema),
741
+ snapshot: workspaceSnapshotSchema.nullable()
738
742
  }).strict();
739
743
  var workspaceListSchema = z7.object({ workspaces: z7.array(workspaceSchema) }).strict();
740
744
  var workspaceBodySchema = z7.object({
@@ -0,0 +1,274 @@
1
+ import {
2
+ SANDBOX_WORKSPACE_ROOT,
3
+ runNonInteractiveCommand
4
+ } from "./chunk-BVREIWBD.js";
5
+ import {
6
+ pluginCatalogRuntime
7
+ } from "./chunk-VNPG55CU.js";
8
+
9
+ // src/chat/sandbox/snapshot/profile.ts
10
+ import { createHash } from "crypto";
11
+
12
+ // src/chat/sandbox/docker.ts
13
+ var DOCKER_DAEMON_JSON = `{
14
+ "storage-driver": "overlay2",
15
+ "live-restore": false
16
+ }
17
+ `;
18
+ var DOCKER_ENSURE_SCRIPT = `#!/bin/sh
19
+ set -eu
20
+
21
+ if [ "$(id -u)" -ne 0 ]; then
22
+ exec sudo -n "$0" "$@"
23
+ fi
24
+
25
+ SOCK=/var/run/docker.sock
26
+ PIDFILE=/var/run/docker.pid
27
+ LOG=/var/log/junior-dockerd.log
28
+
29
+ is_ready() {
30
+ [ -S "$SOCK" ] && /usr/bin/docker info >/dev/null 2>&1
31
+ }
32
+
33
+ if is_ready; then
34
+ chmod 666 "$SOCK" 2>/dev/null || true
35
+ exit 0
36
+ fi
37
+
38
+ mkdir -p /etc/docker /var/lib/docker /var/run /var/log
39
+ if [ ! -f /etc/docker/daemon.json ]; then
40
+ cat > /etc/docker/daemon.json <<'EOF'
41
+ {
42
+ "storage-driver": "overlay2",
43
+ "live-restore": false
44
+ }
45
+ EOF
46
+ fi
47
+
48
+ if [ -f "$PIDFILE" ]; then
49
+ oldpid="$(cat "$PIDFILE" 2>/dev/null || true)"
50
+ if [ -n "\${oldpid:-}" ] && ! kill -0 "$oldpid" 2>/dev/null; then
51
+ rm -f "$PIDFILE"
52
+ fi
53
+ fi
54
+
55
+ if [ ! -f "$PIDFILE" ] || ! kill -0 "$(cat "$PIDFILE" 2>/dev/null)" 2>/dev/null; then
56
+ # dockerd must outlive this helper; nohup + background is intentional.
57
+ nohup dockerd --host="unix://$SOCK" --pidfile="$PIDFILE" >"$LOG" 2>&1 &
58
+ fi
59
+
60
+ i=0
61
+ while [ "$i" -lt 50 ]; do
62
+ if is_ready; then
63
+ chmod 666 "$SOCK" 2>/dev/null || true
64
+ exit 0
65
+ fi
66
+ i=$((i + 1))
67
+ sleep 0.1
68
+ done
69
+
70
+ echo "junior-ensure-docker: dockerd failed to become ready" >&2
71
+ if [ -f "$LOG" ]; then
72
+ tail -n 50 "$LOG" >&2 || true
73
+ fi
74
+ exit 1
75
+ `;
76
+ var DOCKER_CLI_WRAPPER_SCRIPT = `#!/bin/sh
77
+ set -eu
78
+ if command -v junior-ensure-docker >/dev/null 2>&1; then
79
+ junior-ensure-docker
80
+ fi
81
+ exec /usr/bin/docker "$@"
82
+ `;
83
+ var DOCKER_COMPOSE_CLI_WRAPPER_SCRIPT = `#!/bin/sh
84
+ set -eu
85
+ if command -v junior-ensure-docker >/dev/null 2>&1; then
86
+ junior-ensure-docker
87
+ fi
88
+ exec /usr/local/libexec/junior-docker-compose "$@"
89
+ `;
90
+ async function ensureDockerDaemon(sandbox, signal) {
91
+ await runNonInteractiveCommand(sandbox, {
92
+ cmd: "sh",
93
+ args: [
94
+ "-c",
95
+ "command -v junior-ensure-docker >/dev/null 2>&1 && junior-ensure-docker || true"
96
+ ],
97
+ signal
98
+ });
99
+ }
100
+
101
+ // src/chat/sandbox/runtime-dependencies.ts
102
+ var GLOBAL_RUNTIME_DEPENDENCIES = [
103
+ { type: "system", package: "docker" },
104
+ { type: "system", package: "spal-release" },
105
+ { type: "system", package: "ripgrep" }
106
+ ];
107
+ function writeFileCommand(path, contents, mode = "0644") {
108
+ const payload = Buffer.from(contents, "utf8").toString("base64");
109
+ return [
110
+ `printf '%s' '${payload}' | base64 -d > ${path}`,
111
+ `chmod ${mode} ${path}`
112
+ ].join("\n");
113
+ }
114
+ function writeExecutableCommand(path, contents) {
115
+ return writeFileCommand(path, contents, "0755");
116
+ }
117
+ var GLOBAL_RUNTIME_POSTINSTALL = [
118
+ {
119
+ cmd: "sh",
120
+ args: [
121
+ "-c",
122
+ [
123
+ "set -eu",
124
+ 'case "$(uname -m)" in',
125
+ ' x86_64) asset="x86_64"; sha256="7af95166a730b87e172d4fc9aefea8725d3c6c7327d59149267b452114ddb7d4" ;;',
126
+ ' aarch64) asset="aarch64"; sha256="49082844b87f03cdcd5f5bbef1ba8c9c897b7a2dfb80cea18d61ec8ca6117e0c" ;;',
127
+ ' *) echo "unsupported Docker Compose architecture: $(uname -m)" >&2; exit 1 ;;',
128
+ "esac",
129
+ 'tmp="$(mktemp)"',
130
+ `trap 'rm -f "$tmp"' EXIT`,
131
+ 'curl --fail --location --silent --show-error "https://github.com/docker/compose/releases/download/v2.39.4/docker-compose-linux-${asset}" --output "$tmp"',
132
+ 'echo "${sha256} ${tmp}" | sha256sum --check --status',
133
+ // Keep the real Compose binary off PATH; the wrapper below starts dockerd.
134
+ 'install -D -m 0755 "$tmp" /usr/local/libexec/junior-docker-compose',
135
+ "mkdir -p /usr/local/lib/docker/cli-plugins /usr/local/libexec /etc/docker /usr/local/bin",
136
+ `mkdir -p ${SANDBOX_WORKSPACE_ROOT}/.junior/bin`,
137
+ writeFileCommand("/etc/docker/daemon.json", DOCKER_DAEMON_JSON),
138
+ writeExecutableCommand(
139
+ "/usr/local/bin/junior-ensure-docker",
140
+ DOCKER_ENSURE_SCRIPT
141
+ ),
142
+ // docker compose plugin delegates to the real Compose binary.
143
+ "ln -sfn /usr/local/libexec/junior-docker-compose /usr/local/lib/docker/cli-plugins/docker-compose",
144
+ // PATH wrappers auto-start dockerd for both CLI entrypoints.
145
+ writeExecutableCommand(
146
+ "/usr/local/bin/docker-compose",
147
+ DOCKER_COMPOSE_CLI_WRAPPER_SCRIPT
148
+ ),
149
+ writeExecutableCommand(
150
+ `${SANDBOX_WORKSPACE_ROOT}/.junior/bin/docker`,
151
+ DOCKER_CLI_WRAPPER_SCRIPT
152
+ ),
153
+ writeExecutableCommand(
154
+ `${SANDBOX_WORKSPACE_ROOT}/.junior/bin/docker-compose`,
155
+ DOCKER_COMPOSE_CLI_WRAPPER_SCRIPT
156
+ ),
157
+ // Prefer the wrapper over /usr/bin/docker for non-login shells too.
158
+ writeExecutableCommand(
159
+ "/usr/local/bin/docker",
160
+ DOCKER_CLI_WRAPPER_SCRIPT
161
+ )
162
+ ].join("\n")
163
+ ],
164
+ sudo: true
165
+ }
166
+ ];
167
+
168
+ // src/chat/sandbox/snapshot/profile.ts
169
+ var VERSION = 1;
170
+ var DEFAULT_FLOATING_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
171
+ function isExactNpmVersion(version) {
172
+ return /^\d+\.\d+\.\d+(?:[-+][a-z0-9.]+)?$/i.test(version.trim());
173
+ }
174
+ function isFloating(dep) {
175
+ return dep.type === "npm" && !isExactNpmVersion(dep.version);
176
+ }
177
+ function mergeDependencies(dependencies) {
178
+ const seen = /* @__PURE__ */ new Set();
179
+ const npmVersions = /* @__PURE__ */ new Map();
180
+ const merged = [];
181
+ for (const dependency of dependencies) {
182
+ const key = dependency.type === "npm" ? `${dependency.type}:${dependency.package}:${dependency.version}` : "package" in dependency ? `${dependency.type}:package:${dependency.package}` : `${dependency.type}:url:${dependency.url}:${dependency.sha256}`;
183
+ if (seen.has(key)) {
184
+ continue;
185
+ }
186
+ seen.add(key);
187
+ if (dependency.type === "npm") {
188
+ const version = npmVersions.get(dependency.package);
189
+ if (version !== void 0 && version !== dependency.version) {
190
+ throw new Error(
191
+ `Conflicting runtime dependency versions for ${dependency.package}: ${version} and ${dependency.version}`
192
+ );
193
+ }
194
+ npmVersions.set(dependency.package, dependency.version);
195
+ }
196
+ merged.push(dependency);
197
+ }
198
+ return merged;
199
+ }
200
+ function floatingMaxAgeMs() {
201
+ const raw = process.env.SANDBOX_SNAPSHOT_FLOATING_MAX_AGE_MS;
202
+ if (!raw?.trim()) {
203
+ return DEFAULT_FLOATING_MAX_AGE_MS;
204
+ }
205
+ const parsed = Number.parseInt(raw, 10);
206
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : DEFAULT_FLOATING_MAX_AGE_MS;
207
+ }
208
+ function compareCodePoints(left, right) {
209
+ if (left < right) return -1;
210
+ if (left > right) return 1;
211
+ return 0;
212
+ }
213
+ function workspaceRecipe(workspace) {
214
+ const repos = [...workspace.repos].map(({ provider, repo }) => ({
215
+ provider,
216
+ repo
217
+ })).sort((left, right) => {
218
+ const provider = compareCodePoints(left.provider, right.provider);
219
+ if (provider !== 0) return provider;
220
+ return compareCodePoints(left.repo, right.repo);
221
+ });
222
+ return {
223
+ id: workspace.id,
224
+ repos,
225
+ setupScript: workspace.setupScript
226
+ };
227
+ }
228
+ function create(runtime, workspace) {
229
+ const dependencies = mergeDependencies([
230
+ ...GLOBAL_RUNTIME_DEPENDENCIES,
231
+ ...pluginCatalogRuntime.getRuntimeDependencies()
232
+ ]);
233
+ const pluginPostinstall = pluginCatalogRuntime.getRuntimePostinstall();
234
+ const postinstall = [...GLOBAL_RUNTIME_POSTINSTALL, ...pluginPostinstall];
235
+ if (dependencies.length === 0 && postinstall.length === 0 && !workspace) {
236
+ return null;
237
+ }
238
+ const rebuildEpoch = process.env.SANDBOX_SNAPSHOT_REBUILD_EPOCH?.trim() ?? "";
239
+ const floating = dependencies.some((dependency) => isFloating(dependency)) || pluginPostinstall.length > 0 || Boolean(workspace);
240
+ const hash2 = createHash("sha256").update(
241
+ JSON.stringify({
242
+ version: VERSION,
243
+ runtime,
244
+ rebuildEpoch,
245
+ dependencies,
246
+ postinstall,
247
+ ...workspace ? { workspace: workspaceRecipe(workspace) } : {}
248
+ })
249
+ ).digest("hex");
250
+ return {
251
+ hash: hash2,
252
+ dependencyCount: dependencies.length,
253
+ floating,
254
+ dependencies,
255
+ postinstall
256
+ };
257
+ }
258
+ function hash(runtime, workspace) {
259
+ return create(runtime, workspace)?.hash;
260
+ }
261
+ function isStale(profile, createdAtMs) {
262
+ if (!profile.floating) {
263
+ return false;
264
+ }
265
+ const maxAgeMs = floatingMaxAgeMs();
266
+ return maxAgeMs === 0 || Date.now() - createdAtMs > maxAgeMs;
267
+ }
268
+
269
+ export {
270
+ ensureDockerDaemon,
271
+ create,
272
+ hash,
273
+ isStale
274
+ };
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  ToolInputError
3
- } from "./chunk-HHW6ZVIZ.js";
3
+ } from "./chunk-22RO7IDD.js";
4
4
  import {
5
5
  canRouteResourceEvents,
6
6
  getPlugins
7
- } from "./chunk-YHCTPDXS.js";
7
+ } from "./chunk-WX42YNDQ.js";
8
8
  import {
9
9
  getDb
10
- } from "./chunk-LPLVNMVN.js";
10
+ } from "./chunk-JDTCQDRU.js";
11
11
  import {
12
12
  juniorAttachments,
13
13
  juniorConversations,
@@ -15,13 +15,16 @@ import {
15
15
  juniorSchedulerRuns,
16
16
  juniorSchedulerTasks,
17
17
  juniorStats
18
- } from "./chunk-ZSNABC2E.js";
18
+ } from "./chunk-65SNO3WK.js";
19
19
  import {
20
20
  juniorDestinations
21
21
  } from "./chunk-VFUK3X5B.js";
22
22
  import {
23
23
  logInfo
24
- } from "./chunk-VHSEMJTS.js";
24
+ } from "./chunk-JUFZR2LD.js";
25
+
26
+ // src/chat/sandbox/snapshot/runtime.ts
27
+ var SANDBOX_RUNTIME = "node22";
25
28
 
26
29
  // src/chat/event-tasks/store.ts
27
30
  import { and, asc, desc, eq, inArray, or, sql } from "drizzle-orm";
@@ -1899,6 +1902,7 @@ export {
1899
1902
  juniorToolOutputSchema,
1900
1903
  injectContinuationToolName,
1901
1904
  makeStructuredToolOutput,
1905
+ SANDBOX_RUNTIME,
1902
1906
  eventNamespaceSchema,
1903
1907
  registeredEventTypeSchema,
1904
1908
  registeredResourceTypeSchema,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  DEFAULT_SQL_STATEMENT_TIMEOUT_MS
3
- } from "./chunk-FX4PX3SA.js";
3
+ } from "./chunk-AEKBVJMV.js";
4
4
  import {
5
5
  juniorDestinations,
6
6
  timestamptz
@@ -646,9 +646,8 @@ var juniorSchedulerRuns = pgTable16(
646
646
  );
647
647
 
648
648
  // src/db/schema/workspaces.ts
649
- import { sql as sql6 } from "drizzle-orm";
650
649
  import {
651
- boolean as boolean3,
650
+ integer as integer6,
652
651
  pgTable as pgTable17,
653
652
  primaryKey as primaryKey9,
654
653
  text as text17,
@@ -660,6 +659,11 @@ var juniorWorkspaces = pgTable17(
660
659
  id: text17("id").primaryKey(),
661
660
  name: text17("name").notNull(),
662
661
  setupScript: text17("setup_script").notNull().default(""),
662
+ // Last successful Workspace snapshot for the dashboard. Resolve still uses Redis.
663
+ snapshotId: text17("snapshot_id"),
664
+ snapshotGeneratedAt: timestamptz("snapshot_generated_at"),
665
+ snapshotBuildDurationMs: integer6("snapshot_build_duration_ms"),
666
+ snapshotProfileHash: text17("snapshot_profile_hash"),
663
667
  createdAt: timestamptz("created_at").notNull(),
664
668
  updatedAt: timestamptz("updated_at").notNull()
665
669
  },
@@ -670,12 +674,10 @@ var juniorWorkspaceRepos = pgTable17(
670
674
  {
671
675
  workspaceId: text17("workspace_id").notNull().references(() => juniorWorkspaces.id, { onDelete: "cascade" }),
672
676
  provider: text17("provider").notNull(),
673
- repo: text17("repo").notNull(),
674
- isPrimary: boolean3("is_primary").notNull().default(false)
677
+ repo: text17("repo").notNull()
675
678
  },
676
679
  (table) => [
677
- primaryKey9({ columns: [table.workspaceId, table.provider, table.repo] }),
678
- uniqueIndex7("junior_workspace_repos_primary_idx").on(table.workspaceId).where(sql6`${table.isPrimary}`)
680
+ primaryKey9({ columns: [table.workspaceId, table.provider, table.repo] })
679
681
  ]
680
682
  );
681
683
 
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-V7YE4WCP.js";
6
6
  import {
7
7
  toOptionalString
8
- } from "./chunk-VHSEMJTS.js";
8
+ } from "./chunk-JUFZR2LD.js";
9
9
 
10
10
  // src/chat/slack/context.ts
11
11
  import { z } from "zod";
@@ -3,7 +3,7 @@ import {
3
3
  toCanonicalInputMessage,
4
4
  toCanonicalOutputMessage,
5
5
  toGenAiMessagesTraceAttributes
6
- } from "./chunk-RBV4JHCP.js";
6
+ } from "./chunk-KQ5YZGDV.js";
7
7
  import {
8
8
  extractGenAiUsageAttributes,
9
9
  logException,
@@ -11,7 +11,7 @@ import {
11
11
  normalizeGenAiFinishReason,
12
12
  serializeGenAiAttribute,
13
13
  withSpan
14
- } from "./chunk-VHSEMJTS.js";
14
+ } from "./chunk-JUFZR2LD.js";
15
15
 
16
16
  // src/chat/services/provider-error.ts
17
17
  var ProviderError = class extends Error {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  JUNIOR_VERSION
3
- } from "./chunk-5GLGQHO3.js";
3
+ } from "./chunk-YTIKGCPC.js";
4
4
 
5
5
  // src/deployment.ts
6
6
  var JUNIOR_HEARTBEAT_ROUTE = "/api/internal/heartbeat";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createAndEnqueueAgentInvocation
3
- } from "./chunk-Y2B6AXZQ.js";
3
+ } from "./chunk-2ZKFLHVP.js";
4
4
  import {
5
5
  actorFromRun,
6
6
  toolInvocationDestination
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  FUNCTION_TIMEOUT_BUFFER_SECONDS,
3
3
  getChatConfig
4
- } from "./chunk-FX4PX3SA.js";
4
+ } from "./chunk-AEKBVJMV.js";
5
5
 
6
6
  // src/chat/runtime/request-deadline.ts
7
7
  import { AsyncLocalStorage } from "async_hooks";
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  persistConversationMessages
3
- } from "./chunk-HHW6ZVIZ.js";
3
+ } from "./chunk-22RO7IDD.js";
4
4
  import {
5
5
  JUNIOR_THREAD_STATE_TTL_MS
6
6
  } from "./chunk-3Y47VMHV.js";
7
7
  import {
8
8
  getDb
9
- } from "./chunk-LPLVNMVN.js";
9
+ } from "./chunk-JDTCQDRU.js";
10
10
  import {
11
11
  juniorLocationConfigurations
12
- } from "./chunk-ZSNABC2E.js";
12
+ } from "./chunk-65SNO3WK.js";
13
13
  import {
14
14
  getStateAdapter
15
- } from "./chunk-BXBZDV3C.js";
15
+ } from "./chunk-EKBVHDZO.js";
16
16
  import {
17
17
  juniorDestinations
18
18
  } from "./chunk-VFUK3X5B.js";
@@ -20,7 +20,7 @@ import {
20
20
  isRecord,
21
21
  toOptionalNumber,
22
22
  toOptionalString
23
- } from "./chunk-VHSEMJTS.js";
23
+ } from "./chunk-JUFZR2LD.js";
24
24
 
25
25
  // src/chat/conversations/turn-lifecycle.ts
26
26
  var ConversationTurnLifecycleService = class {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getChatConfig
3
- } from "./chunk-FX4PX3SA.js";
3
+ } from "./chunk-AEKBVJMV.js";
4
4
 
5
5
  // src/chat/state/adapter.ts
6
6
  import { createMemoryState } from "@chat-adapter/state-memory";
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  formatProviderLabel,
6
6
  startOAuthFlow
7
- } from "./chunk-JW23XD4I.js";
7
+ } from "./chunk-OYN45QUQ.js";
8
8
  import {
9
9
  parseSandboxEgressAuthRequiredSignal
10
10
  } from "./chunk-7MA4HV4W.js";
@@ -12,16 +12,16 @@ import {
12
12
  abandonReplacedPendingAuth,
13
13
  canReusePendingAuthLink,
14
14
  recordAuthorizationRequested
15
- } from "./chunk-HHW6ZVIZ.js";
15
+ } from "./chunk-22RO7IDD.js";
16
16
  import {
17
17
  AGENT_INVOCATION_MAILBOX_STATUSES
18
- } from "./chunk-ZSNABC2E.js";
18
+ } from "./chunk-65SNO3WK.js";
19
19
  import {
20
20
  TURN_REASONING_LEVELS
21
- } from "./chunk-FX4PX3SA.js";
21
+ } from "./chunk-AEKBVJMV.js";
22
22
  import {
23
23
  pluginCatalogRuntime
24
- } from "./chunk-RULIISEI.js";
24
+ } from "./chunk-VNPG55CU.js";
25
25
  import {
26
26
  credentialContextSchema
27
27
  } from "./chunk-BDUENQD3.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-RF6J3DIO.js";
4
4
  import {
5
5
  resolveBaseUrl
6
- } from "./chunk-JW23XD4I.js";
6
+ } from "./chunk-OYN45QUQ.js";
7
7
  import {
8
8
  isExperimentalFeatureEnabled
9
9
  } from "./chunk-VRS6WDK5.js";
@@ -12,27 +12,27 @@ import {
12
12
  getPlugins,
13
13
  getSlackClient,
14
14
  withSlackRetries
15
- } from "./chunk-YHCTPDXS.js";
15
+ } from "./chunk-WX42YNDQ.js";
16
16
  import {
17
17
  getDb,
18
18
  parseDestination
19
- } from "./chunk-LPLVNMVN.js";
19
+ } from "./chunk-JDTCQDRU.js";
20
20
  import {
21
21
  sleep
22
22
  } from "./chunk-BVREIWBD.js";
23
23
  import {
24
24
  acquireActiveLock,
25
25
  getStateAdapter
26
- } from "./chunk-BXBZDV3C.js";
26
+ } from "./chunk-EKBVHDZO.js";
27
27
  import {
28
28
  pluginCatalogRuntime
29
- } from "./chunk-RULIISEI.js";
29
+ } from "./chunk-VNPG55CU.js";
30
30
  import {
31
31
  fetchWithBoundedOAuthErrorBodies
32
- } from "./chunk-VV2DN24T.js";
32
+ } from "./chunk-P6UQMGM2.js";
33
33
  import {
34
34
  isRecord
35
- } from "./chunk-VHSEMJTS.js";
35
+ } from "./chunk-JUFZR2LD.js";
36
36
 
37
37
  // src/chat/capabilities/router.ts
38
38
  var ProviderCredentialRouter = class {