@sentry/junior 0.162.0 → 0.164.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.
- package/README.md +2 -0
- package/dist/{agent-hooks-TL2SGC5W.js → agent-hooks-WTBPNRTC.js} +10 -10
- package/dist/api/acp/route.d.ts +13 -0
- package/dist/api/schema/workspace.d.ts +47 -0
- package/dist/api/schema.d.ts +2 -0
- package/dist/api/schema.js +15 -3
- package/dist/api/workspaces/routes.d.ts +4 -0
- package/dist/api.js +321 -408
- package/dist/app.d.ts +2 -2
- package/dist/app.js +482 -38
- package/dist/{catalog-runtime-IGSMIADJ.js → catalog-runtime-CZ2SQINY.js} +5 -5
- package/dist/chat/agent/sandbox.d.ts +4 -0
- package/dist/chat/api-turns/cancellation.d.ts +27 -0
- package/dist/chat/api-turns/routing.d.ts +31 -0
- package/dist/chat/api-turns/work.d.ts +12 -29
- package/dist/chat/app/conversation-work.d.ts +6 -1
- package/dist/chat/app/production.d.ts +2 -2
- package/dist/chat/conversations/history.d.ts +3 -0
- package/dist/chat/conversations/turn-lifecycle.d.ts +1 -1
- package/dist/chat/experimental.d.ts +1 -1
- package/dist/chat/plugins/agent-hooks.d.ts +4 -0
- package/dist/chat/repository-instructions.d.ts +1 -1
- package/dist/chat/sandbox/paths.d.ts +1 -0
- package/dist/chat/sandbox/prepare-workspace.d.ts +11 -0
- package/dist/chat/sandbox/ref.d.ts +1 -0
- package/dist/chat/sandbox/sandbox.d.ts +4 -0
- package/dist/chat/sandbox/session.d.ts +4 -0
- package/dist/chat/sandbox/snapshot/profile.d.ts +4 -3
- package/dist/chat/sandbox/snapshot/resolve.d.ts +4 -0
- package/dist/chat/sandbox/workspace.d.ts +4 -0
- package/dist/chat/tools/types.d.ts +5 -0
- package/dist/chat/workspaces/checkout-path.d.ts +4 -0
- package/dist/chat/workspaces/store.d.ts +37 -0
- package/dist/chat/workspaces/tools.d.ts +4 -0
- package/dist/chat/workspaces/types.d.ts +13 -0
- package/dist/chat/workspaces/validation.d.ts +21 -0
- package/dist/{chunk-THXMSSFZ.js → chunk-26JYGL2L.js} +1 -1
- package/dist/{chunk-OPNJRQDP.js → chunk-2K25MRZK.js} +9 -6
- package/dist/{chunk-C3KUKA27.js → chunk-3L23VTY7.js} +17 -17
- package/dist/{chunk-JJ3VXFDI.js → chunk-4GTOFUQF.js} +1 -1
- package/dist/{chunk-RDV4BQRZ.js → chunk-5FWQ73UZ.js} +1 -1
- package/dist/{chunk-BPZQWAZJ.js → chunk-5GLGQHO3.js} +4 -1
- package/dist/{chunk-K7IV6UV3.js → chunk-6BXV63YX.js} +5 -5
- package/dist/{chunk-4WYGQ47U.js → chunk-6ENAACWN.js} +5 -5
- package/dist/{chunk-EHQLTK3X.js → chunk-7WKWMMYQ.js} +323 -127
- package/dist/chunk-BVREIWBD.js +131 -0
- package/dist/{chunk-DZC3F2UI.js → chunk-BXBZDV3C.js} +1 -1
- package/dist/{chunk-HW4BW3PC.js → chunk-CGCNFEAU.js} +4 -4
- package/dist/{chunk-JRVURR3H.js → chunk-FKDY7NTC.js} +543 -164
- package/dist/{chunk-MNCEGXEH.js → chunk-FX4PX3SA.js} +2 -2
- package/dist/{chunk-OBFRMQBY.js → chunk-H36GJVJV.js} +9 -9
- package/dist/{chunk-V7QL4QMW.js → chunk-HHW6ZVIZ.js} +12 -7
- package/dist/{chunk-O6P7DZ6O.js → chunk-JW23XD4I.js} +6 -6
- package/dist/{chunk-DDQ43S5Q.js → chunk-LPLVNMVN.js} +4 -4
- package/dist/{chunk-5NEBOHRG.js → chunk-NAGI2XH3.js} +4 -4
- package/dist/{chunk-FEWT5KPP.js → chunk-NLTQRYNP.js} +2 -2
- package/dist/{chunk-SA6BEEAB.js → chunk-PU45BSBS.js} +108 -74
- package/dist/{chunk-7DTPFFQX.js → chunk-RBV4JHCP.js} +1 -1
- package/dist/{chunk-6BJFIWEV.js → chunk-RJHZNPDH.js} +46 -87
- package/dist/{chunk-FESUWAYU.js → chunk-RULIISEI.js} +1 -1
- package/dist/{chunk-MMBMDSRK.js → chunk-RYYEHWIL.js} +1 -1
- package/dist/{chunk-Y75ZDQB5.js → chunk-VHSEMJTS.js} +1 -1
- package/dist/{chunk-5IDFPCON.js → chunk-VRS6WDK5.js} +1 -1
- package/dist/{chunk-EBEHJPFF.js → chunk-VV2DN24T.js} +1 -1
- package/dist/{chunk-WHAJ3QVY.js → chunk-WJUKESU2.js} +1 -1
- package/dist/{chunk-H2KW7AZC.js → chunk-XAIRI54J.js} +1 -1
- package/dist/{chunk-AJ7J2HWY.js → chunk-Y2B6AXZQ.js} +6 -6
- package/dist/{chunk-QHCIZLIX.js → chunk-YHCTPDXS.js} +356 -13
- package/dist/{chunk-CZ6EHOU5.js → chunk-ZSNABC2E.js} +40 -2
- package/dist/{chunk-KQSO4DJ4.js → chunk-ZUTAGCPH.js} +9 -9
- package/dist/cli/chat.js +32 -32
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +13 -13
- package/dist/cli/snapshot-create.js +10 -10
- package/dist/cli/upgrade.js +7 -7
- package/dist/db/schema/workspaces.d.ts +169 -0
- package/dist/db/schema.d.ts +169 -1
- package/dist/{db-66XZ4HHQ.js → db-32KRFS6L.js} +7 -7
- package/dist/{experimental-HH6OM6UH.js → experimental-XVDOSRBS.js} +1 -1
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-FMLKDUUF.js → oauth-callback-server-CGZP2Z6U.js} +24 -24
- package/dist/{runner-YZONUMNY.js → runner-S5N4Q2XL.js} +32 -34
- package/dist/{skills-3UDJJXSO.js → skills-KYPSHSQR.js} +6 -6
- package/dist/spawn-EGOB3CLV.js +37 -0
- package/dist/{validation-3HTDBONC.js → validation-SZBE7JNF.js} +6 -6
- package/dist/version.js +1 -1
- package/dist/{work-O4YTIS54.js → work-GCZKHEZX.js} +18 -18
- package/dist/worker-6MY5Q4A2.js +24 -0
- package/migrations/0029_dizzy_barracuda.sql +19 -0
- package/migrations/meta/0029_snapshot.json +2709 -0
- package/migrations/meta/_journal.json +8 -1
- package/package.json +7 -4
- package/dist/chunk-EM225ITJ.js +0 -56
- package/dist/spawn-TBPVA5S2.js +0 -37
- package/dist/worker-WHURUEYX.js +0 -24
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getConversationEventStore,
|
|
3
|
-
getDb
|
|
4
|
-
|
|
3
|
+
getDb,
|
|
4
|
+
getSqlExecutor
|
|
5
|
+
} from "./chunk-LPLVNMVN.js";
|
|
5
6
|
import {
|
|
6
7
|
juniorConversationAnnotations,
|
|
7
8
|
juniorConversationEvents,
|
|
8
9
|
juniorIdentities,
|
|
9
|
-
juniorUsers
|
|
10
|
-
|
|
10
|
+
juniorUsers,
|
|
11
|
+
juniorWorkspaceRepos,
|
|
12
|
+
juniorWorkspaces
|
|
13
|
+
} from "./chunk-ZSNABC2E.js";
|
|
11
14
|
import {
|
|
12
15
|
SANDBOX_WORKSPACE_ROOT,
|
|
16
|
+
runNonInteractiveCommand,
|
|
13
17
|
sleep
|
|
14
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-BVREIWBD.js";
|
|
15
19
|
import {
|
|
16
20
|
getStateAdapter
|
|
17
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-BXBZDV3C.js";
|
|
18
22
|
import {
|
|
19
23
|
botConfig,
|
|
20
24
|
completeObject,
|
|
21
25
|
embedTexts,
|
|
22
26
|
getSlackBotToken,
|
|
23
27
|
standardModelId
|
|
24
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-FX4PX3SA.js";
|
|
25
29
|
import {
|
|
26
30
|
isActorUserId,
|
|
27
31
|
parseActorUserId,
|
|
@@ -37,7 +41,7 @@ import {
|
|
|
37
41
|
setSpanAttributes,
|
|
38
42
|
setSpanStatus,
|
|
39
43
|
withSpan
|
|
40
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-VHSEMJTS.js";
|
|
41
45
|
|
|
42
46
|
// src/chat/plugins/agent-hooks.ts
|
|
43
47
|
import {
|
|
@@ -1196,6 +1200,275 @@ function resolveChannelCapabilities(channelId) {
|
|
|
1196
1200
|
|
|
1197
1201
|
// src/chat/plugins/agent-hooks.ts
|
|
1198
1202
|
import { z as z2 } from "zod";
|
|
1203
|
+
|
|
1204
|
+
// src/chat/workspaces/checkout-path.ts
|
|
1205
|
+
function tryWorkspaceRepoCheckoutPath(repo) {
|
|
1206
|
+
const name = repo.split("/").filter(Boolean).at(-1);
|
|
1207
|
+
if (!name || name === "." || name === ".." || !/^[A-Za-z0-9._-]+$/.test(name)) {
|
|
1208
|
+
return void 0;
|
|
1209
|
+
}
|
|
1210
|
+
return `repos/${name}`;
|
|
1211
|
+
}
|
|
1212
|
+
function workspaceRepoCheckoutPath(repo) {
|
|
1213
|
+
const path = tryWorkspaceRepoCheckoutPath(repo);
|
|
1214
|
+
if (!path) {
|
|
1215
|
+
throw new Error(`Invalid repository name for checkout path: ${repo}`);
|
|
1216
|
+
}
|
|
1217
|
+
return path;
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
// src/chat/workspaces/store.ts
|
|
1221
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
1222
|
+
import { and as and4, asc as asc2, eq as eq4, sql as sql2 } from "drizzle-orm";
|
|
1223
|
+
|
|
1224
|
+
// src/chat/workspaces/validation.ts
|
|
1225
|
+
var WORKSPACE_NAME_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;
|
|
1226
|
+
var PROVIDER_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;
|
|
1227
|
+
var REPO_PATTERN = /^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/;
|
|
1228
|
+
var MAX_SETUP_SCRIPT_BYTES = 64 * 1024;
|
|
1229
|
+
var MAX_REPOS = 32;
|
|
1230
|
+
var WorkspaceValidationError = class extends Error {
|
|
1231
|
+
constructor(message) {
|
|
1232
|
+
super(message);
|
|
1233
|
+
this.name = "WorkspaceValidationError";
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1236
|
+
function normalizeWorkspaceRecipe(input) {
|
|
1237
|
+
const name = input.name.trim().toLowerCase();
|
|
1238
|
+
if (!WORKSPACE_NAME_PATTERN.test(name)) {
|
|
1239
|
+
throw new WorkspaceValidationError(
|
|
1240
|
+
"Workspace name must start with a letter and use only lowercase letters, digits, underscores, or hyphens."
|
|
1241
|
+
);
|
|
1242
|
+
}
|
|
1243
|
+
const setupScript = input.setupScript ?? "";
|
|
1244
|
+
if (typeof setupScript !== "string") {
|
|
1245
|
+
throw new WorkspaceValidationError("Setup script must be a string.");
|
|
1246
|
+
}
|
|
1247
|
+
if (Buffer.byteLength(setupScript, "utf8") > MAX_SETUP_SCRIPT_BYTES) {
|
|
1248
|
+
throw new WorkspaceValidationError(
|
|
1249
|
+
`Setup script must be at most ${MAX_SETUP_SCRIPT_BYTES} bytes.`
|
|
1250
|
+
);
|
|
1251
|
+
}
|
|
1252
|
+
if (!Array.isArray(input.repos)) {
|
|
1253
|
+
throw new WorkspaceValidationError("Repositories must be an array.");
|
|
1254
|
+
}
|
|
1255
|
+
if (input.repos.length > MAX_REPOS) {
|
|
1256
|
+
throw new WorkspaceValidationError(
|
|
1257
|
+
`A Workspace can include at most ${MAX_REPOS} repositories.`
|
|
1258
|
+
);
|
|
1259
|
+
}
|
|
1260
|
+
const repos = input.repos.map((entry, index) => {
|
|
1261
|
+
const provider = entry.provider.trim().toLowerCase();
|
|
1262
|
+
if (!PROVIDER_PATTERN.test(provider)) {
|
|
1263
|
+
throw new WorkspaceValidationError(
|
|
1264
|
+
`Repository ${index + 1} provider is invalid.`
|
|
1265
|
+
);
|
|
1266
|
+
}
|
|
1267
|
+
const repo = entry.repo.trim();
|
|
1268
|
+
if (!REPO_PATTERN.test(repo)) {
|
|
1269
|
+
throw new WorkspaceValidationError(
|
|
1270
|
+
`Repository ${index + 1} must use owner/name format.`
|
|
1271
|
+
);
|
|
1272
|
+
}
|
|
1273
|
+
if (!tryWorkspaceRepoCheckoutPath(repo)) {
|
|
1274
|
+
throw new WorkspaceValidationError(
|
|
1275
|
+
`Repository ${index + 1} name cannot be used as a checkout path.`
|
|
1276
|
+
);
|
|
1277
|
+
}
|
|
1278
|
+
return {
|
|
1279
|
+
provider,
|
|
1280
|
+
repo,
|
|
1281
|
+
isPrimary: entry.isPrimary === true
|
|
1282
|
+
};
|
|
1283
|
+
});
|
|
1284
|
+
const identities = /* @__PURE__ */ new Set();
|
|
1285
|
+
for (const repo of repos) {
|
|
1286
|
+
const identity = `${repo.provider}:${repo.repo.toLowerCase()}`;
|
|
1287
|
+
if (identities.has(identity)) {
|
|
1288
|
+
throw new WorkspaceValidationError(
|
|
1289
|
+
`Duplicate repository in Workspace: ${repo.provider}:${repo.repo}`
|
|
1290
|
+
);
|
|
1291
|
+
}
|
|
1292
|
+
identities.add(identity);
|
|
1293
|
+
}
|
|
1294
|
+
const checkoutPaths = /* @__PURE__ */ new Set();
|
|
1295
|
+
for (const repo of repos) {
|
|
1296
|
+
const path = tryWorkspaceRepoCheckoutPath(repo.repo);
|
|
1297
|
+
const key = path.toLowerCase();
|
|
1298
|
+
if (checkoutPaths.has(key)) {
|
|
1299
|
+
throw new WorkspaceValidationError(
|
|
1300
|
+
`Workspace checkout path collision: ${path}`
|
|
1301
|
+
);
|
|
1302
|
+
}
|
|
1303
|
+
checkoutPaths.add(key);
|
|
1304
|
+
}
|
|
1305
|
+
const primaryCount = repos.filter((repo) => repo.isPrimary).length;
|
|
1306
|
+
if (repos.length > 0 && primaryCount === 0) {
|
|
1307
|
+
throw new WorkspaceValidationError(
|
|
1308
|
+
"Select one primary repository for AGENTS.md instructions."
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1311
|
+
if (primaryCount > 1) {
|
|
1312
|
+
throw new WorkspaceValidationError(
|
|
1313
|
+
"A Workspace can have only one primary repository."
|
|
1314
|
+
);
|
|
1315
|
+
}
|
|
1316
|
+
return { name, setupScript, repos };
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
// src/chat/workspaces/store.ts
|
|
1320
|
+
function workspaceFromRows(row, repos) {
|
|
1321
|
+
return {
|
|
1322
|
+
id: row.id,
|
|
1323
|
+
name: row.name,
|
|
1324
|
+
setupScript: row.setupScript,
|
|
1325
|
+
repos: repos.map((repo) => ({
|
|
1326
|
+
provider: repo.provider,
|
|
1327
|
+
repo: repo.repo,
|
|
1328
|
+
isPrimary: repo.isPrimary
|
|
1329
|
+
}))
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
async function loadWorkspaceRepos(db, workspaceId) {
|
|
1333
|
+
return await db.select().from(juniorWorkspaceRepos).where(eq4(juniorWorkspaceRepos.workspaceId, workspaceId)).orderBy(
|
|
1334
|
+
asc2(juniorWorkspaceRepos.provider),
|
|
1335
|
+
asc2(juniorWorkspaceRepos.repo)
|
|
1336
|
+
);
|
|
1337
|
+
}
|
|
1338
|
+
async function replaceWorkspaceRepos(db, workspaceId, repos) {
|
|
1339
|
+
await db.delete(juniorWorkspaceRepos).where(eq4(juniorWorkspaceRepos.workspaceId, workspaceId));
|
|
1340
|
+
if (repos.length === 0) return;
|
|
1341
|
+
await db.insert(juniorWorkspaceRepos).values(
|
|
1342
|
+
repos.map((repo) => ({
|
|
1343
|
+
workspaceId,
|
|
1344
|
+
provider: repo.provider,
|
|
1345
|
+
repo: repo.repo,
|
|
1346
|
+
isPrimary: repo.isPrimary
|
|
1347
|
+
}))
|
|
1348
|
+
);
|
|
1349
|
+
}
|
|
1350
|
+
function isUniqueViolation(error) {
|
|
1351
|
+
let current = error;
|
|
1352
|
+
for (let depth = 0; current && depth < 6; depth += 1) {
|
|
1353
|
+
if (typeof current === "object" && current !== null && "code" in current && current.code === "23505") {
|
|
1354
|
+
return true;
|
|
1355
|
+
}
|
|
1356
|
+
current = typeof current === "object" && current !== null && "cause" in current ? current.cause : void 0;
|
|
1357
|
+
}
|
|
1358
|
+
return false;
|
|
1359
|
+
}
|
|
1360
|
+
async function listWorkspaces(db) {
|
|
1361
|
+
const [workspaces, repos] = await Promise.all([
|
|
1362
|
+
db.select().from(juniorWorkspaces).orderBy(asc2(juniorWorkspaces.name)),
|
|
1363
|
+
db.select().from(juniorWorkspaceRepos).orderBy(
|
|
1364
|
+
asc2(juniorWorkspaceRepos.workspaceId),
|
|
1365
|
+
asc2(juniorWorkspaceRepos.provider),
|
|
1366
|
+
asc2(juniorWorkspaceRepos.repo)
|
|
1367
|
+
)
|
|
1368
|
+
]);
|
|
1369
|
+
return workspaces.map(
|
|
1370
|
+
(workspace) => workspaceFromRows(
|
|
1371
|
+
workspace,
|
|
1372
|
+
repos.filter((repo) => repo.workspaceId === workspace.id)
|
|
1373
|
+
)
|
|
1374
|
+
);
|
|
1375
|
+
}
|
|
1376
|
+
async function listWorkspaceNamesByRepository(db, input) {
|
|
1377
|
+
const provider = input.provider.trim().toLowerCase();
|
|
1378
|
+
const repo = input.repo.trim();
|
|
1379
|
+
const rows = await db.select({ name: juniorWorkspaces.name }).from(juniorWorkspaceRepos).innerJoin(
|
|
1380
|
+
juniorWorkspaces,
|
|
1381
|
+
eq4(juniorWorkspaces.id, juniorWorkspaceRepos.workspaceId)
|
|
1382
|
+
).where(
|
|
1383
|
+
and4(
|
|
1384
|
+
eq4(juniorWorkspaceRepos.provider, provider),
|
|
1385
|
+
// Recipes store the provided repo casing; identity is case-insensitive.
|
|
1386
|
+
sql2`lower(${juniorWorkspaceRepos.repo}) = lower(${repo})`
|
|
1387
|
+
)
|
|
1388
|
+
).orderBy(asc2(juniorWorkspaces.name));
|
|
1389
|
+
return rows.map((row) => row.name);
|
|
1390
|
+
}
|
|
1391
|
+
async function getWorkspaceByName(db, name) {
|
|
1392
|
+
const rows = await db.select().from(juniorWorkspaces).where(eq4(juniorWorkspaces.name, name)).limit(1);
|
|
1393
|
+
const workspace = rows[0];
|
|
1394
|
+
if (!workspace) return void 0;
|
|
1395
|
+
return workspaceFromRows(
|
|
1396
|
+
workspace,
|
|
1397
|
+
await loadWorkspaceRepos(db, workspace.id)
|
|
1398
|
+
);
|
|
1399
|
+
}
|
|
1400
|
+
async function getWorkspace(db, id) {
|
|
1401
|
+
const rows = await db.select().from(juniorWorkspaces).where(eq4(juniorWorkspaces.id, id)).limit(1);
|
|
1402
|
+
const workspace = rows[0];
|
|
1403
|
+
if (!workspace) return void 0;
|
|
1404
|
+
return workspaceFromRows(
|
|
1405
|
+
workspace,
|
|
1406
|
+
await loadWorkspaceRepos(db, workspace.id)
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
async function createWorkspace(input) {
|
|
1410
|
+
const recipe = normalizeWorkspaceRecipe(input);
|
|
1411
|
+
const executor = getSqlExecutor();
|
|
1412
|
+
const now = /* @__PURE__ */ new Date();
|
|
1413
|
+
const id = randomUUID2();
|
|
1414
|
+
try {
|
|
1415
|
+
await executor.transaction(async () => {
|
|
1416
|
+
const db = executor.db();
|
|
1417
|
+
await db.insert(juniorWorkspaces).values({
|
|
1418
|
+
id,
|
|
1419
|
+
name: recipe.name,
|
|
1420
|
+
setupScript: recipe.setupScript,
|
|
1421
|
+
createdAt: now,
|
|
1422
|
+
updatedAt: now
|
|
1423
|
+
});
|
|
1424
|
+
await replaceWorkspaceRepos(db, id, recipe.repos);
|
|
1425
|
+
});
|
|
1426
|
+
} catch (error) {
|
|
1427
|
+
if (isUniqueViolation(error)) {
|
|
1428
|
+
throw new WorkspaceValidationError(
|
|
1429
|
+
`Workspace name already exists: ${recipe.name}`
|
|
1430
|
+
);
|
|
1431
|
+
}
|
|
1432
|
+
throw error;
|
|
1433
|
+
}
|
|
1434
|
+
return await getWorkspace(executor.db(), id);
|
|
1435
|
+
}
|
|
1436
|
+
async function updateWorkspace(id, input) {
|
|
1437
|
+
const recipe = normalizeWorkspaceRecipe(input);
|
|
1438
|
+
const executor = getSqlExecutor();
|
|
1439
|
+
const now = /* @__PURE__ */ new Date();
|
|
1440
|
+
try {
|
|
1441
|
+
const updated = await executor.transaction(async () => {
|
|
1442
|
+
const db = executor.db();
|
|
1443
|
+
const rows = await db.update(juniorWorkspaces).set({
|
|
1444
|
+
name: recipe.name,
|
|
1445
|
+
setupScript: recipe.setupScript,
|
|
1446
|
+
updatedAt: now
|
|
1447
|
+
}).where(eq4(juniorWorkspaces.id, id)).returning();
|
|
1448
|
+
if (!rows[0]) return void 0;
|
|
1449
|
+
await replaceWorkspaceRepos(db, id, recipe.repos);
|
|
1450
|
+
return rows[0];
|
|
1451
|
+
});
|
|
1452
|
+
if (!updated) return void 0;
|
|
1453
|
+
} catch (error) {
|
|
1454
|
+
if (isUniqueViolation(error)) {
|
|
1455
|
+
throw new WorkspaceValidationError(
|
|
1456
|
+
`Workspace name already exists: ${recipe.name}`
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
throw error;
|
|
1460
|
+
}
|
|
1461
|
+
return await getWorkspace(executor.db(), id);
|
|
1462
|
+
}
|
|
1463
|
+
async function deleteWorkspace(id) {
|
|
1464
|
+
const executor = getSqlExecutor();
|
|
1465
|
+
return await executor.transaction(async () => {
|
|
1466
|
+
const rows = await executor.db().delete(juniorWorkspaces).where(eq4(juniorWorkspaces.id, id)).returning({ id: juniorWorkspaces.id });
|
|
1467
|
+
return rows.length > 0;
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
// src/chat/plugins/agent-hooks.ts
|
|
1199
1472
|
var PluginHookDeniedError = class extends Error {
|
|
1200
1473
|
constructor(message) {
|
|
1201
1474
|
super(message);
|
|
@@ -1621,13 +1894,20 @@ function getPluginTools(context, sandbox = createSandboxCapability(context.works
|
|
|
1621
1894
|
resourceEvents,
|
|
1622
1895
|
sandbox,
|
|
1623
1896
|
state: createPluginState(pluginName),
|
|
1624
|
-
users: { resolveActor }
|
|
1897
|
+
users: { resolveActor },
|
|
1898
|
+
workspaces: {
|
|
1899
|
+
async findByRepository(input) {
|
|
1900
|
+
return await listWorkspaceNamesByRepository(getDb(), input);
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1625
1903
|
};
|
|
1626
1904
|
let pluginContext;
|
|
1627
1905
|
switch (context.source.platform) {
|
|
1628
1906
|
case "slack":
|
|
1629
1907
|
if (context.destination.platform !== "slack") {
|
|
1630
|
-
throw new TypeError(
|
|
1908
|
+
throw new TypeError(
|
|
1909
|
+
"Slack plugin context requires Slack destination"
|
|
1910
|
+
);
|
|
1631
1911
|
}
|
|
1632
1912
|
pluginContext = {
|
|
1633
1913
|
...common,
|
|
@@ -1639,7 +1919,9 @@ function getPluginTools(context, sandbox = createSandboxCapability(context.works
|
|
|
1639
1919
|
break;
|
|
1640
1920
|
case "local":
|
|
1641
1921
|
if (context.destination.platform !== "local") {
|
|
1642
|
-
throw new TypeError(
|
|
1922
|
+
throw new TypeError(
|
|
1923
|
+
"Local plugin context requires local destination"
|
|
1924
|
+
);
|
|
1643
1925
|
}
|
|
1644
1926
|
pluginContext = {
|
|
1645
1927
|
...common,
|
|
@@ -2180,7 +2462,12 @@ function normalizeEnv(value) {
|
|
|
2180
2462
|
}
|
|
2181
2463
|
return env;
|
|
2182
2464
|
}
|
|
2183
|
-
function
|
|
2465
|
+
function preparationSignal(inputSignal, ownerSignal) {
|
|
2466
|
+
if (!inputSignal) return ownerSignal;
|
|
2467
|
+
if (!ownerSignal) return inputSignal;
|
|
2468
|
+
return AbortSignal.any([inputSignal, ownerSignal]);
|
|
2469
|
+
}
|
|
2470
|
+
function createSandboxCapability(workspace, ownerSignal) {
|
|
2184
2471
|
return {
|
|
2185
2472
|
root: SANDBOX_WORKSPACE_ROOT,
|
|
2186
2473
|
juniorRoot: `${SANDBOX_WORKSPACE_ROOT}/.junior`,
|
|
@@ -2188,7 +2475,11 @@ function createSandboxCapability(workspace) {
|
|
|
2188
2475
|
return await workspace.readFileToBuffer({ path: filePath }) ?? null;
|
|
2189
2476
|
},
|
|
2190
2477
|
async run(input) {
|
|
2191
|
-
const
|
|
2478
|
+
const signal = preparationSignal(input.signal, ownerSignal);
|
|
2479
|
+
const result = await runNonInteractiveCommand(workspace, {
|
|
2480
|
+
...input,
|
|
2481
|
+
...signal ? { signal } : {}
|
|
2482
|
+
});
|
|
2192
2483
|
return {
|
|
2193
2484
|
exitCode: result.exitCode,
|
|
2194
2485
|
stdout: result.stdout,
|
|
@@ -2243,6 +2534,49 @@ function createPluginHookRunner(input = {}) {
|
|
|
2243
2534
|
}
|
|
2244
2535
|
}
|
|
2245
2536
|
},
|
|
2537
|
+
async prepareWorkspace(sandbox, repos, signal) {
|
|
2538
|
+
const preparers = new Set(
|
|
2539
|
+
loaded.filter((plugin) => plugin.hooks?.workspacePrepare).map((plugin) => plugin.manifest.name)
|
|
2540
|
+
);
|
|
2541
|
+
const unhandledProviders = [
|
|
2542
|
+
...new Set(
|
|
2543
|
+
repos.map((repo) => repo.provider).filter((provider) => !preparers.has(provider))
|
|
2544
|
+
)
|
|
2545
|
+
].sort();
|
|
2546
|
+
if (unhandledProviders.length > 0) {
|
|
2547
|
+
throw new Error(
|
|
2548
|
+
`Workspace repository providers have no preparation hook: ${unhandledProviders.join(", ")}`
|
|
2549
|
+
);
|
|
2550
|
+
}
|
|
2551
|
+
const selectedRepos = repos.map((repo) => ({
|
|
2552
|
+
provider: repo.provider,
|
|
2553
|
+
repo: repo.repo,
|
|
2554
|
+
path: workspaceRepoCheckoutPath(repo.repo)
|
|
2555
|
+
}));
|
|
2556
|
+
const paths = /* @__PURE__ */ new Set();
|
|
2557
|
+
for (const entry of selectedRepos) {
|
|
2558
|
+
const key = entry.path.toLowerCase();
|
|
2559
|
+
if (paths.has(key)) {
|
|
2560
|
+
throw new Error(`Workspace checkout path collision: ${entry.path}`);
|
|
2561
|
+
}
|
|
2562
|
+
paths.add(key);
|
|
2563
|
+
}
|
|
2564
|
+
const sandboxCapability = createSandboxCapability(sandbox, signal);
|
|
2565
|
+
for (const plugin of loaded) {
|
|
2566
|
+
const hook = plugin.hooks?.workspacePrepare;
|
|
2567
|
+
if (!hook) continue;
|
|
2568
|
+
const selected = selectedRepos.filter((repo) => repo.provider === plugin.manifest.name).map((repo) => ({
|
|
2569
|
+
path: repo.path,
|
|
2570
|
+
repo: repo.repo
|
|
2571
|
+
}));
|
|
2572
|
+
if (selected.length === 0) continue;
|
|
2573
|
+
await hook({
|
|
2574
|
+
...basePluginContext(plugin),
|
|
2575
|
+
repos: selected,
|
|
2576
|
+
sandbox: sandboxCapability
|
|
2577
|
+
});
|
|
2578
|
+
}
|
|
2579
|
+
},
|
|
2246
2580
|
async prepareSandbox(sandbox) {
|
|
2247
2581
|
const sandboxCapability = createSandboxCapability(sandbox);
|
|
2248
2582
|
for (const plugin of loaded) {
|
|
@@ -2356,6 +2690,15 @@ export {
|
|
|
2356
2690
|
bindEventTaskCredentialSubject,
|
|
2357
2691
|
verifyEventTaskCredentialSubject,
|
|
2358
2692
|
resolveChannelCapabilities,
|
|
2693
|
+
tryWorkspaceRepoCheckoutPath,
|
|
2694
|
+
workspaceRepoCheckoutPath,
|
|
2695
|
+
WorkspaceValidationError,
|
|
2696
|
+
listWorkspaces,
|
|
2697
|
+
getWorkspaceByName,
|
|
2698
|
+
getWorkspace,
|
|
2699
|
+
createWorkspace,
|
|
2700
|
+
updateWorkspace,
|
|
2701
|
+
deleteWorkspace,
|
|
2359
2702
|
PluginHookDeniedError,
|
|
2360
2703
|
validatePlugins,
|
|
2361
2704
|
setPlugins,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_SQL_STATEMENT_TIMEOUT_MS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FX4PX3SA.js";
|
|
4
4
|
import {
|
|
5
5
|
juniorDestinations,
|
|
6
6
|
timestamptz
|
|
@@ -645,6 +645,40 @@ var juniorSchedulerRuns = pgTable16(
|
|
|
645
645
|
]
|
|
646
646
|
);
|
|
647
647
|
|
|
648
|
+
// src/db/schema/workspaces.ts
|
|
649
|
+
import { sql as sql6 } from "drizzle-orm";
|
|
650
|
+
import {
|
|
651
|
+
boolean as boolean3,
|
|
652
|
+
pgTable as pgTable17,
|
|
653
|
+
primaryKey as primaryKey9,
|
|
654
|
+
text as text17,
|
|
655
|
+
uniqueIndex as uniqueIndex7
|
|
656
|
+
} from "drizzle-orm/pg-core";
|
|
657
|
+
var juniorWorkspaces = pgTable17(
|
|
658
|
+
"junior_workspaces",
|
|
659
|
+
{
|
|
660
|
+
id: text17("id").primaryKey(),
|
|
661
|
+
name: text17("name").notNull(),
|
|
662
|
+
setupScript: text17("setup_script").notNull().default(""),
|
|
663
|
+
createdAt: timestamptz("created_at").notNull(),
|
|
664
|
+
updatedAt: timestamptz("updated_at").notNull()
|
|
665
|
+
},
|
|
666
|
+
(table) => [uniqueIndex7("junior_workspaces_name_idx").on(table.name)]
|
|
667
|
+
);
|
|
668
|
+
var juniorWorkspaceRepos = pgTable17(
|
|
669
|
+
"junior_workspace_repos",
|
|
670
|
+
{
|
|
671
|
+
workspaceId: text17("workspace_id").notNull().references(() => juniorWorkspaces.id, { onDelete: "cascade" }),
|
|
672
|
+
provider: text17("provider").notNull(),
|
|
673
|
+
repo: text17("repo").notNull(),
|
|
674
|
+
isPrimary: boolean3("is_primary").notNull().default(false)
|
|
675
|
+
},
|
|
676
|
+
(table) => [
|
|
677
|
+
primaryKey9({ columns: [table.workspaceId, table.provider, table.repo] }),
|
|
678
|
+
uniqueIndex7("junior_workspace_repos_primary_idx").on(table.workspaceId).where(sql6`${table.isPrimary}`)
|
|
679
|
+
]
|
|
680
|
+
);
|
|
681
|
+
|
|
648
682
|
// src/db/schema.ts
|
|
649
683
|
var juniorSqlSchema = {
|
|
650
684
|
juniorArtifacts,
|
|
@@ -665,7 +699,9 @@ var juniorSqlSchema = {
|
|
|
665
699
|
juniorTaskExecutions,
|
|
666
700
|
juniorSchedulerRuns,
|
|
667
701
|
juniorSchedulerTasks,
|
|
668
|
-
juniorUsers
|
|
702
|
+
juniorUsers,
|
|
703
|
+
juniorWorkspaceRepos,
|
|
704
|
+
juniorWorkspaces
|
|
669
705
|
};
|
|
670
706
|
|
|
671
707
|
// src/db/neon.ts
|
|
@@ -937,5 +973,7 @@ export {
|
|
|
937
973
|
juniorTaskExecutions,
|
|
938
974
|
juniorSchedulerTasks,
|
|
939
975
|
juniorSchedulerRuns,
|
|
976
|
+
juniorWorkspaces,
|
|
977
|
+
juniorWorkspaceRepos,
|
|
940
978
|
createJuniorSqlExecutor
|
|
941
979
|
};
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
coerceThreadConversationState,
|
|
3
3
|
getPersistedThreadState,
|
|
4
4
|
persistThreadStateById
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2K25MRZK.js";
|
|
6
6
|
import {
|
|
7
7
|
pluginTaskId,
|
|
8
8
|
pluginTaskParamsSchema,
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
markTurnCompleted,
|
|
23
23
|
normalizeToolNameFromResult,
|
|
24
24
|
stripRuntimeTurnContext
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-HHW6ZVIZ.js";
|
|
26
26
|
import {
|
|
27
27
|
JUNIOR_THREAD_STATE_TTL_MS
|
|
28
28
|
} from "./chunk-3Y47VMHV.js";
|
|
@@ -33,25 +33,25 @@ import {
|
|
|
33
33
|
createPluginModel,
|
|
34
34
|
createPluginState,
|
|
35
35
|
getPlugins
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-YHCTPDXS.js";
|
|
37
37
|
import {
|
|
38
38
|
getConversationStore,
|
|
39
39
|
getDb,
|
|
40
40
|
sameActorIdentity
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-LPLVNMVN.js";
|
|
42
42
|
import {
|
|
43
43
|
juniorConversations,
|
|
44
44
|
juniorTaskExecutions
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-ZSNABC2E.js";
|
|
46
46
|
import {
|
|
47
47
|
getStateAdapter
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-BXBZDV3C.js";
|
|
49
49
|
import {
|
|
50
50
|
ProviderError,
|
|
51
51
|
findProviderError,
|
|
52
52
|
getProviderErrorAttributes,
|
|
53
53
|
getProviderErrorUserMessage
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-FX4PX3SA.js";
|
|
55
55
|
import {
|
|
56
56
|
credentialSubjectSchema
|
|
57
57
|
} from "./chunk-BDUENQD3.js";
|
|
@@ -61,7 +61,7 @@ import {
|
|
|
61
61
|
import {
|
|
62
62
|
buildTurnFailureResponse,
|
|
63
63
|
logWarn
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-VHSEMJTS.js";
|
|
65
65
|
|
|
66
66
|
// src/chat/runtime/delivered-turn-state.ts
|
|
67
67
|
function buildDeliveredTurnStatePatch(args) {
|
|
@@ -87,7 +87,7 @@ import { pluginRunContextSchema } from "@sentry/junior-plugin-api";
|
|
|
87
87
|
|
|
88
88
|
// src/chat/services/turn-session-routing.ts
|
|
89
89
|
async function resolveTurnSessionRouting(args) {
|
|
90
|
-
const conversationStore = args.conversationStore ?? (await import("./db-
|
|
90
|
+
const conversationStore = args.conversationStore ?? (await import("./db-32KRFS6L.js")).getConversationStore();
|
|
91
91
|
const conversation = await conversationStore.get({
|
|
92
92
|
conversationId: args.conversationId
|
|
93
93
|
});
|
package/dist/cli/chat.js
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
1
|
import {
|
|
2
2
|
executeAgentRun
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-7WKWMMYQ.js";
|
|
4
|
+
import "../chunk-6BXV63YX.js";
|
|
5
5
|
import "../chunk-DIB4GX3G.js";
|
|
6
6
|
import {
|
|
7
7
|
createAgentRunner
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-H36GJVJV.js";
|
|
9
9
|
import "../chunk-RF6J3DIO.js";
|
|
10
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-JW23XD4I.js";
|
|
11
11
|
import "../chunk-7MA4HV4W.js";
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-VRS6WDK5.js";
|
|
13
|
+
import "../chunk-RJHZNPDH.js";
|
|
14
|
+
import "../chunk-6ENAACWN.js";
|
|
15
|
+
import "../chunk-WJUKESU2.js";
|
|
16
|
+
import "../chunk-HHW6ZVIZ.js";
|
|
17
17
|
import "../chunk-3Y47VMHV.js";
|
|
18
18
|
import "../chunk-PDO5BLNM.js";
|
|
19
19
|
import "../chunk-UIE3R5XU.js";
|
|
20
20
|
import {
|
|
21
21
|
loadAppPluginSet
|
|
22
22
|
} from "../chunk-Y2CM7HXH.js";
|
|
23
|
-
import "../chunk-
|
|
24
|
-
import "../chunk-
|
|
25
|
-
import "../chunk-
|
|
26
|
-
import "../chunk-
|
|
27
|
-
import "../chunk-
|
|
28
|
-
import "../chunk-
|
|
23
|
+
import "../chunk-YHCTPDXS.js";
|
|
24
|
+
import "../chunk-LPLVNMVN.js";
|
|
25
|
+
import "../chunk-ZSNABC2E.js";
|
|
26
|
+
import "../chunk-BVREIWBD.js";
|
|
27
|
+
import "../chunk-BXBZDV3C.js";
|
|
28
|
+
import "../chunk-FX4PX3SA.js";
|
|
29
29
|
import "../chunk-VFUK3X5B.js";
|
|
30
|
-
import "../chunk-
|
|
31
|
-
import "../chunk-
|
|
32
|
-
import "../chunk-
|
|
33
|
-
import "../chunk-
|
|
30
|
+
import "../chunk-RBV4JHCP.js";
|
|
31
|
+
import "../chunk-NLTQRYNP.js";
|
|
32
|
+
import "../chunk-RULIISEI.js";
|
|
33
|
+
import "../chunk-VV2DN24T.js";
|
|
34
34
|
import "../chunk-BDUENQD3.js";
|
|
35
35
|
import "../chunk-V7YE4WCP.js";
|
|
36
|
-
import "../chunk-
|
|
36
|
+
import "../chunk-VHSEMJTS.js";
|
|
37
37
|
import "../chunk-6GWA276C.js";
|
|
38
38
|
import "../chunk-OOUNJNMR.js";
|
|
39
39
|
import "../chunk-H4HBKISO.js";
|
|
40
|
-
import "../chunk-
|
|
41
|
-
import "../chunk-
|
|
40
|
+
import "../chunk-26JYGL2L.js";
|
|
41
|
+
import "../chunk-5GLGQHO3.js";
|
|
42
42
|
import "../chunk-MLKGABMK.js";
|
|
43
43
|
|
|
44
44
|
// src/cli/chat.ts
|
|
@@ -161,10 +161,10 @@ async function configureLocalChatPlugins(pluginSet) {
|
|
|
161
161
|
databaseModule
|
|
162
162
|
] = await Promise.all([
|
|
163
163
|
import("../plugins-HW4VWW6G.js"),
|
|
164
|
-
import("../agent-hooks-
|
|
165
|
-
import("../catalog-runtime-
|
|
166
|
-
import("../validation-
|
|
167
|
-
import("../db-
|
|
164
|
+
import("../agent-hooks-WTBPNRTC.js"),
|
|
165
|
+
import("../catalog-runtime-CZ2SQINY.js"),
|
|
166
|
+
import("../validation-SZBE7JNF.js"),
|
|
167
|
+
import("../db-32KRFS6L.js")
|
|
168
168
|
]);
|
|
169
169
|
const resolvedPluginSet = pluginSet === void 0 ? await loadLocalPluginSet() : pluginSet ?? void 0;
|
|
170
170
|
const plugins = pluginsModule.pluginRuntimeRegistrationsFromPluginSet(resolvedPluginSet);
|
|
@@ -228,16 +228,16 @@ function localDevServerUrl() {
|
|
|
228
228
|
async function prepareLocalChatRun(io, pluginSet) {
|
|
229
229
|
defaultStateAdapterForLocalChat();
|
|
230
230
|
await configureLocalChatPlugins(pluginSet);
|
|
231
|
-
const { setExperimentalFeatures } = await import("../experimental-
|
|
231
|
+
const { setExperimentalFeatures } = await import("../experimental-XVDOSRBS.js");
|
|
232
232
|
setExperimentalFeatures({ subagents: true });
|
|
233
|
-
const { runLocalAgentTurn } = await import("../runner-
|
|
234
|
-
const { startLocalOAuthCallbackServer } = await import("../oauth-callback-server-
|
|
233
|
+
const { runLocalAgentTurn } = await import("../runner-S5N4Q2XL.js");
|
|
234
|
+
const { startLocalOAuthCallbackServer } = await import("../oauth-callback-server-CGZP2Z6U.js");
|
|
235
235
|
const { createLocalOAuthState } = await import("../oauth-relay-3ZU72UGL.js");
|
|
236
236
|
const { createLocalSandboxEgressSignalTransport } = await import("../sandbox-egress-signals-U3ZX7C5W.js");
|
|
237
|
-
const { bindSpawnAgent } = await import("../spawn-
|
|
238
|
-
const { createAgentInvocationWorker, routeAgentInvocationWork } = await import("../work-
|
|
237
|
+
const { bindSpawnAgent } = await import("../spawn-EGOB3CLV.js");
|
|
238
|
+
const { createAgentInvocationWorker, routeAgentInvocationWork } = await import("../work-GCZKHEZX.js");
|
|
239
239
|
const { createLocalConversationWork } = await import("../conversation-work-KATFHLG3.js");
|
|
240
|
-
const { processConversationWork } = await import("../worker-
|
|
240
|
+
const { processConversationWork } = await import("../worker-6MY5Q4A2.js");
|
|
241
241
|
let agentRunner;
|
|
242
242
|
const localConversationWork = createLocalConversationWork(async (message) => {
|
|
243
243
|
if (!agentRunner) {
|