@sentry/junior 0.74.1 → 0.76.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 (121) hide show
  1. package/README.md +1 -1
  2. package/bin/junior.mjs +4 -66
  3. package/dist/agent-hooks-ZOE7RIED.js +37 -0
  4. package/dist/api-reference.d.ts +3 -1
  5. package/dist/app.js +5516 -5422
  6. package/dist/build/copy-build-content.d.ts +1 -1
  7. package/dist/build/virtual-config.d.ts +2 -2
  8. package/dist/chat/agent-dispatch/context.d.ts +2 -3
  9. package/dist/chat/agent-dispatch/runner.d.ts +2 -0
  10. package/dist/chat/agent-dispatch/types.d.ts +2 -1
  11. package/dist/chat/config.d.ts +3 -0
  12. package/dist/chat/credentials/state-adapter-token-store.d.ts +2 -0
  13. package/dist/chat/credentials/subject.d.ts +3 -3
  14. package/dist/chat/credentials/user-token-store.d.ts +17 -12
  15. package/dist/chat/db.d.ts +8 -0
  16. package/dist/chat/mcp/auth-store.d.ts +2 -1
  17. package/dist/chat/mcp/oauth.d.ts +2 -1
  18. package/dist/chat/oauth-flow.d.ts +3 -1
  19. package/dist/chat/pi/client.d.ts +15 -7
  20. package/dist/chat/plugins/agent-hooks.d.ts +20 -13
  21. package/dist/chat/plugins/auth/oauth-request.d.ts +11 -7
  22. package/dist/chat/plugins/credential-hooks.d.ts +6 -6
  23. package/dist/chat/plugins/logging.d.ts +2 -2
  24. package/dist/chat/plugins/model.d.ts +9 -0
  25. package/dist/chat/plugins/package-discovery.d.ts +2 -1
  26. package/dist/chat/plugins/prompt.d.ts +5 -0
  27. package/dist/chat/plugins/registry.d.ts +4 -0
  28. package/dist/chat/plugins/state.d.ts +3 -5
  29. package/dist/chat/plugins/task-callback.d.ts +5 -0
  30. package/dist/chat/plugins/task-message.d.ts +23 -0
  31. package/dist/chat/plugins/task-queue.d.ts +5 -0
  32. package/dist/chat/plugins/task-runner.d.ts +12 -0
  33. package/dist/chat/plugins/task-signing.d.ts +31 -0
  34. package/dist/chat/plugins/types.d.ts +1 -0
  35. package/dist/chat/plugins/validation.d.ts +5 -0
  36. package/dist/chat/prompt.d.ts +15 -1
  37. package/dist/chat/requester.d.ts +6 -5
  38. package/dist/chat/respond-helpers.d.ts +2 -0
  39. package/dist/chat/respond.d.ts +13 -2
  40. package/dist/chat/runtime/agent-continue-runner.d.ts +4 -0
  41. package/dist/chat/runtime/reply-executor.d.ts +5 -1
  42. package/dist/chat/runtime/slack-resume.d.ts +10 -2
  43. package/dist/chat/runtime/slack-runtime.d.ts +6 -1
  44. package/dist/chat/sandbox/egress-credentials.d.ts +8 -8
  45. package/dist/chat/sandbox/sandbox.d.ts +2 -2
  46. package/dist/chat/sentry.d.ts +1 -0
  47. package/dist/chat/services/mcp-auth-orchestration.d.ts +2 -1
  48. package/dist/chat/services/plugin-auth-orchestration.d.ts +2 -1
  49. package/dist/chat/services/subscribed-decision.d.ts +2 -2
  50. package/dist/chat/services/turn-session-record.d.ts +11 -7
  51. package/dist/chat/sql/db.d.ts +3 -0
  52. package/dist/chat/sql/executor.d.ts +7 -0
  53. package/dist/chat/sql/neon.d.ts +2 -4
  54. package/dist/chat/sql/postgres.d.ts +6 -0
  55. package/dist/chat/state/turn-session.d.ts +8 -5
  56. package/dist/chat/task-execution/state.d.ts +7 -2
  57. package/dist/chat/task-execution/worker.d.ts +1 -1
  58. package/dist/chat/tools/agent-tools.d.ts +9 -2
  59. package/dist/chat/tools/slack/context.d.ts +2 -2
  60. package/dist/chat/tools/types.d.ts +7 -4
  61. package/dist/chat/vercel-queue-client.d.ts +3 -0
  62. package/dist/{chunk-YOHFWWBV.js → chunk-2ECJXSVQ.js} +5 -107
  63. package/dist/{chunk-OR6NQJ5E.js → chunk-4SCWV7TJ.js} +3 -3
  64. package/dist/chunk-4UO6FK4G.js +64 -0
  65. package/dist/chunk-56TBVRJG.js +115 -0
  66. package/dist/{chunk-3BYAPS6B.js → chunk-EJN6G5A2.js} +17 -11
  67. package/dist/{chunk-SQGMG7OD.js → chunk-HHDUKWVG.js} +508 -149
  68. package/dist/{chunk-6UP2Z2RZ.js → chunk-JBASI5VV.js} +7 -7
  69. package/dist/chunk-KNFROR7R.js +127 -0
  70. package/dist/{chunk-HYHKTFG2.js → chunk-KOIMO7S3.js} +186 -910
  71. package/dist/chunk-MLKGABMK.js +9 -0
  72. package/dist/chunk-NFTMTIP3.js +964 -0
  73. package/dist/chunk-NYKJ3KON.js +1082 -0
  74. package/dist/{chunk-SJHUF3DP.js → chunk-OJ53FYVG.js} +2 -10
  75. package/dist/{chunk-KVZL5NZS.js → chunk-Q3XNY442.js} +17 -7
  76. package/dist/{chunk-YRDS7VKO.js → chunk-Q6XFTRV5.js} +2 -2
  77. package/dist/chunk-R6Z5XWY3.js +1076 -0
  78. package/dist/chunk-RV5RYIJW.js +56 -0
  79. package/dist/chunk-SG5WAA7H.js +132 -0
  80. package/dist/chunk-ST6YNAXG.js +54 -0
  81. package/dist/{chunk-GM7HTXYC.js → chunk-T77LUIX3.js} +148 -151
  82. package/dist/{chunk-CYUI7JU5.js → chunk-VALUBQ7R.js} +22 -30
  83. package/dist/chunk-XBBC6W45.js +71 -0
  84. package/dist/chunk-Y2CM7HXH.js +111 -0
  85. package/dist/{chunk-F6HWCPOC.js → chunk-Y5OFBCBZ.js} +1 -1
  86. package/dist/{chunk-M4FLLXXD.js → chunk-Z4CIQ3EB.js} +5 -1
  87. package/dist/{chunk-7Q5YOUUT.js → chunk-ZLMBNBUG.js} +146 -52
  88. package/dist/{chunk-2LUZA3LY.js → chunk-ZQB37HUX.js} +11 -11
  89. package/dist/cli/chat.js +87 -8
  90. package/dist/cli/check.js +8 -7
  91. package/dist/cli/env.js +4 -53
  92. package/dist/cli/init.js +6 -1
  93. package/dist/cli/main.js +84 -0
  94. package/dist/cli/plugins.js +244 -0
  95. package/dist/cli/run.js +5 -52
  96. package/dist/cli/snapshot-warmup.js +12 -11
  97. package/dist/cli/upgrade.js +385 -26
  98. package/dist/db-7A7PFRGL.js +17 -0
  99. package/dist/deployment.d.ts +1 -0
  100. package/dist/handlers/sandbox-egress-route.d.ts +4 -0
  101. package/dist/handlers/slack-webhook.d.ts +4 -0
  102. package/dist/handlers/webhooks.d.ts +6 -13
  103. package/dist/instrumentation.js +14 -18
  104. package/dist/nitro.d.ts +1 -1
  105. package/dist/nitro.js +67 -101
  106. package/dist/plugin-module.d.ts +21 -0
  107. package/dist/plugins-PZMDS7AT.js +15 -0
  108. package/dist/plugins.d.ts +9 -5
  109. package/dist/registry-OIPAJU2O.js +46 -0
  110. package/dist/reporting/conversations.d.ts +3 -3
  111. package/dist/reporting.d.ts +6 -5
  112. package/dist/reporting.js +42 -28
  113. package/dist/{runner-27NP2TEO.js → runner-KPLNHDCV.js} +77 -19
  114. package/dist/sentry-4CP5NNQ5.js +31 -0
  115. package/dist/validation-SLA6IGF7.js +15 -0
  116. package/dist/vercel.js +1 -1
  117. package/package.json +14 -11
  118. package/dist/chat/conversations/configured.d.ts +0 -5
  119. package/dist/chat/conversations/state.d.ts +0 -4
  120. package/dist/chunk-2KG3PWR4.js +0 -17
  121. package/dist/chunk-JL2SLRAT.js +0 -1970
