@sentry/junior 0.24.0 → 0.25.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/dist/app.js +1100 -871
- package/dist/{chunk-B5O2EJUV.js → chunk-A75TWGF2.js} +1 -1
- package/dist/{chunk-DGN3WLA4.js → chunk-ICIRAL6Y.js} +9 -52
- package/dist/{chunk-J7JEFMVD.js → chunk-RZJDO55D.js} +138 -158
- package/dist/cli/check.js +2 -2
- package/dist/cli/snapshot-warmup.js +2 -2
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getPluginSkillRoots,
|
|
6
6
|
logInfo,
|
|
7
7
|
logWarn
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-RZJDO55D.js";
|
|
9
9
|
import {
|
|
10
10
|
skillRoots
|
|
11
11
|
} from "./chunk-XPXD3FCE.js";
|
|
@@ -18,19 +18,6 @@ import { parse as parseYaml } from "yaml";
|
|
|
18
18
|
|
|
19
19
|
// src/chat/capabilities/catalog.ts
|
|
20
20
|
var cachedCatalog;
|
|
21
|
-
function cloneProviderDefinition(provider) {
|
|
22
|
-
return {
|
|
23
|
-
...provider,
|
|
24
|
-
capabilities: [...provider.capabilities],
|
|
25
|
-
configKeys: [...provider.configKeys],
|
|
26
|
-
...provider.target ? {
|
|
27
|
-
target: {
|
|
28
|
-
...provider.target,
|
|
29
|
-
...provider.target.commandFlags ? { commandFlags: [...provider.target.commandFlags] } : {}
|
|
30
|
-
}
|
|
31
|
-
} : {}
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
21
|
function getCapabilityCatalog() {
|
|
35
22
|
const signature = getPluginCatalogSignature();
|
|
36
23
|
if (cachedCatalog?.signature === signature) return cachedCatalog;
|
|
@@ -53,19 +40,9 @@ function getCapabilityCatalog() {
|
|
|
53
40
|
cachedCatalog = { signature, providers, capabilityToProvider, configKeys };
|
|
54
41
|
return cachedCatalog;
|
|
55
42
|
}
|
|
56
|
-
function getCapabilityProvider(capability) {
|
|
57
|
-
const provider = getCapabilityCatalog().capabilityToProvider.get(capability);
|
|
58
|
-
return provider ? cloneProviderDefinition(provider) : void 0;
|
|
59
|
-
}
|
|
60
|
-
function isKnownCapability(capability) {
|
|
61
|
-
return getCapabilityCatalog().capabilityToProvider.has(capability);
|
|
62
|
-
}
|
|
63
43
|
function isKnownConfigKey(key) {
|
|
64
44
|
return getCapabilityCatalog().configKeys.has(key);
|
|
65
45
|
}
|
|
66
|
-
function listCapabilityProviders() {
|
|
67
|
-
return getCapabilityCatalog().providers.map(cloneProviderDefinition);
|
|
68
|
-
}
|
|
69
46
|
var catalogLogged = false;
|
|
70
47
|
function logCapabilityCatalogLoadedOnce() {
|
|
71
48
|
if (catalogLogged) return;
|
|
@@ -184,10 +161,6 @@ var skillFrontmatterSchema = z.object({
|
|
|
184
161
|
"allowed-tools": z.string({
|
|
185
162
|
error: 'Frontmatter field "allowed-tools" must be a string when present'
|
|
186
163
|
}).optional(),
|
|
187
|
-
"requires-capabilities": createTokenFieldSchema(
|
|
188
|
-
"requires-capabilities",
|
|
189
|
-
"provider.scope.write"
|
|
190
|
-
).optional(),
|
|
191
164
|
"uses-config": createTokenFieldSchema(
|
|
192
165
|
"uses-config",
|
|
193
166
|
"provider.repo"
|
|
@@ -213,6 +186,12 @@ function parseSkillFile(raw, expectedName) {
|
|
|
213
186
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
214
187
|
return { ok: false, error: "Frontmatter must be a YAML object" };
|
|
215
188
|
}
|
|
189
|
+
if ("requires-capabilities" in parsed) {
|
|
190
|
+
return {
|
|
191
|
+
ok: false,
|
|
192
|
+
error: 'Frontmatter field "requires-capabilities" is no longer supported; plugin-backed skills inherit credentials from their plugin.'
|
|
193
|
+
};
|
|
194
|
+
}
|
|
216
195
|
const result = skillFrontmatterSchema.safeParse(parsed);
|
|
217
196
|
if (!result.success) {
|
|
218
197
|
return {
|
|
@@ -227,9 +206,6 @@ function parseSkillFile(raw, expectedName) {
|
|
|
227
206
|
};
|
|
228
207
|
}
|
|
229
208
|
const allowedTools = parseTokenList(result.data["allowed-tools"]);
|
|
230
|
-
const requiresCapabilities = parseTokenList(
|
|
231
|
-
result.data["requires-capabilities"]
|
|
232
|
-
);
|
|
233
209
|
const usesConfig = parseTokenList(result.data["uses-config"]);
|
|
234
210
|
return {
|
|
235
211
|
ok: true,
|
|
@@ -241,7 +217,6 @@ function parseSkillFile(raw, expectedName) {
|
|
|
241
217
|
...result.data.compatibility !== void 0 ? { compatibility: result.data.compatibility } : {},
|
|
242
218
|
...result.data.license !== void 0 ? { license: result.data.license } : {},
|
|
243
219
|
...allowedTools ? { allowedTools } : {},
|
|
244
|
-
...requiresCapabilities ? { requiresCapabilities } : {},
|
|
245
220
|
...usesConfig ? { usesConfig } : {}
|
|
246
221
|
}
|
|
247
222
|
};
|
|
@@ -271,12 +246,6 @@ function resolveSkillRoots(options) {
|
|
|
271
246
|
return resolved;
|
|
272
247
|
}
|
|
273
248
|
function validateSkillMetadata(input) {
|
|
274
|
-
const unknownCapabilities = (input.requiresCapabilities ?? []).filter(
|
|
275
|
-
(capability) => !isKnownCapability(capability)
|
|
276
|
-
);
|
|
277
|
-
if (unknownCapabilities.length > 0) {
|
|
278
|
-
return `Unknown requires-capabilities values: ${unknownCapabilities.join(", ")}`;
|
|
279
|
-
}
|
|
280
249
|
const unknownConfigKeys = (input.usesConfig ?? []).filter(
|
|
281
250
|
(configKey) => !isKnownConfigKey(configKey)
|
|
282
251
|
);
|
|
@@ -302,18 +271,9 @@ async function readSkillDirectory(skillDir) {
|
|
|
302
271
|
);
|
|
303
272
|
return null;
|
|
304
273
|
}
|
|
305
|
-
const {
|
|
306
|
-
name,
|
|
307
|
-
description,
|
|
308
|
-
allowedTools,
|
|
309
|
-
requiresCapabilities,
|
|
310
|
-
usesConfig
|
|
311
|
-
} = parsed.skill;
|
|
274
|
+
const { name, description, allowedTools, usesConfig } = parsed.skill;
|
|
312
275
|
const plugin = getPluginForSkillPath(skillDir);
|
|
313
|
-
const metadataError = validateSkillMetadata({
|
|
314
|
-
requiresCapabilities,
|
|
315
|
-
usesConfig
|
|
316
|
-
});
|
|
276
|
+
const metadataError = validateSkillMetadata({ usesConfig });
|
|
317
277
|
if (metadataError) {
|
|
318
278
|
logWarn(
|
|
319
279
|
"skill_frontmatter_invalid",
|
|
@@ -332,7 +292,6 @@ async function readSkillDirectory(skillDir) {
|
|
|
332
292
|
skillPath: skillDir,
|
|
333
293
|
...plugin ? { pluginProvider: plugin.manifest.name } : {},
|
|
334
294
|
allowedTools,
|
|
335
|
-
requiresCapabilities,
|
|
336
295
|
usesConfig
|
|
337
296
|
};
|
|
338
297
|
} catch (error) {
|
|
@@ -433,8 +392,6 @@ async function loadSkillsByName(skillNames, available) {
|
|
|
433
392
|
}
|
|
434
393
|
|
|
435
394
|
export {
|
|
436
|
-
getCapabilityProvider,
|
|
437
|
-
listCapabilityProviders,
|
|
438
395
|
logCapabilityCatalogLoadedOnce,
|
|
439
396
|
parseSkillFile,
|
|
440
397
|
discoverSkills,
|
|
@@ -1195,72 +1195,42 @@ function toFiniteTokenCount(value) {
|
|
|
1195
1195
|
const rounded = Math.floor(value);
|
|
1196
1196
|
return rounded >= 0 ? rounded : void 0;
|
|
1197
1197
|
}
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1198
|
+
var PI_USAGE_FIELDS = [
|
|
1199
|
+
["input", "inputTokens"],
|
|
1200
|
+
["output", "outputTokens"],
|
|
1201
|
+
["cacheRead", "cachedInputTokens"],
|
|
1202
|
+
["cacheWrite", "cacheCreationTokens"],
|
|
1203
|
+
["totalTokens", "totalTokens"]
|
|
1204
|
+
];
|
|
1205
|
+
function readPiUsage(source) {
|
|
1206
|
+
const record = asRecord(source);
|
|
1207
|
+
if (!record) {
|
|
1208
|
+
return {};
|
|
1209
|
+
}
|
|
1210
|
+
const usage = asRecord(record.usage) ?? record;
|
|
1211
|
+
const summary = {};
|
|
1212
|
+
for (const [piKey, ourKey] of PI_USAGE_FIELDS) {
|
|
1213
|
+
const value = toFiniteTokenCount(usage[piKey]);
|
|
1201
1214
|
if (value !== void 0) {
|
|
1202
|
-
|
|
1215
|
+
summary[ourKey] = value;
|
|
1203
1216
|
}
|
|
1204
1217
|
}
|
|
1205
|
-
return
|
|
1218
|
+
return summary;
|
|
1206
1219
|
}
|
|
1207
|
-
function
|
|
1208
|
-
const
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
roots.push(usage);
|
|
1216
|
-
}
|
|
1217
|
-
const tokenUsage = asRecord(sourceRecord.tokenUsage);
|
|
1218
|
-
if (tokenUsage) {
|
|
1219
|
-
roots.push(tokenUsage);
|
|
1220
|
-
}
|
|
1221
|
-
const providerMetadata = asRecord(sourceRecord.providerMetadata);
|
|
1222
|
-
if (providerMetadata) {
|
|
1223
|
-
roots.push(providerMetadata);
|
|
1224
|
-
const providerUsage = asRecord(providerMetadata.usage);
|
|
1225
|
-
if (providerUsage) {
|
|
1226
|
-
roots.push(providerUsage);
|
|
1220
|
+
function extractGenAiUsageSummary(...sources) {
|
|
1221
|
+
const summary = {};
|
|
1222
|
+
for (const source of sources) {
|
|
1223
|
+
const single = readPiUsage(source);
|
|
1224
|
+
for (const field of Object.keys(single)) {
|
|
1225
|
+
const value = single[field];
|
|
1226
|
+
if (value === void 0) continue;
|
|
1227
|
+
summary[field] = (summary[field] ?? 0) + value;
|
|
1227
1228
|
}
|
|
1228
1229
|
}
|
|
1229
|
-
|
|
1230
|
-
if (response) {
|
|
1231
|
-
roots.push(response);
|
|
1232
|
-
const responseUsage = asRecord(response.usage);
|
|
1233
|
-
if (responseUsage) {
|
|
1234
|
-
roots.push(responseUsage);
|
|
1235
|
-
}
|
|
1236
|
-
}
|
|
1237
|
-
return roots;
|
|
1230
|
+
return summary;
|
|
1238
1231
|
}
|
|
1239
1232
|
function extractGenAiUsageAttributes(...sources) {
|
|
1240
|
-
const
|
|
1241
|
-
if (roots.length === 0) {
|
|
1242
|
-
return {};
|
|
1243
|
-
}
|
|
1244
|
-
const inputTokens = roots.map(
|
|
1245
|
-
(root) => readTokenCount(root, [
|
|
1246
|
-
"input_tokens",
|
|
1247
|
-
"inputTokens",
|
|
1248
|
-
"prompt_tokens",
|
|
1249
|
-
"promptTokens",
|
|
1250
|
-
"inputTokenCount",
|
|
1251
|
-
"promptTokenCount"
|
|
1252
|
-
])
|
|
1253
|
-
).find((value) => value !== void 0) ?? void 0;
|
|
1254
|
-
const outputTokens = roots.map(
|
|
1255
|
-
(root) => readTokenCount(root, [
|
|
1256
|
-
"output_tokens",
|
|
1257
|
-
"outputTokens",
|
|
1258
|
-
"completion_tokens",
|
|
1259
|
-
"completionTokens",
|
|
1260
|
-
"outputTokenCount",
|
|
1261
|
-
"completionTokenCount"
|
|
1262
|
-
])
|
|
1263
|
-
).find((value) => value !== void 0) ?? void 0;
|
|
1233
|
+
const { inputTokens, outputTokens } = extractGenAiUsageSummary(...sources);
|
|
1264
1234
|
return {
|
|
1265
1235
|
...inputTokens !== void 0 ? { "gen_ai.usage.input_tokens": inputTokens } : {},
|
|
1266
1236
|
...outputTokens !== void 0 ? { "gen_ai.usage.output_tokens": outputTokens } : {}
|
|
@@ -1275,6 +1245,7 @@ var SHORT_CAPABILITY_RE = /^[a-z0-9-]+(\.[a-z0-9-]+)*$/;
|
|
|
1275
1245
|
var SHORT_CONFIG_KEY_RE = /^[a-z0-9]+(\.[a-z0-9-]+)*$/;
|
|
1276
1246
|
var TARGET_FLAG_RE = /^-{1,2}[A-Za-z0-9][A-Za-z0-9-]*$/;
|
|
1277
1247
|
var AUTH_TOKEN_ENV_RE = /^[A-Z][A-Z0-9_]*$/;
|
|
1248
|
+
var ENV_VAR_NAME_RE = /^[A-Z_][A-Z0-9_]*$/;
|
|
1278
1249
|
var API_DOMAIN_RE = /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
1279
1250
|
var RUNTIME_POSTINSTALL_CMD_RE = /^[A-Za-z0-9._/-]+$/;
|
|
1280
1251
|
var RESERVED_AUTHORIZE_PARAM_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -1471,6 +1442,9 @@ var manifestSourceSchema = z.object({
|
|
|
1471
1442
|
"runtime-postinstall": z.array(z.unknown(), {
|
|
1472
1443
|
error: "must be an array"
|
|
1473
1444
|
}).optional(),
|
|
1445
|
+
"env-vars": z.record(z.string(), z.unknown(), {
|
|
1446
|
+
error: "must be an object"
|
|
1447
|
+
}).optional(),
|
|
1474
1448
|
mcp: z.record(z.string(), z.unknown(), {
|
|
1475
1449
|
error: "must be an object"
|
|
1476
1450
|
}).optional(),
|
|
@@ -1676,8 +1650,67 @@ function normalizeRuntimePostinstall(commands, name) {
|
|
|
1676
1650
|
}
|
|
1677
1651
|
return parsed.length > 0 ? parsed : void 0;
|
|
1678
1652
|
}
|
|
1679
|
-
|
|
1680
|
-
|
|
1653
|
+
var ENV_PLACEHOLDER_RE = /\$\{([A-Z_][A-Z0-9_]*)\}/g;
|
|
1654
|
+
var envVarDeclarationSchema = z.preprocess(
|
|
1655
|
+
(value) => value === null || value === void 0 ? {} : value,
|
|
1656
|
+
z.object({
|
|
1657
|
+
default: z.string().optional()
|
|
1658
|
+
}).passthrough()
|
|
1659
|
+
);
|
|
1660
|
+
function normalizeEnvVars(data, pluginName) {
|
|
1661
|
+
const normalized = {};
|
|
1662
|
+
for (const [rawName, rawDecl] of Object.entries(data)) {
|
|
1663
|
+
const name = rawName.trim();
|
|
1664
|
+
if (!ENV_VAR_NAME_RE.test(name)) {
|
|
1665
|
+
throw new Error(
|
|
1666
|
+
`Plugin ${pluginName} env-vars key "${rawName}" must match [A-Z_][A-Z0-9_]*`
|
|
1667
|
+
);
|
|
1668
|
+
}
|
|
1669
|
+
const parsed = envVarDeclarationSchema.safeParse(rawDecl);
|
|
1670
|
+
if (!parsed.success) {
|
|
1671
|
+
throw new Error(
|
|
1672
|
+
issueMessage(parsed.error, `Plugin ${pluginName} env-vars.${name}`)
|
|
1673
|
+
);
|
|
1674
|
+
}
|
|
1675
|
+
const decl = {};
|
|
1676
|
+
if (parsed.data.default !== void 0) {
|
|
1677
|
+
decl.default = parsed.data.default;
|
|
1678
|
+
}
|
|
1679
|
+
normalized[name] = decl;
|
|
1680
|
+
}
|
|
1681
|
+
return normalized;
|
|
1682
|
+
}
|
|
1683
|
+
function expandEnvPlaceholders(template, envVars, context) {
|
|
1684
|
+
return template.replace(ENV_PLACEHOLDER_RE, (_match, name) => {
|
|
1685
|
+
const varName = name;
|
|
1686
|
+
if (!Object.prototype.hasOwnProperty.call(envVars, varName)) {
|
|
1687
|
+
throw new Error(
|
|
1688
|
+
`${context} references env var ${varName} which is not declared in env-vars`
|
|
1689
|
+
);
|
|
1690
|
+
}
|
|
1691
|
+
const decl = envVars[varName];
|
|
1692
|
+
const fromProcess = process.env[varName];
|
|
1693
|
+
if (fromProcess !== void 0 && fromProcess !== "") {
|
|
1694
|
+
return fromProcess;
|
|
1695
|
+
}
|
|
1696
|
+
if (decl.default !== void 0) {
|
|
1697
|
+
return decl.default;
|
|
1698
|
+
}
|
|
1699
|
+
throw new Error(
|
|
1700
|
+
`${context} env var ${varName} is unset and has no default in env-vars`
|
|
1701
|
+
);
|
|
1702
|
+
});
|
|
1703
|
+
}
|
|
1704
|
+
function normalizeMcp(data, envVars, name) {
|
|
1705
|
+
const prepared = { ...data };
|
|
1706
|
+
if (typeof prepared.url === "string") {
|
|
1707
|
+
prepared.url = expandEnvPlaceholders(
|
|
1708
|
+
prepared.url,
|
|
1709
|
+
envVars,
|
|
1710
|
+
`Plugin ${name} mcp.url`
|
|
1711
|
+
);
|
|
1712
|
+
}
|
|
1713
|
+
const result = mcpSourceSchema.safeParse(prepared);
|
|
1681
1714
|
if (!result.success) {
|
|
1682
1715
|
throw new Error(issueMessage(result.error, `Plugin ${name} mcp`));
|
|
1683
1716
|
}
|
|
@@ -1743,6 +1776,11 @@ function parsePluginManifest(raw, dir) {
|
|
|
1743
1776
|
`Plugin ${parsedYaml.name ?? "unknown"} runtime-postinstall must be an array`
|
|
1744
1777
|
);
|
|
1745
1778
|
}
|
|
1779
|
+
if (path3 === "env-vars") {
|
|
1780
|
+
throw new Error(
|
|
1781
|
+
`Plugin ${parsedYaml.name ?? "unknown"} env-vars must be an object`
|
|
1782
|
+
);
|
|
1783
|
+
}
|
|
1746
1784
|
if (path3 === "mcp") {
|
|
1747
1785
|
throw new Error(
|
|
1748
1786
|
`Plugin ${parsedYaml.name ?? "unknown"} mcp must be an object`
|
|
@@ -1778,12 +1816,14 @@ function parsePluginManifest(raw, dir) {
|
|
|
1778
1816
|
const credentials = data.credentials ? normalizeCredentials(data.credentials, data.name) : void 0;
|
|
1779
1817
|
const runtimeDependencies = data["runtime-dependencies"] ? normalizeRuntimeDependencies(data["runtime-dependencies"], data.name) : void 0;
|
|
1780
1818
|
const runtimePostinstall = data["runtime-postinstall"] ? normalizeRuntimePostinstall(data["runtime-postinstall"], data.name) : void 0;
|
|
1781
|
-
const
|
|
1819
|
+
const envVars = data["env-vars"] ? normalizeEnvVars(data["env-vars"], data.name) : {};
|
|
1820
|
+
const mcp = data.mcp ? normalizeMcp(data.mcp, envVars, data.name) : void 0;
|
|
1782
1821
|
const manifest = {
|
|
1783
1822
|
name: data.name,
|
|
1784
1823
|
description: data.description,
|
|
1785
1824
|
capabilities,
|
|
1786
1825
|
configKeys,
|
|
1826
|
+
...Object.keys(envVars).length > 0 ? { envVars } : {},
|
|
1787
1827
|
...credentials ? { credentials } : {},
|
|
1788
1828
|
...runtimeDependencies ? { runtimeDependencies } : {},
|
|
1789
1829
|
...runtimePostinstall ? { runtimePostinstall } : {},
|
|
@@ -1876,27 +1916,6 @@ function resolveAuthTokenPlaceholder(credentials) {
|
|
|
1876
1916
|
|
|
1877
1917
|
// src/chat/plugins/auth/github-app-broker.ts
|
|
1878
1918
|
var MAX_LEASE_MS = 60 * 60 * 1e3;
|
|
1879
|
-
function parseRepoTarget(value) {
|
|
1880
|
-
const trimmed = value.trim();
|
|
1881
|
-
if (!trimmed) {
|
|
1882
|
-
return void 0;
|
|
1883
|
-
}
|
|
1884
|
-
const [repoRef] = trimmed.split("#");
|
|
1885
|
-
const [owner, repo, extra] = repoRef.split("/");
|
|
1886
|
-
if (!owner || !repo || extra) {
|
|
1887
|
-
return void 0;
|
|
1888
|
-
}
|
|
1889
|
-
return {
|
|
1890
|
-
owner: owner.toLowerCase(),
|
|
1891
|
-
repo: repo.toLowerCase()
|
|
1892
|
-
};
|
|
1893
|
-
}
|
|
1894
|
-
function getRepoTarget(target) {
|
|
1895
|
-
if (!target || target.type !== "repo") {
|
|
1896
|
-
return void 0;
|
|
1897
|
-
}
|
|
1898
|
-
return parseRepoTarget(target.value);
|
|
1899
|
-
}
|
|
1900
1919
|
function base64Url(input) {
|
|
1901
1920
|
return Buffer.from(input).toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
1902
1921
|
}
|
|
@@ -2002,26 +2021,31 @@ var KNOWN_SCOPES = /* @__PURE__ */ new Set([
|
|
|
2002
2021
|
"vulnerability_alerts",
|
|
2003
2022
|
"workflows"
|
|
2004
2023
|
]);
|
|
2005
|
-
function
|
|
2024
|
+
function capabilitiesToPermissions(capabilities, pluginName) {
|
|
2025
|
+
const permissions = {};
|
|
2006
2026
|
const prefix = `${pluginName}.`;
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2027
|
+
for (const capability of capabilities) {
|
|
2028
|
+
if (!capability.startsWith(prefix)) {
|
|
2029
|
+
throw new Error(`Unsupported GitHub capability: ${capability}`);
|
|
2030
|
+
}
|
|
2031
|
+
const suffix = capability.slice(prefix.length);
|
|
2032
|
+
const lastDot = suffix.lastIndexOf(".");
|
|
2033
|
+
if (lastDot === -1) {
|
|
2034
|
+
throw new Error(`Unsupported GitHub capability: ${capability}`);
|
|
2035
|
+
}
|
|
2036
|
+
const scopeRaw = suffix.slice(0, lastDot);
|
|
2037
|
+
const level = suffix.slice(lastDot + 1);
|
|
2038
|
+
if (level !== "read" && level !== "write") {
|
|
2039
|
+
throw new Error(`Unsupported GitHub capability: ${capability}`);
|
|
2040
|
+
}
|
|
2041
|
+
const scope = scopeRaw.replace(/-/g, "_");
|
|
2042
|
+
if (!KNOWN_SCOPES.has(scope)) {
|
|
2043
|
+
throw new Error(`Unsupported GitHub capability: ${capability}`);
|
|
2044
|
+
}
|
|
2045
|
+
const existing = permissions[scope];
|
|
2046
|
+
permissions[scope] = existing === "write" || level === "write" ? "write" : "read";
|
|
2023
2047
|
}
|
|
2024
|
-
return
|
|
2048
|
+
return permissions;
|
|
2025
2049
|
}
|
|
2026
2050
|
function createGitHubAppBroker(manifest, credentials) {
|
|
2027
2051
|
const tokenCache = /* @__PURE__ */ new Map();
|
|
@@ -2041,16 +2065,19 @@ function createGitHubAppBroker(manifest, credentials) {
|
|
|
2041
2065
|
`${provider}.contents.read`,
|
|
2042
2066
|
`${provider}.contents.write`
|
|
2043
2067
|
]);
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2068
|
+
const leaseDomains = manifest.capabilities.some(
|
|
2069
|
+
(capability) => GIT_CAPABILITIES.has(capability)
|
|
2070
|
+
) ? [...apiDomains, GIT_DOMAIN] : apiDomains;
|
|
2047
2071
|
function authorizationFor(domain, token) {
|
|
2048
2072
|
if (domain === GIT_DOMAIN) {
|
|
2049
2073
|
return `Basic ${Buffer.from(`x-access-token:${token}`).toString("base64")}`;
|
|
2050
2074
|
}
|
|
2051
2075
|
return `Bearer ${token}`;
|
|
2052
2076
|
}
|
|
2053
|
-
const
|
|
2077
|
+
const permissions = capabilitiesToPermissions(
|
|
2078
|
+
manifest.capabilities,
|
|
2079
|
+
provider
|
|
2080
|
+
);
|
|
2054
2081
|
function resolveInstallationId() {
|
|
2055
2082
|
const installationIdRaw = process.env[installationIdEnv]?.trim();
|
|
2056
2083
|
if (!installationIdRaw) {
|
|
@@ -2064,37 +2091,16 @@ function createGitHubAppBroker(manifest, credentials) {
|
|
|
2064
2091
|
}
|
|
2065
2092
|
return {
|
|
2066
2093
|
async issue(input) {
|
|
2067
|
-
if (!supportedCapabilities.has(input.capability)) {
|
|
2068
|
-
throw new Error(
|
|
2069
|
-
`Unsupported ${provider} capability: ${input.capability}`
|
|
2070
|
-
);
|
|
2071
|
-
}
|
|
2072
|
-
const permissions = capabilityToPermissions(input.capability, provider);
|
|
2073
2094
|
const installationId = resolveInstallationId();
|
|
2074
|
-
|
|
2075
|
-
if (input.target) {
|
|
2076
|
-
if (input.target.type !== "repo") {
|
|
2077
|
-
throw new Error(
|
|
2078
|
-
`Unsupported github target type: ${input.target.type}`
|
|
2079
|
-
);
|
|
2080
|
-
}
|
|
2081
|
-
repoTarget = getRepoTarget(input.target);
|
|
2082
|
-
if (!repoTarget) {
|
|
2083
|
-
throw new Error("Invalid github repo target: expected owner/repo");
|
|
2084
|
-
}
|
|
2085
|
-
}
|
|
2086
|
-
const targetScope = repoTarget ? `${repoTarget.owner}/${repoTarget.repo}` : "all";
|
|
2087
|
-
const cacheKey = `${installationId}:${input.capability}:${targetScope}`;
|
|
2095
|
+
const cacheKey = String(installationId);
|
|
2088
2096
|
const cached = tokenCache.get(cacheKey);
|
|
2089
2097
|
const now = Date.now();
|
|
2090
2098
|
if (cached && cached.expiresAt - now > 2 * 60 * 1e3) {
|
|
2091
|
-
const domains2 = leaseDomainsFor(input.capability);
|
|
2092
2099
|
return {
|
|
2093
2100
|
id: randomUUID(),
|
|
2094
2101
|
provider,
|
|
2095
|
-
capability: input.capability,
|
|
2096
2102
|
env: { [authTokenEnv]: placeholder },
|
|
2097
|
-
headerTransforms:
|
|
2103
|
+
headerTransforms: leaseDomains.map((domain) => ({
|
|
2098
2104
|
domain,
|
|
2099
2105
|
headers: {
|
|
2100
2106
|
...apiHeaders ?? {},
|
|
@@ -2104,7 +2110,6 @@ function createGitHubAppBroker(manifest, credentials) {
|
|
|
2104
2110
|
expiresAt: new Date(cached.expiresAt).toISOString(),
|
|
2105
2111
|
metadata: {
|
|
2106
2112
|
installationId: String(cached.installationId),
|
|
2107
|
-
targetScope,
|
|
2108
2113
|
reason: input.reason
|
|
2109
2114
|
}
|
|
2110
2115
|
};
|
|
@@ -2112,9 +2117,6 @@ function createGitHubAppBroker(manifest, credentials) {
|
|
|
2112
2117
|
const tokenRequestBody = {
|
|
2113
2118
|
permissions
|
|
2114
2119
|
};
|
|
2115
|
-
if (repoTarget) {
|
|
2116
|
-
tokenRequestBody.repositories = [repoTarget.repo];
|
|
2117
|
-
}
|
|
2118
2120
|
const appId = process.env[appIdEnv];
|
|
2119
2121
|
if (!appId) {
|
|
2120
2122
|
throw new Error(`Missing ${appIdEnv}`);
|
|
@@ -2135,13 +2137,11 @@ function createGitHubAppBroker(manifest, credentials) {
|
|
|
2135
2137
|
token: accessTokenResponse.token,
|
|
2136
2138
|
expiresAt: expiresAtMs
|
|
2137
2139
|
});
|
|
2138
|
-
const domains = leaseDomainsFor(input.capability);
|
|
2139
2140
|
return {
|
|
2140
2141
|
id: randomUUID(),
|
|
2141
2142
|
provider,
|
|
2142
|
-
capability: input.capability,
|
|
2143
2143
|
env: { [authTokenEnv]: placeholder },
|
|
2144
|
-
headerTransforms:
|
|
2144
|
+
headerTransforms: leaseDomains.map((domain) => ({
|
|
2145
2145
|
domain,
|
|
2146
2146
|
headers: {
|
|
2147
2147
|
...apiHeaders ?? {},
|
|
@@ -2151,7 +2151,6 @@ function createGitHubAppBroker(manifest, credentials) {
|
|
|
2151
2151
|
expiresAt: new Date(expiresAtMs).toISOString(),
|
|
2152
2152
|
metadata: {
|
|
2153
2153
|
installationId: String(installationId),
|
|
2154
|
-
targetScope,
|
|
2155
2154
|
reason: input.reason
|
|
2156
2155
|
}
|
|
2157
2156
|
};
|
|
@@ -2307,14 +2306,12 @@ function getLeaseExpiry(expiresAt) {
|
|
|
2307
2306
|
}
|
|
2308
2307
|
function createOAuthBearerBroker(manifest, credentials, deps) {
|
|
2309
2308
|
const provider = manifest.name;
|
|
2310
|
-
const supportedCapabilities = new Set(manifest.capabilities);
|
|
2311
2309
|
const { apiDomains, apiHeaders, authTokenEnv } = credentials;
|
|
2312
2310
|
const authTokenPlaceholder = resolveAuthTokenPlaceholder(credentials);
|
|
2313
|
-
function buildLease(token,
|
|
2311
|
+
function buildLease(token, expiresAtMs, reason) {
|
|
2314
2312
|
return {
|
|
2315
2313
|
id: randomUUID2(),
|
|
2316
2314
|
provider,
|
|
2317
|
-
capability,
|
|
2318
2315
|
env: { [authTokenEnv]: authTokenPlaceholder },
|
|
2319
2316
|
headerTransforms: apiDomains.map((domain) => ({
|
|
2320
2317
|
domain,
|
|
@@ -2326,21 +2323,11 @@ function createOAuthBearerBroker(manifest, credentials, deps) {
|
|
|
2326
2323
|
}
|
|
2327
2324
|
return {
|
|
2328
2325
|
async issue(input) {
|
|
2329
|
-
if (!supportedCapabilities.has(input.capability)) {
|
|
2330
|
-
throw new Error(
|
|
2331
|
-
`Unsupported ${provider} capability: ${input.capability}`
|
|
2332
|
-
);
|
|
2333
|
-
}
|
|
2334
2326
|
const envToken = process.env[authTokenEnv]?.trim();
|
|
2335
2327
|
const oauth = manifest.oauth;
|
|
2336
2328
|
if (!oauth) {
|
|
2337
2329
|
if (envToken) {
|
|
2338
|
-
return buildLease(
|
|
2339
|
-
envToken,
|
|
2340
|
-
input.capability,
|
|
2341
|
-
Date.now() + MAX_LEASE_MS2,
|
|
2342
|
-
input.reason
|
|
2343
|
-
);
|
|
2330
|
+
return buildLease(envToken, Date.now() + MAX_LEASE_MS2, input.reason);
|
|
2344
2331
|
}
|
|
2345
2332
|
throw new CredentialUnavailableError(
|
|
2346
2333
|
provider,
|
|
@@ -2380,7 +2367,6 @@ function createOAuthBearerBroker(manifest, credentials, deps) {
|
|
|
2380
2367
|
);
|
|
2381
2368
|
return buildLease(
|
|
2382
2369
|
refreshed.accessToken,
|
|
2383
|
-
input.capability,
|
|
2384
2370
|
getLeaseExpiry(refreshed.expiresAt),
|
|
2385
2371
|
input.reason
|
|
2386
2372
|
);
|
|
@@ -2391,7 +2377,6 @@ function createOAuthBearerBroker(manifest, credentials, deps) {
|
|
|
2391
2377
|
if (stored.expiresAt > Date.now()) {
|
|
2392
2378
|
return buildLease(
|
|
2393
2379
|
stored.accessToken,
|
|
2394
|
-
input.capability,
|
|
2395
2380
|
getLeaseExpiry(stored.expiresAt),
|
|
2396
2381
|
input.reason
|
|
2397
2382
|
);
|
|
@@ -2405,7 +2390,6 @@ function createOAuthBearerBroker(manifest, credentials, deps) {
|
|
|
2405
2390
|
if (stored.expiresAt === void 0 || stored.expiresAt > Date.now()) {
|
|
2406
2391
|
return buildLease(
|
|
2407
2392
|
stored.accessToken,
|
|
2408
|
-
input.capability,
|
|
2409
2393
|
getLeaseExpiry(stored.expiresAt),
|
|
2410
2394
|
input.reason
|
|
2411
2395
|
);
|
|
@@ -2421,12 +2405,7 @@ function createOAuthBearerBroker(manifest, credentials, deps) {
|
|
|
2421
2405
|
);
|
|
2422
2406
|
}
|
|
2423
2407
|
if (envToken) {
|
|
2424
|
-
return buildLease(
|
|
2425
|
-
envToken,
|
|
2426
|
-
input.capability,
|
|
2427
|
-
getLeaseExpiry(),
|
|
2428
|
-
input.reason
|
|
2429
|
-
);
|
|
2408
|
+
return buildLease(envToken, getLeaseExpiry(), input.reason);
|
|
2430
2409
|
}
|
|
2431
2410
|
throw new CredentialUnavailableError(
|
|
2432
2411
|
provider,
|
|
@@ -2789,6 +2768,7 @@ export {
|
|
|
2789
2768
|
getActiveTraceId,
|
|
2790
2769
|
resolveErrorReference,
|
|
2791
2770
|
serializeGenAiAttribute,
|
|
2771
|
+
extractGenAiUsageSummary,
|
|
2792
2772
|
extractGenAiUsageAttributes,
|
|
2793
2773
|
resolveAuthTokenPlaceholder,
|
|
2794
2774
|
parsePluginManifest,
|
package/dist/cli/check.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseSkillFile
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-ICIRAL6Y.js";
|
|
4
4
|
import {
|
|
5
5
|
parsePluginManifest
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-RZJDO55D.js";
|
|
7
7
|
import "../chunk-Z3YD6NHK.js";
|
|
8
8
|
import "../chunk-XPXD3FCE.js";
|
|
9
9
|
import "../chunk-2KG3PWR4.js";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
disconnectStateAdapter,
|
|
3
3
|
resolveRuntimeDependencySnapshot
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-A75TWGF2.js";
|
|
5
5
|
import {
|
|
6
6
|
getPluginProviders,
|
|
7
7
|
getPluginRuntimeDependencies,
|
|
8
8
|
getPluginRuntimePostinstall
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-RZJDO55D.js";
|
|
10
10
|
import "../chunk-Z3YD6NHK.js";
|
|
11
11
|
import "../chunk-XPXD3FCE.js";
|
|
12
12
|
import "../chunk-2KG3PWR4.js";
|