@agentsky/sky 2.3.0 → 2.5.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/{chunk-2KQLWHHC.js → chunk-MHL5Z6IQ.js} +845 -10
- package/dist/index.js +652 -21
- package/dist/products.d.ts +30 -0
- package/dist/products.js +1 -1
- package/dist/{src-EGXYUSME.js → src-GLBJHVIJ.js} +3 -3
- package/package.json +1 -1
|
@@ -18978,6 +18978,15 @@ var REASONING_EFFORT_VALUES = [
|
|
|
18978
18978
|
"max",
|
|
18979
18979
|
"ultra"
|
|
18980
18980
|
];
|
|
18981
|
+
var MODEL_REASONING_EFFORTS = {
|
|
18982
|
+
"claude-haiku-4-5": [],
|
|
18983
|
+
"gemini-3.8-flash": ["low", "medium", "high"],
|
|
18984
|
+
"gemini-3.5-flash": ["low", "medium", "high"],
|
|
18985
|
+
"glm-5.3": ["low", "high", "max"],
|
|
18986
|
+
"glm-5.3-flash": ["low", "high", "max"],
|
|
18987
|
+
"grok-4.6": ["low", "medium", "high"],
|
|
18988
|
+
"grok-4.7": ["low", "medium", "high", "xhigh"]
|
|
18989
|
+
};
|
|
18981
18990
|
var REASONING_EFFORTS = {
|
|
18982
18991
|
agoragentic_acp: null,
|
|
18983
18992
|
amp_acp: null,
|
|
@@ -19032,15 +19041,20 @@ var REASONING_EFFORTS = {
|
|
|
19032
19041
|
};
|
|
19033
19042
|
function reasoningEffortsForModel(agentType, model) {
|
|
19034
19043
|
const normalized = model?.split("/").at(-1);
|
|
19044
|
+
const levels = REASONING_EFFORTS[agentType];
|
|
19045
|
+
if (levels === null) return null;
|
|
19035
19046
|
if (normalized === "gpt-6.1-sol" && (agentType === "codex" || agentType === "hermes")) return ["low", "medium", "high", "xhigh", "max"];
|
|
19036
|
-
return
|
|
19047
|
+
if (agentType === "opencode" && (normalized === "muse-spark-1.1" || normalized === "muse-spark-1.2")) return ["minimal", "low", "medium", "high", "xhigh"];
|
|
19048
|
+
const modelLevels = normalized ? MODEL_REASONING_EFFORTS[normalized] : void 0;
|
|
19049
|
+
return modelLevels ? levels.filter((level) => modelLevels.includes(level)) : levels;
|
|
19037
19050
|
}
|
|
19038
19051
|
function isModelEffortSupported(agentType, model, effort) {
|
|
19039
|
-
|
|
19040
|
-
return allowed !== null && allowed.includes(effort);
|
|
19052
|
+
return reasoningEffortsForModel(agentType, model)?.includes(effort) ?? false;
|
|
19041
19053
|
}
|
|
19042
19054
|
function reasoningEffortDocLine() {
|
|
19043
|
-
|
|
19055
|
+
const harness = Object.entries(REASONING_EFFORTS).map(([type, values]) => values ? `${type}: ${values.join("/")}` : `${type}: not supported`).join("; ");
|
|
19056
|
+
const models = Object.entries(MODEL_REASONING_EFFORTS).map(([model, values]) => `${model}: ${values.length ? values.join("/") : "not supported"}`).join("; ");
|
|
19057
|
+
return `${harness}; models: ${models}; codex/hermes + gpt-6.1-sol: low/medium/high/xhigh/max`;
|
|
19044
19058
|
}
|
|
19045
19059
|
|
|
19046
19060
|
// ../../packages/spec/src/acp-catalog.ts
|
|
@@ -21080,6 +21094,8 @@ var podTurnBodySchema = external_exports.object({
|
|
|
21080
21094
|
// ../../packages/spec/src/resources.ts
|
|
21081
21095
|
var MAX_RESOURCES_PER_CREATE = 100;
|
|
21082
21096
|
var MAX_REPOSITORY_TOKEN_CHARS = 1024;
|
|
21097
|
+
var MAX_SESSION_MEMORY_SNAPSHOT_BYTES = 8 * 1024 * 1024;
|
|
21098
|
+
var MAX_MEMORY_STORE_INSTRUCTIONS_CHARS = 4096;
|
|
21083
21099
|
var mountPathSchema = external_exports.string().min(1).max(4096).nullish();
|
|
21084
21100
|
var fileResourceParamSchema = external_exports.object({
|
|
21085
21101
|
type: external_exports.literal("file"),
|
|
@@ -21097,14 +21113,28 @@ var githubRepositoryResourceParamSchema = external_exports.object({
|
|
|
21097
21113
|
checkout: repositoryCheckoutSchema.nullish(),
|
|
21098
21114
|
mount_path: mountPathSchema
|
|
21099
21115
|
});
|
|
21116
|
+
var memoryStoreResourceParamSchema = external_exports.object({
|
|
21117
|
+
type: external_exports.literal("memory_store"),
|
|
21118
|
+
memory_store_id: external_exports.string().min(1).max(255),
|
|
21119
|
+
/** Write access must be explicitly granted for this session. */
|
|
21120
|
+
access: external_exports.enum(["read_only", "read_write"]),
|
|
21121
|
+
/** Optional per-session instructions passed to the agent about this store (≤ 4096 chars). */
|
|
21122
|
+
instructions: external_exports.string().max(MAX_MEMORY_STORE_INSTRUCTIONS_CHARS).optional(),
|
|
21123
|
+
/** Where the store's memories land; defaults to /mnt/memory/<memory_store_id>. */
|
|
21124
|
+
mount_path: external_exports.string().min(1).max(4096).nullish()
|
|
21125
|
+
});
|
|
21100
21126
|
var sessionResourceParamSchema = external_exports.discriminatedUnion("type", [
|
|
21101
21127
|
fileResourceParamSchema,
|
|
21102
|
-
githubRepositoryResourceParamSchema
|
|
21128
|
+
githubRepositoryResourceParamSchema,
|
|
21129
|
+
memoryStoreResourceParamSchema
|
|
21103
21130
|
]);
|
|
21104
21131
|
var sessionResourcesParamSchema = external_exports.array(sessionResourceParamSchema).max(MAX_RESOURCES_PER_CREATE);
|
|
21105
21132
|
var updateSessionResourceSchema = external_exports.object({
|
|
21106
21133
|
authorization_token: external_exports.string().min(1).max(MAX_REPOSITORY_TOKEN_CHARS)
|
|
21107
21134
|
});
|
|
21135
|
+
var MAX_MEMORY_MOUNT_PATH_BYTES = 4095 - 1024 - 2 * 13;
|
|
21136
|
+
var MAX_FILESYSTEM_COMPONENT_BYTES = 255;
|
|
21137
|
+
var MAX_STAGED_COMPONENT_BYTES = MAX_FILESYSTEM_COMPONENT_BYTES - 13;
|
|
21108
21138
|
|
|
21109
21139
|
// ../../packages/spec/src/usage.ts
|
|
21110
21140
|
var usageReportSchema = external_exports.object({
|
|
@@ -21151,6 +21181,693 @@ var connectionSupportSchema = external_exports.object({
|
|
|
21151
21181
|
connectors: external_exports.enum(["all", "none"])
|
|
21152
21182
|
}).strict();
|
|
21153
21183
|
|
|
21184
|
+
// ../../packages/spec/src/question.ts
|
|
21185
|
+
var QUESTION_REQUEST_KINDS = ["connect_app"];
|
|
21186
|
+
var questionSchema = external_exports.object({
|
|
21187
|
+
requestId: external_exports.string().min(1),
|
|
21188
|
+
question: external_exports.string().trim().min(1),
|
|
21189
|
+
options: external_exports.array(
|
|
21190
|
+
external_exports.object({
|
|
21191
|
+
id: external_exports.string().min(1),
|
|
21192
|
+
label: external_exports.string().trim().min(1),
|
|
21193
|
+
description: external_exports.string().optional()
|
|
21194
|
+
})
|
|
21195
|
+
).default([]),
|
|
21196
|
+
allowFreeText: external_exports.boolean().default(true),
|
|
21197
|
+
allowMultiple: external_exports.boolean().optional(),
|
|
21198
|
+
/** Authenticated platform user id; a share-link visitor cannot impersonate it. */
|
|
21199
|
+
requiredUserId: external_exports.string().trim().min(1).optional(),
|
|
21200
|
+
/** Holds the current Goal until an authenticated answer is admitted. */
|
|
21201
|
+
blocksGoal: external_exports.boolean().optional(),
|
|
21202
|
+
/** Informational deadline. Passing it never approves or answers the question. */
|
|
21203
|
+
dueAt: external_exports.string().datetime({ offset: true }).optional(),
|
|
21204
|
+
/** Hard permission deadline; unlike dueAt, later answers are refused. */
|
|
21205
|
+
expiresAt: external_exports.string().datetime({ offset: true }).optional(),
|
|
21206
|
+
/** The owner withdrew this question. Never a human answer or consent. */
|
|
21207
|
+
cancelledAt: external_exports.string().datetime({ offset: true }).optional(),
|
|
21208
|
+
/** What the platform is asking for when the question is one of its own
|
|
21209
|
+
* requests rather than an agent's free question. Absent on an ordinary question. */
|
|
21210
|
+
kind: external_exports.enum(QUESTION_REQUEST_KINDS).optional(),
|
|
21211
|
+
/** What the request is about: the app to connect, for `connect_app`. */
|
|
21212
|
+
subject: external_exports.string().trim().min(1).max(200).optional()
|
|
21213
|
+
}).superRefine((value, context) => {
|
|
21214
|
+
if (new Set(value.options.map((option) => option.id)).size !== value.options.length) {
|
|
21215
|
+
context.addIssue({ code: "custom", message: "Option identifiers must be unique." });
|
|
21216
|
+
}
|
|
21217
|
+
if (!value.options.length && !value.allowFreeText) {
|
|
21218
|
+
context.addIssue({ code: "custom", message: "The question must allow an answer." });
|
|
21219
|
+
}
|
|
21220
|
+
});
|
|
21221
|
+
var replySchema = external_exports.object({
|
|
21222
|
+
question: questionSchema,
|
|
21223
|
+
answer: external_exports.union([external_exports.object({ optionId: external_exports.string() }), external_exports.object({ optionIds: external_exports.array(external_exports.string()) }), external_exports.object({ text: external_exports.string() })])
|
|
21224
|
+
});
|
|
21225
|
+
|
|
21226
|
+
// ../../packages/spec/src/import-base64.ts
|
|
21227
|
+
function isCanonicalBase64(value) {
|
|
21228
|
+
if (value.length === 0 || value.length % 4 !== 0) return false;
|
|
21229
|
+
const padding = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
|
|
21230
|
+
for (let index = 0; index < value.length - padding; index += 1) {
|
|
21231
|
+
const code = value.charCodeAt(index);
|
|
21232
|
+
const alphabet = code >= 65 && code <= 90 || code >= 97 && code <= 122 || code >= 48 && code <= 57 || code === 43 || code === 47;
|
|
21233
|
+
if (!alphabet) return false;
|
|
21234
|
+
}
|
|
21235
|
+
return Buffer.from(value, "base64").toString("base64") === value;
|
|
21236
|
+
}
|
|
21237
|
+
|
|
21238
|
+
// ../../packages/spec/src/import-redact.ts
|
|
21239
|
+
function ci(word) {
|
|
21240
|
+
return word.split("").map((c) => /[a-z]/i.test(c) ? `[${c.toUpperCase()}${c.toLowerCase()}]` : c).join("");
|
|
21241
|
+
}
|
|
21242
|
+
var UnsafeImportError = class extends Error {
|
|
21243
|
+
};
|
|
21244
|
+
var TEXT_ATTACHMENT_MEDIA_TYPES = [
|
|
21245
|
+
"application/json",
|
|
21246
|
+
"application/xml",
|
|
21247
|
+
"application/javascript",
|
|
21248
|
+
"application/ecmascript",
|
|
21249
|
+
"application/x-javascript",
|
|
21250
|
+
"application/yaml",
|
|
21251
|
+
"application/x-yaml",
|
|
21252
|
+
"application/x-www-form-urlencoded",
|
|
21253
|
+
"image/svg+xml",
|
|
21254
|
+
"application/toml",
|
|
21255
|
+
"application/x-toml",
|
|
21256
|
+
"application/sql",
|
|
21257
|
+
"application/x-sql",
|
|
21258
|
+
"application/pem-certificate-chain",
|
|
21259
|
+
"application/x-pem-file",
|
|
21260
|
+
"application/x-pem-key",
|
|
21261
|
+
"application/x-ndjson",
|
|
21262
|
+
"application/ndjson"
|
|
21263
|
+
];
|
|
21264
|
+
var textAttachmentMediaTypes = new Set(TEXT_ATTACHMENT_MEDIA_TYPES);
|
|
21265
|
+
function isTextMediaType(value) {
|
|
21266
|
+
const media = typeof value === "string" ? value.split(";", 1)[0].trim().toLowerCase() : "";
|
|
21267
|
+
return media.startsWith("text/") || textAttachmentMediaTypes.has(media) || /\+(?:json|xml)$/.test(media);
|
|
21268
|
+
}
|
|
21269
|
+
var MASK = "\u25CF\u25CF\u25CF\u25CF\u25CF";
|
|
21270
|
+
var SECRET_PATTERNS = [
|
|
21271
|
+
{ name: "anthropic key", source: "(?<![A-Za-z0-9_])(sk-ant-)[A-Za-z0-9_-]{10,}", replacement: `\\1${MASK}` },
|
|
21272
|
+
{ name: "openai key", source: "(?<![A-Za-z0-9_])(sk-proj-|sk-)[A-Za-z0-9_-]{8,}", replacement: `\\1${MASK}` },
|
|
21273
|
+
{ name: "github token", source: "(?<![A-Za-z0-9_])(gh[pousr]_)[A-Za-z0-9]{16,}", replacement: `\\1${MASK}` },
|
|
21274
|
+
{ name: "github fine-grained token", source: "(?<![A-Za-z0-9_])(github_pat_)[A-Za-z0-9_]{20,}", replacement: `\\1${MASK}` },
|
|
21275
|
+
{ name: "slack token", source: "(?<![A-Za-z0-9_])(xox[abeprs]-|xapp-)[A-Za-z0-9-]{10,}", replacement: `\\1${MASK}` },
|
|
21276
|
+
{ name: "agentsky token", source: "(?<![A-Za-z0-9_])(ast_)[A-Za-z0-9_-]{10,}", replacement: `\\1${MASK}` },
|
|
21277
|
+
{ name: "guild broker token", source: "(?<![A-Za-z0-9_])(gbk_)[A-Za-z0-9_-]{10,}", replacement: `\\1${MASK}` },
|
|
21278
|
+
{ name: "jwt", source: "(?<![A-Za-z0-9_])eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*", replacement: MASK },
|
|
21279
|
+
{ name: "private key", source: "-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\\s\\S]*?(?:-----END [A-Z0-9 ]*PRIVATE KEY-----|$)", replacement: MASK },
|
|
21280
|
+
{ name: "google oauth token", source: "(ya29\\.)[A-Za-z0-9_-]{20,}", replacement: `\\1${MASK}` },
|
|
21281
|
+
{ name: "google api key", source: "(?<![A-Za-z0-9_])(AIza)[A-Za-z0-9_-]{30,}", replacement: `\\1${MASK}` },
|
|
21282
|
+
{ name: "aws key id", source: "(?<![A-Za-z0-9_])(AKIA)[0-9A-Z]{16}(?![A-Za-z0-9_])", replacement: `\\1${MASK}` },
|
|
21283
|
+
{ name: "import key", source: "(agt_)[A-Za-z0-9_-]{20,}", replacement: `\\1${MASK}` },
|
|
21284
|
+
{
|
|
21285
|
+
name: "database url",
|
|
21286
|
+
source: "(postgres://|postgresql://|mysql://|mongodb\\+srv://|mongodb://|redis://)([^:@/ ]+):[^@ ]+@",
|
|
21287
|
+
replacement: `\\1\\2:${MASK}@`
|
|
21288
|
+
},
|
|
21289
|
+
{ name: "bearer header", source: `(?<![A-Za-z0-9_])(${ci("bearer")}\\s+)[A-Za-z0-9._~+/=-]{16,}`, replacement: `\\1${MASK}` },
|
|
21290
|
+
{ name: "api key header", source: `(${ci("x-api-key")}: )[A-Za-z0-9_.=-]{16,}`, replacement: `\\1${MASK}` }
|
|
21291
|
+
];
|
|
21292
|
+
var compiled = SECRET_PATTERNS.map((p) => ({
|
|
21293
|
+
name: p.name,
|
|
21294
|
+
re: new RegExp(p.source, "g"),
|
|
21295
|
+
replacement: p.replacement.replace(/\\(\d)/g, "$$$1")
|
|
21296
|
+
}));
|
|
21297
|
+
function asPlainDecimal(token) {
|
|
21298
|
+
const m = /^([+-]?)(\d+)(?:\.(\d*))?(?:[eE]([+-]?\d+))?$/.exec(token);
|
|
21299
|
+
if (!m) return null;
|
|
21300
|
+
const [, sign, whole, fraction = "", exponent = "0"] = m;
|
|
21301
|
+
const digits = whole + fraction;
|
|
21302
|
+
if (Math.abs(Number(exponent)) > 400) return /[1-9]/.test(digits) ? null : "0";
|
|
21303
|
+
let pointAt = whole.length + Number(exponent);
|
|
21304
|
+
let padded = digits;
|
|
21305
|
+
if (pointAt <= 0) {
|
|
21306
|
+
padded = "0".repeat(1 - pointAt) + digits;
|
|
21307
|
+
pointAt += 1 - pointAt;
|
|
21308
|
+
}
|
|
21309
|
+
if (pointAt >= padded.length) padded += "0".repeat(pointAt - padded.length + 1);
|
|
21310
|
+
const intPart = padded.slice(0, pointAt).replace(/^0+(?=\d)/, "");
|
|
21311
|
+
const fracPart = padded.slice(pointAt).replace(/0+$/, "");
|
|
21312
|
+
const value = fracPart ? `${intPart}.${fracPart}` : intPart;
|
|
21313
|
+
return (sign === "-" && /[1-9]/.test(digits) ? "-" : "") + value;
|
|
21314
|
+
}
|
|
21315
|
+
function changesWhenRead(token) {
|
|
21316
|
+
const value = Number(token);
|
|
21317
|
+
if (!Number.isFinite(value)) return true;
|
|
21318
|
+
const mine = asPlainDecimal(token);
|
|
21319
|
+
const theirs = asPlainDecimal(String(value));
|
|
21320
|
+
if (mine === null) return /[1-9]/.test(token);
|
|
21321
|
+
if (theirs === null) return true;
|
|
21322
|
+
return mine !== theirs;
|
|
21323
|
+
}
|
|
21324
|
+
function unsafeNumberSpans(line) {
|
|
21325
|
+
const spans = [];
|
|
21326
|
+
let inString = false;
|
|
21327
|
+
for (let i = 0; i < line.length; i += 1) {
|
|
21328
|
+
const c = line[i];
|
|
21329
|
+
if (inString) {
|
|
21330
|
+
if (c === "\\") i += 1;
|
|
21331
|
+
else if (c === '"') inString = false;
|
|
21332
|
+
continue;
|
|
21333
|
+
}
|
|
21334
|
+
if (c === '"') {
|
|
21335
|
+
inString = true;
|
|
21336
|
+
continue;
|
|
21337
|
+
}
|
|
21338
|
+
if (c !== "-" && (c < "0" || c > "9")) continue;
|
|
21339
|
+
const start = i;
|
|
21340
|
+
if (c === "-") i += 1;
|
|
21341
|
+
while (i < line.length && line[i] >= "0" && line[i] <= "9") i += 1;
|
|
21342
|
+
if (line[i] === ".") {
|
|
21343
|
+
i += 1;
|
|
21344
|
+
while (i < line.length && line[i] >= "0" && line[i] <= "9") i += 1;
|
|
21345
|
+
}
|
|
21346
|
+
if (line[i] === "e" || line[i] === "E") {
|
|
21347
|
+
i += 1;
|
|
21348
|
+
if (line[i] === "+" || line[i] === "-") i += 1;
|
|
21349
|
+
while (i < line.length && line[i] >= "0" && line[i] <= "9") i += 1;
|
|
21350
|
+
}
|
|
21351
|
+
const token = line.slice(start, i);
|
|
21352
|
+
if (changesWhenRead(token)) spans.push([start, i]);
|
|
21353
|
+
i -= 1;
|
|
21354
|
+
}
|
|
21355
|
+
return spans;
|
|
21356
|
+
}
|
|
21357
|
+
function withPreservedNumbers(line) {
|
|
21358
|
+
const spans = unsafeNumberSpans(line);
|
|
21359
|
+
if (spans.length === 0) return { parse: () => JSON.parse(line), serialize: (v) => JSON.stringify(v) };
|
|
21360
|
+
let sentinel = "n";
|
|
21361
|
+
while (line.includes(`@@${sentinel}`)) sentinel += "n";
|
|
21362
|
+
const token = (index) => `@@${sentinel}${index}@@`;
|
|
21363
|
+
let out = "";
|
|
21364
|
+
let cursor = 0;
|
|
21365
|
+
const originals = [];
|
|
21366
|
+
spans.forEach(([start, end], index) => {
|
|
21367
|
+
out += line.slice(cursor, start) + JSON.stringify(token(index));
|
|
21368
|
+
originals.push(line.slice(start, end));
|
|
21369
|
+
cursor = end;
|
|
21370
|
+
});
|
|
21371
|
+
out += line.slice(cursor);
|
|
21372
|
+
return {
|
|
21373
|
+
parse: () => JSON.parse(out),
|
|
21374
|
+
serialize: (value) => {
|
|
21375
|
+
let text = JSON.stringify(value);
|
|
21376
|
+
originals.forEach((original, index) => {
|
|
21377
|
+
text = text.split(JSON.stringify(token(index))).join(original);
|
|
21378
|
+
});
|
|
21379
|
+
return text;
|
|
21380
|
+
}
|
|
21381
|
+
};
|
|
21382
|
+
}
|
|
21383
|
+
function hasDuplicateJsonKeys(line) {
|
|
21384
|
+
const stack = [];
|
|
21385
|
+
const skipSpace = (at) => {
|
|
21386
|
+
while (at < line.length && /\s/.test(line[at])) at += 1;
|
|
21387
|
+
return at;
|
|
21388
|
+
};
|
|
21389
|
+
for (let i = 0; i < line.length; i += 1) {
|
|
21390
|
+
const c = line[i];
|
|
21391
|
+
if (c === '"') {
|
|
21392
|
+
const start = i;
|
|
21393
|
+
i += 1;
|
|
21394
|
+
while (i < line.length) {
|
|
21395
|
+
if (line[i] === "\\") {
|
|
21396
|
+
i += 2;
|
|
21397
|
+
continue;
|
|
21398
|
+
}
|
|
21399
|
+
if (line[i] === '"') break;
|
|
21400
|
+
i += 1;
|
|
21401
|
+
}
|
|
21402
|
+
const frame = stack[stack.length - 1];
|
|
21403
|
+
const colon = skipSpace(i + 1);
|
|
21404
|
+
if (frame?.kind === "object" && frame.expectingKey && line[colon] === ":") {
|
|
21405
|
+
try {
|
|
21406
|
+
const key = JSON.parse(line.slice(start, i + 1));
|
|
21407
|
+
if (frame.keys.has(key)) return true;
|
|
21408
|
+
frame.keys.add(key);
|
|
21409
|
+
frame.expectingKey = false;
|
|
21410
|
+
} catch {
|
|
21411
|
+
}
|
|
21412
|
+
}
|
|
21413
|
+
continue;
|
|
21414
|
+
}
|
|
21415
|
+
if (c === "{") stack.push({ kind: "object", expectingKey: true, keys: /* @__PURE__ */ new Set() });
|
|
21416
|
+
else if (c === "[") stack.push({ kind: "array", expectingKey: false });
|
|
21417
|
+
else if (c === "}" || c === "]") stack.pop();
|
|
21418
|
+
else if (c === "," && stack.at(-1)?.kind === "object") stack.at(-1).expectingKey = true;
|
|
21419
|
+
}
|
|
21420
|
+
return false;
|
|
21421
|
+
}
|
|
21422
|
+
var FIELD_ASSIGNMENTS = new RegExp(
|
|
21423
|
+
String.raw`(?<![A-Za-z0-9_.])(\\{0,8}["']?([A-Za-z_][A-Za-z0-9_.-]{0,255})\\{0,8}["']?\s{0,8}\\{0,8}[:=]\\{0,8}\s{0,8}\\{0,8}(["']?))`,
|
|
21424
|
+
"g"
|
|
21425
|
+
);
|
|
21426
|
+
var JSON_NUMBER = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
21427
|
+
var COMPLETE_MASKED_VALUE = new RegExp(`^(?:${MASK}|${ci("bearer")} ${MASK})$`);
|
|
21428
|
+
function codeIdentifierEnd(value, at) {
|
|
21429
|
+
if (!/[A-Za-z_$]/.test(value[at] ?? "")) return -1;
|
|
21430
|
+
at += 1;
|
|
21431
|
+
while (/[A-Za-z0-9_$]/.test(value[at] ?? "")) at += 1;
|
|
21432
|
+
return at;
|
|
21433
|
+
}
|
|
21434
|
+
function codeGroupEnd(value, at) {
|
|
21435
|
+
const pairs = { "(": ")", "[": "]", "{": "}" };
|
|
21436
|
+
const stack = [pairs[value[at]]];
|
|
21437
|
+
for (let i = at + 1; i < value.length; i += 1) {
|
|
21438
|
+
const c = value[i];
|
|
21439
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
21440
|
+
for (i += 1; i < value.length; i += 1) {
|
|
21441
|
+
if (value[i] === "\\") i += 1;
|
|
21442
|
+
else if (value[i] === c) break;
|
|
21443
|
+
}
|
|
21444
|
+
if (i >= value.length) return -1;
|
|
21445
|
+
continue;
|
|
21446
|
+
}
|
|
21447
|
+
if (pairs[c]) stack.push(pairs[c]);
|
|
21448
|
+
else if (c === ")" || c === "]" || c === "}") {
|
|
21449
|
+
if (stack.pop() !== c) return -1;
|
|
21450
|
+
if (stack.length === 0) return i + 1;
|
|
21451
|
+
}
|
|
21452
|
+
}
|
|
21453
|
+
return -1;
|
|
21454
|
+
}
|
|
21455
|
+
function credentialRhsBoundary(value, start, lineEnd) {
|
|
21456
|
+
const pairs = { "(": ")", "[": "]", "{": "}" };
|
|
21457
|
+
const stack = [];
|
|
21458
|
+
for (let i = start; i < lineEnd; i += 1) {
|
|
21459
|
+
const c = value[i];
|
|
21460
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
21461
|
+
for (i += 1; i < lineEnd; i += 1) {
|
|
21462
|
+
if (value[i] === "\\") i += 1;
|
|
21463
|
+
else if (value[i] === c) break;
|
|
21464
|
+
}
|
|
21465
|
+
if (i >= lineEnd) return { end: lineEnd, unsafe: true };
|
|
21466
|
+
continue;
|
|
21467
|
+
}
|
|
21468
|
+
if (c === "/") return { end: lineEnd, unsafe: true };
|
|
21469
|
+
if (pairs[c]) stack.push(pairs[c]);
|
|
21470
|
+
else if (c === ")" || c === "]" || c === "}") {
|
|
21471
|
+
if (stack.pop() !== c) return { end: lineEnd, unsafe: true };
|
|
21472
|
+
}
|
|
21473
|
+
}
|
|
21474
|
+
return { end: lineEnd, unsafe: stack.length > 0 };
|
|
21475
|
+
}
|
|
21476
|
+
function maskExpressionLiterals(value) {
|
|
21477
|
+
let out = "";
|
|
21478
|
+
const groups = [];
|
|
21479
|
+
let previousNonWhitespace = "";
|
|
21480
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
21481
|
+
const c = value[i];
|
|
21482
|
+
if (c === "(" || c === "{") {
|
|
21483
|
+
groups.push(c);
|
|
21484
|
+
out += c;
|
|
21485
|
+
previousNonWhitespace = c;
|
|
21486
|
+
continue;
|
|
21487
|
+
}
|
|
21488
|
+
if (c === "[") {
|
|
21489
|
+
let kind = /[A-Za-z0-9_$.)\]}]/.test(previousNonWhitespace) ? "index" : "array";
|
|
21490
|
+
if (kind === "index") {
|
|
21491
|
+
const end = codeGroupEnd(value, i);
|
|
21492
|
+
if (end < 0) return null;
|
|
21493
|
+
const content = value.slice(i + 1, end - 1).trim();
|
|
21494
|
+
if (/^[-+.0-9]/.test(content) && !/^(?:0|[1-9][0-9]*)$/.test(content)) return null;
|
|
21495
|
+
if (/^(?:0|[1-9][0-9]*)$/.test(content)) kind = "index-number";
|
|
21496
|
+
}
|
|
21497
|
+
groups.push(kind);
|
|
21498
|
+
out += c;
|
|
21499
|
+
previousNonWhitespace = c;
|
|
21500
|
+
continue;
|
|
21501
|
+
}
|
|
21502
|
+
if (c === ")" || c === "]" || c === "}") {
|
|
21503
|
+
groups.pop();
|
|
21504
|
+
out += c;
|
|
21505
|
+
previousNonWhitespace = c;
|
|
21506
|
+
continue;
|
|
21507
|
+
}
|
|
21508
|
+
const previousIsIdentifier = i > 0 && /[A-Za-z0-9_$]/.test(value[i - 1]);
|
|
21509
|
+
const numberLooking = !previousIsIdentifier && (/[0-9]/.test(c) || c === "." && /[0-9]/.test(value[i + 1] ?? "") || (c === "+" || c === "-") && (/[0-9]/.test(value[i + 1] ?? "") || value[i + 1] === "." && /[0-9]/.test(value[i + 2] ?? "")));
|
|
21510
|
+
if (numberLooking && groups.at(-1) !== "index-number") return null;
|
|
21511
|
+
if (c !== '"' && c !== "'" && c !== "`") {
|
|
21512
|
+
out += c;
|
|
21513
|
+
if (!/\s/.test(c)) previousNonWhitespace = c;
|
|
21514
|
+
continue;
|
|
21515
|
+
}
|
|
21516
|
+
const start = i;
|
|
21517
|
+
for (i += 1; i < value.length; i += 1) {
|
|
21518
|
+
if (value[i] === "\\") i += 1;
|
|
21519
|
+
else if (value[i] === c) break;
|
|
21520
|
+
}
|
|
21521
|
+
const literal2 = value.slice(start, i + 1);
|
|
21522
|
+
out += groups.at(-1)?.startsWith("index") ? literal2 : `${c}${MASK}${c}`;
|
|
21523
|
+
previousNonWhitespace = c;
|
|
21524
|
+
}
|
|
21525
|
+
return out;
|
|
21526
|
+
}
|
|
21527
|
+
function rewriteCodeExpression(value, declaration) {
|
|
21528
|
+
let source = value.trim();
|
|
21529
|
+
const semicolon = source.endsWith(";");
|
|
21530
|
+
if (semicolon) source = source.slice(0, -1).trimEnd();
|
|
21531
|
+
if (/^(?:null|undefined)$/.test(source)) return value;
|
|
21532
|
+
if (source.startsWith("`")) {
|
|
21533
|
+
if (codeGroupEnd(`(${source})`, 0) !== source.length + 2) return null;
|
|
21534
|
+
return value.replace(source, `\`${MASK}\``);
|
|
21535
|
+
}
|
|
21536
|
+
const awaitPrefix = /^await\s+/.exec(source)?.[0] ?? "";
|
|
21537
|
+
if (awaitPrefix) source = source.slice(awaitPrefix.length);
|
|
21538
|
+
if (source.startsWith("[") || source.startsWith("{")) {
|
|
21539
|
+
if (codeGroupEnd(source, 0) !== source.length) return null;
|
|
21540
|
+
const full2 = semicolon ? `${MASK};` : MASK;
|
|
21541
|
+
return value.replace(value.trim(), full2);
|
|
21542
|
+
}
|
|
21543
|
+
let at = codeIdentifierEnd(source, 0);
|
|
21544
|
+
if (at < 0) return null;
|
|
21545
|
+
let syntax = false;
|
|
21546
|
+
while (at < source.length) {
|
|
21547
|
+
if (source.startsWith("?.", at)) {
|
|
21548
|
+
at += 2;
|
|
21549
|
+
if (source[at] === "[" || source[at] === "(") {
|
|
21550
|
+
const end2 = codeGroupEnd(source, at);
|
|
21551
|
+
if (end2 < 0) return null;
|
|
21552
|
+
syntax = true;
|
|
21553
|
+
at = end2;
|
|
21554
|
+
continue;
|
|
21555
|
+
}
|
|
21556
|
+
} else if (source[at] === ".") at += 1;
|
|
21557
|
+
else if (source[at] === "[" || source[at] === "(") {
|
|
21558
|
+
const end2 = codeGroupEnd(source, at);
|
|
21559
|
+
if (end2 < 0) return null;
|
|
21560
|
+
syntax = true;
|
|
21561
|
+
at = end2;
|
|
21562
|
+
continue;
|
|
21563
|
+
} else return null;
|
|
21564
|
+
const end = codeIdentifierEnd(source, at);
|
|
21565
|
+
if (end < 0) return null;
|
|
21566
|
+
syntax = true;
|
|
21567
|
+
at = end;
|
|
21568
|
+
}
|
|
21569
|
+
if (!syntax && !declaration) return null;
|
|
21570
|
+
const rewritten = maskExpressionLiterals(source);
|
|
21571
|
+
if (rewritten === null) return null;
|
|
21572
|
+
const full = semicolon ? `${awaitPrefix}${rewritten};` : `${awaitPrefix}${rewritten}`;
|
|
21573
|
+
return value.replace(value.trim(), full);
|
|
21574
|
+
}
|
|
21575
|
+
function redactPlainText(text) {
|
|
21576
|
+
const hits = {};
|
|
21577
|
+
let out = redactFieldAssignments(text, () => {
|
|
21578
|
+
hits["secret field"] = (hits["secret field"] ?? 0) + 1;
|
|
21579
|
+
});
|
|
21580
|
+
for (const p of compiled) {
|
|
21581
|
+
p.re.lastIndex = 0;
|
|
21582
|
+
out = out.replace(p.re, (...m) => {
|
|
21583
|
+
hits[p.name] = (hits[p.name] ?? 0) + 1;
|
|
21584
|
+
return p.replacement.replace(/\$(\d)/g, (_, i) => String(m[Number(i)] ?? ""));
|
|
21585
|
+
});
|
|
21586
|
+
}
|
|
21587
|
+
return { text: out, hits };
|
|
21588
|
+
}
|
|
21589
|
+
function nameSegments(name) {
|
|
21590
|
+
return name.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^A-Za-z0-9]+/).filter(Boolean).map((part) => part.toLowerCase());
|
|
21591
|
+
}
|
|
21592
|
+
var CREDENTIAL_WORDS = /* @__PURE__ */ new Set([
|
|
21593
|
+
"token",
|
|
21594
|
+
"secret",
|
|
21595
|
+
"secrets",
|
|
21596
|
+
"password",
|
|
21597
|
+
"passwords",
|
|
21598
|
+
"passwd",
|
|
21599
|
+
"credential",
|
|
21600
|
+
"credentials",
|
|
21601
|
+
"authorization",
|
|
21602
|
+
"cookie",
|
|
21603
|
+
"cookies"
|
|
21604
|
+
]);
|
|
21605
|
+
var KEY_OWNERS = /* @__PURE__ */ new Set(["api", "access", "private", "secret", "signing", "encryption"]);
|
|
21606
|
+
var COUNT_QUALIFIERS = /* @__PURE__ */ new Set(["max", "min", "num", "total", "input", "output", "cache", "prompt", "completion", "reasoning", "thinking", "used", "remaining", "limit", "budget"]);
|
|
21607
|
+
var COUNT_SUFFIXES = /* @__PURE__ */ new Set(["count", "counts", "used", "usage", "remaining", "limit", "limits", "budget", "price", "cost", "total", "size", "length"]);
|
|
21608
|
+
function ownsKey(segment) {
|
|
21609
|
+
if (!segment) return false;
|
|
21610
|
+
for (const owner of KEY_OWNERS) if (segment === owner || segment.endsWith(owner)) return true;
|
|
21611
|
+
return false;
|
|
21612
|
+
}
|
|
21613
|
+
function isCredentialField(name) {
|
|
21614
|
+
const segments = nameSegments(name);
|
|
21615
|
+
for (let i = 0; i < segments.length; i += 1) {
|
|
21616
|
+
const segment = segments[i];
|
|
21617
|
+
if (segment === "token") {
|
|
21618
|
+
if (!COUNT_QUALIFIERS.has(segments[i - 1] ?? "") && !COUNT_SUFFIXES.has(segments[i + 1] ?? "")) return true;
|
|
21619
|
+
continue;
|
|
21620
|
+
}
|
|
21621
|
+
if (CREDENTIAL_WORDS.has(segment)) return true;
|
|
21622
|
+
if ((segment === "key" || segment === "keys") && i > 0 && ownsKey(segments[i - 1])) return true;
|
|
21623
|
+
if (segment === "id" && i > 0 && segments[i - 1] === "session") return true;
|
|
21624
|
+
if (segment === "sessionid" || segment === "apikey" || segment === "accesskey" || segment === "privatekey") return true;
|
|
21625
|
+
}
|
|
21626
|
+
return false;
|
|
21627
|
+
}
|
|
21628
|
+
function redactFieldAssignments(value, onHit) {
|
|
21629
|
+
FIELD_ASSIGNMENTS.lastIndex = 0;
|
|
21630
|
+
let out = "";
|
|
21631
|
+
let copiedThrough = 0;
|
|
21632
|
+
for (let match = FIELD_ASSIGNMENTS.exec(value); match; match = FIELD_ASSIGNMENTS.exec(value)) {
|
|
21633
|
+
const name = match[2];
|
|
21634
|
+
if (!isCredentialField(name)) continue;
|
|
21635
|
+
const valueStart = FIELD_ASSIGNMENTS.lastIndex;
|
|
21636
|
+
const quote = match[3];
|
|
21637
|
+
const limit = value.length;
|
|
21638
|
+
const lineEnd = value.slice(valueStart, limit).search(/[\r\n]/);
|
|
21639
|
+
const boundedLineEnd = lineEnd < 0 ? limit : valueStart + lineEnd;
|
|
21640
|
+
const boundary = quote ? { end: boundedLineEnd, unsafe: false } : credentialRhsBoundary(value, valueStart, boundedLineEnd);
|
|
21641
|
+
const expressionEnd = boundary.end;
|
|
21642
|
+
const lineStart = value.lastIndexOf("\n", match.index - 1) + 1;
|
|
21643
|
+
const declaration = /(?:^|[;{}]\s*)(?:const|let|var)\s+$/.test(value.slice(lineStart, match.index));
|
|
21644
|
+
const expression = quote || boundary.unsafe ? null : rewriteCodeExpression(value.slice(valueStart, expressionEnd), declaration);
|
|
21645
|
+
if (expression !== null) {
|
|
21646
|
+
if (expression !== value.slice(valueStart, expressionEnd)) {
|
|
21647
|
+
out += value.slice(copiedThrough, valueStart) + expression;
|
|
21648
|
+
copiedThrough = expressionEnd;
|
|
21649
|
+
onHit(value.slice(valueStart, expressionEnd));
|
|
21650
|
+
}
|
|
21651
|
+
FIELD_ASSIGNMENTS.lastIndex = expressionEnd;
|
|
21652
|
+
continue;
|
|
21653
|
+
}
|
|
21654
|
+
if (!quote) {
|
|
21655
|
+
const fieldValue2 = value.slice(valueStart, expressionEnd);
|
|
21656
|
+
const trimmed2 = fieldValue2.trim();
|
|
21657
|
+
if (!COMPLETE_MASKED_VALUE.test(trimmed2)) {
|
|
21658
|
+
out += value.slice(copiedThrough, valueStart) + (JSON_NUMBER.test(trimmed2) ? `"${MASK}"` : MASK);
|
|
21659
|
+
copiedThrough = expressionEnd;
|
|
21660
|
+
onHit(fieldValue2);
|
|
21661
|
+
}
|
|
21662
|
+
FIELD_ASSIGNMENTS.lastIndex = expressionEnd;
|
|
21663
|
+
continue;
|
|
21664
|
+
}
|
|
21665
|
+
let valueEnd = valueStart;
|
|
21666
|
+
if (quote) {
|
|
21667
|
+
let openingSlashes = 0;
|
|
21668
|
+
for (let i = match[1].length - 2; i >= 0 && match[1][i] === "\\"; i -= 1) openingSlashes += 1;
|
|
21669
|
+
while (valueEnd < limit && value[valueEnd] !== "\r" && value[valueEnd] !== "\n") {
|
|
21670
|
+
if (value[valueEnd] === quote) {
|
|
21671
|
+
let syntaxStart = valueEnd;
|
|
21672
|
+
while (syntaxStart > valueStart && value[syntaxStart - 1] === "\\") syntaxStart -= 1;
|
|
21673
|
+
if (valueEnd - syntaxStart === openingSlashes) {
|
|
21674
|
+
valueEnd = syntaxStart;
|
|
21675
|
+
break;
|
|
21676
|
+
}
|
|
21677
|
+
}
|
|
21678
|
+
valueEnd += 1;
|
|
21679
|
+
}
|
|
21680
|
+
} else {
|
|
21681
|
+
while (valueEnd < limit && !/["'\r\n,}]/.test(value[valueEnd])) valueEnd += 1;
|
|
21682
|
+
}
|
|
21683
|
+
if (valueEnd === valueStart) continue;
|
|
21684
|
+
const fieldValue = value.slice(valueStart, valueEnd);
|
|
21685
|
+
const trimmed = fieldValue.trim();
|
|
21686
|
+
if (COMPLETE_MASKED_VALUE.test(trimmed)) continue;
|
|
21687
|
+
out += value.slice(copiedThrough, valueStart) + (!match[3] && JSON_NUMBER.test(trimmed) ? `"${MASK}"` : MASK);
|
|
21688
|
+
copiedThrough = valueEnd;
|
|
21689
|
+
onHit(fieldValue);
|
|
21690
|
+
FIELD_ASSIGNMENTS.lastIndex = valueEnd;
|
|
21691
|
+
}
|
|
21692
|
+
return copiedThrough ? out + value.slice(copiedThrough) : value;
|
|
21693
|
+
}
|
|
21694
|
+
var B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
21695
|
+
function base64Bytes(value) {
|
|
21696
|
+
const clean = value.endsWith("==") ? value.slice(0, -2) : value.endsWith("=") ? value.slice(0, -1) : value;
|
|
21697
|
+
const out = [];
|
|
21698
|
+
let bits = 0;
|
|
21699
|
+
let acc = 0;
|
|
21700
|
+
for (const ch of clean) {
|
|
21701
|
+
const index = B64.indexOf(ch);
|
|
21702
|
+
if (index < 0) throw new Error("not base64");
|
|
21703
|
+
acc = acc << 6 | index;
|
|
21704
|
+
bits += 6;
|
|
21705
|
+
if (bits >= 8) {
|
|
21706
|
+
bits -= 8;
|
|
21707
|
+
out.push(acc >> bits & 255);
|
|
21708
|
+
}
|
|
21709
|
+
}
|
|
21710
|
+
return Uint8Array.from(out);
|
|
21711
|
+
}
|
|
21712
|
+
function bytesBase64(bytes) {
|
|
21713
|
+
let out = "";
|
|
21714
|
+
for (let i = 0; i < bytes.length; i += 3) {
|
|
21715
|
+
const a = bytes[i], b = bytes[i + 1], c = bytes[i + 2];
|
|
21716
|
+
out += B64[a >> 2] + B64[(a & 3) << 4 | (b ?? 0) >> 4] + (b === void 0 ? "=" : B64[(b & 15) << 2 | (c ?? 0) >> 6]) + (c === void 0 ? "=" : B64[c & 63]);
|
|
21717
|
+
}
|
|
21718
|
+
return out;
|
|
21719
|
+
}
|
|
21720
|
+
function redactLine(line, options = {}) {
|
|
21721
|
+
const hits = {};
|
|
21722
|
+
function fieldCredentials(value) {
|
|
21723
|
+
return redactFieldAssignments(value, (fieldValue) => {
|
|
21724
|
+
const kind = /^[A-Za-z0-9_/+.=-]{12,}$/.test(fieldValue) ? "env assignment" : "secret field";
|
|
21725
|
+
hits[kind] = (hits[kind] ?? 0) + 1;
|
|
21726
|
+
});
|
|
21727
|
+
}
|
|
21728
|
+
function redactPatterns(value) {
|
|
21729
|
+
let out = value;
|
|
21730
|
+
for (const p of compiled) {
|
|
21731
|
+
p.re.lastIndex = 0;
|
|
21732
|
+
out = out.replace(p.re, (...m) => {
|
|
21733
|
+
hits[p.name] = (hits[p.name] ?? 0) + 1;
|
|
21734
|
+
return p.replacement.replace(/\$(\d)/g, (_, i) => String(m[Number(i)] ?? ""));
|
|
21735
|
+
});
|
|
21736
|
+
}
|
|
21737
|
+
return fieldCredentials(out);
|
|
21738
|
+
}
|
|
21739
|
+
function redactDuplicateRecord(value) {
|
|
21740
|
+
let out = value;
|
|
21741
|
+
for (const p of compiled) {
|
|
21742
|
+
p.re.lastIndex = 0;
|
|
21743
|
+
out = out.replace(p.re, (...m) => {
|
|
21744
|
+
hits[p.name] = (hits[p.name] ?? 0) + 1;
|
|
21745
|
+
return p.replacement.replace(/\$(\d)/g, (_, i) => String(m[Number(i)] ?? ""));
|
|
21746
|
+
});
|
|
21747
|
+
}
|
|
21748
|
+
return out.replace(/("(?:\\.|[^"\\])*"\s*:\s*")((?:\\.|[^"\\])*)(")/g, (whole, prefix, fieldValue, suffix) => {
|
|
21749
|
+
const rawKey = prefix.slice(0, prefix.indexOf(":")).trim();
|
|
21750
|
+
let key;
|
|
21751
|
+
try {
|
|
21752
|
+
key = JSON.parse(rawKey);
|
|
21753
|
+
} catch {
|
|
21754
|
+
return whole;
|
|
21755
|
+
}
|
|
21756
|
+
if (!isCredentialField(key) || fieldValue === MASK) return whole;
|
|
21757
|
+
hits["secret field"] = (hits["secret field"] ?? 0) + 1;
|
|
21758
|
+
return prefix + MASK + suffix;
|
|
21759
|
+
});
|
|
21760
|
+
}
|
|
21761
|
+
function restoreHits(snapshot) {
|
|
21762
|
+
for (const key of Object.keys(hits)) delete hits[key];
|
|
21763
|
+
Object.assign(hits, snapshot);
|
|
21764
|
+
}
|
|
21765
|
+
function redactText(value) {
|
|
21766
|
+
const uri = BASE64_DATA_URI_PREFIX.exec(value);
|
|
21767
|
+
if (uri && isCanonicalBase64(uri[2])) {
|
|
21768
|
+
const prefix = uri[1];
|
|
21769
|
+
const metadata = redactPlainText(prefix.slice(0, -8));
|
|
21770
|
+
for (const [kind, n] of Object.entries(metadata.hits)) hits[kind] = (hits[kind] ?? 0) + n;
|
|
21771
|
+
const mediaType = /^data:([^;,]*)/i.exec(prefix)?.[1] || "text/plain";
|
|
21772
|
+
return metadata.text + prefix.slice(-8) + recodePayload(uri[2], mediaType);
|
|
21773
|
+
}
|
|
21774
|
+
const trimmed = value.trim();
|
|
21775
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
21776
|
+
if (hasDuplicateJsonKeys(value)) throw new UnsafeImportError("Duplicate keys in serialized JSON are not safe to import.");
|
|
21777
|
+
const snapshot = { ...hits };
|
|
21778
|
+
try {
|
|
21779
|
+
const json3 = withPreservedNumbers(value);
|
|
21780
|
+
if (json3) {
|
|
21781
|
+
const parsed = json3.parse();
|
|
21782
|
+
const walked = walk(parsed);
|
|
21783
|
+
if (JSON.stringify(walked) !== JSON.stringify(parsed)) return json3.serialize(walked);
|
|
21784
|
+
restoreHits(snapshot);
|
|
21785
|
+
return value;
|
|
21786
|
+
}
|
|
21787
|
+
} catch (error61) {
|
|
21788
|
+
if (error61 instanceof UnsafeImportError) throw error61;
|
|
21789
|
+
restoreHits(snapshot);
|
|
21790
|
+
}
|
|
21791
|
+
}
|
|
21792
|
+
return redactPatterns(value);
|
|
21793
|
+
}
|
|
21794
|
+
function recodePayload(data, mediaType) {
|
|
21795
|
+
const bytes = base64Bytes(data);
|
|
21796
|
+
if (!isTextMediaType(mediaType)) return data;
|
|
21797
|
+
let content;
|
|
21798
|
+
try {
|
|
21799
|
+
content = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
21800
|
+
} catch {
|
|
21801
|
+
throw new UnsafeImportError("A declared text attachment is not valid UTF-8.");
|
|
21802
|
+
}
|
|
21803
|
+
const cleaned = redactText(content);
|
|
21804
|
+
return cleaned === content ? data : bytesBase64(new TextEncoder().encode(cleaned));
|
|
21805
|
+
}
|
|
21806
|
+
function maskDescendants(value) {
|
|
21807
|
+
if (typeof value === "string") return value === MASK ? value : MASK;
|
|
21808
|
+
if (typeof value === "number" || typeof value === "boolean") return MASK;
|
|
21809
|
+
if (Array.isArray(value)) return value.map(maskDescendants);
|
|
21810
|
+
if (value && typeof value === "object") {
|
|
21811
|
+
const result = {};
|
|
21812
|
+
for (const [key, item] of Object.entries(value)) {
|
|
21813
|
+
const name = redactText(key);
|
|
21814
|
+
let at = name;
|
|
21815
|
+
for (let n = 2; at in result; n += 1) at = `${name} (${n})`;
|
|
21816
|
+
result[at] = maskDescendants(item);
|
|
21817
|
+
}
|
|
21818
|
+
return result;
|
|
21819
|
+
}
|
|
21820
|
+
return value;
|
|
21821
|
+
}
|
|
21822
|
+
function walk(value) {
|
|
21823
|
+
if (typeof value === "string") return redactText(value);
|
|
21824
|
+
if (Array.isArray(value)) return value.map(walk);
|
|
21825
|
+
if (!value || typeof value !== "object") return value;
|
|
21826
|
+
const node2 = value;
|
|
21827
|
+
const payload = isFilePayload(node2);
|
|
21828
|
+
const out = {};
|
|
21829
|
+
const place = (name, item) => {
|
|
21830
|
+
let at = name;
|
|
21831
|
+
for (let n = 2; at in out; n += 1) at = `${name} (${n})`;
|
|
21832
|
+
out[at] = item;
|
|
21833
|
+
};
|
|
21834
|
+
for (const [key, item] of Object.entries(node2)) {
|
|
21835
|
+
const name = redactText(key);
|
|
21836
|
+
if (payload && key === "data") {
|
|
21837
|
+
place(name, recodePayload(item, node2.media_type ?? node2.mime_type));
|
|
21838
|
+
continue;
|
|
21839
|
+
}
|
|
21840
|
+
if (isCredentialField(key) && item !== null && item !== void 0) {
|
|
21841
|
+
const masked = maskDescendants(item);
|
|
21842
|
+
if (JSON.stringify(masked) !== JSON.stringify(item)) {
|
|
21843
|
+
hits["secret field"] = (hits["secret field"] ?? 0) + 1;
|
|
21844
|
+
}
|
|
21845
|
+
place(name, masked);
|
|
21846
|
+
continue;
|
|
21847
|
+
}
|
|
21848
|
+
place(name, walk(item));
|
|
21849
|
+
}
|
|
21850
|
+
return out;
|
|
21851
|
+
}
|
|
21852
|
+
if (hasDuplicateJsonKeys(line)) return { line: redactDuplicateRecord(line), hits };
|
|
21853
|
+
const json2 = withPreservedNumbers(line);
|
|
21854
|
+
if (!json2) {
|
|
21855
|
+
if (options.requireStructured) throw new Error("Could not preserve JSON numbers during redaction.");
|
|
21856
|
+
return { line: redactPatterns(line), hits };
|
|
21857
|
+
}
|
|
21858
|
+
try {
|
|
21859
|
+
const walked = json2.serialize(walk(json2.parse()));
|
|
21860
|
+
return { line: Object.keys(hits).length ? walked : line, hits };
|
|
21861
|
+
} catch (error61) {
|
|
21862
|
+
if (options.requireStructured || error61 instanceof UnsafeImportError) throw error61;
|
|
21863
|
+
return { line: redactPatterns(line), hits };
|
|
21864
|
+
}
|
|
21865
|
+
}
|
|
21866
|
+
var BASE64_DATA_URI_PREFIX = /^(data:[^,]*;base64,)([\s\S]*)(?![\s\S])/i;
|
|
21867
|
+
function isFilePayload(node2) {
|
|
21868
|
+
return typeof node2.data === "string" && node2.data !== "" && (typeof node2.media_type === "string" || typeof node2.mime_type === "string" || node2.type === "import.resource" || node2.type === "base64");
|
|
21869
|
+
}
|
|
21870
|
+
|
|
21154
21871
|
// ../../packages/spec/src/index.ts
|
|
21155
21872
|
var NATIVE_AGENT_TYPES = [
|
|
21156
21873
|
"hermes",
|
|
@@ -21174,6 +21891,7 @@ var LEGACY_CAPABILITY_IDS = [
|
|
|
21174
21891
|
"exa.contents",
|
|
21175
21892
|
"tinyfish.fetch",
|
|
21176
21893
|
"tinyfish.browser",
|
|
21894
|
+
"tinyfish.agent",
|
|
21177
21895
|
"dataforseo.serp",
|
|
21178
21896
|
"dataforseo.ai-keywords",
|
|
21179
21897
|
"dataforseo.llm-responses",
|
|
@@ -21344,6 +22062,8 @@ var allowedLlms = {
|
|
|
21344
22062
|
"kimi-k3",
|
|
21345
22063
|
"kimi-k2.7-code",
|
|
21346
22064
|
"grok-4.6",
|
|
22065
|
+
"muse-spark-1.1",
|
|
22066
|
+
"muse-spark-1.2",
|
|
21347
22067
|
"claude-opus-5-5",
|
|
21348
22068
|
"claude-opus-5",
|
|
21349
22069
|
"claude-fable-5-1",
|
|
@@ -21397,6 +22117,8 @@ var allowedLlms = {
|
|
|
21397
22117
|
"kimi-k3",
|
|
21398
22118
|
"kimi-k2.7-code",
|
|
21399
22119
|
"grok-4.6",
|
|
22120
|
+
"muse-spark-1.1",
|
|
22121
|
+
"muse-spark-1.2",
|
|
21400
22122
|
"claude-opus-5-5",
|
|
21401
22123
|
"claude-opus-5",
|
|
21402
22124
|
"claude-fable-5-1",
|
|
@@ -21434,11 +22156,38 @@ function isCompatible(agentType, llm) {
|
|
|
21434
22156
|
function defaultLlm(agentType) {
|
|
21435
22157
|
return allowedLlms[agentType][0];
|
|
21436
22158
|
}
|
|
22159
|
+
var CHATGPT_PLAN_MODELS = /* @__PURE__ */ new Set([
|
|
22160
|
+
"gpt-6-astra",
|
|
22161
|
+
"gpt-5.6-sol",
|
|
22162
|
+
"gpt-5.6-terra",
|
|
22163
|
+
"gpt-5.6-luna",
|
|
22164
|
+
"gpt-5.5"
|
|
22165
|
+
]);
|
|
22166
|
+
var CLAUDE_PLAN_MODELS = /* @__PURE__ */ new Set([
|
|
22167
|
+
"claude-opus-5",
|
|
22168
|
+
"claude-fable-5-1",
|
|
22169
|
+
"claude-sonnet-5",
|
|
22170
|
+
"claude-haiku-4-5",
|
|
22171
|
+
"claude-sonnet-4-6",
|
|
22172
|
+
"claude-opus-4-8",
|
|
22173
|
+
"claude-fable-5"
|
|
22174
|
+
]);
|
|
21437
22175
|
function modelSubscriptionProviderFor(agentType, llm) {
|
|
21438
|
-
if (agentType === "claude_code" &&
|
|
21439
|
-
if (agentType === "codex" &&
|
|
22176
|
+
if (agentType === "claude_code" && CLAUDE_PLAN_MODELS.has(llm)) return "anthropic";
|
|
22177
|
+
if (agentType === "codex" && CHATGPT_PLAN_MODELS.has(llm)) return "openai";
|
|
22178
|
+
if (agentType === "cursor" && llm === "harness-default") return "cursor";
|
|
21440
22179
|
return null;
|
|
21441
22180
|
}
|
|
22181
|
+
var MODEL_SUBSCRIPTION_PROVIDER_NAME = {
|
|
22182
|
+
anthropic: "Claude",
|
|
22183
|
+
openai: "ChatGPT",
|
|
22184
|
+
cursor: "Cursor"
|
|
22185
|
+
};
|
|
22186
|
+
var MODEL_SUBSCRIPTION_PLAN_PHRASE = {
|
|
22187
|
+
anthropic: "Claude subscription",
|
|
22188
|
+
openai: "ChatGPT plan",
|
|
22189
|
+
cursor: "Cursor plan"
|
|
22190
|
+
};
|
|
21442
22191
|
var AGENT_TYPE_META = {
|
|
21443
22192
|
...Object.fromEntries(ACP_AGENT_TYPES.map((agentType) => [agentType, {
|
|
21444
22193
|
label: ACP_AGENTS[agentType].label,
|
|
@@ -21491,6 +22240,10 @@ function canonicalCapabilityId(value) {
|
|
|
21491
22240
|
}
|
|
21492
22241
|
var capabilityIdInputSchema = external_exports.preprocess(canonicalCapabilityId, external_exports.enum(CAPABILITY_IDS));
|
|
21493
22242
|
var capabilitiesSchema = external_exports.array(capabilityIdInputSchema).default([]);
|
|
22243
|
+
var CAPABILITY_PERMISSION_POLICIES = ["always_allow", "always_ask", "auto"];
|
|
22244
|
+
var capabilityPermissionPolicySchema = external_exports.enum(
|
|
22245
|
+
CAPABILITY_PERMISSION_POLICIES
|
|
22246
|
+
);
|
|
21494
22247
|
var basicsSchema = external_exports.object({
|
|
21495
22248
|
name: external_exports.string().trim().min(1, "Give your agent a name."),
|
|
21496
22249
|
description: external_exports.string().default("")
|
|
@@ -21529,8 +22282,7 @@ var skillRefSchema = external_exports.discriminatedUnion("type", [
|
|
|
21529
22282
|
storeSkillRefSchema,
|
|
21530
22283
|
githubSkillRefSchema
|
|
21531
22284
|
]);
|
|
21532
|
-
var
|
|
21533
|
-
var skillsArraySchema = external_exports.array(skillRefSchema).max(MAX_SKILLS_PER_AGENT, `At most ${MAX_SKILLS_PER_AGENT} skills per agent.`).superRefine((arr, ctx) => {
|
|
22285
|
+
var skillsArraySchema = external_exports.array(skillRefSchema).superRefine((arr, ctx) => {
|
|
21534
22286
|
const targets = arr.map((s) => s.type === "skill" ? `skill:${s.skillId}` : `github:${s.url}`);
|
|
21535
22287
|
if (new Set(targets).size !== targets.length) {
|
|
21536
22288
|
ctx.addIssue({ code: "custom", message: "Duplicate skill entries." });
|
|
@@ -21567,6 +22319,74 @@ var mcpServerSchema = external_exports.object({
|
|
|
21567
22319
|
tools: mcpToolFilterSchema.optional()
|
|
21568
22320
|
});
|
|
21569
22321
|
var mcpServersSchema = external_exports.array(mcpServerSchema).max(20);
|
|
22322
|
+
var HOOK_EVENTS = [
|
|
22323
|
+
"pre_session_start",
|
|
22324
|
+
"session_start",
|
|
22325
|
+
"user_prompt_submit",
|
|
22326
|
+
"pre_tool_use",
|
|
22327
|
+
"post_tool_use",
|
|
22328
|
+
"stop",
|
|
22329
|
+
"session_end"
|
|
22330
|
+
];
|
|
22331
|
+
var HOOK_MATCHER = /^(?:[A-Za-z0-9_-]|\.\*)+(?:\|(?:[A-Za-z0-9_-]|\.\*)+)*$/;
|
|
22332
|
+
var hookSchema = external_exports.object({
|
|
22333
|
+
event: external_exports.enum(HOOK_EVENTS),
|
|
22334
|
+
command: external_exports.string().min(1).max(4e3).refine((value) => !/[\u0000\uD800-\uDFFF]/u.test(value), {
|
|
22335
|
+
message: "command must be plain text without a NUL character"
|
|
22336
|
+
}),
|
|
22337
|
+
matcher: external_exports.string().min(1).max(255).refine((value) => HOOK_MATCHER.test(value), {
|
|
22338
|
+
message: "matcher must be tool names separated by |, with .* as the only wildcard"
|
|
22339
|
+
}).optional(),
|
|
22340
|
+
timeout_s: external_exports.number().int().min(1).max(600).optional()
|
|
22341
|
+
}).strict().refine((hook) => hook.matcher === void 0 || hook.event === "pre_tool_use" || hook.event === "post_tool_use", {
|
|
22342
|
+
message: "matcher applies only to pre_tool_use and post_tool_use hooks",
|
|
22343
|
+
path: ["matcher"]
|
|
22344
|
+
});
|
|
22345
|
+
var hooksSchema = external_exports.array(hookSchema).max(20);
|
|
22346
|
+
var POLICY_ACTIONS = ["allow", "ask", "deny"];
|
|
22347
|
+
var toolCallPolicyConfigSchema = external_exports.object({
|
|
22348
|
+
action: external_exports.enum(POLICY_ACTIONS),
|
|
22349
|
+
matcher: external_exports.string().min(1).max(255).refine((v) => /^(?:[A-Za-z0-9_:.-]|\.\*)+(?:\|(?:[A-Za-z0-9_:.-]|\.\*)+)*$/.test(v), {
|
|
22350
|
+
message: "matcher must be tool names or patterns separated by |"
|
|
22351
|
+
}).optional(),
|
|
22352
|
+
commandPatterns: external_exports.array(external_exports.string().min(1).max(500)).max(20).optional()
|
|
22353
|
+
}).strict();
|
|
22354
|
+
var spendCapPolicyConfigSchema = external_exports.object({
|
|
22355
|
+
warnUsdMicros: external_exports.number().int().min(0).nullish(),
|
|
22356
|
+
hardCapUsdMicros: external_exports.number().int().min(1)
|
|
22357
|
+
}).strict().refine((c) => !c.warnUsdMicros || c.warnUsdMicros < c.hardCapUsdMicros, {
|
|
22358
|
+
message: "warnUsdMicros must be less than hardCapUsdMicros"
|
|
22359
|
+
});
|
|
22360
|
+
var callCountPolicyConfigSchema = external_exports.object({ limitPerSession: external_exports.number().int().min(1).max(1e5) }).strict();
|
|
22361
|
+
var capabilityPolicyConfigSchema = external_exports.record(external_exports.string(), external_exports.enum(POLICY_ACTIONS)).superRefine((obj, ctx) => {
|
|
22362
|
+
for (const k of Object.keys(obj)) {
|
|
22363
|
+
if (!CAPABILITY_IDS.includes(k)) {
|
|
22364
|
+
ctx.addIssue({ code: "custom", message: `unknown capability id: ${k}`, path: [k] });
|
|
22365
|
+
}
|
|
22366
|
+
}
|
|
22367
|
+
});
|
|
22368
|
+
var policyRuleBaseSchema = external_exports.object({
|
|
22369
|
+
name: external_exports.string().min(1).max(128),
|
|
22370
|
+
enabled: external_exports.boolean().default(true),
|
|
22371
|
+
position: external_exports.number().int().min(0).max(9999).default(0)
|
|
22372
|
+
});
|
|
22373
|
+
var policyRuleSchema = external_exports.discriminatedUnion("kind", [
|
|
22374
|
+
policyRuleBaseSchema.extend({ kind: external_exports.literal("TOOL_CALL"), config: toolCallPolicyConfigSchema }),
|
|
22375
|
+
policyRuleBaseSchema.extend({ kind: external_exports.literal("SPEND_CAP"), config: spendCapPolicyConfigSchema }),
|
|
22376
|
+
policyRuleBaseSchema.extend({ kind: external_exports.literal("CALL_COUNT"), config: callCountPolicyConfigSchema }),
|
|
22377
|
+
policyRuleBaseSchema.extend({ kind: external_exports.literal("CAPABILITY"), config: capabilityPolicyConfigSchema })
|
|
22378
|
+
]);
|
|
22379
|
+
var policyRulePatchSchema = external_exports.object({
|
|
22380
|
+
name: external_exports.string().min(1).max(128).optional(),
|
|
22381
|
+
enabled: external_exports.boolean().optional(),
|
|
22382
|
+
position: external_exports.number().int().min(0).max(9999).optional(),
|
|
22383
|
+
config: external_exports.union([
|
|
22384
|
+
toolCallPolicyConfigSchema,
|
|
22385
|
+
spendCapPolicyConfigSchema,
|
|
22386
|
+
callCountPolicyConfigSchema,
|
|
22387
|
+
capabilityPolicyConfigSchema
|
|
22388
|
+
]).optional()
|
|
22389
|
+
});
|
|
21570
22390
|
var packagesSchema = external_exports.object({
|
|
21571
22391
|
apt: external_exports.array(packageNameSchema).max(32).default([]),
|
|
21572
22392
|
pip: external_exports.array(packageNameSchema).max(32).default([]),
|
|
@@ -21602,6 +22422,11 @@ var dataSchema = external_exports.object({
|
|
|
21602
22422
|
}
|
|
21603
22423
|
})
|
|
21604
22424
|
});
|
|
22425
|
+
var capabilityPoliciesSchema = external_exports.record(
|
|
22426
|
+
capabilityIdInputSchema,
|
|
22427
|
+
capabilityPermissionPolicySchema
|
|
22428
|
+
);
|
|
22429
|
+
var nativeToolPolicySchema = external_exports.enum(["always_allow", "always_ask"]);
|
|
21605
22430
|
var publishSchema = external_exports.object({
|
|
21606
22431
|
name: external_exports.string().trim().min(1, "Give your agent a name."),
|
|
21607
22432
|
description: external_exports.string().default(""),
|
|
@@ -21610,7 +22435,9 @@ var publishSchema = external_exports.object({
|
|
|
21610
22435
|
instructions: external_exports.array(instructionFileSchema),
|
|
21611
22436
|
skills: external_exports.array(skillRefSchema),
|
|
21612
22437
|
customData: external_exports.array(customDataSchema),
|
|
21613
|
-
capabilities: capabilitiesSchema
|
|
22438
|
+
capabilities: capabilitiesSchema,
|
|
22439
|
+
/** Platform-owned capability permission-policy map. Absent keys default to always_allow. */
|
|
22440
|
+
capabilityPolicies: capabilityPoliciesSchema.optional()
|
|
21614
22441
|
}).refine((v) => isCompatible(v.agentType, v.llm), {
|
|
21615
22442
|
path: ["llm"],
|
|
21616
22443
|
message: "This model isn't available for the selected agent type."
|
|
@@ -21624,6 +22451,11 @@ var specPatchSchema = external_exports.object({
|
|
|
21624
22451
|
skills: external_exports.array(skillRefSchema).optional(),
|
|
21625
22452
|
customData: external_exports.array(customDataSchema).optional(),
|
|
21626
22453
|
capabilities: capabilitiesSchema.optional()
|
|
22454
|
+
// capabilityPolicies is intentionally absent: the chat update_spec tool cannot
|
|
22455
|
+
// set it because Guild's applySpecPatch does not persist it (the policy map
|
|
22456
|
+
// lives in a separate AgentSpecPolicyMap table on the asteroids side and is
|
|
22457
|
+
// written exclusively via PATCH /api/v1/agents/:id). Including it here would
|
|
22458
|
+
// create an accept-and-drop field.
|
|
21627
22459
|
}).partial();
|
|
21628
22460
|
|
|
21629
22461
|
export {
|
|
@@ -21637,10 +22469,13 @@ export {
|
|
|
21637
22469
|
isModelEffortSupported,
|
|
21638
22470
|
reasoningEffortDocLine,
|
|
21639
22471
|
sessionResourcesParamSchema,
|
|
22472
|
+
redactLine,
|
|
21640
22473
|
AGENT_TYPES,
|
|
21641
22474
|
supersededBy,
|
|
21642
22475
|
defaultLlm,
|
|
21643
22476
|
modelSubscriptionProviderFor,
|
|
22477
|
+
MODEL_SUBSCRIPTION_PROVIDER_NAME,
|
|
22478
|
+
MODEL_SUBSCRIPTION_PLAN_PHRASE,
|
|
21644
22479
|
capabilitiesSchema,
|
|
21645
22480
|
instructionFileSchema,
|
|
21646
22481
|
skillRefSchema,
|