@@ -1,22 +1,22 @@
1
- import {
2
- normalizeSlackConversationId
3
- } from "./chunk-YRDS7VKO.js";
4
1
  import {
5
2
  getStateAdapter
6
- } from "./chunk-F6HWCPOC.js";
3
+ } from "./chunk-Y5OFBCBZ.js";
4
+ import {
5
+ normalizeSlackConversationId
6
+ } from "./chunk-Q6XFTRV5.js";
7
7
  import {
8
8
  parseSlackThreadId
9
- } from "./chunk-GM7HTXYC.js";
9
+ } from "./chunk-T77LUIX3.js";
10
10
  import {
11
11
  parseStoredSlackRequester
12
- } from "./chunk-CYUI7JU5.js";
12
+ } from "./chunk-VALUBQ7R.js";
13
13
  import {
14
14
  isRecord,
15
15
  toOptionalNumber
16
- } from "./chunk-3BYAPS6B.js";
16
+ } from "./chunk-EJN6G5A2.js";
17
17
  import {
18
- sentry_exports
19
- } from "./chunk-SJHUF3DP.js";
18
+ getClient
19
+ } from "./chunk-ST6YNAXG.js";
20
20
 
21
21
  // src/handlers/health.ts
22
22
  function GET() {
@@ -44,7 +44,7 @@ function buildSentryWebBaseUrl(dsn) {
44
44
  return `${dsn.protocol}://${dsn.host}${port}${path}`;
45
45
  }
46
46
  function buildSentryConversationUrl(conversationId) {
47
- const client = sentry_exports.getClient();
47
+ const client = getClient();
48
48
  const dsn = client?.getDsn();
49
49
  if (!dsn?.host || !dsn.projectId) {
50
50
  return void 0;
@@ -63,7 +63,7 @@ function buildSentryConversationUrl(conversationId) {
63
63
  return `${buildSentryWebBaseUrl(dsn)}/organizations/${orgSlug}/${path}`;
64
64
  }
65
65
  function buildSentryTraceUrl(traceId) {
66
- const client = sentry_exports.getClient();
66
+ const client = getClient();
67
67
  const dsn = client?.getDsn();
68
68
  if (!dsn?.host || !dsn.projectId) {
69
69
  return void 0;
package/dist/cli/chat.js CHANGED
@@ -1,4 +1,7 @@
1
- import "../chunk-2KG3PWR4.js";
1
+ import {
2
+ loadAppPluginSet
3
+ } from "../chunk-Y2CM7HXH.js";
4
+ import "../chunk-MLKGABMK.js";
2
5
 
3
6
  // src/cli/chat.ts
4
7
  import {
@@ -8,6 +11,7 @@ import {
8
11
  } from "process";
9
12
  import { randomUUID } from "crypto";
10
13
  import * as readline from "readline/promises";
14
+ import { createJiti } from "jiti";
11
15
 
12
16
  // src/chat/local/conversation.ts
13
17
  import { createHash } from "crypto";
@@ -40,6 +44,7 @@ var DEFAULT_IO = {
40
44
  output: defaultStdout,
41
45
  write: (text) => writeStream(defaultStdout, text)
42
46
  };
47
+ var localPluginLoader = createJiti(import.meta.url, { moduleCache: false });
43
48
  var ChatOutputError = class extends Error {
44
49
  constructor(error) {
45
50
  super(errorMessage(error));
@@ -70,6 +75,29 @@ async function reportStatus(io, status) {
70
75
  throw new ChatOutputError(error);
71
76
  }
72
77
  }
78
+ function formatToolPayload(payload) {
79
+ if (payload && typeof payload === "object" && !Array.isArray(payload) && Object.keys(payload).length === 0) {
80
+ return "";
81
+ }
82
+ const rendered = JSON.stringify(payload);
83
+ if (rendered.length <= 500) {
84
+ return ` ${rendered}`;
85
+ }
86
+ return ` ${rendered.slice(0, 497)}...`;
87
+ }
88
+ async function reportToolResult(io, result) {
89
+ if (!result.ok) {
90
+ await reportStatus(
91
+ io,
92
+ `tool: ${result.toolName} error ${result.error ?? "Tool execution failed"}`
93
+ );
94
+ return;
95
+ }
96
+ await reportStatus(
97
+ io,
98
+ `tool: ${result.toolName} ok${formatToolPayload(result.result ?? {})}`
99
+ );
100
+ }
73
101
  function writeStream(stream, text) {
74
102
  return new Promise((resolve, reject) => {
75
103
  stream.write(text, (error) => {
@@ -87,6 +115,49 @@ function defaultStateAdapterForLocalChat() {
87
115
  }
88
116
  process.env.JUNIOR_STATE_ADAPTER = "memory";
89
117
  }
118
+ async function loadLocalPluginSet() {
119
+ return await loadAppPluginSet(
120
+ process.cwd(),
121
+ async (moduleRef) => localPluginLoader.import(moduleRef.importPath)
122
+ );
123
+ }
124
+ async function configureLocalChatPlugins(pluginSet) {
125
+ const [
126
+ pluginsModule,
127
+ agentHooksModule,
128
+ registryModule,
129
+ validationModule,
130
+ databaseModule
131
+ ] = await Promise.all([
132
+ import("../plugins-PZMDS7AT.js"),
133
+ import("../agent-hooks-ZOE7RIED.js"),
134
+ import("../registry-OIPAJU2O.js"),
135
+ import("../validation-SLA6IGF7.js"),
136
+ import("../db-7A7PFRGL.js")
137
+ ]);
138
+ const resolvedPluginSet = pluginSet === void 0 ? await loadLocalPluginSet() : pluginSet ?? void 0;
139
+ const plugins = pluginsModule.pluginRuntimeRegistrationsFromPluginSet(resolvedPluginSet);
140
+ const pluginConfig = resolvedPluginSet ? pluginsModule.pluginCatalogConfigFromPluginSet(resolvedPluginSet) : pluginsModule.pluginCatalogConfigFromEnv();
141
+ const shouldValidatePluginCatalog = Boolean(pluginConfig) || Boolean(resolvedPluginSet?.registrations.length);
142
+ agentHooksModule.validatePlugins(plugins);
143
+ const previousPluginCatalogConfig = registryModule.setPluginCatalogConfig(pluginConfig);
144
+ try {
145
+ if (shouldValidatePluginCatalog) {
146
+ registryModule.getPluginCatalogSignature();
147
+ validationModule.validatePluginRegistrations(
148
+ resolvedPluginSet?.registrations ?? []
149
+ );
150
+ validationModule.validatePluginEgressCredentialHooks(
151
+ resolvedPluginSet?.registrations ?? []
152
+ );
153
+ }
154
+ databaseModule.getDb();
155
+ agentHooksModule.setPlugins(plugins);
156
+ } catch (error) {
157
+ registryModule.setPluginCatalogConfig(previousPluginCatalogConfig);
158
+ throw error;
159
+ }
160
+ }
90
161
  function parseChatArgs(argv) {
91
162
  if (argv.length === 0) {
92
163
  return { mode: "interactive" };
@@ -118,10 +189,11 @@ function newRunConversationId() {
118
189
  }
119
190
  return conversationId;
120
191
  }
121
- async function runPrompt(options, io) {
192
+ async function runPrompt(options, io, pluginSet) {
122
193
  defaultStateAdapterForLocalChat();
194
+ await configureLocalChatPlugins(pluginSet);
123
195
  const conversationId = newRunConversationId();
124
- const { runLocalAgentTurn } = await import("../runner-27NP2TEO.js");
196
+ const { runLocalAgentTurn } = await import("../runner-KPLNHDCV.js");
125
197
  const result = await runLocalAgentTurn(
126
198
  {
127
199
  conversationId,
@@ -133,15 +205,19 @@ async function runPrompt(options, io) {
133
205
  },
134
206
  onStatus: async (status) => {
135
207
  await reportStatus(io, status);
208
+ },
209
+ onToolResult: async (result2) => {
210
+ await reportToolResult(io, result2);
136
211
  }
137
212
  }
138
213
  );
139
214
  return result.outcome === "success" ? 0 : 1;
140
215
  }
141
- async function runInteractive(io) {
216
+ async function runInteractive(io, pluginSet) {
142
217
  defaultStateAdapterForLocalChat();
218
+ await configureLocalChatPlugins(pluginSet);
143
219
  const conversationId = newRunConversationId();
144
- const { runLocalAgentTurn } = await import("../runner-27NP2TEO.js");
220
+ const { runLocalAgentTurn } = await import("../runner-KPLNHDCV.js");
145
221
  const rl = readline.createInterface({
146
222
  input: io.input,
147
223
  output: io.output,
@@ -168,6 +244,9 @@ async function runInteractive(io) {
168
244
  },
169
245
  onStatus: async (status) => {
170
246
  await reportStatus(io, status);
247
+ },
248
+ onToolResult: async (result) => {
249
+ await reportToolResult(io, result);
171
250
  }
172
251
  }
173
252
  );
@@ -182,7 +261,7 @@ async function runInteractive(io) {
182
261
  rl.close();
183
262
  }
184
263
  }
185
- async function runChat(argv, io = DEFAULT_IO) {
264
+ async function runChat(argv, io = DEFAULT_IO, deps = {}) {
186
265
  const options = parseChatArgs(argv);
187
266
  if (!options) {
188
267
  await io.error(CHAT_USAGE);
@@ -190,9 +269,9 @@ async function runChat(argv, io = DEFAULT_IO) {
190
269
  }
191
270
  try {
192
271
  if (options.mode === "prompt") {
193
- return await runPrompt(options, io);
272
+ return await runPrompt(options, io, deps.pluginSet);
194
273
  }
195
- await runInteractive(io);
274
+ await runInteractive(io, deps.pluginSet);
196
275
  return 0;
197
276
  } catch (error) {
198
277
  await io.error(errorMessage(error));
package/dist/cli/check.js CHANGED
@@ -1,19 +1,20 @@
1
1
  import {
2
2
  parseSkillFile
3
- } from "../chunk-OR6NQJ5E.js";
3
+ } from "../chunk-4SCWV7TJ.js";
4
4
  import {
5
5
  parseInlinePluginManifest,
6
6
  parsePluginManifest
7
- } from "../chunk-7Q5YOUUT.js";
8
- import "../chunk-KVZL5NZS.js";
9
- import "../chunk-CYUI7JU5.js";
10
- import "../chunk-3BYAPS6B.js";
7
+ } from "../chunk-ZLMBNBUG.js";
8
+ import "../chunk-VALUBQ7R.js";
9
+ import "../chunk-Q3XNY442.js";
10
+ import "../chunk-EJN6G5A2.js";
11
11
  import {
12
12
  JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE,
13
13
  JUNIOR_HEARTBEAT_ROUTE,
14
14
  LEGACY_JUNIOR_CONVERSATION_WORK_FUNCTION
15
- } from "../chunk-SJHUF3DP.js";
16
- import "../chunk-2KG3PWR4.js";
15
+ } from "../chunk-OJ53FYVG.js";
16
+ import "../chunk-ST6YNAXG.js";
17
+ import "../chunk-MLKGABMK.js";
17
18
 
18
19
  // src/cli/check.ts
19
20
  import fs from "fs/promises";
package/dist/cli/env.js CHANGED
@@ -1,56 +1,7 @@
1
- import "../chunk-2KG3PWR4.js";
2
-
3
- // src/cli/env.ts
4
- import fs from "fs";
5
- import path from "path";
6
- function envFileNames(nodeEnv) {
7
- return [
8
- `.env.${nodeEnv}.local`,
9
- ...nodeEnv === "test" ? [] : [".env.local"],
10
- `.env.${nodeEnv}`,
11
- ".env"
12
- ];
13
- }
14
- function hasEnvRootMarker(dir) {
15
- return fs.existsSync(path.join(dir, "package.json")) || fs.existsSync(path.join(dir, "pnpm-workspace.yaml"));
16
- }
17
- function resolveCliEnvRoots(cwd) {
18
- const roots = [];
19
- const seen = /* @__PURE__ */ new Set();
20
- const addRoot = (candidate) => {
21
- const resolved = path.resolve(candidate);
22
- if (seen.has(resolved)) {
23
- return;
24
- }
25
- seen.add(resolved);
26
- roots.push(resolved);
27
- };
28
- let current = path.resolve(cwd);
29
- addRoot(current);
30
- while (true) {
31
- if (hasEnvRootMarker(current)) {
32
- addRoot(current);
33
- }
34
- const parent = path.dirname(current);
35
- if (parent === current) {
36
- break;
37
- }
38
- current = parent;
39
- }
40
- return roots;
41
- }
42
- function loadCliEnvFiles(cwd = process.cwd()) {
43
- const nodeEnv = process.env.NODE_ENV ?? "development";
44
- for (const root of resolveCliEnvRoots(cwd)) {
45
- for (const envFile of envFileNames(nodeEnv)) {
46
- const absolutePath = path.join(root, envFile);
47
- if (!fs.existsSync(absolutePath)) {
48
- continue;
49
- }
50
- process.loadEnvFile(absolutePath);
51
- }
52
- }
53
- }
1
+ import {
2
+ loadCliEnvFiles
3
+ } from "../chunk-RV5RYIJW.js";
4
+ import "../chunk-MLKGABMK.js";
54
5
  export {
55
6
  loadCliEnvFiles
56
7
  };
package/dist/cli/init.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  juniorVercelConfig
3
3
  } from "../chunk-Y7X25LFY.js";
4
- import "../chunk-2KG3PWR4.js";
4
+ import "../chunk-MLKGABMK.js";
5
5
 
6
6
  // src/cli/init.ts
7
7
  import fs from "fs";
@@ -35,8 +35,10 @@ function writePluginsFile(targetDir) {
35
35
  fs.writeFileSync(
36
36
  path.join(targetDir, "plugins.ts"),
37
37
  `import { defineJuniorPlugins } from "@sentry/junior";
38
+ import { createMemoryPlugin } from "@sentry/junior-memory";
38
39
 
39
40
  export const plugins = defineJuniorPlugins([
41
+ createMemoryPlugin(),
40
42
  "@sentry/junior-maintenance",
41
43
  ]);
42
44
  `
@@ -144,6 +146,7 @@ async function runInit(dir, log = console.log) {
144
146
  },
145
147
  dependencies: {
146
148
  "@sentry/junior": "latest",
149
+ "@sentry/junior-memory": "latest",
147
150
  "@sentry/junior-maintenance": "latest",
148
151
  hono: "^4.12.0"
149
152
  },
@@ -205,6 +208,8 @@ JUNIOR_BOT_NAME=
205
208
  JUNIOR_SLASH_COMMAND=
206
209
  AI_MODEL=
207
210
  AI_FAST_MODEL=
211
+ AI_MEMORY_MODEL=
212
+ AI_EMBEDDING_MODEL=
208
213
  AI_VISION_MODEL=
209
214
  AI_WEB_SEARCH_MODEL=
210
215
  REDIS_URL=
@@ -0,0 +1,84 @@
1
+ import {
2
+ loadCliEnvFiles
3
+ } from "../chunk-RV5RYIJW.js";
4
+ import {
5
+ runCli
6
+ } from "../chunk-4UO6FK4G.js";
7
+ import "../chunk-MLKGABMK.js";
8
+
9
+ // src/cli/main.ts
10
+ import { pathToFileURL } from "url";
11
+ var SENTRY_FLUSH_TIMEOUT_MS = 2e3;
12
+ async function flushSentry() {
13
+ const mod = await import("../sentry-4CP5NNQ5.js");
14
+ await mod.flush(SENTRY_FLUSH_TIMEOUT_MS);
15
+ }
16
+ async function initSentry() {
17
+ const mod = await import("../instrumentation.js");
18
+ mod.initSentry();
19
+ }
20
+ async function runInit(dir) {
21
+ const mod = await import("./init.js");
22
+ await mod.runInit(dir);
23
+ }
24
+ async function runSnapshotCreate() {
25
+ const mod = await import("./snapshot-warmup.js");
26
+ await mod.runSnapshotCreate();
27
+ }
28
+ async function runCheck(dir) {
29
+ const mod = await import("./check.js");
30
+ await mod.runCheck(dir);
31
+ }
32
+ async function runUpgrade(pluginSet) {
33
+ const mod = await import("./upgrade.js");
34
+ await mod.runUpgrade(void 0, { pluginSet });
35
+ }
36
+ async function runChat(argv, pluginSet) {
37
+ const mod = await import("./chat.js");
38
+ return await mod.runChat(argv, void 0, { pluginSet });
39
+ }
40
+ function topLevelCommand(argv) {
41
+ const normalized = argv[0] === "--" ? argv.slice(1) : argv;
42
+ return normalized[0];
43
+ }
44
+ async function runMain(argv, options = {}) {
45
+ loadCliEnvFiles();
46
+ const instrument = options.instrument ?? true;
47
+ if (instrument) {
48
+ await initSentry();
49
+ }
50
+ const command = topLevelCommand(argv);
51
+ const cliPluginsModule = command && command !== "init" ? await import("./plugins.js") : void 0;
52
+ const pluginSet = cliPluginsModule ? await cliPluginsModule.loadCliPluginSet() ?? null : void 0;
53
+ const pluginCommands = cliPluginsModule ? await cliPluginsModule.loadCliPluginCommands(pluginSet) : void 0;
54
+ const exitCode = await runCli(argv, {
55
+ runChat: async (chatArgv) => await runChat(chatArgv, pluginSet),
56
+ runInit,
57
+ runSnapshotCreate,
58
+ runCheck,
59
+ runUpgrade: async () => await runUpgrade(pluginSet),
60
+ ...pluginCommands ? { runPluginCommand: pluginCommands.run } : {}
61
+ });
62
+ if (instrument) {
63
+ await flushSentry();
64
+ }
65
+ process.exit(exitCode);
66
+ }
67
+ function isDirectCliEntry() {
68
+ return Boolean(
69
+ process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href
70
+ );
71
+ }
72
+ if (isDirectCliEntry()) {
73
+ runMain(process.argv.slice(2)).catch((error) => {
74
+ void (async () => {
75
+ const message = error instanceof Error ? error.message : String(error);
76
+ console.error(`junior command failed: ${message}`);
77
+ await flushSentry();
78
+ process.exit(1);
79
+ })();
80
+ });
81
+ }
82
+ export {
83
+ runMain
84
+ };
@@ -0,0 +1,244 @@
1
+ import {
2
+ validatePluginEgressCredentialHooks,
3
+ validatePluginRegistrations
4
+ } from "../chunk-XBBC6W45.js";
5
+ import {
6
+ pluginCatalogConfigFromPluginSet,
7
+ pluginCliRegistrationsFromPluginSet,
8
+ pluginRuntimeRegistrationsFromPluginSet
9
+ } from "../chunk-SG5WAA7H.js";
10
+ import {
11
+ setPlugins,
12
+ validatePlugins
13
+ } from "../chunk-NFTMTIP3.js";
14
+ import {
15
+ createPluginLogger
16
+ } from "../chunk-56TBVRJG.js";
17
+ import {
18
+ getDb
19
+ } from "../chunk-NYKJ3KON.js";
20
+ import "../chunk-G3E7SCME.js";
21
+ import "../chunk-Y5OFBCBZ.js";
22
+ import "../chunk-Q6XFTRV5.js";
23
+ import "../chunk-T77LUIX3.js";
24
+ import {
25
+ loadAppPluginSet
26
+ } from "../chunk-Y2CM7HXH.js";
27
+ import {
28
+ setPluginCatalogConfig
29
+ } from "../chunk-ZLMBNBUG.js";
30
+ import "../chunk-VALUBQ7R.js";
31
+ import "../chunk-Q3XNY442.js";
32
+ import "../chunk-EJN6G5A2.js";
33
+ import "../chunk-OJ53FYVG.js";
34
+ import "../chunk-ST6YNAXG.js";
35
+ import "../chunk-MLKGABMK.js";
36
+
37
+ // src/cli/plugins.ts
38
+ import { stderr as defaultStderr, stdout as defaultStdout } from "process";
39
+ import { createJiti } from "jiti";
40
+ import { Command, CommanderError } from "commander";
41
+ var pluginCliLoader = createJiti(import.meta.url, { moduleCache: false });
42
+ var CORE_COMMAND_NAMES = /* @__PURE__ */ new Set([
43
+ "chat",
44
+ "check",
45
+ "init",
46
+ "snapshot",
47
+ "upgrade"
48
+ ]);
49
+ var PLUGIN_COMMAND_NAME_RE = /^[a-z][a-z0-9-]*$/;
50
+ var DEFAULT_IO = {
51
+ writeError: (text) => writeStream(defaultStderr, text),
52
+ writeOutput: (text) => writeStream(defaultStdout, text)
53
+ };
54
+ function writeStream(stream, text) {
55
+ return new Promise((resolve, reject) => {
56
+ stream.write(text, (error) => {
57
+ if (error) {
58
+ reject(error);
59
+ return;
60
+ }
61
+ resolve();
62
+ });
63
+ });
64
+ }
65
+ async function loadCliPluginSet() {
66
+ return await loadAppPluginSet(
67
+ process.cwd(),
68
+ async (moduleRef) => pluginCliLoader.import(moduleRef.importPath)
69
+ );
70
+ }
71
+ function findPluginCommand(plugins, commandName) {
72
+ for (const plugin of plugins) {
73
+ const command = plugin.cli?.commands.find(
74
+ (candidate) => candidate.name === commandName
75
+ );
76
+ if (command) {
77
+ return { command, plugin };
78
+ }
79
+ }
80
+ return void 0;
81
+ }
82
+ function createPluginCliHost(args) {
83
+ return {
84
+ action(handler) {
85
+ return async (...actionArgs) => {
86
+ const pluginName = args.plugin.manifest.name;
87
+ const result = await handler(
88
+ {
89
+ db: getDb(),
90
+ command: {
91
+ name: args.command.name,
92
+ summary: args.command.summary
93
+ },
94
+ io: args.io,
95
+ log: createPluginLogger(pluginName),
96
+ plugin: { name: pluginName }
97
+ },
98
+ ...actionArgs
99
+ );
100
+ args.setExitCode(result ?? 0);
101
+ };
102
+ }
103
+ };
104
+ }
105
+ function createPluginCommanderCommand(args) {
106
+ const command = new Command(args.command.name).description(args.command.summary).exitOverride().showHelpAfterError().showSuggestionAfterError().configureOutput({
107
+ writeOut: (text) => {
108
+ void args.io.writeOutput(text);
109
+ },
110
+ writeErr: (text) => {
111
+ void args.io.writeError(text);
112
+ },
113
+ outputError: (text, write) => {
114
+ write(text);
115
+ }
116
+ });
117
+ args.command.configure(command, createPluginCliHost(args));
118
+ return command;
119
+ }
120
+ function validateConfiguredPluginCommand(args) {
121
+ const pluginName = args.plugin.manifest.name;
122
+ if (args.command.name() !== args.definition.name) {
123
+ throw new Error(
124
+ `Plugin CLI command "${args.definition.name}" from plugin "${pluginName}" must not rename its top-level command`
125
+ );
126
+ }
127
+ if (args.command.commands.length === 0) {
128
+ throw new Error(
129
+ `Plugin CLI command "${args.definition.name}" from plugin "${pluginName}" must define at least one subcommand`
130
+ );
131
+ }
132
+ if (args.command.aliases().length > 0) {
133
+ throw new Error(
134
+ `Plugin CLI command "${args.definition.name}" from plugin "${pluginName}" must not define top-level aliases`
135
+ );
136
+ }
137
+ }
138
+ function validateConfiguredPluginCommands(plugins) {
139
+ const ownerByName = /* @__PURE__ */ new Map();
140
+ const validationIo = DEFAULT_IO;
141
+ for (const plugin of plugins) {
142
+ for (const definition of plugin.cli?.commands ?? []) {
143
+ const pluginName = plugin.manifest.name;
144
+ const existingOwner = ownerByName.get(definition.name);
145
+ if (!PLUGIN_COMMAND_NAME_RE.test(definition.name)) {
146
+ throw new Error(
147
+ `Plugin CLI command "${definition.name}" from plugin "${pluginName}" must be a lowercase command identifier`
148
+ );
149
+ }
150
+ if (CORE_COMMAND_NAMES.has(definition.name)) {
151
+ throw new Error(
152
+ `Plugin CLI command "${definition.name}" from plugin "${pluginName}" conflicts with a core command`
153
+ );
154
+ }
155
+ if (existingOwner) {
156
+ throw new Error(
157
+ `Plugin CLI command "${definition.name}" from plugin "${pluginName}" conflicts with plugin "${existingOwner}"`
158
+ );
159
+ }
160
+ ownerByName.set(definition.name, pluginName);
161
+ if (typeof definition.configure !== "function") {
162
+ throw new Error(
163
+ `Plugin CLI command "${definition.name}" from plugin "${pluginName}" must define a configure function`
164
+ );
165
+ }
166
+ let exitCode = 0;
167
+ validateConfiguredPluginCommand({
168
+ command: createPluginCommanderCommand({
169
+ command: definition,
170
+ io: validationIo,
171
+ plugin,
172
+ setExitCode: (nextExitCode) => {
173
+ exitCode = nextExitCode;
174
+ }
175
+ }),
176
+ definition,
177
+ plugin
178
+ });
179
+ void exitCode;
180
+ }
181
+ }
182
+ }
183
+ async function loadPluginRegistrations(args) {
184
+ const pluginSet = args.pluginSet;
185
+ if (!pluginSet) {
186
+ return { cliPlugins: [], runtimePlugins: [] };
187
+ }
188
+ const cliPlugins = pluginCliRegistrationsFromPluginSet(pluginSet);
189
+ const runtimePlugins = pluginRuntimeRegistrationsFromPluginSet(pluginSet);
190
+ const pluginConfig = pluginCatalogConfigFromPluginSet(pluginSet);
191
+ validatePlugins(runtimePlugins);
192
+ const previousPluginCatalogConfig = setPluginCatalogConfig(pluginConfig);
193
+ try {
194
+ validatePluginRegistrations(pluginSet.registrations);
195
+ validatePluginEgressCredentialHooks(pluginSet.registrations);
196
+ args.validateConfiguredCommands?.(cliPlugins);
197
+ setPlugins(runtimePlugins);
198
+ return { cliPlugins, runtimePlugins };
199
+ } catch (error) {
200
+ setPluginCatalogConfig(previousPluginCatalogConfig);
201
+ throw error;
202
+ }
203
+ }
204
+ async function loadCliPluginCommands(pluginSet) {
205
+ const resolvedPluginSet = pluginSet === void 0 ? await loadCliPluginSet() : pluginSet ?? void 0;
206
+ const { cliPlugins } = await loadPluginRegistrations({
207
+ pluginSet: resolvedPluginSet,
208
+ validateConfiguredCommands: validateConfiguredPluginCommands
209
+ });
210
+ const commandNames = cliPlugins.flatMap(
211
+ (plugin) => (plugin.cli?.commands ?? []).map((command) => command.name)
212
+ );
213
+ return {
214
+ commandNames,
215
+ async run(commandName, argv, io = DEFAULT_IO) {
216
+ const resolved = findPluginCommand(cliPlugins, commandName);
217
+ if (!resolved) {
218
+ return void 0;
219
+ }
220
+ let exitCode = 0;
221
+ const command = createPluginCommanderCommand({
222
+ command: resolved.command,
223
+ io,
224
+ plugin: resolved.plugin,
225
+ setExitCode: (nextExitCode) => {
226
+ exitCode = nextExitCode;
227
+ }
228
+ });
229
+ try {
230
+ await command.parseAsync(argv, { from: "user" });
231
+ } catch (error) {
232
+ if (error instanceof CommanderError) {
233
+ return error.exitCode;
234
+ }
235
+ throw error;
236
+ }
237
+ return exitCode;
238
+ }
239
+ };
240
+ }
241
+ export {
242
+ loadCliPluginCommands,
243
+ loadCliPluginSet
244
+ };