finitemonkey 0.1.0-next.28 → 0.1.0-next.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.es.md +8 -1
- package/README.md +8 -1
- package/README.pt-BR.md +8 -1
- package/dist/finitemonkey.mjs +848 -304
- package/package.json +1 -1
package/dist/finitemonkey.mjs
CHANGED
|
@@ -40,8 +40,8 @@ var parseJsonObject = (text9) => {
|
|
|
40
40
|
if (!parsed.ok) return parsed;
|
|
41
41
|
return isRecord(parsed.value) ? accept(parsed.value) : reject("expected a JSON object");
|
|
42
42
|
};
|
|
43
|
-
var optionalString = (
|
|
44
|
-
const value =
|
|
43
|
+
var optionalString = (record4, key) => {
|
|
44
|
+
const value = record4[key];
|
|
45
45
|
return typeof value === "string" ? value : void 0;
|
|
46
46
|
};
|
|
47
47
|
|
|
@@ -620,7 +620,7 @@ var GLOBAL_OPTIONS = {
|
|
|
620
620
|
};
|
|
621
621
|
var flag = (values, name) => values[name] === true;
|
|
622
622
|
var looseArgs = (argv) => {
|
|
623
|
-
const { values, positionals } = parseArgs({
|
|
623
|
+
const { values, positionals: positionals2 } = parseArgs({
|
|
624
624
|
args: [...argv],
|
|
625
625
|
options: GLOBAL_OPTIONS,
|
|
626
626
|
strict: false,
|
|
@@ -628,7 +628,7 @@ var looseArgs = (argv) => {
|
|
|
628
628
|
});
|
|
629
629
|
const lang = values.lang;
|
|
630
630
|
return {
|
|
631
|
-
positionals,
|
|
631
|
+
positionals: positionals2,
|
|
632
632
|
json: flag(values, "json"),
|
|
633
633
|
yes: flag(values, "yes"),
|
|
634
634
|
dryRun: flag(values, "dry-run"),
|
|
@@ -637,7 +637,7 @@ var looseArgs = (argv) => {
|
|
|
637
637
|
lang: typeof lang === "string" ? lang : void 0
|
|
638
638
|
};
|
|
639
639
|
};
|
|
640
|
-
var resolveCommand = (registry,
|
|
640
|
+
var resolveCommand = (registry, positionals2) => registry.filter((spec2) => spec2.path.every((part2, index) => positionals2[index] === part2)).reduce(
|
|
641
641
|
(best, spec2) => best === void 0 || spec2.path.length > best.consumed ? { spec: spec2, consumed: spec2.path.length } : best,
|
|
642
642
|
void 0
|
|
643
643
|
);
|
|
@@ -796,20 +796,20 @@ var entryOf = (kind, xy, path) => ({
|
|
|
796
796
|
staged: kind !== "untracked" && !xy.startsWith("."),
|
|
797
797
|
unstaged: kind === "untracked" || xy.charAt(1) !== "."
|
|
798
798
|
});
|
|
799
|
-
var afterFields = (
|
|
799
|
+
var afterFields = (record4, count4) => record4.split(" ").slice(count4).join(" ");
|
|
800
800
|
var parsePorcelainV2 = (stdout) => {
|
|
801
801
|
const records = stdout.split("\0");
|
|
802
802
|
const out = [];
|
|
803
803
|
for (let index = 0; index < records.length; index += 1) {
|
|
804
|
-
const
|
|
805
|
-
const xy =
|
|
806
|
-
if (
|
|
807
|
-
else if (
|
|
808
|
-
out.push(entryOf("changed", xy, afterFields(
|
|
804
|
+
const record4 = records[index] ?? "";
|
|
805
|
+
const xy = record4.split(" ")[1] ?? "..";
|
|
806
|
+
if (record4.startsWith("1 ")) out.push(entryOf("changed", xy, afterFields(record4, PORCELAIN_FIELDS.ordinary)));
|
|
807
|
+
else if (record4.startsWith("2 ")) {
|
|
808
|
+
out.push(entryOf("changed", xy, afterFields(record4, PORCELAIN_FIELDS.renamed)));
|
|
809
809
|
index += 1;
|
|
810
|
-
} else if (
|
|
811
|
-
out.push(entryOf("unmerged", xy, afterFields(
|
|
812
|
-
} else if (
|
|
810
|
+
} else if (record4.startsWith("u ")) {
|
|
811
|
+
out.push(entryOf("unmerged", xy, afterFields(record4, PORCELAIN_FIELDS.unmerged)));
|
|
812
|
+
} else if (record4.startsWith("? ")) out.push(entryOf("untracked", "??", record4.slice(2)));
|
|
813
813
|
}
|
|
814
814
|
return out.filter((entry2) => entry2.path !== "" && !entry2.path.startsWith(STATE_PREFIX));
|
|
815
815
|
};
|
|
@@ -1023,8 +1023,8 @@ var withDeadline = (work, ms, startTimer) => new Promise((resolve2, reject2) =>
|
|
|
1023
1023
|
// src/review/findings.ts
|
|
1024
1024
|
var GROUPS = ["must", "should", "nice"];
|
|
1025
1025
|
var VERDICTS = ["approve", "approve-with-changes", "request-changes"];
|
|
1026
|
-
var text2 = (
|
|
1027
|
-
const value =
|
|
1026
|
+
var text2 = (record4, key) => {
|
|
1027
|
+
const value = record4[key];
|
|
1028
1028
|
return typeof value === "string" ? value.trim() : "";
|
|
1029
1029
|
};
|
|
1030
1030
|
var reproOf = (value) => {
|
|
@@ -1422,11 +1422,11 @@ var parseEntries = (value) => {
|
|
|
1422
1422
|
const entries = value.map(parseEntry);
|
|
1423
1423
|
return entries.every((entry2) => entry2 !== void 0) ? entries : void 0;
|
|
1424
1424
|
};
|
|
1425
|
-
var fromRecord = (
|
|
1426
|
-
const { schema, version, preset, installedAt, updatedAt } =
|
|
1425
|
+
var fromRecord = (record4) => {
|
|
1426
|
+
const { schema, version, preset, installedAt, updatedAt } = record4;
|
|
1427
1427
|
const known2 = PRESETS.find((item2) => item2 === preset);
|
|
1428
|
-
const entries = parseEntries(
|
|
1429
|
-
const createdDirs = strings(
|
|
1428
|
+
const entries = parseEntries(record4["entries"]);
|
|
1429
|
+
const createdDirs = strings(record4["createdDirs"]);
|
|
1430
1430
|
if (schema !== LOCK_SCHEMA) return reject(`schema is not ${LOCK_SCHEMA}`);
|
|
1431
1431
|
if (typeof version !== "string" || typeof installedAt !== "string" || typeof updatedAt !== "string") {
|
|
1432
1432
|
return reject("version, installedAt and updatedAt must be text");
|
|
@@ -1682,7 +1682,7 @@ var GUARD_MODES = ["off", "shadow", "active"];
|
|
|
1682
1682
|
var LEVELS = ["light", "standard", "strict"];
|
|
1683
1683
|
var SEVERITIES = ["low", "medium", "high"];
|
|
1684
1684
|
var DEFAULT_PROMOTE_AFTER = 20;
|
|
1685
|
-
var OPTIONAL_GUARDS = ["prose"];
|
|
1685
|
+
var OPTIONAL_GUARDS = ["prose", "deps"];
|
|
1686
1686
|
var DEFAULT_POLICY = {
|
|
1687
1687
|
exists: false,
|
|
1688
1688
|
level: "standard",
|
|
@@ -1904,10 +1904,10 @@ var renderJson = (value, style) => `${JSON.stringify(value, null, style.indent)}
|
|
|
1904
1904
|
var parseSettings = (text9) => text9 === void 0 || text9.trim() === "" ? { ok: true, value: {} } : parseJsonObject(text9);
|
|
1905
1905
|
var asList = (value) => Array.isArray(value) ? value : [];
|
|
1906
1906
|
var asRecord = (value) => isRecord(value) ? value : {};
|
|
1907
|
-
var setKey = (
|
|
1908
|
-
if (!(key in
|
|
1907
|
+
var setKey = (record4, key, value) => {
|
|
1908
|
+
if (!(key in record4)) return value === void 0 ? record4 : { ...record4, [key]: value };
|
|
1909
1909
|
return Object.fromEntries(
|
|
1910
|
-
Object.entries(
|
|
1910
|
+
Object.entries(record4).flatMap(([name, current2]) => {
|
|
1911
1911
|
if (name !== key) return [[name, current2]];
|
|
1912
1912
|
return value === void 0 ? [] : [[name, value]];
|
|
1913
1913
|
})
|
|
@@ -3697,68 +3697,8 @@ var deadlineFor = (event, raw) => {
|
|
|
3697
3697
|
return EVENT_DEADLINES[event] ?? DEFAULT_HOOK_DEADLINE_MS;
|
|
3698
3698
|
};
|
|
3699
3699
|
|
|
3700
|
-
// src/
|
|
3701
|
-
|
|
3702
|
-
var DEFAULT_GATE_BUDGET_MS = 3e5;
|
|
3703
|
-
var sessionCwd = (input) => input.payload.cwd === void 0 ? input.cwd : toAbsolutePath(input.payload.cwd, input.cwd);
|
|
3704
|
-
var MAX_DEPTH = 64;
|
|
3705
|
-
var findRepoRoot = (runtime, start) => {
|
|
3706
|
-
let current2 = start;
|
|
3707
|
-
for (let depth = 0; depth < MAX_DEPTH; depth += 1) {
|
|
3708
|
-
if (runtime.stat(toAbsolutePath(join13(current2, ".git"))) !== void 0) return current2;
|
|
3709
|
-
const parent = toAbsolutePath(dirname5(current2));
|
|
3710
|
-
if (parent === current2) return void 0;
|
|
3711
|
-
current2 = parent;
|
|
3712
|
-
}
|
|
3713
|
-
return void 0;
|
|
3714
|
-
};
|
|
3715
|
-
var projectPaths = (input) => {
|
|
3716
|
-
const root = findRepoRoot(input.runtime, sessionCwd(input));
|
|
3717
|
-
return root === void 0 ? void 0 : fmPaths(root);
|
|
3718
|
-
};
|
|
3719
|
-
var gateBudget = (input) => {
|
|
3720
|
-
const parsed = Number.parseInt(input.env["FINITEMONKEY_GATE_BUDGET_MS"] ?? "", 10);
|
|
3721
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_GATE_BUDGET_MS;
|
|
3722
|
-
};
|
|
3723
|
-
var allowWith = (output) => ({ kind: "allow", output });
|
|
3724
|
-
var contextOutput = (event, additionalContext, systemMessage) => ({
|
|
3725
|
-
hookSpecificOutput: { hookEventName: event, additionalContext },
|
|
3726
|
-
...systemMessage === void 0 ? {} : { systemMessage }
|
|
3727
|
-
});
|
|
3728
|
-
var human = (text9) => `finitemonkey: ${text9}`;
|
|
3729
|
-
|
|
3730
|
-
// src/hooks/fields.ts
|
|
3731
|
-
var textField = (record3, ...names) => {
|
|
3732
|
-
for (const name of names) {
|
|
3733
|
-
const value = record3[name];
|
|
3734
|
-
if (typeof value === "string") return value;
|
|
3735
|
-
}
|
|
3736
|
-
return void 0;
|
|
3737
|
-
};
|
|
3738
|
-
var toolName = (raw) => textField(raw, "tool_name") ?? "";
|
|
3739
|
-
var toolInput = (raw) => {
|
|
3740
|
-
const value = raw["tool_input"];
|
|
3741
|
-
return isRecord(value) ? value : {};
|
|
3742
|
-
};
|
|
3743
|
-
var editsOf = (input) => {
|
|
3744
|
-
const single2 = textField(input, "old_string");
|
|
3745
|
-
const replacement = textField(input, "new_string");
|
|
3746
|
-
if (single2 !== void 0 && replacement !== void 0) {
|
|
3747
|
-
return [{ oldText: single2, newText: replacement, all: input["replace_all"] === true }];
|
|
3748
|
-
}
|
|
3749
|
-
const edits = input["edits"];
|
|
3750
|
-
if (!Array.isArray(edits)) return [];
|
|
3751
|
-
return edits.flatMap((edit) => {
|
|
3752
|
-
if (!isRecord(edit)) return [];
|
|
3753
|
-
const oldText = textField(edit, "old_string");
|
|
3754
|
-
const newText = textField(edit, "new_string");
|
|
3755
|
-
return oldText === void 0 || newText === void 0 ? [] : [{ oldText, newText, all: edit["replace_all"] === true }];
|
|
3756
|
-
});
|
|
3757
|
-
};
|
|
3758
|
-
var applyEdits = (before, edits) => edits.reduce(
|
|
3759
|
-
(text9, edit) => edit.all ? text9.split(edit.oldText).join(edit.newText) : text9.replace(edit.oldText, () => edit.newText),
|
|
3760
|
-
before
|
|
3761
|
-
);
|
|
3700
|
+
// src/core/clock.ts
|
|
3701
|
+
var nowMs = (runtime) => Date.parse(runtime.now());
|
|
3762
3702
|
|
|
3763
3703
|
// src/hooks/reason.ts
|
|
3764
3704
|
var REASON_LIMIT = 1e4;
|
|
@@ -3791,9 +3731,6 @@ var modelReason = (t, base, params2 = {}) => {
|
|
|
3791
3731
|
);
|
|
3792
3732
|
};
|
|
3793
3733
|
|
|
3794
|
-
// src/core/clock.ts
|
|
3795
|
-
var nowMs = (runtime) => Date.parse(runtime.now());
|
|
3796
|
-
|
|
3797
3734
|
// src/task/state.ts
|
|
3798
3735
|
var toCounter = (value) => {
|
|
3799
3736
|
if (!isRecord(value)) return void 0;
|
|
@@ -3856,8 +3793,8 @@ var closeTask = (state, id) => assemble({
|
|
|
3856
3793
|
|
|
3857
3794
|
// src/guards/release/grants.ts
|
|
3858
3795
|
var GRANT_MINUTES = 30;
|
|
3859
|
-
var text3 = (
|
|
3860
|
-
const value =
|
|
3796
|
+
var text3 = (record4, key) => {
|
|
3797
|
+
const value = record4[key];
|
|
3861
3798
|
return typeof value === "string" ? value : void 0;
|
|
3862
3799
|
};
|
|
3863
3800
|
var toGrant = (value) => {
|
|
@@ -3915,6 +3852,47 @@ var deny = (fullReason, humanText) => {
|
|
|
3915
3852
|
var FILE_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit", "MultiEdit", "NotebookEdit"]);
|
|
3916
3853
|
var SHELL_TOOLS = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
|
|
3917
3854
|
|
|
3855
|
+
// src/secrets/guards/tool-input.ts
|
|
3856
|
+
var toolName = (payload) => optionalString(payload.raw, "tool_name") ?? "";
|
|
3857
|
+
var toolInput = (payload) => {
|
|
3858
|
+
const input = payload.raw["tool_input"];
|
|
3859
|
+
return isRecord(input) ? input : {};
|
|
3860
|
+
};
|
|
3861
|
+
var editTexts = (input, file) => {
|
|
3862
|
+
const edits = input["edits"];
|
|
3863
|
+
if (!Array.isArray(edits)) return [];
|
|
3864
|
+
return edits.flatMap((edit) => {
|
|
3865
|
+
if (!isRecord(edit)) return [];
|
|
3866
|
+
const text9 = optionalString(edit, "new_string");
|
|
3867
|
+
return text9 === void 0 ? [] : [{ file, text: text9, whole: false }];
|
|
3868
|
+
});
|
|
3869
|
+
};
|
|
3870
|
+
var writtenTexts = (tool, input) => {
|
|
3871
|
+
const file = optionalString(input, "file_path") ?? optionalString(input, "notebook_path") ?? "";
|
|
3872
|
+
const single2 = (key, whole) => {
|
|
3873
|
+
const text9 = optionalString(input, key);
|
|
3874
|
+
return text9 === void 0 ? [] : [{ file, text: text9, whole }];
|
|
3875
|
+
};
|
|
3876
|
+
switch (tool) {
|
|
3877
|
+
case "Write":
|
|
3878
|
+
return single2("content", true);
|
|
3879
|
+
case "Edit":
|
|
3880
|
+
return single2("new_string", false);
|
|
3881
|
+
case "MultiEdit":
|
|
3882
|
+
return editTexts(input, file);
|
|
3883
|
+
case "NotebookEdit":
|
|
3884
|
+
return single2("new_source", false);
|
|
3885
|
+
default:
|
|
3886
|
+
return [];
|
|
3887
|
+
}
|
|
3888
|
+
};
|
|
3889
|
+
var stringLeaves = (value, out = []) => {
|
|
3890
|
+
if (typeof value === "string") out.push(value);
|
|
3891
|
+
else if (Array.isArray(value)) for (const item2 of value) stringLeaves(item2, out);
|
|
3892
|
+
else if (isRecord(value)) for (const item2 of Object.values(value)) stringLeaves(item2, out);
|
|
3893
|
+
return out;
|
|
3894
|
+
};
|
|
3895
|
+
|
|
3918
3896
|
// src/shell/normalize.ts
|
|
3919
3897
|
import { posix } from "node:path";
|
|
3920
3898
|
|
|
@@ -4322,9 +4300,9 @@ var ALIASES = {
|
|
|
4322
4300
|
var powershellProgram = (name) => ALIASES[name.toLowerCase()] ?? name.toLowerCase();
|
|
4323
4301
|
|
|
4324
4302
|
// src/shell/wrappers.ts
|
|
4325
|
-
var spec = (withValue,
|
|
4303
|
+
var spec = (withValue, positionals2 = 0, queries = []) => ({
|
|
4326
4304
|
withValue: new Set(withValue),
|
|
4327
|
-
positionals,
|
|
4305
|
+
positionals: positionals2,
|
|
4328
4306
|
queries: new Set(queries)
|
|
4329
4307
|
});
|
|
4330
4308
|
var WRAPPERS = {
|
|
@@ -4494,7 +4472,7 @@ var unwrap = (initial, stdin) => {
|
|
|
4494
4472
|
};
|
|
4495
4473
|
|
|
4496
4474
|
// src/shell/normalize.ts
|
|
4497
|
-
var
|
|
4475
|
+
var MAX_DEPTH = 8;
|
|
4498
4476
|
var ASSIGNMENT2 = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/s;
|
|
4499
4477
|
var PS_ENV = /^\$env:([A-Za-z_][A-Za-z0-9_]*)=?(.*)$/is;
|
|
4500
4478
|
var CHANGES_DIR = /* @__PURE__ */ new Set(["cd", "pushd", "set-location", "push-location"]);
|
|
@@ -4570,7 +4548,7 @@ var visit = (raw, language, context, depth, collector) => {
|
|
|
4570
4548
|
for (const extra of result.extra) emit(extra, raw, language, context, collector);
|
|
4571
4549
|
};
|
|
4572
4550
|
var collect = (text9, language, context, depth, collector) => {
|
|
4573
|
-
if (depth >
|
|
4551
|
+
if (depth > MAX_DEPTH) {
|
|
4574
4552
|
collector.incomplete = true;
|
|
4575
4553
|
return;
|
|
4576
4554
|
}
|
|
@@ -4593,6 +4571,572 @@ var segmentsOf = (command) => normalizeCommand(command).commands.map((item2) =>
|
|
|
4593
4571
|
redirectedFrom: item2.redirects.filter((redirect) => redirect.op === "<").map((redirect) => redirect.target)
|
|
4594
4572
|
}));
|
|
4595
4573
|
|
|
4574
|
+
// src/deps/popular.ts
|
|
4575
|
+
var NPM = [
|
|
4576
|
+
"react",
|
|
4577
|
+
"react-dom",
|
|
4578
|
+
"preact",
|
|
4579
|
+
"next",
|
|
4580
|
+
"vue",
|
|
4581
|
+
"svelte",
|
|
4582
|
+
"angular",
|
|
4583
|
+
"express",
|
|
4584
|
+
"fastify",
|
|
4585
|
+
"koa",
|
|
4586
|
+
"lodash",
|
|
4587
|
+
"underscore",
|
|
4588
|
+
"axios",
|
|
4589
|
+
"request",
|
|
4590
|
+
"chalk",
|
|
4591
|
+
"commander",
|
|
4592
|
+
"yargs",
|
|
4593
|
+
"debug",
|
|
4594
|
+
"dotenv",
|
|
4595
|
+
"moment",
|
|
4596
|
+
"dayjs",
|
|
4597
|
+
"date-fns",
|
|
4598
|
+
"uuid",
|
|
4599
|
+
"nanoid",
|
|
4600
|
+
"zod",
|
|
4601
|
+
"yup",
|
|
4602
|
+
"joi",
|
|
4603
|
+
"typescript",
|
|
4604
|
+
"eslint",
|
|
4605
|
+
"prettier",
|
|
4606
|
+
"webpack",
|
|
4607
|
+
"vite",
|
|
4608
|
+
"rollup",
|
|
4609
|
+
"esbuild",
|
|
4610
|
+
"babel-core",
|
|
4611
|
+
"jest",
|
|
4612
|
+
"mocha",
|
|
4613
|
+
"vitest",
|
|
4614
|
+
"chai",
|
|
4615
|
+
"sinon",
|
|
4616
|
+
"cross-env",
|
|
4617
|
+
"rimraf",
|
|
4618
|
+
"glob",
|
|
4619
|
+
"minimist",
|
|
4620
|
+
"semver",
|
|
4621
|
+
"async",
|
|
4622
|
+
"bluebird",
|
|
4623
|
+
"classnames",
|
|
4624
|
+
"jquery",
|
|
4625
|
+
"redux",
|
|
4626
|
+
"mobx",
|
|
4627
|
+
"graphql",
|
|
4628
|
+
"mongoose",
|
|
4629
|
+
"sequelize",
|
|
4630
|
+
"prisma",
|
|
4631
|
+
"drizzle-orm",
|
|
4632
|
+
"pg",
|
|
4633
|
+
"mysql",
|
|
4634
|
+
"mysql2",
|
|
4635
|
+
"redis",
|
|
4636
|
+
"ioredis",
|
|
4637
|
+
"socket.io",
|
|
4638
|
+
"ws",
|
|
4639
|
+
"jsonwebtoken",
|
|
4640
|
+
"bcrypt",
|
|
4641
|
+
"bcryptjs",
|
|
4642
|
+
"passport",
|
|
4643
|
+
"cors",
|
|
4644
|
+
"helmet",
|
|
4645
|
+
"body-parser",
|
|
4646
|
+
"cookie-parser",
|
|
4647
|
+
"multer",
|
|
4648
|
+
"nodemon",
|
|
4649
|
+
"tailwindcss",
|
|
4650
|
+
"postcss",
|
|
4651
|
+
"autoprefixer",
|
|
4652
|
+
"sass",
|
|
4653
|
+
"styled-components",
|
|
4654
|
+
"openai",
|
|
4655
|
+
"stripe",
|
|
4656
|
+
"puppeteer",
|
|
4657
|
+
"playwright",
|
|
4658
|
+
"cheerio",
|
|
4659
|
+
"node-fetch",
|
|
4660
|
+
"form-data",
|
|
4661
|
+
"colors",
|
|
4662
|
+
"inquirer",
|
|
4663
|
+
"ora",
|
|
4664
|
+
"execa",
|
|
4665
|
+
"fs-extra",
|
|
4666
|
+
"tslib",
|
|
4667
|
+
"core-js",
|
|
4668
|
+
"rxjs",
|
|
4669
|
+
"electron",
|
|
4670
|
+
"three",
|
|
4671
|
+
"d3",
|
|
4672
|
+
"socket.io-client"
|
|
4673
|
+
];
|
|
4674
|
+
var PYPI = [
|
|
4675
|
+
"requests",
|
|
4676
|
+
"numpy",
|
|
4677
|
+
"pandas",
|
|
4678
|
+
"django",
|
|
4679
|
+
"flask",
|
|
4680
|
+
"fastapi",
|
|
4681
|
+
"uvicorn",
|
|
4682
|
+
"pydantic",
|
|
4683
|
+
"sqlalchemy",
|
|
4684
|
+
"alembic",
|
|
4685
|
+
"celery",
|
|
4686
|
+
"redis",
|
|
4687
|
+
"boto3",
|
|
4688
|
+
"botocore",
|
|
4689
|
+
"urllib3",
|
|
4690
|
+
"certifi",
|
|
4691
|
+
"setuptools",
|
|
4692
|
+
"wheel",
|
|
4693
|
+
"pip",
|
|
4694
|
+
"six",
|
|
4695
|
+
"python-dateutil",
|
|
4696
|
+
"pytz",
|
|
4697
|
+
"pyyaml",
|
|
4698
|
+
"jinja2",
|
|
4699
|
+
"click",
|
|
4700
|
+
"rich",
|
|
4701
|
+
"typer",
|
|
4702
|
+
"httpx",
|
|
4703
|
+
"aiohttp",
|
|
4704
|
+
"beautifulsoup4",
|
|
4705
|
+
"lxml",
|
|
4706
|
+
"scipy",
|
|
4707
|
+
"matplotlib",
|
|
4708
|
+
"seaborn",
|
|
4709
|
+
"scikit-learn",
|
|
4710
|
+
"tensorflow",
|
|
4711
|
+
"torch",
|
|
4712
|
+
"keras",
|
|
4713
|
+
"transformers",
|
|
4714
|
+
"openai",
|
|
4715
|
+
"anthropic",
|
|
4716
|
+
"langchain",
|
|
4717
|
+
"pillow",
|
|
4718
|
+
"opencv-python",
|
|
4719
|
+
"psycopg2",
|
|
4720
|
+
"psycopg2-binary",
|
|
4721
|
+
"pymongo",
|
|
4722
|
+
"pytest",
|
|
4723
|
+
"black",
|
|
4724
|
+
"flake8",
|
|
4725
|
+
"mypy",
|
|
4726
|
+
"ruff",
|
|
4727
|
+
"cryptography",
|
|
4728
|
+
"pyjwt",
|
|
4729
|
+
"paramiko",
|
|
4730
|
+
"selenium",
|
|
4731
|
+
"colorama",
|
|
4732
|
+
"tqdm",
|
|
4733
|
+
"python-dotenv",
|
|
4734
|
+
"gunicorn"
|
|
4735
|
+
];
|
|
4736
|
+
var POPULAR = { npm: NPM, pypi: PYPI };
|
|
4737
|
+
var distance = (left, right) => {
|
|
4738
|
+
const rows = Array.from(
|
|
4739
|
+
{ length: left.length + 1 },
|
|
4740
|
+
(_, row) => Array.from({ length: right.length + 1 }, (_2, column) => row === 0 ? column : column === 0 ? row : 0)
|
|
4741
|
+
);
|
|
4742
|
+
const cell = (row, column) => rows[row]?.[column] ?? Number.POSITIVE_INFINITY;
|
|
4743
|
+
for (let row = 1; row <= left.length; row += 1) {
|
|
4744
|
+
const current2 = rows[row] ?? [];
|
|
4745
|
+
for (let column = 1; column <= right.length; column += 1) {
|
|
4746
|
+
const cost = left[row - 1] === right[column - 1] ? 0 : 1;
|
|
4747
|
+
let best = Math.min(cell(row - 1, column) + 1, cell(row, column - 1) + 1, cell(row - 1, column - 1) + cost);
|
|
4748
|
+
const swapped = left[row - 1] === right[column - 2] && left[row - 2] === right[column - 1];
|
|
4749
|
+
if (row > 1 && column > 1 && swapped) best = Math.min(best, cell(row - 2, column - 2) + 1);
|
|
4750
|
+
current2[column] = best;
|
|
4751
|
+
}
|
|
4752
|
+
}
|
|
4753
|
+
return cell(left.length, right.length);
|
|
4754
|
+
};
|
|
4755
|
+
var squash2 = (name) => name.replace(/^@[^/]+\//, "").replace(/[-_.]/g, "");
|
|
4756
|
+
var closePopular = (ecosystem, name) => {
|
|
4757
|
+
const list4 = POPULAR[ecosystem];
|
|
4758
|
+
if (list4.includes(name)) return void 0;
|
|
4759
|
+
const limit = name.length <= 4 ? 0 : name.length <= 8 ? 1 : 2;
|
|
4760
|
+
return list4.find((popular) => {
|
|
4761
|
+
if (squash2(popular) === squash2(name)) return true;
|
|
4762
|
+
return Math.abs(popular.length - name.length) <= limit && distance(popular, name) <= limit;
|
|
4763
|
+
});
|
|
4764
|
+
};
|
|
4765
|
+
|
|
4766
|
+
// src/deps/assess.ts
|
|
4767
|
+
var MIN_HISTORY_DAYS = 30;
|
|
4768
|
+
var MIN_VERSION_AGE_DAYS = 3;
|
|
4769
|
+
var DAY_MS2 = 864e5;
|
|
4770
|
+
var HOUR_MS = 36e5;
|
|
4771
|
+
var registryFindings = (pkg, lookup2, nowMs2) => {
|
|
4772
|
+
if (lookup2.kind === "missing") return [{ kind: "missing", name: pkg.name, ecosystem: pkg.ecosystem }];
|
|
4773
|
+
if (lookup2.kind === "unreachable") return [{ kind: "unchecked", name: pkg.name, ecosystem: pkg.ecosystem }];
|
|
4774
|
+
const { facts } = lookup2;
|
|
4775
|
+
const out = [];
|
|
4776
|
+
if (facts.createdMs !== void 0 && nowMs2 - facts.createdMs < MIN_HISTORY_DAYS * DAY_MS2) {
|
|
4777
|
+
const days = Math.max(0, Math.floor((nowMs2 - facts.createdMs) / DAY_MS2));
|
|
4778
|
+
out.push({ kind: "young", name: pkg.name, days, count: facts.versionCount });
|
|
4779
|
+
}
|
|
4780
|
+
const { version, versionMs } = facts;
|
|
4781
|
+
if (version !== void 0 && versionMs !== void 0 && nowMs2 - versionMs < MIN_VERSION_AGE_DAYS * DAY_MS2) {
|
|
4782
|
+
out.push({ kind: "fresh", name: pkg.name, version, hours: Math.max(0, Math.floor((nowMs2 - versionMs) / HOUR_MS)) });
|
|
4783
|
+
}
|
|
4784
|
+
if (version !== void 0 && facts.installScript && !facts.previousInstallScript) {
|
|
4785
|
+
out.push({ kind: "script", name: pkg.name, version });
|
|
4786
|
+
}
|
|
4787
|
+
return out;
|
|
4788
|
+
};
|
|
4789
|
+
var assessPackage = (pkg, lookup2, nowMs2) => {
|
|
4790
|
+
const popular = closePopular(pkg.ecosystem, pkg.name);
|
|
4791
|
+
const typo = popular === void 0 ? [] : [{ kind: "typo", name: pkg.name, popular }];
|
|
4792
|
+
return [...typo, ...registryFindings(pkg, lookup2, nowMs2)];
|
|
4793
|
+
};
|
|
4794
|
+
|
|
4795
|
+
// src/deps/install-command.ts
|
|
4796
|
+
var NPM_ADD = {
|
|
4797
|
+
npm: /* @__PURE__ */ new Set(["i", "install", "add", "in", "ins", "inst", "insta", "instal", "isnt", "isntall"]),
|
|
4798
|
+
pnpm: /* @__PURE__ */ new Set(["add"]),
|
|
4799
|
+
yarn: /* @__PURE__ */ new Set(["add"]),
|
|
4800
|
+
bun: /* @__PURE__ */ new Set(["add", "a", "i", "install"])
|
|
4801
|
+
};
|
|
4802
|
+
var NPM_VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
4803
|
+
"--tag",
|
|
4804
|
+
"--registry",
|
|
4805
|
+
"--prefix",
|
|
4806
|
+
"-w",
|
|
4807
|
+
"--workspace",
|
|
4808
|
+
"--filter",
|
|
4809
|
+
"--cwd",
|
|
4810
|
+
"--omit"
|
|
4811
|
+
]);
|
|
4812
|
+
var PIP_VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
4813
|
+
"-r",
|
|
4814
|
+
"--requirement",
|
|
4815
|
+
"-c",
|
|
4816
|
+
"--constraint",
|
|
4817
|
+
"-e",
|
|
4818
|
+
"--editable",
|
|
4819
|
+
"-i",
|
|
4820
|
+
"--index-url",
|
|
4821
|
+
"--extra-index-url",
|
|
4822
|
+
"-t",
|
|
4823
|
+
"--target",
|
|
4824
|
+
"--prefix",
|
|
4825
|
+
"-f",
|
|
4826
|
+
"--find-links",
|
|
4827
|
+
"--python",
|
|
4828
|
+
"-p",
|
|
4829
|
+
"--group",
|
|
4830
|
+
"--optional",
|
|
4831
|
+
"--extra",
|
|
4832
|
+
"--index",
|
|
4833
|
+
"--default-index",
|
|
4834
|
+
"--package",
|
|
4835
|
+
"--directory",
|
|
4836
|
+
"--project"
|
|
4837
|
+
]);
|
|
4838
|
+
var PYTHONS = /^(?:python(?:3(?:\.\d+)?)?|py)$/;
|
|
4839
|
+
var pipArgs = (command) => {
|
|
4840
|
+
const { program, args: args2 } = command;
|
|
4841
|
+
if ((program === "pip" || program === "pip3") && args2[0] === "install") return args2.slice(1);
|
|
4842
|
+
if (PYTHONS.test(program) && args2[0] === "-m" && (args2[1] === "pip" || args2[1] === "pip3") && args2[2] === "install")
|
|
4843
|
+
return args2.slice(3);
|
|
4844
|
+
if (program === "uv" && args2[0] === "add") return args2.slice(1);
|
|
4845
|
+
if (program === "uv" && args2[0] === "pip" && args2[1] === "install") return args2.slice(2);
|
|
4846
|
+
return void 0;
|
|
4847
|
+
};
|
|
4848
|
+
var installerOf = (command) => {
|
|
4849
|
+
const adds = NPM_ADD[command.program];
|
|
4850
|
+
const [verb, ...rest] = command.args;
|
|
4851
|
+
if (adds !== void 0 && verb !== void 0 && adds.has(verb))
|
|
4852
|
+
return { ecosystem: "npm", tool: command.program, args: rest };
|
|
4853
|
+
const pip = pipArgs(command);
|
|
4854
|
+
return pip === void 0 ? void 0 : { ecosystem: "pypi", tool: command.program, args: pip };
|
|
4855
|
+
};
|
|
4856
|
+
var positionals = (args2, valueFlags) => {
|
|
4857
|
+
const out = [];
|
|
4858
|
+
for (let index = 0; index < args2.length; index += 1) {
|
|
4859
|
+
const arg = args2[index] ?? "";
|
|
4860
|
+
if (arg.startsWith("-")) {
|
|
4861
|
+
if (valueFlags.has(arg)) index += 1;
|
|
4862
|
+
continue;
|
|
4863
|
+
}
|
|
4864
|
+
out.push(arg);
|
|
4865
|
+
}
|
|
4866
|
+
return out;
|
|
4867
|
+
};
|
|
4868
|
+
var NPM_NAME = /^(@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/;
|
|
4869
|
+
var NOT_REGISTRY = /^(?:\.|\/|~|file:|link:|git|https?:|npm:|workspace:|github:)|\.tgz$/;
|
|
4870
|
+
var npmSpec = (word2) => {
|
|
4871
|
+
if (NOT_REGISTRY.test(word2)) return void 0;
|
|
4872
|
+
const at = word2.indexOf("@", 1);
|
|
4873
|
+
const name = at === -1 ? word2 : word2.slice(0, at);
|
|
4874
|
+
const version = at === -1 ? void 0 : word2.slice(at + 1);
|
|
4875
|
+
if (!NPM_NAME.test(name) || version?.includes(":") === true) return void 0;
|
|
4876
|
+
return { name, version: version === "" ? void 0 : version };
|
|
4877
|
+
};
|
|
4878
|
+
var PYPI_SPEC = /^([A-Za-z0-9][A-Za-z0-9._-]*)(?:\[[^\]]*\])?\s*(?:(==|===|>=|<=|~=|!=|>|<)\s*([^,;\s]+))?/;
|
|
4879
|
+
var pypiSpec = (word2) => {
|
|
4880
|
+
if (/^(?:\.|\/|~|https?:|git\+|file:)/.test(word2) || /\.(?:whl|tar\.gz|zip)$/.test(word2)) return void 0;
|
|
4881
|
+
const match = PYPI_SPEC.exec(word2);
|
|
4882
|
+
const name = match?.[1];
|
|
4883
|
+
if (match === null || name === void 0 || match[0].length === 0) return void 0;
|
|
4884
|
+
const exact2 = match[2] === "==" || match[2] === "===";
|
|
4885
|
+
return { name: name.toLowerCase().replace(/[._]+/g, "-"), version: exact2 ? match[3] : void 0 };
|
|
4886
|
+
};
|
|
4887
|
+
var requested = (installer) => {
|
|
4888
|
+
const npm = installer.ecosystem === "npm";
|
|
4889
|
+
return positionals(installer.args, npm ? NPM_VALUE_FLAGS : PIP_VALUE_FLAGS).flatMap((word2) => {
|
|
4890
|
+
const spec2 = npm ? npmSpec(word2) : pypiSpec(word2);
|
|
4891
|
+
return spec2 === void 0 ? [] : [{ ...spec2, ecosystem: installer.ecosystem, tool: installer.tool }];
|
|
4892
|
+
});
|
|
4893
|
+
};
|
|
4894
|
+
var packagesInCommand = (text9, dialect = "bash") => normalizeCommand(text9, dialect).commands.flatMap((command) => {
|
|
4895
|
+
const installer = installerOf(command);
|
|
4896
|
+
return installer === void 0 ? [] : requested(installer);
|
|
4897
|
+
});
|
|
4898
|
+
|
|
4899
|
+
// src/deps/registry.ts
|
|
4900
|
+
var REGISTRY_HOSTS = {
|
|
4901
|
+
npm: "registry.npmjs.org",
|
|
4902
|
+
pypi: "pypi.org"
|
|
4903
|
+
};
|
|
4904
|
+
var urlFor = (pkg) => pkg.ecosystem === "npm" ? `https://${REGISTRY_HOSTS.npm}/${pkg.name.replace("/", "%2F")}` : `https://${REGISTRY_HOSTS.pypi}/pypi/${encodeURIComponent(pkg.name)}/json`;
|
|
4905
|
+
var registryRequest = (pkg, cwd, timeoutMs) => ({
|
|
4906
|
+
command: "curl",
|
|
4907
|
+
args: [
|
|
4908
|
+
"--silent",
|
|
4909
|
+
"--show-error",
|
|
4910
|
+
"--location",
|
|
4911
|
+
"--proto",
|
|
4912
|
+
"=https",
|
|
4913
|
+
"--max-time",
|
|
4914
|
+
(Math.max(1, timeoutMs) / 1e3).toFixed(1),
|
|
4915
|
+
"--write-out",
|
|
4916
|
+
"\n%{http_code}",
|
|
4917
|
+
urlFor(pkg)
|
|
4918
|
+
],
|
|
4919
|
+
cwd,
|
|
4920
|
+
timeoutMs: timeoutMs + 500
|
|
4921
|
+
});
|
|
4922
|
+
var timeOf = (value) => {
|
|
4923
|
+
if (typeof value !== "string") return void 0;
|
|
4924
|
+
const parsed = Date.parse(value);
|
|
4925
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
4926
|
+
};
|
|
4927
|
+
var record = (value, key) => {
|
|
4928
|
+
const inner = isRecord(value) ? value[key] : void 0;
|
|
4929
|
+
return isRecord(inner) ? inner : {};
|
|
4930
|
+
};
|
|
4931
|
+
var INSTALL_SCRIPTS = ["preinstall", "install", "postinstall"];
|
|
4932
|
+
var hasInstallScript = (manifest) => {
|
|
4933
|
+
if (manifest["hasInstallScript"] === true) return true;
|
|
4934
|
+
const scripts = record(manifest, "scripts");
|
|
4935
|
+
return INSTALL_SCRIPTS.some((name) => typeof scripts[name] === "string");
|
|
4936
|
+
};
|
|
4937
|
+
var npmFacts = (doc, wanted) => {
|
|
4938
|
+
const times = record(doc, "time");
|
|
4939
|
+
const versions = record(doc, "versions");
|
|
4940
|
+
const tags = record(doc, "dist-tags");
|
|
4941
|
+
const tagged = wanted === void 0 ? tags["latest"] : tags[wanted] ?? wanted;
|
|
4942
|
+
const version = typeof tagged === "string" && tagged in versions ? tagged : void 0;
|
|
4943
|
+
const ordered = Object.keys(versions).sort((left, right) => (timeOf(times[left]) ?? 0) - (timeOf(times[right]) ?? 0));
|
|
4944
|
+
const index = version === void 0 ? -1 : ordered.indexOf(version);
|
|
4945
|
+
const previous = index > 0 ? ordered[index - 1] : void 0;
|
|
4946
|
+
return {
|
|
4947
|
+
createdMs: timeOf(times["created"]),
|
|
4948
|
+
versionCount: ordered.length,
|
|
4949
|
+
version,
|
|
4950
|
+
versionMs: version === void 0 ? void 0 : timeOf(times[version]),
|
|
4951
|
+
installScript: version === void 0 ? false : hasInstallScript(record(versions, version)),
|
|
4952
|
+
previousInstallScript: previous === void 0 ? false : hasInstallScript(record(versions, previous))
|
|
4953
|
+
};
|
|
4954
|
+
};
|
|
4955
|
+
var uploadMs = (files) => {
|
|
4956
|
+
if (!Array.isArray(files)) return void 0;
|
|
4957
|
+
const times = files.flatMap((file) => {
|
|
4958
|
+
const time = isRecord(file) ? timeOf(file["upload_time_iso_8601"] ?? file["upload_time"]) : void 0;
|
|
4959
|
+
return time === void 0 ? [] : [time];
|
|
4960
|
+
});
|
|
4961
|
+
return times.length === 0 ? void 0 : Math.min(...times);
|
|
4962
|
+
};
|
|
4963
|
+
var pypiFacts = (doc, wanted) => {
|
|
4964
|
+
const releases = record(doc, "releases");
|
|
4965
|
+
const latest = record(doc, "info")["version"];
|
|
4966
|
+
const chosen = wanted ?? (typeof latest === "string" ? latest : void 0);
|
|
4967
|
+
const version = chosen !== void 0 && chosen in releases ? chosen : void 0;
|
|
4968
|
+
const uploads = Object.values(releases).flatMap((files) => {
|
|
4969
|
+
const time = uploadMs(files);
|
|
4970
|
+
return time === void 0 ? [] : [time];
|
|
4971
|
+
});
|
|
4972
|
+
return {
|
|
4973
|
+
createdMs: uploads.length === 0 ? void 0 : Math.min(...uploads),
|
|
4974
|
+
versionCount: uploads.length,
|
|
4975
|
+
version,
|
|
4976
|
+
versionMs: version === void 0 ? void 0 : uploadMs(releases[version]),
|
|
4977
|
+
installScript: false,
|
|
4978
|
+
previousInstallScript: false
|
|
4979
|
+
};
|
|
4980
|
+
};
|
|
4981
|
+
var lookupOf = (pkg, result) => {
|
|
4982
|
+
if (!result.found || result.exitCode !== 0) return { kind: "unreachable" };
|
|
4983
|
+
const lines3 = result.stdout.trimEnd().split("\n");
|
|
4984
|
+
const status = Number.parseInt(lines3.at(-1) ?? "", 10);
|
|
4985
|
+
if (status === 404) return { kind: "missing" };
|
|
4986
|
+
if (status < 200 || status >= 300) return { kind: "unreachable" };
|
|
4987
|
+
const doc = parseJsonObject(lines3.slice(0, -1).join("\n"));
|
|
4988
|
+
if (!doc.ok) return { kind: "unreachable" };
|
|
4989
|
+
const facts = pkg.ecosystem === "npm" ? npmFacts(doc.value, pkg.version) : pypiFacts(doc.value, pkg.version);
|
|
4990
|
+
return { kind: "found", facts };
|
|
4991
|
+
};
|
|
4992
|
+
|
|
4993
|
+
// src/deps/guard.ts
|
|
4994
|
+
var NETWORK_BUDGET_MS = 2e3;
|
|
4995
|
+
var MAX_PACKAGES = 5;
|
|
4996
|
+
var MIN_REQUEST_MS = 500;
|
|
4997
|
+
var ALLOW = { kind: "allow" };
|
|
4998
|
+
var NPM_SECTIONS = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
|
|
4999
|
+
var PYTHON_MANIFESTS = ["pyproject.toml", "requirements.txt", "requirements-dev.txt", "Pipfile"];
|
|
5000
|
+
var npmDeclared = (runtime, root) => {
|
|
5001
|
+
const text9 = runtime.readText(toAbsolutePath("package.json", root));
|
|
5002
|
+
const parsed = text9.ok ? parseJsonObject(text9.value) : void 0;
|
|
5003
|
+
if (parsed?.ok !== true) return /* @__PURE__ */ new Set();
|
|
5004
|
+
return new Set(
|
|
5005
|
+
NPM_SECTIONS.flatMap((section2) => {
|
|
5006
|
+
const value = parsed.value[section2];
|
|
5007
|
+
return isRecord(value) ? Object.keys(value) : [];
|
|
5008
|
+
})
|
|
5009
|
+
);
|
|
5010
|
+
};
|
|
5011
|
+
var pythonText = (runtime, root) => PYTHON_MANIFESTS.map((file) => {
|
|
5012
|
+
const text9 = runtime.readText(toAbsolutePath(file, root));
|
|
5013
|
+
return text9.ok ? text9.value.toLowerCase() : "";
|
|
5014
|
+
}).join("\n");
|
|
5015
|
+
var escape = (text9) => text9.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5016
|
+
var newPackages = (input, packages) => {
|
|
5017
|
+
const root = guardRoot(input);
|
|
5018
|
+
const npm = npmDeclared(input.runtime, root);
|
|
5019
|
+
const python = packages.some((pkg) => pkg.ecosystem === "pypi") ? pythonText(input.runtime, root) : "";
|
|
5020
|
+
return packages.filter(
|
|
5021
|
+
(pkg) => pkg.ecosystem === "npm" ? !npm.has(pkg.name) : !new RegExp(`(^|[\\s"'\\[])${escape(pkg.name).replace(/-/g, "[-_.]")}($|[\\s"'=<>~!\\[;,])`, "m").test(python)
|
|
5022
|
+
);
|
|
5023
|
+
};
|
|
5024
|
+
var lookup = (input, pkg, deadline, offline) => {
|
|
5025
|
+
const remaining = deadline - Date.now();
|
|
5026
|
+
if (offline || remaining < MIN_REQUEST_MS) return { kind: "unreachable" };
|
|
5027
|
+
return lookupOf(pkg, input.runtime.exec(registryRequest(pkg, input.cwd, remaining)));
|
|
5028
|
+
};
|
|
5029
|
+
var describe = (t, finding4) => {
|
|
5030
|
+
switch (finding4.kind) {
|
|
5031
|
+
case "missing":
|
|
5032
|
+
return t("deps.finding.missing", { name: finding4.name, registry: REGISTRY_HOSTS[finding4.ecosystem] });
|
|
5033
|
+
case "typo":
|
|
5034
|
+
return t("deps.finding.typo", { name: finding4.name, popular: finding4.popular });
|
|
5035
|
+
case "young":
|
|
5036
|
+
return t("deps.finding.young", { name: finding4.name, days: finding4.days, count: finding4.count });
|
|
5037
|
+
case "fresh":
|
|
5038
|
+
return t("deps.finding.fresh", {
|
|
5039
|
+
name: finding4.name,
|
|
5040
|
+
version: finding4.version,
|
|
5041
|
+
hours: finding4.hours,
|
|
5042
|
+
days: MIN_VERSION_AGE_DAYS
|
|
5043
|
+
});
|
|
5044
|
+
case "script":
|
|
5045
|
+
return t("deps.finding.script", { name: finding4.name, version: finding4.version });
|
|
5046
|
+
case "unchecked":
|
|
5047
|
+
return t("deps.finding.unchecked", { name: finding4.name, registry: REGISTRY_HOSTS[finding4.ecosystem] });
|
|
5048
|
+
}
|
|
5049
|
+
};
|
|
5050
|
+
var isOffline = (env) => {
|
|
5051
|
+
const value = env["FINITEMONKEY_OFFLINE"];
|
|
5052
|
+
return value !== void 0 && value !== "" && value !== "0";
|
|
5053
|
+
};
|
|
5054
|
+
var depsGuard = (input) => {
|
|
5055
|
+
const tool = toolName(input.payload);
|
|
5056
|
+
if (!SHELL_TOOLS.has(tool)) return ALLOW;
|
|
5057
|
+
const command = optionalString(toolInput(input.payload), "command") ?? "";
|
|
5058
|
+
const packages = newPackages(input, packagesInCommand(command, dialectOf(tool))).slice(0, MAX_PACKAGES);
|
|
5059
|
+
if (packages.length === 0) return ALLOW;
|
|
5060
|
+
const deadline = Date.now() + NETWORK_BUDGET_MS;
|
|
5061
|
+
const offline = isOffline(input.env);
|
|
5062
|
+
const now = nowMs(input.runtime);
|
|
5063
|
+
const findings = packages.flatMap((pkg) => assessPackage(pkg, lookup(input, pkg, deadline, offline), now));
|
|
5064
|
+
if (findings.length === 0) return ALLOW;
|
|
5065
|
+
const lines3 = findings.map((finding4) => `- ${describe(input.t, finding4)}`);
|
|
5066
|
+
const additionalContext = `finitemonkey: ${input.t("deps.warn.header")}
|
|
5067
|
+
${lines3.join("\n")}`;
|
|
5068
|
+
return {
|
|
5069
|
+
kind: "allow",
|
|
5070
|
+
output: {
|
|
5071
|
+
hookSpecificOutput: { hookEventName: "PreToolUse", additionalContext },
|
|
5072
|
+
systemMessage: `finitemonkey: ${input.t("deps.warn.human", { count: findings.length })}`
|
|
5073
|
+
}
|
|
5074
|
+
};
|
|
5075
|
+
};
|
|
5076
|
+
|
|
5077
|
+
// src/gate/hooks/common.ts
|
|
5078
|
+
import { dirname as dirname5, join as join13 } from "node:path";
|
|
5079
|
+
var DEFAULT_GATE_BUDGET_MS = 3e5;
|
|
5080
|
+
var sessionCwd = (input) => input.payload.cwd === void 0 ? input.cwd : toAbsolutePath(input.payload.cwd, input.cwd);
|
|
5081
|
+
var MAX_DEPTH2 = 64;
|
|
5082
|
+
var findRepoRoot = (runtime, start) => {
|
|
5083
|
+
let current2 = start;
|
|
5084
|
+
for (let depth = 0; depth < MAX_DEPTH2; depth += 1) {
|
|
5085
|
+
if (runtime.stat(toAbsolutePath(join13(current2, ".git"))) !== void 0) return current2;
|
|
5086
|
+
const parent = toAbsolutePath(dirname5(current2));
|
|
5087
|
+
if (parent === current2) return void 0;
|
|
5088
|
+
current2 = parent;
|
|
5089
|
+
}
|
|
5090
|
+
return void 0;
|
|
5091
|
+
};
|
|
5092
|
+
var projectPaths = (input) => {
|
|
5093
|
+
const root = findRepoRoot(input.runtime, sessionCwd(input));
|
|
5094
|
+
return root === void 0 ? void 0 : fmPaths(root);
|
|
5095
|
+
};
|
|
5096
|
+
var gateBudget = (input) => {
|
|
5097
|
+
const parsed = Number.parseInt(input.env["FINITEMONKEY_GATE_BUDGET_MS"] ?? "", 10);
|
|
5098
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_GATE_BUDGET_MS;
|
|
5099
|
+
};
|
|
5100
|
+
var allowWith = (output) => ({ kind: "allow", output });
|
|
5101
|
+
var contextOutput = (event, additionalContext, systemMessage) => ({
|
|
5102
|
+
hookSpecificOutput: { hookEventName: event, additionalContext },
|
|
5103
|
+
...systemMessage === void 0 ? {} : { systemMessage }
|
|
5104
|
+
});
|
|
5105
|
+
var human = (text9) => `finitemonkey: ${text9}`;
|
|
5106
|
+
|
|
5107
|
+
// src/hooks/fields.ts
|
|
5108
|
+
var textField = (record4, ...names) => {
|
|
5109
|
+
for (const name of names) {
|
|
5110
|
+
const value = record4[name];
|
|
5111
|
+
if (typeof value === "string") return value;
|
|
5112
|
+
}
|
|
5113
|
+
return void 0;
|
|
5114
|
+
};
|
|
5115
|
+
var toolName2 = (raw) => textField(raw, "tool_name") ?? "";
|
|
5116
|
+
var toolInput2 = (raw) => {
|
|
5117
|
+
const value = raw["tool_input"];
|
|
5118
|
+
return isRecord(value) ? value : {};
|
|
5119
|
+
};
|
|
5120
|
+
var editsOf = (input) => {
|
|
5121
|
+
const single2 = textField(input, "old_string");
|
|
5122
|
+
const replacement = textField(input, "new_string");
|
|
5123
|
+
if (single2 !== void 0 && replacement !== void 0) {
|
|
5124
|
+
return [{ oldText: single2, newText: replacement, all: input["replace_all"] === true }];
|
|
5125
|
+
}
|
|
5126
|
+
const edits = input["edits"];
|
|
5127
|
+
if (!Array.isArray(edits)) return [];
|
|
5128
|
+
return edits.flatMap((edit) => {
|
|
5129
|
+
if (!isRecord(edit)) return [];
|
|
5130
|
+
const oldText = textField(edit, "old_string");
|
|
5131
|
+
const newText = textField(edit, "new_string");
|
|
5132
|
+
return oldText === void 0 || newText === void 0 ? [] : [{ oldText, newText, all: edit["replace_all"] === true }];
|
|
5133
|
+
});
|
|
5134
|
+
};
|
|
5135
|
+
var applyEdits = (before, edits) => edits.reduce(
|
|
5136
|
+
(text9, edit) => edit.all ? text9.split(edit.oldText).join(edit.newText) : text9.replace(edit.oldText, () => edit.newText),
|
|
5137
|
+
before
|
|
5138
|
+
);
|
|
5139
|
+
|
|
4596
5140
|
// src/guards/shell.ts
|
|
4597
5141
|
var HEREDOC = /^<<[-<]?$/;
|
|
4598
5142
|
var parseShell = (text9) => normalizeCommand(text9).commands.map((command) => ({
|
|
@@ -4688,8 +5232,8 @@ var detectBypass = (commandLine) => parseShell(commandLine).flatMap((command) =>
|
|
|
4688
5232
|
|
|
4689
5233
|
// src/guards/bypass/hook.ts
|
|
4690
5234
|
var bypassGuard = (input) => {
|
|
4691
|
-
if (!SHELL_TOOLS.has(
|
|
4692
|
-
const command = textField(
|
|
5235
|
+
if (!SHELL_TOOLS.has(toolName2(input.payload.raw))) return { kind: "allow" };
|
|
5236
|
+
const command = textField(toolInput2(input.payload.raw), "command") ?? "";
|
|
4693
5237
|
const findings = detectBypass(command);
|
|
4694
5238
|
const first = findings[0];
|
|
4695
5239
|
if (first === void 0 || grantFor(input, "bypass") !== void 0) return { kind: "allow" };
|
|
@@ -4709,47 +5253,6 @@ var reviewAgentGuard = (input) => {
|
|
|
4709
5253
|
return { kind: "block", reason: input.t("review.guard.read_only", { agent, tool }) };
|
|
4710
5254
|
};
|
|
4711
5255
|
|
|
4712
|
-
// src/secrets/guards/tool-input.ts
|
|
4713
|
-
var toolName2 = (payload) => optionalString(payload.raw, "tool_name") ?? "";
|
|
4714
|
-
var toolInput2 = (payload) => {
|
|
4715
|
-
const input = payload.raw["tool_input"];
|
|
4716
|
-
return isRecord(input) ? input : {};
|
|
4717
|
-
};
|
|
4718
|
-
var editTexts = (input, file) => {
|
|
4719
|
-
const edits = input["edits"];
|
|
4720
|
-
if (!Array.isArray(edits)) return [];
|
|
4721
|
-
return edits.flatMap((edit) => {
|
|
4722
|
-
if (!isRecord(edit)) return [];
|
|
4723
|
-
const text9 = optionalString(edit, "new_string");
|
|
4724
|
-
return text9 === void 0 ? [] : [{ file, text: text9, whole: false }];
|
|
4725
|
-
});
|
|
4726
|
-
};
|
|
4727
|
-
var writtenTexts = (tool, input) => {
|
|
4728
|
-
const file = optionalString(input, "file_path") ?? optionalString(input, "notebook_path") ?? "";
|
|
4729
|
-
const single2 = (key, whole) => {
|
|
4730
|
-
const text9 = optionalString(input, key);
|
|
4731
|
-
return text9 === void 0 ? [] : [{ file, text: text9, whole }];
|
|
4732
|
-
};
|
|
4733
|
-
switch (tool) {
|
|
4734
|
-
case "Write":
|
|
4735
|
-
return single2("content", true);
|
|
4736
|
-
case "Edit":
|
|
4737
|
-
return single2("new_string", false);
|
|
4738
|
-
case "MultiEdit":
|
|
4739
|
-
return editTexts(input, file);
|
|
4740
|
-
case "NotebookEdit":
|
|
4741
|
-
return single2("new_source", false);
|
|
4742
|
-
default:
|
|
4743
|
-
return [];
|
|
4744
|
-
}
|
|
4745
|
-
};
|
|
4746
|
-
var stringLeaves = (value, out = []) => {
|
|
4747
|
-
if (typeof value === "string") out.push(value);
|
|
4748
|
-
else if (Array.isArray(value)) for (const item2 of value) stringLeaves(item2, out);
|
|
4749
|
-
else if (isRecord(value)) for (const item2 of Object.values(value)) stringLeaves(item2, out);
|
|
4750
|
-
return out;
|
|
4751
|
-
};
|
|
4752
|
-
|
|
4753
5256
|
// src/prod/guard.ts
|
|
4754
5257
|
import { join as join15 } from "node:path";
|
|
4755
5258
|
|
|
@@ -5343,7 +5846,7 @@ var toolUseId = (input) => {
|
|
|
5343
5846
|
const id = optionalString(input.payload.raw, "tool_use_id");
|
|
5344
5847
|
return id !== void 0 && /^[A-Za-z0-9_-]{1,120}$/.test(id) ? id : void 0;
|
|
5345
5848
|
};
|
|
5346
|
-
var commandOf = (input) => SHELL_TOOLS.has(
|
|
5849
|
+
var commandOf = (input) => SHELL_TOOLS.has(toolName(input.payload)) ? optionalString(toolInput(input.payload), "command") : void 0;
|
|
5347
5850
|
var checkedPath = (paths, id) => paths.cache(`checked-${id}.json`);
|
|
5348
5851
|
var same = (left, right) => left.trim().replace(/\s+/g, " ") === right.trim().replace(/\s+/g, " ");
|
|
5349
5852
|
var recordChecked = (input) => {
|
|
@@ -5351,7 +5854,7 @@ var recordChecked = (input) => {
|
|
|
5351
5854
|
const command = commandOf(input);
|
|
5352
5855
|
const paths = projectPaths(input);
|
|
5353
5856
|
if (id === void 0 || command === void 0 || paths === void 0) return { kind: "allow" };
|
|
5354
|
-
if (!isSensitiveCommand(command, dialectOf(
|
|
5857
|
+
if (!isSensitiveCommand(command, dialectOf(toolName(input.payload)))) return { kind: "allow" };
|
|
5355
5858
|
input.runtime.writeText(checkedPath(paths, id), `${JSON.stringify({ command })}
|
|
5356
5859
|
`);
|
|
5357
5860
|
return { kind: "allow" };
|
|
@@ -5367,18 +5870,18 @@ var compareRan = (input) => {
|
|
|
5367
5870
|
const checked = parsed.ok ? optionalString(parsed.value, "command") : void 0;
|
|
5368
5871
|
const ran = commandOf(input) ?? "";
|
|
5369
5872
|
if (checked === void 0 || same(checked, ran)) return { kind: "allow" };
|
|
5370
|
-
const
|
|
5371
|
-
tool:
|
|
5873
|
+
const record4 = {
|
|
5874
|
+
tool: toolName(input.payload),
|
|
5372
5875
|
checked: maskText(checked),
|
|
5373
5876
|
ran: maskText(ran),
|
|
5374
5877
|
sessionId: input.payload.sessionId ?? null
|
|
5375
5878
|
};
|
|
5376
|
-
logEvent(input.runtime, paths, "input_rewritten",
|
|
5377
|
-
input.runtime.writeText(paths.cache(REWRITTEN), `${JSON.stringify(
|
|
5879
|
+
logEvent(input.runtime, paths, "input_rewritten", record4);
|
|
5880
|
+
input.runtime.writeText(paths.cache(REWRITTEN), `${JSON.stringify(record4)}
|
|
5378
5881
|
`);
|
|
5379
5882
|
return {
|
|
5380
5883
|
kind: "block",
|
|
5381
|
-
reason: modelReason(input.t, "gate.guard.rewrite", { checked:
|
|
5884
|
+
reason: modelReason(input.t, "gate.guard.rewrite", { checked: record4.checked, ran: record4.ran }),
|
|
5382
5885
|
human: input.t("gate.guard.rewrite.human")
|
|
5383
5886
|
};
|
|
5384
5887
|
};
|
|
@@ -5464,8 +5967,8 @@ var bashSelfTargets = (root, commandLine) => parseShell(commandLine).flatMap(
|
|
|
5464
5967
|
|
|
5465
5968
|
// src/guards/self/hook.ts
|
|
5466
5969
|
var targets = (input) => {
|
|
5467
|
-
const tool =
|
|
5468
|
-
const args2 =
|
|
5970
|
+
const tool = toolName2(input.payload.raw);
|
|
5971
|
+
const args2 = toolInput2(input.payload.raw);
|
|
5469
5972
|
const root = guardRoot(input);
|
|
5470
5973
|
if (FILE_TOOLS.has(tool)) {
|
|
5471
5974
|
const path = textField(args2, "file_path", "notebook_path") ?? "";
|
|
@@ -5664,8 +6167,8 @@ var proposed = (tool, args2, before) => {
|
|
|
5664
6167
|
return before === void 0 ? void 0 : applyEdits(before, editsOf(args2));
|
|
5665
6168
|
};
|
|
5666
6169
|
var fileViolations = (input, root) => {
|
|
5667
|
-
const tool =
|
|
5668
|
-
const args2 =
|
|
6170
|
+
const tool = toolName2(input.payload.raw);
|
|
6171
|
+
const args2 = toolInput2(input.payload.raw);
|
|
5669
6172
|
const file = textField(args2, "file_path") ?? "";
|
|
5670
6173
|
if (tool === "NotebookEdit" || file === "") return [];
|
|
5671
6174
|
const local = localPath(root, file);
|
|
@@ -5678,7 +6181,7 @@ var fileViolations = (input, root) => {
|
|
|
5678
6181
|
return [...compareTestFile(local, before, after), ...compareConfig(local, before, after, accepted2)];
|
|
5679
6182
|
};
|
|
5680
6183
|
var shellViolations = (input, root) => {
|
|
5681
|
-
const command = textField(
|
|
6184
|
+
const command = textField(toolInput2(input.payload.raw), "command") ?? "";
|
|
5682
6185
|
return parseShell(command).flatMap(
|
|
5683
6186
|
(simple) => writtenPaths(simple).flatMap((path) => {
|
|
5684
6187
|
const local = localPath(root, path);
|
|
@@ -5690,7 +6193,7 @@ var shellViolations = (input, root) => {
|
|
|
5690
6193
|
);
|
|
5691
6194
|
};
|
|
5692
6195
|
var testsGuard = (input) => {
|
|
5693
|
-
const tool =
|
|
6196
|
+
const tool = toolName2(input.payload.raw);
|
|
5694
6197
|
const root = guardRoot(input);
|
|
5695
6198
|
const found = FILE_TOOLS.has(tool) ? fileViolations(input, root) : SHELL_TOOLS.has(tool) ? shellViolations(input, root) : [];
|
|
5696
6199
|
const first = found[0];
|
|
@@ -5718,8 +6221,8 @@ var lookCaptureOf = (paths, file) => {
|
|
|
5718
6221
|
return relativePath.startsWith(".finitemonkey/look/") && relativePath.endsWith(".png") ? relativePath : void 0;
|
|
5719
6222
|
};
|
|
5720
6223
|
var lookReadTracker = (input) => {
|
|
5721
|
-
if (
|
|
5722
|
-
const file = textField(
|
|
6224
|
+
if (toolName2(input.payload.raw) !== "Read") return { kind: "allow" };
|
|
6225
|
+
const file = textField(toolInput2(input.payload.raw), "file_path");
|
|
5723
6226
|
const paths = projectPaths(input);
|
|
5724
6227
|
if (file === void 0 || paths === void 0) return { kind: "allow" };
|
|
5725
6228
|
const capture2 = lookCaptureOf(paths, file);
|
|
@@ -6220,8 +6723,8 @@ var TASK_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
|
6220
6723
|
var TASK_SCHEMA = "finitemonkey/task@1";
|
|
6221
6724
|
|
|
6222
6725
|
// src/task/validate.ts
|
|
6223
|
-
var str = (
|
|
6224
|
-
const value =
|
|
6726
|
+
var str = (record4, key, at, issues, required) => {
|
|
6727
|
+
const value = record4[key];
|
|
6225
6728
|
if (value === void 0 || value === null) {
|
|
6226
6729
|
if (required) issues.push(`${at}${key}: required`);
|
|
6227
6730
|
return void 0;
|
|
@@ -6232,8 +6735,8 @@ var str = (record3, key, at, issues, required) => {
|
|
|
6232
6735
|
}
|
|
6233
6736
|
return value;
|
|
6234
6737
|
};
|
|
6235
|
-
var positive2 = (
|
|
6236
|
-
const value =
|
|
6738
|
+
var positive2 = (record4, key, at, issues) => {
|
|
6739
|
+
const value = record4[key];
|
|
6237
6740
|
if (value === void 0 || value === null) return void 0;
|
|
6238
6741
|
if (typeof value === "number" && Number.isInteger(value) && value > 0) return value;
|
|
6239
6742
|
issues.push(`${at}${key}: must be a positive integer`);
|
|
@@ -6252,13 +6755,13 @@ var gitRequire = (value, at, issues) => {
|
|
|
6252
6755
|
if (known2.some((item2) => item2 === void 0)) issues.push(`${at}: use ${GIT_REQUIREMENTS.join(", ")}`);
|
|
6253
6756
|
return known2.filter((item2) => item2 !== void 0);
|
|
6254
6757
|
};
|
|
6255
|
-
var appFields = (
|
|
6256
|
-
const port = positive2(
|
|
6758
|
+
var appFields = (record4, kind, at, issues) => {
|
|
6759
|
+
const port = positive2(record4, "port", at, issues);
|
|
6257
6760
|
if (kind === "runtime" && port === void 0) issues.push(`${at}port: required`);
|
|
6258
6761
|
if (port !== void 0 && port > 65535) issues.push(`${at}port: must be at most 65535`);
|
|
6259
|
-
const status = positive2(
|
|
6260
|
-
const route = str(
|
|
6261
|
-
const body2 = str(
|
|
6762
|
+
const status = positive2(record4, "status", at, issues);
|
|
6763
|
+
const route = str(record4, "route", at, issues, false);
|
|
6764
|
+
const body2 = str(record4, "body", at, issues, false);
|
|
6262
6765
|
return {
|
|
6263
6766
|
...port === void 0 ? {} : { port },
|
|
6264
6767
|
...route === void 0 ? {} : { route },
|
|
@@ -6266,13 +6769,13 @@ var appFields = (record3, kind, at, issues) => {
|
|
|
6266
6769
|
...body2 === void 0 ? {} : { body: body2 }
|
|
6267
6770
|
};
|
|
6268
6771
|
};
|
|
6269
|
-
var checkFields = (
|
|
6270
|
-
const run4 = str(
|
|
6271
|
-
const timeoutS = positive2(
|
|
6272
|
-
const description = str(
|
|
6273
|
-
const require2 = kind === "git" ? gitRequire(
|
|
6274
|
-
const app = appFields(
|
|
6275
|
-
const open =
|
|
6772
|
+
var checkFields = (record4, kind, at, issues) => {
|
|
6773
|
+
const run4 = str(record4, "run", at, issues, kind === "command");
|
|
6774
|
+
const timeoutS = positive2(record4, "timeout_s", at, issues);
|
|
6775
|
+
const description = str(record4, "description", at, issues, kind === "manual");
|
|
6776
|
+
const require2 = kind === "git" ? gitRequire(record4["require"] ?? ["committed"], `${at}require`, issues) : void 0;
|
|
6777
|
+
const app = appFields(record4, kind, at, issues);
|
|
6778
|
+
const open = record4["require_open"];
|
|
6276
6779
|
if (open !== void 0 && typeof open !== "boolean") issues.push(`${at}require_open: must be true or false`);
|
|
6277
6780
|
return {
|
|
6278
6781
|
...run4 === void 0 ? {} : { run: run4 },
|
|
@@ -6571,18 +7074,18 @@ var ciChecks = (value) => Array.isArray(value) ? value.flatMap((item2) => {
|
|
|
6571
7074
|
var parsePrView = (text9) => {
|
|
6572
7075
|
const parsed = parseJsonObject(text9);
|
|
6573
7076
|
if (!parsed.ok) return void 0;
|
|
6574
|
-
const
|
|
6575
|
-
const number2 =
|
|
7077
|
+
const record4 = parsed.value;
|
|
7078
|
+
const number2 = record4["number"];
|
|
6576
7079
|
if (typeof number2 !== "number") return void 0;
|
|
6577
7080
|
return {
|
|
6578
7081
|
number: number2,
|
|
6579
|
-
url: optionalString(
|
|
6580
|
-
state: optionalString(
|
|
6581
|
-
mergeable: optionalString(
|
|
6582
|
-
mergeStateStatus: optionalString(
|
|
6583
|
-
baseRefName: optionalString(
|
|
6584
|
-
headRefOid: optionalString(
|
|
6585
|
-
checks: ciChecks(
|
|
7082
|
+
url: optionalString(record4, "url") ?? "",
|
|
7083
|
+
state: optionalString(record4, "state") ?? "",
|
|
7084
|
+
mergeable: optionalString(record4, "mergeable") ?? "UNKNOWN",
|
|
7085
|
+
mergeStateStatus: optionalString(record4, "mergeStateStatus") ?? "UNKNOWN",
|
|
7086
|
+
baseRefName: optionalString(record4, "baseRefName") ?? "",
|
|
7087
|
+
headRefOid: optionalString(record4, "headRefOid") ?? "",
|
|
7088
|
+
checks: ciChecks(record4["statusCheckRollup"])
|
|
6586
7089
|
};
|
|
6587
7090
|
};
|
|
6588
7091
|
var isConflicting = (pr) => pr.mergeable === "CONFLICTING" || pr.mergeStateStatus === "DIRTY";
|
|
@@ -6643,7 +7146,7 @@ var conflictFiles = (git2, base) => {
|
|
|
6643
7146
|
};
|
|
6644
7147
|
|
|
6645
7148
|
// src/core/glob.ts
|
|
6646
|
-
var
|
|
7149
|
+
var escape2 = (char) => /[.+^${}()|[\]\\]/.test(char) ? `\\${char}` : char;
|
|
6647
7150
|
var globToRegExp = (glob) => {
|
|
6648
7151
|
const pattern = glob.replace(/^\.\//, "");
|
|
6649
7152
|
let out = "";
|
|
@@ -6655,7 +7158,7 @@ var globToRegExp = (glob) => {
|
|
|
6655
7158
|
index += slash ? 2 : 1;
|
|
6656
7159
|
} else if (char === "*") out += "[^/]*";
|
|
6657
7160
|
else if (char === "?") out += "[^/]";
|
|
6658
|
-
else out +=
|
|
7161
|
+
else out += escape2(char);
|
|
6659
7162
|
}
|
|
6660
7163
|
return new RegExp(`^${out}${pattern.endsWith("/") ? ".*" : ""}$`);
|
|
6661
7164
|
};
|
|
@@ -7015,19 +7518,19 @@ var params = (value) => isRecord(value) ? Object.fromEntries(
|
|
|
7015
7518
|
var notes = (value) => Array.isArray(value) ? value.flatMap(
|
|
7016
7519
|
(item2) => isRecord(item2) && typeof item2["key"] === "string" ? [{ key: item2["key"], params: params(item2["params"]) }] : []
|
|
7017
7520
|
) : [];
|
|
7018
|
-
var text4 = (
|
|
7019
|
-
const value =
|
|
7521
|
+
var text4 = (record4, key) => {
|
|
7522
|
+
const value = record4[key];
|
|
7020
7523
|
return typeof value === "string" ? value : void 0;
|
|
7021
7524
|
};
|
|
7022
|
-
var optional = (
|
|
7023
|
-
const exitCode =
|
|
7024
|
-
const durationMs =
|
|
7025
|
-
const command = text4(
|
|
7026
|
-
const stdoutSha256 = text4(
|
|
7027
|
-
const releasedBy = text4(
|
|
7028
|
-
const reason = oneOf2(UNVERIFIED_REASONS,
|
|
7029
|
-
const failures =
|
|
7030
|
-
const testCount =
|
|
7525
|
+
var optional = (record4) => {
|
|
7526
|
+
const exitCode = record4["exitCode"];
|
|
7527
|
+
const durationMs = record4["durationMs"];
|
|
7528
|
+
const command = text4(record4, "command");
|
|
7529
|
+
const stdoutSha256 = text4(record4, "stdoutSha256");
|
|
7530
|
+
const releasedBy = text4(record4, "releasedBy");
|
|
7531
|
+
const reason = oneOf2(UNVERIFIED_REASONS, record4["reason"]);
|
|
7532
|
+
const failures = record4["failures"];
|
|
7533
|
+
const testCount = record4["testCount"];
|
|
7031
7534
|
return {
|
|
7032
7535
|
...command === void 0 ? {} : { command },
|
|
7033
7536
|
...typeof exitCode === "number" || exitCode === null ? { exitCode } : {},
|
|
@@ -7042,14 +7545,14 @@ var optional = (record3) => {
|
|
|
7042
7545
|
var parseEvidence = (line2) => {
|
|
7043
7546
|
const parsed = parseJsonObject(line2);
|
|
7044
7547
|
if (!parsed.ok) return void 0;
|
|
7045
|
-
const
|
|
7046
|
-
const status = oneOf2(EVIDENCE_STATUSES,
|
|
7047
|
-
const task = text4(
|
|
7048
|
-
const check2 = text4(
|
|
7049
|
-
const kind = text4(
|
|
7050
|
-
const treeHash2 = text4(
|
|
7051
|
-
const at = text4(
|
|
7052
|
-
if (
|
|
7548
|
+
const record4 = parsed.value;
|
|
7549
|
+
const status = oneOf2(EVIDENCE_STATUSES, record4["status"]);
|
|
7550
|
+
const task = text4(record4, "task");
|
|
7551
|
+
const check2 = text4(record4, "check");
|
|
7552
|
+
const kind = text4(record4, "kind");
|
|
7553
|
+
const treeHash2 = text4(record4, "treeHash");
|
|
7554
|
+
const at = text4(record4, "at");
|
|
7555
|
+
if (record4["schema"] !== EVIDENCE_SCHEMA || status === void 0) return void 0;
|
|
7053
7556
|
if (task === void 0 || check2 === void 0 || kind === void 0 || treeHash2 === void 0 || at === void 0) {
|
|
7054
7557
|
return void 0;
|
|
7055
7558
|
}
|
|
@@ -7061,8 +7564,8 @@ var parseEvidence = (line2) => {
|
|
|
7061
7564
|
status,
|
|
7062
7565
|
treeHash: treeHash2,
|
|
7063
7566
|
at,
|
|
7064
|
-
notes: notes(
|
|
7065
|
-
...optional(
|
|
7567
|
+
notes: notes(record4["notes"]),
|
|
7568
|
+
...optional(record4)
|
|
7066
7569
|
};
|
|
7067
7570
|
};
|
|
7068
7571
|
var readLedger2 = (runtime, path) => {
|
|
@@ -7774,7 +8277,15 @@ var en_default = {
|
|
|
7774
8277
|
"gate.guard.rewrite.not": "a rewrite that looks equivalent, or running the same command again through the same hook",
|
|
7775
8278
|
"gate.guard.rewrite.human": "Another hook changed a sensitive command after Finite Monkey checked it; both versions are in .finitemonkey/log.jsonl.",
|
|
7776
8279
|
"doctor.hooks.rewriters": "{hooks, plural, one {# other hook sees} other {# other hooks see}} shell commands before they run and can rewrite them ({list}); a sensitive command they change fails the gate",
|
|
7777
|
-
"doctor.hooks.fix_rewriters": "If a hook rewrites commands (updatedInput), make it skip git, rm, ssh, kubectl and .env commands, or remove it"
|
|
8280
|
+
"doctor.hooks.fix_rewriters": "If a hook rewrites commands (updatedInput), make it skip git, rm, ssh, kubectl and .env commands, or remove it",
|
|
8281
|
+
"deps.warn.header": "Check these new packages before installing them (a warning, nothing was blocked):",
|
|
8282
|
+
"deps.warn.human": "{count, plural, one {# warning about a new package} other {# warnings about new packages}}; see the details before installing.",
|
|
8283
|
+
"deps.finding.missing": "{name} does not exist on {registry}; the name may be made up.",
|
|
8284
|
+
"deps.finding.typo": "{name} is one or two letters away from the popular package {popular}; check the spelling.",
|
|
8285
|
+
"deps.finding.young": "{name} has little history: first published {days, plural, one {# day} other {# days}} ago, {count, plural, one {# version} other {# versions}}.",
|
|
8286
|
+
"deps.finding.fresh": "{name}@{version} was published {hours, plural, one {# hour} other {# hours}} ago; prefer a version at least {days, plural, one {# day} other {# days}} old.",
|
|
8287
|
+
"deps.finding.script": "{name}@{version} adds an install script that the previous version did not have; read it before installing.",
|
|
8288
|
+
"deps.finding.unchecked": "{name} was not checked on {registry} (offline or no answer in time), so only the spelling was checked."
|
|
7778
8289
|
};
|
|
7779
8290
|
|
|
7780
8291
|
// src/i18n/es.json
|
|
@@ -8471,7 +8982,15 @@ var es_default = {
|
|
|
8471
8982
|
"gate.guard.rewrite.not": "una reescritura que parece equivalente, o ejecutar el mismo comando otra vez por el mismo hook",
|
|
8472
8983
|
"gate.guard.rewrite.human": "Otro hook cambió un comando sensible después de que Finite Monkey lo revisara; las dos versiones están en .finitemonkey/log.jsonl.",
|
|
8473
8984
|
"doctor.hooks.rewriters": "{hooks, plural, one {# otro hook ve} other {# otros hooks ven}} los comandos de shell antes de ejecutarse y pueden reescribirlos ({list}); un comando sensible que cambien hace fallar la compuerta",
|
|
8474
|
-
"doctor.hooks.fix_rewriters": "Si un hook reescribe comandos (updatedInput), haz que ignore los comandos de git, rm, ssh, kubectl y .env, o quítalo"
|
|
8985
|
+
"doctor.hooks.fix_rewriters": "Si un hook reescribe comandos (updatedInput), haz que ignore los comandos de git, rm, ssh, kubectl y .env, o quítalo",
|
|
8986
|
+
"deps.warn.header": "Revisa estos paquetes nuevos antes de instalarlos (es un aviso, no se bloqueó nada):",
|
|
8987
|
+
"deps.warn.human": "{count, plural, one {# aviso sobre un paquete nuevo} other {# avisos sobre paquetes nuevos}}; mira los detalles antes de instalar.",
|
|
8988
|
+
"deps.finding.missing": "{name} no existe en {registry}; puede que el nombre sea inventado.",
|
|
8989
|
+
"deps.finding.typo": "{name} está a una o dos letras del paquete popular {popular}; revisa cómo se escribe.",
|
|
8990
|
+
"deps.finding.young": "{name} tiene poco historial: se publicó por primera vez hace {days, plural, one {# día} other {# días}}, {count, plural, one {# versión} other {# versiones}}.",
|
|
8991
|
+
"deps.finding.fresh": "{name}@{version} salió hace {hours, plural, one {# hora} other {# horas}}; mejor una versión con al menos {days, plural, one {# día} other {# días}}.",
|
|
8992
|
+
"deps.finding.script": "{name}@{version} trae un script de instalación que la versión anterior no tenía; léelo antes de instalar.",
|
|
8993
|
+
"deps.finding.unchecked": "{name} no se comprobó en {registry} (sin red o sin respuesta a tiempo), así que solo se revisó la ortografía."
|
|
8475
8994
|
};
|
|
8476
8995
|
|
|
8477
8996
|
// src/i18n/pt-BR.json
|
|
@@ -9168,7 +9687,15 @@ var pt_BR_default = {
|
|
|
9168
9687
|
"gate.guard.rewrite.not": "uma reescrita que parece equivalente, ou rodar o mesmo comando de novo pelo mesmo hook",
|
|
9169
9688
|
"gate.guard.rewrite.human": "Outro hook mudou um comando sensível depois que o Finite Monkey o conferiu; as duas versões estão em .finitemonkey/log.jsonl.",
|
|
9170
9689
|
"doctor.hooks.rewriters": "{hooks, plural, one {# outro hook vê} other {# outros hooks veem}} comandos de shell antes de rodarem e podem reescrevê-los ({list}); um comando sensível que eles mudarem reprova o portão",
|
|
9171
|
-
"doctor.hooks.fix_rewriters": "Se um hook reescreve comandos (updatedInput), faça ele pular comandos de git, rm, ssh, kubectl e .env, ou remova o hook"
|
|
9690
|
+
"doctor.hooks.fix_rewriters": "Se um hook reescreve comandos (updatedInput), faça ele pular comandos de git, rm, ssh, kubectl e .env, ou remova o hook",
|
|
9691
|
+
"deps.warn.header": "Confira estes pacotes novos antes de instalar (é um aviso, nada foi bloqueado):",
|
|
9692
|
+
"deps.warn.human": "{count, plural, one {# aviso sobre pacote novo} other {# avisos sobre pacotes novos}}; veja os detalhes antes de instalar.",
|
|
9693
|
+
"deps.finding.missing": "{name} não existe no {registry}; o nome pode ter sido inventado.",
|
|
9694
|
+
"deps.finding.typo": "{name} está a uma ou duas letras do pacote popular {popular}; confira a grafia.",
|
|
9695
|
+
"deps.finding.young": "{name} tem pouco histórico: publicado pela primeira vez há {days, plural, one {# dia} other {# dias}}, {count, plural, one {# versão} other {# versões}}.",
|
|
9696
|
+
"deps.finding.fresh": "{name}@{version} saiu há {hours, plural, one {# hora} other {# horas}}; prefira uma versão com pelo menos {days, plural, one {# dia} other {# dias}}.",
|
|
9697
|
+
"deps.finding.script": "{name}@{version} traz um script de instalação que a versão anterior não tinha; leia antes de instalar.",
|
|
9698
|
+
"deps.finding.unchecked": "{name} não foi conferido no {registry} (sem rede ou sem resposta a tempo), então só a grafia foi checada."
|
|
9172
9699
|
};
|
|
9173
9700
|
|
|
9174
9701
|
// src/i18n/review.json
|
|
@@ -9866,7 +10393,15 @@ var review_default = {
|
|
|
9866
10393
|
"gate.guard.rewrite.not": "machine",
|
|
9867
10394
|
"gate.guard.rewrite.human": "machine",
|
|
9868
10395
|
"doctor.hooks.rewriters": "machine",
|
|
9869
|
-
"doctor.hooks.fix_rewriters": "machine"
|
|
10396
|
+
"doctor.hooks.fix_rewriters": "machine",
|
|
10397
|
+
"deps.warn.header": "machine",
|
|
10398
|
+
"deps.warn.human": "machine",
|
|
10399
|
+
"deps.finding.missing": "machine",
|
|
10400
|
+
"deps.finding.typo": "machine",
|
|
10401
|
+
"deps.finding.young": "machine",
|
|
10402
|
+
"deps.finding.fresh": "machine",
|
|
10403
|
+
"deps.finding.script": "machine",
|
|
10404
|
+
"deps.finding.unchecked": "machine"
|
|
9870
10405
|
},
|
|
9871
10406
|
es: {
|
|
9872
10407
|
"command.init.summary": "machine",
|
|
@@ -10561,7 +11096,15 @@ var review_default = {
|
|
|
10561
11096
|
"gate.guard.rewrite.not": "machine",
|
|
10562
11097
|
"gate.guard.rewrite.human": "machine",
|
|
10563
11098
|
"doctor.hooks.rewriters": "machine",
|
|
10564
|
-
"doctor.hooks.fix_rewriters": "machine"
|
|
11099
|
+
"doctor.hooks.fix_rewriters": "machine",
|
|
11100
|
+
"deps.warn.header": "machine",
|
|
11101
|
+
"deps.warn.human": "machine",
|
|
11102
|
+
"deps.finding.missing": "machine",
|
|
11103
|
+
"deps.finding.typo": "machine",
|
|
11104
|
+
"deps.finding.young": "machine",
|
|
11105
|
+
"deps.finding.fresh": "machine",
|
|
11106
|
+
"deps.finding.script": "machine",
|
|
11107
|
+
"deps.finding.unchecked": "machine"
|
|
10565
11108
|
}
|
|
10566
11109
|
};
|
|
10567
11110
|
|
|
@@ -10845,8 +11388,8 @@ var FLAGGED_EVENT = "callers.flagged";
|
|
|
10845
11388
|
var RELEASED_EVENT = "callers.released";
|
|
10846
11389
|
var MIN_SAMPLE = 20;
|
|
10847
11390
|
var MAX_FALSE_POSITIVE = 0.05;
|
|
10848
|
-
var pairs = (
|
|
10849
|
-
const { task, names } =
|
|
11391
|
+
var pairs = (record4) => {
|
|
11392
|
+
const { task, names } = record4;
|
|
10850
11393
|
if (typeof task !== "string" || !Array.isArray(names)) return [];
|
|
10851
11394
|
return names.filter((name) => typeof name === "string").map((name) => `${task}\0${name}`);
|
|
10852
11395
|
};
|
|
@@ -11063,7 +11606,7 @@ var siteNotes = (open) => [
|
|
|
11063
11606
|
...[...open].map(([name, sites]) => note("gate.callers.open", { name, count: sites.length })),
|
|
11064
11607
|
...[...open.values()].flat().slice(0, MAX_SITES).map((site) => note("gate.callers.at", { name: site.name, file: site.file, line: site.line }))
|
|
11065
11608
|
];
|
|
11066
|
-
var
|
|
11609
|
+
var record2 = (ctx, event, names) => {
|
|
11067
11610
|
if (names.length > 0) logEvent(ctx.runtime, ctx.paths, event, { task: ctx.contract.id, names: [...names] });
|
|
11068
11611
|
};
|
|
11069
11612
|
var callersCheck = (_check, ctx) => {
|
|
@@ -11071,12 +11614,12 @@ var callersCheck = (_check, ctx) => {
|
|
|
11071
11614
|
const grouped = byName(callSites(ctx.runtime, ctx.git, symbols));
|
|
11072
11615
|
const ignore = new Set(ctx.contract.callersIgnore ?? []);
|
|
11073
11616
|
const open = new Map([...grouped].filter(([name]) => !ignore.has(name)));
|
|
11074
|
-
|
|
11617
|
+
record2(
|
|
11075
11618
|
ctx,
|
|
11076
11619
|
RELEASED_EVENT,
|
|
11077
11620
|
[...grouped.keys()].filter((name) => ignore.has(name))
|
|
11078
11621
|
);
|
|
11079
|
-
|
|
11622
|
+
record2(ctx, FLAGGED_EVENT, [...open.keys()]);
|
|
11080
11623
|
if (open.size === 0) return passed([note("gate.callers.none", { count: symbols.length })]);
|
|
11081
11624
|
const rate = callersRate(ctx.runtime, ctx.paths);
|
|
11082
11625
|
if (!rate.downgraded) return failed(siteNotes(open));
|
|
@@ -12287,8 +12830,8 @@ var BASELINE_STATES = ["aceito", "falso-positivo"];
|
|
|
12287
12830
|
var EXCEPTION_MAX_DAYS = 90;
|
|
12288
12831
|
var EMPTY_BASELINE = { schema: BASELINE_SCHEMA, entries: [] };
|
|
12289
12832
|
var baselinePath = (root) => toAbsolutePath(join25(root, BASELINE_FILE2));
|
|
12290
|
-
var text7 = (
|
|
12291
|
-
const value =
|
|
12833
|
+
var text7 = (record4, key) => {
|
|
12834
|
+
const value = record4[key];
|
|
12292
12835
|
return typeof value === "string" && value !== "" ? value : void 0;
|
|
12293
12836
|
};
|
|
12294
12837
|
var stateOf = (value) => BASELINE_STATES.find((state) => state === value);
|
|
@@ -12355,8 +12898,8 @@ var incidentId = (rule, fingerprint) => `inc-${sha256Hex(`${rule}\0${fingerprint
|
|
|
12355
12898
|
var incidentsDir = (root) => toAbsolutePath(join26(root, INCIDENTS_DIR));
|
|
12356
12899
|
var incidentFile = (root, id) => toAbsolutePath(join26(incidentsDir(root), `${id}.json`));
|
|
12357
12900
|
var pick3 = (options, value) => options.find((option) => option === value);
|
|
12358
|
-
var str2 = (
|
|
12359
|
-
const value =
|
|
12901
|
+
var str2 = (record4, key) => {
|
|
12902
|
+
const value = record4[key];
|
|
12360
12903
|
return typeof value === "string" ? value : void 0;
|
|
12361
12904
|
};
|
|
12362
12905
|
var parseEvent = (value) => {
|
|
@@ -12374,12 +12917,12 @@ var parseHistory = (value) => {
|
|
|
12374
12917
|
var parseIncident = (raw) => {
|
|
12375
12918
|
const parsed = parseJsonObject(raw);
|
|
12376
12919
|
if (!parsed.ok) return parsed;
|
|
12377
|
-
const
|
|
12378
|
-
const [id, rule, where, fingerprint, createdAt, updatedAt] = ["id", "rule", "where", "fingerprint", "createdAt", "updatedAt"].map((key) => str2(
|
|
12379
|
-
const state = pick3(INCIDENT_STATES,
|
|
12380
|
-
const source = pick3(INCIDENT_SOURCES,
|
|
12381
|
-
const history = parseHistory(
|
|
12382
|
-
const firstCommit = str2(
|
|
12920
|
+
const record4 = parsed.value;
|
|
12921
|
+
const [id, rule, where, fingerprint, createdAt, updatedAt] = ["id", "rule", "where", "fingerprint", "createdAt", "updatedAt"].map((key) => str2(record4, key));
|
|
12922
|
+
const state = pick3(INCIDENT_STATES, record4["state"]);
|
|
12923
|
+
const source = pick3(INCIDENT_SOURCES, record4["source"]);
|
|
12924
|
+
const history = parseHistory(record4["history"]);
|
|
12925
|
+
const firstCommit = str2(record4, "firstCommit");
|
|
12383
12926
|
if (id === void 0 || !ID.test(id) || rule === void 0 || where === void 0) return reject("incomplete");
|
|
12384
12927
|
if (fingerprint === void 0 || createdAt === void 0 || updatedAt === void 0) return reject("incomplete");
|
|
12385
12928
|
if (state === void 0 || source === void 0 || history === void 0) return reject("incomplete");
|
|
@@ -14590,23 +15133,23 @@ var headsOf = (value) => isRecord(value) ? Object.fromEntries(
|
|
|
14590
15133
|
var parseJournalLine = (line2) => {
|
|
14591
15134
|
const parsed = parseJsonObject(line2);
|
|
14592
15135
|
if (!parsed.ok) return void 0;
|
|
14593
|
-
const
|
|
14594
|
-
const ref = optionalString(
|
|
14595
|
-
const commit2 = optionalString(
|
|
14596
|
-
const at = optionalString(
|
|
15136
|
+
const record4 = parsed.value;
|
|
15137
|
+
const ref = optionalString(record4, "ref");
|
|
15138
|
+
const commit2 = optionalString(record4, "commit");
|
|
15139
|
+
const at = optionalString(record4, "at");
|
|
14597
15140
|
if (ref === void 0 || commit2 === void 0 || at === void 0) return void 0;
|
|
14598
15141
|
return {
|
|
14599
15142
|
schema: JOURNAL_SCHEMA,
|
|
14600
15143
|
at,
|
|
14601
|
-
op: optionalString(
|
|
15144
|
+
op: optionalString(record4, "op") ?? "",
|
|
14602
15145
|
ref,
|
|
14603
15146
|
commit: commit2,
|
|
14604
|
-
head: optionalString(
|
|
14605
|
-
branch: optionalString(
|
|
14606
|
-
index: optionalString(
|
|
14607
|
-
owner: optionalString(
|
|
14608
|
-
command: optionalString(
|
|
14609
|
-
heads: headsOf(
|
|
15147
|
+
head: optionalString(record4, "head"),
|
|
15148
|
+
branch: optionalString(record4, "branch"),
|
|
15149
|
+
index: optionalString(record4, "index"),
|
|
15150
|
+
owner: optionalString(record4, "owner"),
|
|
15151
|
+
command: optionalString(record4, "command"),
|
|
15152
|
+
heads: headsOf(record4["heads"])
|
|
14610
15153
|
};
|
|
14611
15154
|
};
|
|
14612
15155
|
var readJournal = (runtime, root) => {
|
|
@@ -14709,8 +15252,8 @@ var listSnapshots = (runtime, repo) => {
|
|
|
14709
15252
|
var SHELL_TOOLS2 = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
|
|
14710
15253
|
var ownerOf2 = (payload) => ownerKey(optionalString(payload.raw, "agent_id") ?? payload.sessionId);
|
|
14711
15254
|
var shellText = (payload) => {
|
|
14712
|
-
if (!SHELL_TOOLS2.has(
|
|
14713
|
-
const command = optionalString(
|
|
15255
|
+
if (!SHELL_TOOLS2.has(toolName(payload))) return void 0;
|
|
15256
|
+
const command = optionalString(toolInput(payload), "command") ?? "";
|
|
14714
15257
|
return command.trim() === "" ? void 0 : command;
|
|
14715
15258
|
};
|
|
14716
15259
|
|
|
@@ -14758,7 +15301,7 @@ var outcomeMessage = (t, outcome2) => {
|
|
|
14758
15301
|
};
|
|
14759
15302
|
|
|
14760
15303
|
// src/git/hooks/pre-tool.ts
|
|
14761
|
-
var
|
|
15304
|
+
var ALLOW2 = { kind: "allow" };
|
|
14762
15305
|
var rmOutcome = (input, command, worktrees) => {
|
|
14763
15306
|
if (removalTargets(command) === void 0) return void 0;
|
|
14764
15307
|
const verdict = rmVerdict(input.runtime, { cwd: input.cwd, home: input.runtime.homeDir(), worktrees }, command);
|
|
@@ -14778,7 +15321,7 @@ var snapshotsOf = (input, owner, pending) => {
|
|
|
14778
15321
|
}
|
|
14779
15322
|
done.set(item2.repo.root, input.t("git.snapshot.context", { command: item2.command, ref: taken.value.ref }));
|
|
14780
15323
|
}
|
|
14781
|
-
if (done.size === 0) return
|
|
15324
|
+
if (done.size === 0) return ALLOW2;
|
|
14782
15325
|
const context = [...done.values()].join("\n");
|
|
14783
15326
|
return { kind: "allow", output: { hookSpecificOutput: { hookEventName: "PreToolUse", additionalContext: context } } };
|
|
14784
15327
|
};
|
|
@@ -14805,9 +15348,9 @@ var review = (input, commands, owner) => {
|
|
|
14805
15348
|
};
|
|
14806
15349
|
var gitPreToolUse = (input) => {
|
|
14807
15350
|
const text9 = shellText(input.payload);
|
|
14808
|
-
if (text9 === void 0) return
|
|
14809
|
-
const commands = normalizeCommand(text9, dialectOf(
|
|
14810
|
-
if (commands.length === 0) return
|
|
15351
|
+
if (text9 === void 0) return ALLOW2;
|
|
15352
|
+
const commands = normalizeCommand(text9, dialectOf(toolName(input.payload))).commands;
|
|
15353
|
+
if (commands.length === 0) return ALLOW2;
|
|
14811
15354
|
const owner = ownerOf2(input.payload);
|
|
14812
15355
|
const result = review(input, commands, owner);
|
|
14813
15356
|
if (result.blocked !== void 0) {
|
|
@@ -14826,15 +15369,15 @@ var gitPreToolUse = (input) => {
|
|
|
14826
15369
|
|
|
14827
15370
|
// src/git/hooks/session.ts
|
|
14828
15371
|
import { dirname as dirname6, relative as relative7 } from "node:path";
|
|
14829
|
-
var
|
|
15372
|
+
var ALLOW3 = { kind: "allow" };
|
|
14830
15373
|
var EDIT_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
|
|
14831
15374
|
var gitSessionStart = (input) => {
|
|
14832
15375
|
const repo = openRepo(input.runtime, input.cwd);
|
|
14833
15376
|
if (repo !== void 0) recordBaseline(input.runtime, repo, ownerOf2(input.payload));
|
|
14834
|
-
return
|
|
15377
|
+
return ALLOW3;
|
|
14835
15378
|
};
|
|
14836
15379
|
var editedPath = (input) => {
|
|
14837
|
-
const inputs =
|
|
15380
|
+
const inputs = toolInput(input.payload);
|
|
14838
15381
|
const raw = optionalString(inputs, "file_path") ?? optionalString(inputs, "notebook_path");
|
|
14839
15382
|
if (raw === void 0 || raw === "") return void 0;
|
|
14840
15383
|
const file = toAbsolutePath(raw, input.cwd);
|
|
@@ -14844,16 +15387,16 @@ var editedPath = (input) => {
|
|
|
14844
15387
|
return path === "" || path.startsWith("..") || path.startsWith(STATE_PREFIX) ? void 0 : { repo, path };
|
|
14845
15388
|
};
|
|
14846
15389
|
var gitPostToolUse = (input) => {
|
|
14847
|
-
const tool =
|
|
15390
|
+
const tool = toolName(input.payload);
|
|
14848
15391
|
if (EDIT_TOOLS.has(tool)) {
|
|
14849
15392
|
const edited = editedPath(input);
|
|
14850
15393
|
if (edited !== void 0) recordEdits(input.runtime, edited.repo, ownerOf2(input.payload), [edited.path]);
|
|
14851
|
-
return
|
|
15394
|
+
return ALLOW3;
|
|
14852
15395
|
}
|
|
14853
|
-
if (!SHELL_TOOLS2.has(tool)) return
|
|
15396
|
+
if (!SHELL_TOOLS2.has(tool)) return ALLOW3;
|
|
14854
15397
|
const repo = openRepo(input.runtime, input.cwd);
|
|
14855
15398
|
if (repo !== void 0) recordShellChanges(input.runtime, repo, ownerOf2(input.payload));
|
|
14856
|
-
return
|
|
15399
|
+
return ALLOW3;
|
|
14857
15400
|
};
|
|
14858
15401
|
|
|
14859
15402
|
// src/git/hooks/index.ts
|
|
@@ -14907,7 +15450,7 @@ var recordShadow = (input, paths, set, policy, reason) => {
|
|
|
14907
15450
|
logEvent(runtime, paths, "guard_shadow", {
|
|
14908
15451
|
guard: set.id,
|
|
14909
15452
|
hook: input.event,
|
|
14910
|
-
tool:
|
|
15453
|
+
tool: toolName(input.payload),
|
|
14911
15454
|
wouldHave: "block",
|
|
14912
15455
|
reason
|
|
14913
15456
|
});
|
|
@@ -15018,7 +15561,7 @@ var heredocIn = (value, heredocs) => {
|
|
|
15018
15561
|
};
|
|
15019
15562
|
|
|
15020
15563
|
// src/prose/marker-guard.ts
|
|
15021
|
-
var
|
|
15564
|
+
var ALLOW4 = { kind: "allow" };
|
|
15022
15565
|
var SHELLS2 = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
|
|
15023
15566
|
var READ_ONLY = /* @__PURE__ */ new Set(["grep", "rg", "cat", "less", "head", "tail", "ls", "wc", "finitemonkey", "fm"]);
|
|
15024
15567
|
var GIT_READ_ONLY = /* @__PURE__ */ new Set(["grep", "log", "show", "diff", "status", "blame"]);
|
|
@@ -15059,10 +15602,10 @@ var blocked = (input, file) => ({
|
|
|
15059
15602
|
human: input.t("prose.block.human")
|
|
15060
15603
|
});
|
|
15061
15604
|
var proseMarkerGuard = (input) => {
|
|
15062
|
-
const tool =
|
|
15063
|
-
const inputs =
|
|
15605
|
+
const tool = toolName(input.payload);
|
|
15606
|
+
const inputs = toolInput(input.payload);
|
|
15064
15607
|
if (SHELLS2.has(tool)) {
|
|
15065
|
-
if (!shellAddsMarker(optionalString(inputs, "command") ?? "")) return
|
|
15608
|
+
if (!shellAddsMarker(optionalString(inputs, "command") ?? "")) return ALLOW4;
|
|
15066
15609
|
return {
|
|
15067
15610
|
kind: "block",
|
|
15068
15611
|
reason: modelReason(input.t, "prose.block.marker_shell", { marker: ALLOW_COMMENT }),
|
|
@@ -15070,7 +15613,7 @@ var proseMarkerGuard = (input) => {
|
|
|
15070
15613
|
};
|
|
15071
15614
|
}
|
|
15072
15615
|
const file = optionalString(inputs, "file_path") ?? optionalString(inputs, "notebook_path") ?? "";
|
|
15073
|
-
return addsMarker(input, tool, inputs, file) ? blocked(input, shown2(input.cwd, file)) :
|
|
15616
|
+
return addsMarker(input, tool, inputs, file) ? blocked(input, shown2(input.cwd, file)) : ALLOW4;
|
|
15074
15617
|
};
|
|
15075
15618
|
|
|
15076
15619
|
// src/secrets/project.ts
|
|
@@ -15186,7 +15729,7 @@ var describeSpans = (t, spans) => spans.slice(0, MAX_SPANS).map((span) => t("pro
|
|
|
15186
15729
|
var describeFixes = (t, spans) => rulesOf2(spans).slice(0, MAX_FIXES).map((rule) => t("prose.fix_item", { rule, fix: t(RULE_FIX_KEYS[rule]) })).join("; ");
|
|
15187
15730
|
|
|
15188
15731
|
// src/prose/text-guard.ts
|
|
15189
|
-
var
|
|
15732
|
+
var ALLOW5 = { kind: "allow" };
|
|
15190
15733
|
var SHELLS3 = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
|
|
15191
15734
|
var TARGET_KEYS = {
|
|
15192
15735
|
commit: "prose.target.commit",
|
|
@@ -15233,15 +15776,15 @@ var decisionFor = (input, found, blocking2) => {
|
|
|
15233
15776
|
return { kind: "allow", output: { hookSpecificOutput: { hookEventName: "PreToolUse", additionalContext } } };
|
|
15234
15777
|
};
|
|
15235
15778
|
var proseCommandGuard = (input) => {
|
|
15236
|
-
if (!SHELLS3.has(
|
|
15237
|
-
const found = proseInCommand(optionalString(
|
|
15238
|
-
if (found.length === 0) return
|
|
15779
|
+
if (!SHELLS3.has(toolName(input.payload))) return ALLOW5;
|
|
15780
|
+
const found = proseInCommand(optionalString(toolInput(input.payload), "command") ?? "");
|
|
15781
|
+
if (found.length === 0) return ALLOW5;
|
|
15239
15782
|
const blocking2 = projectPreset(input.runtime, projectRoot(input)) === "gabriel";
|
|
15240
15783
|
for (const item2 of found) {
|
|
15241
15784
|
const decision = decisionFor(input, item2, blocking2);
|
|
15242
15785
|
if (decision !== void 0) return decision;
|
|
15243
15786
|
}
|
|
15244
|
-
return
|
|
15787
|
+
return ALLOW5;
|
|
15245
15788
|
};
|
|
15246
15789
|
|
|
15247
15790
|
// src/prose/hooks.ts
|
|
@@ -15265,7 +15808,7 @@ var liveFindings = (input, texts2) => {
|
|
|
15265
15808
|
const accepted2 = acceptedFingerprints(baseline.ok ? baseline.value : EMPTY_BASELINE, input.runtime.now());
|
|
15266
15809
|
return texts2.flatMap((text9) => scanText(text9, { rules: CREDENTIAL_RULES })).filter((finding4) => !accepted2.has(finding4.fingerprint));
|
|
15267
15810
|
};
|
|
15268
|
-
var
|
|
15811
|
+
var record3 = (input, findings, draft, where) => {
|
|
15269
15812
|
const ids2 = findings.map((finding4) => {
|
|
15270
15813
|
const saved = recordIncident(
|
|
15271
15814
|
input.runtime,
|
|
@@ -15281,7 +15824,7 @@ var secretsUserPromptSubmit = (input) => {
|
|
|
15281
15824
|
const prompt = optionalString(input.payload.raw, "prompt") ?? "";
|
|
15282
15825
|
const findings = liveFindings(input, [prompt]);
|
|
15283
15826
|
if (findings.length === 0) return { kind: "allow" };
|
|
15284
|
-
const incident =
|
|
15827
|
+
const incident = record3(input, findings, { source: "prompt", state: "exposicao-local" }, "prompt");
|
|
15285
15828
|
const items = findings.map((finding4) => ({ ruleId: finding4.ruleId, where: lineWhere(input.t, finding4) }));
|
|
15286
15829
|
return {
|
|
15287
15830
|
kind: "block",
|
|
@@ -15291,8 +15834,8 @@ var secretsUserPromptSubmit = (input) => {
|
|
|
15291
15834
|
var secretsPostToolUse = (input) => {
|
|
15292
15835
|
const findings = liveFindings(input, stringLeaves(input.payload.raw["tool_response"]));
|
|
15293
15836
|
if (findings.length === 0) return { kind: "allow" };
|
|
15294
|
-
const tool =
|
|
15295
|
-
const incident =
|
|
15837
|
+
const tool = toolName(input.payload) || "tool";
|
|
15838
|
+
const incident = record3(input, findings, { source: "tool-output", state: "aberto" }, `tool-output:${tool}`);
|
|
15296
15839
|
const items = findings.map((finding4) => ({ ruleId: finding4.ruleId, where: lineWhere(input.t, finding4) }));
|
|
15297
15840
|
const context = input.t("secrets.post.context", { tool, found: describeFindings(input.t, items), incident });
|
|
15298
15841
|
return {
|
|
@@ -15396,21 +15939,21 @@ var commitIntent = (segments) => {
|
|
|
15396
15939
|
};
|
|
15397
15940
|
|
|
15398
15941
|
// src/secrets/guards/pre-tool.ts
|
|
15399
|
-
var
|
|
15942
|
+
var ALLOW6 = { kind: "allow" };
|
|
15400
15943
|
var relativeFile = (cwd, file) => {
|
|
15401
15944
|
if (file === "") return file;
|
|
15402
15945
|
const rel = relative9(cwd, file).split("\\").join("/");
|
|
15403
15946
|
return rel.startsWith("..") || rel === "" ? file : rel;
|
|
15404
15947
|
};
|
|
15405
15948
|
var warningDecision = (t, warnings) => {
|
|
15406
|
-
if (warnings.length === 0) return
|
|
15949
|
+
if (warnings.length === 0) return ALLOW6;
|
|
15407
15950
|
const context = t("secrets.warn.write", { found: describeFindings(t, warnings) });
|
|
15408
15951
|
return { kind: "allow", output: { hookSpecificOutput: { hookEventName: "PreToolUse", additionalContext: context } } };
|
|
15409
15952
|
};
|
|
15410
15953
|
var writeDecision = (input, tool) => {
|
|
15411
15954
|
const { t } = input;
|
|
15412
15955
|
const warnings = [];
|
|
15413
|
-
for (const written of writtenTexts(tool,
|
|
15956
|
+
for (const written of writtenTexts(tool, toolInput(input.payload))) {
|
|
15414
15957
|
const file = relativeFile(input.cwd, written.file);
|
|
15415
15958
|
const all = scanText(written.text, { path: file });
|
|
15416
15959
|
warnings.push(
|
|
@@ -15446,7 +15989,7 @@ var bashMessage = (t, finding4) => {
|
|
|
15446
15989
|
var commitDecision = (input, includeUnstaged) => {
|
|
15447
15990
|
const staged = scanStaged(input.runtime, input.cwd, includeUnstaged);
|
|
15448
15991
|
const found = staged.ok ? blocking(staged.value) : [];
|
|
15449
|
-
if (found.length === 0) return
|
|
15992
|
+
if (found.length === 0) return ALLOW6;
|
|
15450
15993
|
const items = found.map((finding4) => ({
|
|
15451
15994
|
ruleId: finding4.ruleId,
|
|
15452
15995
|
where: input.t("secrets.where.file", { file: finding4.file, line: finding4.line, column: finding4.column })
|
|
@@ -15458,8 +16001,8 @@ var commitDecision = (input, includeUnstaged) => {
|
|
|
15458
16001
|
};
|
|
15459
16002
|
};
|
|
15460
16003
|
var bashDecision = (input) => {
|
|
15461
|
-
const command = optionalString(
|
|
15462
|
-
if (command === "") return
|
|
16004
|
+
const command = optionalString(toolInput(input.payload), "command") ?? "";
|
|
16005
|
+
if (command === "") return ALLOW6;
|
|
15463
16006
|
const segments = segmentsOf(command);
|
|
15464
16007
|
const [first] = bashFindings(command, segments);
|
|
15465
16008
|
if (first !== void 0) return { kind: "block", reason: bashMessage(input.t, first) };
|
|
@@ -15473,12 +16016,12 @@ var bashDecision = (input) => {
|
|
|
15473
16016
|
};
|
|
15474
16017
|
}
|
|
15475
16018
|
const commit2 = commitIntent(segments);
|
|
15476
|
-
return commit2 === void 0 ?
|
|
16019
|
+
return commit2 === void 0 ? ALLOW6 : commitDecision(input, commit2.includeUnstaged);
|
|
15477
16020
|
};
|
|
15478
16021
|
var readDecision = (input) => {
|
|
15479
|
-
const inputs =
|
|
16022
|
+
const inputs = toolInput(input.payload);
|
|
15480
16023
|
const target2 = optionalString(inputs, "file_path") ?? optionalString(inputs, "path") ?? "";
|
|
15481
|
-
if (target2 === "" || !isSensitivePath(target2)) return
|
|
16024
|
+
if (target2 === "" || !isSensitivePath(target2)) return ALLOW6;
|
|
15482
16025
|
return {
|
|
15483
16026
|
kind: "block",
|
|
15484
16027
|
reason: modelReason(input.t, "secrets.block.read", { target: relativeFile(input.cwd, target2) }),
|
|
@@ -15489,11 +16032,11 @@ var WRITERS2 = /* @__PURE__ */ new Set(["Write", "Edit", "MultiEdit", "NotebookE
|
|
|
15489
16032
|
var SHELLS4 = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
|
|
15490
16033
|
var READS = /* @__PURE__ */ new Set(["Read", "Grep"]);
|
|
15491
16034
|
var secretsPreToolUse = (input) => {
|
|
15492
|
-
const tool =
|
|
16035
|
+
const tool = toolName(input.payload);
|
|
15493
16036
|
if (WRITERS2.has(tool)) return writeDecision(input, tool);
|
|
15494
16037
|
if (SHELLS4.has(tool)) return bashDecision(input);
|
|
15495
16038
|
if (READS.has(tool)) return readDecision(input);
|
|
15496
|
-
return
|
|
16039
|
+
return ALLOW6;
|
|
15497
16040
|
};
|
|
15498
16041
|
|
|
15499
16042
|
// src/secrets/remotes.ts
|
|
@@ -15570,7 +16113,7 @@ var recordBlock = (input, decision) => {
|
|
|
15570
16113
|
if (paths === void 0) return;
|
|
15571
16114
|
logEvent(input.runtime, paths, "guard_block", {
|
|
15572
16115
|
hook: input.event,
|
|
15573
|
-
tool:
|
|
16116
|
+
tool: toolName(input.payload),
|
|
15574
16117
|
sessionId: input.payload.sessionId ?? null,
|
|
15575
16118
|
claim: (decision.reason.split("\n")[0] ?? "").slice(0, 200)
|
|
15576
16119
|
});
|
|
@@ -15617,7 +16160,8 @@ var GUARD_SETS = [
|
|
|
15617
16160
|
{ id: "secrets", damage: true, handlers: SECRETS_HANDLERS },
|
|
15618
16161
|
{ id: "gate", damage: true, handlers: PORTAO_HANDLERS },
|
|
15619
16162
|
{ id: "prose", damage: false, handlers: PROSE_HANDLERS },
|
|
15620
|
-
{ id: "git", damage: true, handlers: GIT_HANDLERS }
|
|
16163
|
+
{ id: "git", damage: true, handlers: GIT_HANDLERS },
|
|
16164
|
+
{ id: "deps", damage: false, handlers: { PreToolUse: [depsGuard] } }
|
|
15621
16165
|
];
|
|
15622
16166
|
var DEFAULT_HANDLERS = mergeHandlers(...GUARD_SETS.map(withPolicy));
|
|
15623
16167
|
|
|
@@ -15993,9 +16537,9 @@ var hookSchemaProblems = (hooks, claude) => {
|
|
|
15993
16537
|
import { join as join35 } from "node:path";
|
|
15994
16538
|
var entriesOf = (source, hooks, own) => Object.entries(asRecord(hooks)).flatMap(
|
|
15995
16539
|
([event, groups]) => asList(groups).flatMap((group) => {
|
|
15996
|
-
const
|
|
15997
|
-
const matcher = optionalString(
|
|
15998
|
-
return asList(
|
|
16540
|
+
const record4 = asRecord(group);
|
|
16541
|
+
const matcher = optionalString(record4, "matcher");
|
|
16542
|
+
return asList(record4["hooks"]).filter((handler) => isRecord(handler) && own(handler)).map((handler) => ({ source, event, matcher, handler }));
|
|
15999
16543
|
})
|
|
16000
16544
|
);
|
|
16001
16545
|
var PROJECT_SCOPES = { project: "project", local: "local" };
|
|
@@ -16006,7 +16550,7 @@ var projectHookFiles = (env) => readSettings(env).flatMap(({ scope: scope2, path
|
|
|
16006
16550
|
var pluginsDir = ({ env, runtime }) => join35(env["CLAUDE_CONFIG_DIR"] ?? join35(runtime.homeDir(), ".claude"), "plugins");
|
|
16007
16551
|
var installRecord = (value, root) => {
|
|
16008
16552
|
const records = Array.isArray(value) ? value.filter(isRecord) : isRecord(value) ? [value] : [];
|
|
16009
|
-
return records.find((
|
|
16553
|
+
return records.find((record4) => record4["projectPath"] === root) ?? records[0];
|
|
16010
16554
|
};
|
|
16011
16555
|
var readJson = (env, path) => {
|
|
16012
16556
|
const text9 = env.runtime.readText(path);
|
|
@@ -16015,9 +16559,9 @@ var readJson = (env, path) => {
|
|
|
16015
16559
|
};
|
|
16016
16560
|
var installedPlugin = (env) => {
|
|
16017
16561
|
const index = readJson(env, toAbsolutePath(join35(pluginsDir(env), "installed_plugins.json")));
|
|
16018
|
-
const
|
|
16019
|
-
const installPath =
|
|
16020
|
-
if (
|
|
16562
|
+
const record4 = installRecord(asRecord(index?.["plugins"])[PLUGIN_ID], env.root);
|
|
16563
|
+
const installPath = record4 === void 0 ? void 0 : optionalString(record4, "installPath");
|
|
16564
|
+
if (record4 === void 0 || installPath === void 0) return void 0;
|
|
16021
16565
|
const root = toAbsolutePath(installPath);
|
|
16022
16566
|
const manifest = readJson(env, toAbsolutePath(join35(root, ".claude-plugin", "plugin.json")));
|
|
16023
16567
|
const hooksPath = toAbsolutePath(join35(root, "hooks", "hooks.json"));
|
|
@@ -16025,7 +16569,7 @@ var installedPlugin = (env) => {
|
|
|
16025
16569
|
const parsed = text9.ok ? parseJsonObject(text9.value) : void 0;
|
|
16026
16570
|
return {
|
|
16027
16571
|
root,
|
|
16028
|
-
version: (manifest === void 0 ? void 0 : optionalString(manifest, "version")) ?? optionalString(
|
|
16572
|
+
version: (manifest === void 0 ? void 0 : optionalString(manifest, "version")) ?? optionalString(record4, "version"),
|
|
16029
16573
|
hooksFile: parsed?.ok === true ? { source: "plugin", path: hooksPath, hooks: parsed.value["hooks"] } : void 0,
|
|
16030
16574
|
hooksText: text9.ok ? text9.value : void 0
|
|
16031
16575
|
};
|
|
@@ -16517,8 +17061,8 @@ var doctorCommand = {
|
|
|
16517
17061
|
// src/gain/gain.ts
|
|
16518
17062
|
import { join as join41 } from "node:path";
|
|
16519
17063
|
var GAIN_SCHEMA = "finitemonkey/gain@1";
|
|
16520
|
-
var
|
|
16521
|
-
var SAVE_WINDOW_MS =
|
|
17064
|
+
var DAY_MS3 = 864e5;
|
|
17065
|
+
var SAVE_WINDOW_MS = DAY_MS3;
|
|
16522
17066
|
var readLog = (runtime, paths) => {
|
|
16523
17067
|
const text9 = runtime.readText(paths.log);
|
|
16524
17068
|
if (!text9.ok) return [];
|
|
@@ -16554,7 +17098,7 @@ var countsIn = (log, gates, from, to) => {
|
|
|
16554
17098
|
};
|
|
16555
17099
|
var gainReport = (runtime, paths, days) => {
|
|
16556
17100
|
const to = Date.parse(runtime.now());
|
|
16557
|
-
const from = to - days *
|
|
17101
|
+
const from = to - days * DAY_MS3;
|
|
16558
17102
|
const log = readLog(runtime, paths);
|
|
16559
17103
|
const gates = readGates(runtime, paths);
|
|
16560
17104
|
return {
|
|
@@ -16563,7 +17107,7 @@ var gainReport = (runtime, paths, days) => {
|
|
|
16563
17107
|
from: new Date(from).toISOString(),
|
|
16564
17108
|
to: new Date(to).toISOString(),
|
|
16565
17109
|
current: countsIn(log, gates, from, to + 1),
|
|
16566
|
-
previous: countsIn(log, gates, from - days *
|
|
17110
|
+
previous: countsIn(log, gates, from - days * DAY_MS3, from)
|
|
16567
17111
|
};
|
|
16568
17112
|
};
|
|
16569
17113
|
|
|
@@ -16762,8 +17306,8 @@ var secretsInRange = (runtime, root, range) => {
|
|
|
16762
17306
|
var RECORD = "";
|
|
16763
17307
|
var commitMessagesInRange = (runtime, root, range) => {
|
|
16764
17308
|
const log = runtime.git(["log", "--no-merges", `--format=%H%x00%B${RECORD}`, ...range, "--"], root);
|
|
16765
|
-
const failures = log.ok ? log.stdout.split(RECORD).map((
|
|
16766
|
-
const [sha = "", body2 = ""] =
|
|
17309
|
+
const failures = log.ok ? log.stdout.split(RECORD).map((record4) => record4.replace(/^\n/, "")).filter((record4) => record4.includes("\0")).flatMap((record4) => {
|
|
17310
|
+
const [sha = "", body2 = ""] = record4.split("\0");
|
|
16767
17311
|
return commitMessageProblems(body2).map((problem4) => `${short(sha)} ${problem4}`);
|
|
16768
17312
|
}) : [`git log ${range.join(" ")} failed`];
|
|
16769
17313
|
return { id: "commit-messages", failures, fix: "git rebase -i <base> and reword the listed commits" };
|
|
@@ -17061,7 +17605,7 @@ var fsckDangling = (runtime, repo) => {
|
|
|
17061
17605
|
});
|
|
17062
17606
|
return { commits: pick4("commit"), blobs: pick4("blob").length };
|
|
17063
17607
|
};
|
|
17064
|
-
var
|
|
17608
|
+
var describe2 = (runtime, repo, shas) => {
|
|
17065
17609
|
if (shas.length === 0) return /* @__PURE__ */ new Map();
|
|
17066
17610
|
const result = runtime.git(["log", "--no-walk=unsorted", "--format=%H%x09%cr%x09%s", ...shas], repo.root);
|
|
17067
17611
|
return new Map(
|
|
@@ -17080,7 +17624,7 @@ var rescueReport = (runtime, repo) => {
|
|
|
17080
17624
|
const seen = new Set(fromReflog.map((line2) => line2.sha));
|
|
17081
17625
|
const dangling = fsckDangling(runtime, repo);
|
|
17082
17626
|
const extra = dangling.commits.filter((sha) => !seen.has(sha));
|
|
17083
|
-
const details =
|
|
17627
|
+
const details = describe2(runtime, repo, [...fromReflog.map((line2) => line2.sha), ...extra].slice(0, LIST_LIMIT));
|
|
17084
17628
|
const commit2 = (sha, source, ref) => {
|
|
17085
17629
|
const detail = details.get(sha);
|
|
17086
17630
|
return detail === void 0 ? [] : [{ sha, when: detail[0], subject: detail[1], source, ref }];
|
|
@@ -17328,7 +17872,7 @@ var GLOBAL_FLAGS = [
|
|
|
17328
17872
|
];
|
|
17329
17873
|
var exitCodeHelp = (ctx) => EXIT_CODE_NAMES.map((name) => ({ code: ExitCode[name], name, summary: ctx.t(exitCodeDocs[ExitCode[name]]) }));
|
|
17330
17874
|
var pad = (text9, width) => text9.padEnd(Math.max(width, text9.length + 1));
|
|
17331
|
-
var
|
|
17875
|
+
var describe3 = (ctx, spec2) => ({
|
|
17332
17876
|
name: commandName(spec2),
|
|
17333
17877
|
usage: spec2.usage,
|
|
17334
17878
|
summary: ctx.t(spec2.summaryKey),
|
|
@@ -17337,7 +17881,7 @@ var describe2 = (ctx, spec2) => ({
|
|
|
17337
17881
|
});
|
|
17338
17882
|
var summaryLine = (ctx, help) => help.status === "planned" ? `${help.summary} ${ctx.t("help.planned")}` : help.summary;
|
|
17339
17883
|
var overview = (ctx, registry) => {
|
|
17340
|
-
const commands = registry.map((spec2) =>
|
|
17884
|
+
const commands = registry.map((spec2) => describe3(ctx, spec2));
|
|
17341
17885
|
const flags = GLOBAL_FLAGS.map(({ flag: flag2, key }) => ({ flag: flag2, summary: ctx.t(key) }));
|
|
17342
17886
|
const width = Math.max(...commands.map(({ name }) => name.length)) + 2;
|
|
17343
17887
|
const flagWidth = Math.max(...flags.map(({ flag: flag2 }) => flag2.length)) + 2;
|
|
@@ -17362,7 +17906,7 @@ var overview = (ctx, registry) => {
|
|
|
17362
17906
|
return success({ commands, flags, exitCodes }, human2);
|
|
17363
17907
|
};
|
|
17364
17908
|
var helpFor = (ctx, spec2) => {
|
|
17365
|
-
const help =
|
|
17909
|
+
const help = describe3(ctx, spec2);
|
|
17366
17910
|
const human2 = [
|
|
17367
17911
|
`${ctx.t("help.usage")}: ${help.usage}`,
|
|
17368
17912
|
"",
|
|
@@ -18751,14 +19295,14 @@ var gitUnavailable = (detail) => ({
|
|
|
18751
19295
|
});
|
|
18752
19296
|
|
|
18753
19297
|
// src/commands/secrets-accept.ts
|
|
18754
|
-
var
|
|
19298
|
+
var DAY_MS4 = 864e5;
|
|
18755
19299
|
var daysOf = (values) => {
|
|
18756
19300
|
const raw = stringOption(values, "days");
|
|
18757
19301
|
if (raw === void 0) return EXCEPTION_MAX_DAYS;
|
|
18758
19302
|
const days = Number.parseInt(raw, 10);
|
|
18759
19303
|
return Number.isInteger(days) && days > 0 && days <= EXCEPTION_MAX_DAYS ? days : void 0;
|
|
18760
19304
|
};
|
|
18761
|
-
var plusDays = (iso, days) => new Date(Date.parse(iso) + days *
|
|
19305
|
+
var plusDays = (iso, days) => new Date(Date.parse(iso) + days * DAY_MS4).toISOString();
|
|
18762
19306
|
var failure3 = (ctx, problem4) => failureFrom(ctx.t, problem4);
|
|
18763
19307
|
var inputProblem = (ctx, id, reason, days) => {
|
|
18764
19308
|
const fix = "finitemonkey secrets accept <id> --reason <why> [--days 1-90] [--false-positive]";
|
|
@@ -19276,8 +19820,8 @@ var usedTokens = (usage) => {
|
|
|
19276
19820
|
if (!isRecord(usage)) return void 0;
|
|
19277
19821
|
return (num(usage["input_tokens"]) ?? 0) + (num(usage["cache_creation_input_tokens"]) ?? 0) + (num(usage["cache_read_input_tokens"]) ?? 0);
|
|
19278
19822
|
};
|
|
19279
|
-
var contextPercent = (
|
|
19280
|
-
const window =
|
|
19823
|
+
var contextPercent = (record4) => {
|
|
19824
|
+
const window = record4["context_window"];
|
|
19281
19825
|
if (!isRecord(window)) return void 0;
|
|
19282
19826
|
const direct = window["used_percentage"];
|
|
19283
19827
|
if (typeof direct === "number" && Number.isFinite(direct)) return Math.round(direct);
|
|
@@ -19287,12 +19831,12 @@ var contextPercent = (record3) => {
|
|
|
19287
19831
|
};
|
|
19288
19832
|
var parseStatusInput = (raw) => {
|
|
19289
19833
|
const parsed = parseJsonObject(raw.trim() === "" ? "{}" : raw);
|
|
19290
|
-
const
|
|
19291
|
-
const workspace = isRecord(
|
|
19834
|
+
const record4 = parsed.ok ? parsed.value : {};
|
|
19835
|
+
const workspace = isRecord(record4["workspace"]) ? record4["workspace"] : {};
|
|
19292
19836
|
return {
|
|
19293
|
-
sessionId: text8(
|
|
19294
|
-
dir: text8(workspace["project_dir"]) ?? text8(workspace["current_dir"]) ?? text8(
|
|
19295
|
-
contextPercent: contextPercent(
|
|
19837
|
+
sessionId: text8(record4["session_id"]),
|
|
19838
|
+
dir: text8(workspace["project_dir"]) ?? text8(workspace["current_dir"]) ?? text8(record4["cwd"]),
|
|
19839
|
+
contextPercent: contextPercent(record4),
|
|
19296
19840
|
raw
|
|
19297
19841
|
};
|
|
19298
19842
|
};
|
|
@@ -19987,7 +20531,7 @@ var langSettings = (runtime, cwd, env, platform) => {
|
|
|
19987
20531
|
};
|
|
19988
20532
|
|
|
19989
20533
|
// src/core/suggest.ts
|
|
19990
|
-
var
|
|
20534
|
+
var distance2 = (a, b) => {
|
|
19991
20535
|
const row = Array.from({ length: b.length + 1 }, (_, index) => index);
|
|
19992
20536
|
for (let i = 1; i <= a.length; i += 1) {
|
|
19993
20537
|
let diagonal = row[0] ?? 0;
|
|
@@ -20007,7 +20551,7 @@ var closest = (input, candidates) => {
|
|
|
20007
20551
|
const limit = Math.max(1, Math.floor(input.length / 3));
|
|
20008
20552
|
let best;
|
|
20009
20553
|
for (const name of candidates) {
|
|
20010
|
-
const score =
|
|
20554
|
+
const score = distance2(input, name.split(" ")[0] ?? name);
|
|
20011
20555
|
if (score <= limit && (best === void 0 || score < best.score)) best = { name, score };
|
|
20012
20556
|
}
|
|
20013
20557
|
return best?.name;
|