finitemonkey 0.1.0-next.21 → 0.1.0-next.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/finitemonkey.mjs +609 -227
- package/package.json +1 -1
package/dist/finitemonkey.mjs
CHANGED
|
@@ -3141,6 +3141,36 @@ var applyEdits = (before, edits) => edits.reduce(
|
|
|
3141
3141
|
before
|
|
3142
3142
|
);
|
|
3143
3143
|
|
|
3144
|
+
// src/hooks/reason.ts
|
|
3145
|
+
var REASON_LIMIT = 1e4;
|
|
3146
|
+
var familyOf = (base) => {
|
|
3147
|
+
const families = [
|
|
3148
|
+
"gate.guard.bypass",
|
|
3149
|
+
"gate.guard.self",
|
|
3150
|
+
"gate.guard.tests",
|
|
3151
|
+
"secrets.block",
|
|
3152
|
+
"git.block",
|
|
3153
|
+
"prod.block",
|
|
3154
|
+
"prose.block"
|
|
3155
|
+
];
|
|
3156
|
+
const found = families.find((family) => base.startsWith(`${family}.`) || base === family);
|
|
3157
|
+
if (found === void 0) throw new Error(`no reason family for ${base}`);
|
|
3158
|
+
return found;
|
|
3159
|
+
};
|
|
3160
|
+
var capReason = (text7) => text7.length <= REASON_LIMIT ? text7 : `${text7.slice(0, REASON_LIMIT - 1)}…`;
|
|
3161
|
+
var modelReason = (t, base, params2 = {}) => {
|
|
3162
|
+
const claim = `${base}.claim`;
|
|
3163
|
+
const requires = `${base}.requires`;
|
|
3164
|
+
const not = `${familyOf(base)}.not`;
|
|
3165
|
+
return capReason(
|
|
3166
|
+
[
|
|
3167
|
+
`${t("reason.label.blocked")}: ${t(claim, params2)}.`,
|
|
3168
|
+
`${t("reason.label.requires")}: ${t(requires, params2)}.`,
|
|
3169
|
+
`${t("reason.label.not")}: ${t(not, params2)}.`
|
|
3170
|
+
].join("\n")
|
|
3171
|
+
);
|
|
3172
|
+
};
|
|
3173
|
+
|
|
3144
3174
|
// src/core/clock.ts
|
|
3145
3175
|
var nowMs = (runtime) => Date.parse(runtime.now());
|
|
3146
3176
|
|
|
@@ -3254,7 +3284,8 @@ var grantFor = (input, guard) => {
|
|
|
3254
3284
|
const { runtime } = input;
|
|
3255
3285
|
return activeGrant(runtime, fmPaths(guardRoot(input)), guard, nowMs(runtime), input.payload.sessionId);
|
|
3256
3286
|
};
|
|
3257
|
-
var deny = (
|
|
3287
|
+
var deny = (fullReason, humanText) => {
|
|
3288
|
+
const reason = capReason(fullReason);
|
|
3258
3289
|
const output = {
|
|
3259
3290
|
hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: reason },
|
|
3260
3291
|
systemMessage: `finitemonkey: ${humanText}`
|
|
@@ -4044,7 +4075,7 @@ var bypassGuard = (input) => {
|
|
|
4044
4075
|
if (first === void 0 || grantFor(input, "bypass") !== void 0) return { kind: "allow" };
|
|
4045
4076
|
const { t } = input;
|
|
4046
4077
|
return deny(
|
|
4047
|
-
t
|
|
4078
|
+
modelReason(t, `gate.guard.bypass.${first.kind}`, { detail: first.detail }),
|
|
4048
4079
|
t("gate.guard.bypass.human", { detail: first.detail })
|
|
4049
4080
|
);
|
|
4050
4081
|
};
|
|
@@ -4127,12 +4158,15 @@ var selfGuard = (input) => {
|
|
|
4127
4158
|
const { t } = input;
|
|
4128
4159
|
if (store !== void 0)
|
|
4129
4160
|
return deny(
|
|
4130
|
-
t
|
|
4161
|
+
modelReason(t, "gate.guard.self.allow_store", { file: store.path }),
|
|
4131
4162
|
t("gate.guard.self.human", { file: store.path })
|
|
4132
4163
|
);
|
|
4133
4164
|
const first = found[0];
|
|
4134
4165
|
if (first === void 0 || grantFor(input, "self") !== void 0) return { kind: "allow" };
|
|
4135
|
-
return deny(
|
|
4166
|
+
return deny(
|
|
4167
|
+
modelReason(t, "gate.guard.self.policy", { file: first.path }),
|
|
4168
|
+
t("gate.guard.self.human", { file: first.path })
|
|
4169
|
+
);
|
|
4136
4170
|
};
|
|
4137
4171
|
|
|
4138
4172
|
// src/guards/tests/hook.ts
|
|
@@ -4342,7 +4376,7 @@ var testsGuard = (input) => {
|
|
|
4342
4376
|
const { t } = input;
|
|
4343
4377
|
const params2 = { file: first.path, before: first.before ?? 0, after: first.after ?? 0 };
|
|
4344
4378
|
const reason = SHELL_TOOLS.has(tool) ? t("gate.guard.tests.shell", params2) : t(`gate.tests.${first.kind}`, params2);
|
|
4345
|
-
return deny(t
|
|
4379
|
+
return deny(modelReason(t, "gate.guard.tests", { detail: reason }), t("gate.guard.tests.human", { detail: reason }));
|
|
4346
4380
|
};
|
|
4347
4381
|
|
|
4348
4382
|
// src/look/reads.ts
|
|
@@ -5802,6 +5836,7 @@ var en_default = {
|
|
|
5802
5836
|
"i18n.problem.placeholder": "placeholders differ (expected: {expected}; found: {actual})",
|
|
5803
5837
|
"i18n.problem.plural": "plural branches missing (needs: {expected}; found: {actual})",
|
|
5804
5838
|
"i18n.problem.status": "no review status (use: {expected})",
|
|
5839
|
+
"i18n.problem.release_hint": "release instructions in text the model reads ({actual}); move them to a key the person reads",
|
|
5805
5840
|
"i18n.problem.empty": "empty text",
|
|
5806
5841
|
"i18n.problem.not_string": "value is not text",
|
|
5807
5842
|
"doctor.title": "finitemonkey doctor ({version})",
|
|
@@ -5928,12 +5963,20 @@ var en_default = {
|
|
|
5928
5963
|
"secrets.where.line": "line {line}, column {column}",
|
|
5929
5964
|
"secrets.where.file": "{file}:{line}:{column}",
|
|
5930
5965
|
"secrets.where.new_text": "{file} (line {line} of the new text)",
|
|
5931
|
-
"secrets.block.write": "
|
|
5932
|
-
"secrets.block.
|
|
5933
|
-
"secrets.block.
|
|
5934
|
-
"secrets.block.
|
|
5935
|
-
"secrets.block.
|
|
5936
|
-
"secrets.block.
|
|
5966
|
+
"secrets.block.write.claim": "the new text for {file} has a credential ({found})",
|
|
5967
|
+
"secrets.block.write.requires": "Nothing was written. Keep the value in .env (outside git) and read it by its variable name. If the key is real, treat it as exposed and rotate it",
|
|
5968
|
+
"secrets.block.not": "an encoded, split, commented or renamed copy of the same value",
|
|
5969
|
+
"secrets.block.human": "Kept a credential out of a file, command or commit.",
|
|
5970
|
+
"secrets.block.bash.claim": "this command has a credential ({found}) and did not run",
|
|
5971
|
+
"secrets.block.bash.requires": "Read the value from an environment variable instead of writing it in the command. If the key is real, treat it as exposed and rotate it",
|
|
5972
|
+
"secrets.block.commit.claim": "the staged changes have a credential ({found}), so the commit did not run",
|
|
5973
|
+
"secrets.block.commit.requires": "Remove it from the staged files, keep it in .env (outside git) and rotate it if it is real",
|
|
5974
|
+
"secrets.block.read.claim": "{target} holds secrets, and reading it would put their values in the conversation",
|
|
5975
|
+
"secrets.block.read.requires": "Ask the person for the variable names, or read .env.example",
|
|
5976
|
+
"secrets.block.env_dump.claim": "`{command}` prints every environment variable, secrets included",
|
|
5977
|
+
"secrets.block.env_dump.requires": 'Print only the variable you need by name, or check that it exists with `test -n "$NAME"`',
|
|
5978
|
+
"secrets.block.person_only.claim": "`{command}` is a decision for the person, not the model",
|
|
5979
|
+
"secrets.block.person_only.requires": "Ask the person to run it in their own terminal",
|
|
5937
5980
|
"secrets.block.prompt": "your message was not sent to the model: it has a credential ({found}). If this key was pasted anywhere else, treat it as exposed and rotate it. To use it, put it in .env and tell me only the variable name. Never paste keys into the chat. Incident: {incident}.",
|
|
5938
5981
|
"secrets.post.context": "Finite Monkey: the {tool} output contained a credential ({found}). Incident {incident} is open; rotating the key is the person's decision. Finite Monkey output never repeats the value.",
|
|
5939
5982
|
"secrets.incident.unsaved": "not recorded ({detail})",
|
|
@@ -6126,16 +6169,27 @@ var en_default = {
|
|
|
6126
6169
|
"gate.config.disabled": "Finite Monkey: this change sets disableAllHooks in {file}; it was not applied.",
|
|
6127
6170
|
"gate.config.human": "Kept the Finite Monkey hooks in {file}. If you meant it, type on its own line: finitemonkey: allow config <reason>",
|
|
6128
6171
|
"gate.config.released": "Config change to {file} accepted under your release.",
|
|
6129
|
-
"gate.guard.bypass.no_verify": "
|
|
6130
|
-
"gate.guard.bypass.
|
|
6131
|
-
"gate.guard.bypass.
|
|
6132
|
-
"gate.guard.bypass.
|
|
6133
|
-
"gate.guard.bypass.
|
|
6172
|
+
"gate.guard.bypass.no_verify.claim": "{detail} skips the git hooks",
|
|
6173
|
+
"gate.guard.bypass.no_verify.requires": "the hooks run on every commit and push",
|
|
6174
|
+
"gate.guard.bypass.not": "the same switch through another variable, flag, alias or script",
|
|
6175
|
+
"gate.guard.bypass.hooks_path.claim": "{detail} points git away from the project hooks",
|
|
6176
|
+
"gate.guard.bypass.hooks_path.requires": "core.hooksPath stays as configured",
|
|
6177
|
+
"gate.guard.bypass.hook_env.claim": "{detail} turns hooks or guards off",
|
|
6178
|
+
"gate.guard.bypass.hook_env.requires": "hooks and guards stay on",
|
|
6179
|
+
"gate.guard.bypass.fm_allow.claim": "releases are made by the person, not by a tool call",
|
|
6180
|
+
"gate.guard.bypass.fm_allow.requires": "a release comes from the person typing it in the prompt",
|
|
6181
|
+
"gate.guard.bypass.fm_pause.claim": "only the person pauses or resumes the gate",
|
|
6182
|
+
"gate.guard.bypass.fm_pause.requires": "the gate stays on unless the person pauses it",
|
|
6134
6183
|
"gate.guard.bypass.human": "Blocked {detail}: it would switch the safety net off. If you really want it, type on its own line: finitemonkey: allow bypass <reason>",
|
|
6135
|
-
"gate.guard.self.policy": "
|
|
6136
|
-
"gate.guard.self.
|
|
6184
|
+
"gate.guard.self.policy.claim": "{file} is written only by the finitemonkey executable (evidence, policy and state)",
|
|
6185
|
+
"gate.guard.self.policy.requires": "change it through finitemonkey commands",
|
|
6186
|
+
"gate.guard.self.not": "a copy, move, redirect or script that writes the same file",
|
|
6187
|
+
"gate.guard.self.allow_store.claim": "{file} records what the person released; tools never write it",
|
|
6188
|
+
"gate.guard.self.allow_store.requires": "leave this file to the person",
|
|
6137
6189
|
"gate.guard.self.human": "Kept {file} out of reach: the monkey does not grade its own homework.",
|
|
6138
|
-
"gate.guard.tests.
|
|
6190
|
+
"gate.guard.tests.claim": "{detail}",
|
|
6191
|
+
"gate.guard.tests.requires": "make the code pass the tests as they are",
|
|
6192
|
+
"gate.guard.tests.not": "a test that still runs but no longer checks the behavior",
|
|
6139
6193
|
"gate.guard.tests.shell": "a shell command writes or deletes {file}",
|
|
6140
6194
|
"gate.guard.tests.human": "Blocked: {detail}. Tests are the only witness we have. Fix the code, not the witness. If the change is intended, type on its own line: finitemonkey: allow tests <reason>",
|
|
6141
6195
|
"gate.release.allowed": "Released {guard} until {until}, by your request.",
|
|
@@ -6171,9 +6225,14 @@ var en_default = {
|
|
|
6171
6225
|
"prose.span": "lines {start}-{end}: {rules}",
|
|
6172
6226
|
"prose.fix_item": "{rule}: {fix}",
|
|
6173
6227
|
"prose.warn.command": "{target} reads as machine-written ({spans}). Rewrite it before sending. {fixes}. If it is brand text written on purpose, show the person two alternatives.",
|
|
6174
|
-
"prose.block.command": "
|
|
6175
|
-
"prose.block.
|
|
6176
|
-
"prose.block.
|
|
6228
|
+
"prose.block.command.claim": "{target} reads as machine-written ({spans}), and this project's preset does not send it. {fixes}",
|
|
6229
|
+
"prose.block.command.requires": "Rewrite it and run the command again",
|
|
6230
|
+
"prose.block.not": "the same text with a few words swapped",
|
|
6231
|
+
"prose.block.human": "Held back text that reads as machine-written.",
|
|
6232
|
+
"prose.block.unreadable.claim": "could not read {file} to check its text ({detail})",
|
|
6233
|
+
"prose.block.unreadable.requires": "Check the path and run the command again",
|
|
6234
|
+
"prose.block.marker.claim": "this would add the marker {marker} to {file}, and only the person can add it",
|
|
6235
|
+
"prose.block.marker.requires": "Rewrite the passage instead, or ask the person to add the marker in their own editor",
|
|
6177
6236
|
"prose.check.file": "{file}: {count, plural, one {# passage that reads} other {# passages that read}} as machine-written",
|
|
6178
6237
|
"prose.check.span": " {file}:{start}-{end} score {score}: {rules}",
|
|
6179
6238
|
"prose.check.fix": " do instead: {fix}",
|
|
@@ -6182,7 +6241,8 @@ var en_default = {
|
|
|
6182
6241
|
"prose.error.found": "{count, plural, one {# passage reads} other {# passages read}} as machine-written",
|
|
6183
6242
|
"prose.error.no_input": "nothing to check: pass files, --stdin, or run it inside a git repository to check the changed Markdown files",
|
|
6184
6243
|
"prose.error.unreadable": "could not read {file} ({detail})",
|
|
6185
|
-
"prose.block.marker_shell": "
|
|
6244
|
+
"prose.block.marker_shell.claim": "this command writes the marker {marker}, and only the person can add it",
|
|
6245
|
+
"prose.block.marker_shell.requires": "Rewrite the passage instead, or ask the person to add the marker in their own editor",
|
|
6186
6246
|
"prose.rule.requester-reference": "state the technical reason for the change; leave out who asked for it",
|
|
6187
6247
|
"prose.rule.person-as-reason": "name the property of the change instead of a person",
|
|
6188
6248
|
"prose.rule.origin-project": "describe the technical property you copied instead of naming where it came from",
|
|
@@ -6197,30 +6257,55 @@ var en_default = {
|
|
|
6197
6257
|
"git.command.undo": "List the snapshots or restore one, into a new worktree by default",
|
|
6198
6258
|
"git.command.rescue": "List lost commits from the reflog and fsck, and restore one into a new branch",
|
|
6199
6259
|
"git.command.merge_verify": "Check that a merge kept every change from both sides",
|
|
6200
|
-
"git.block.force_push": "
|
|
6201
|
-
"git.block.
|
|
6202
|
-
"git.block.
|
|
6203
|
-
"git.block.
|
|
6204
|
-
"git.block.
|
|
6205
|
-
"git.block.
|
|
6206
|
-
"git.block.
|
|
6207
|
-
"git.block.
|
|
6208
|
-
"git.block.
|
|
6209
|
-
"git.block.
|
|
6210
|
-
"git.block.
|
|
6211
|
-
"git.block.
|
|
6212
|
-
"git.block.
|
|
6213
|
-
"git.block.
|
|
6214
|
-
"git.block.
|
|
6215
|
-
"git.block.
|
|
6216
|
-
"git.block.
|
|
6260
|
+
"git.block.force_push.claim": "`{command}` rewrites the remote branch and can erase commits someone else pushed",
|
|
6261
|
+
"git.block.force_push.requires": "Fetch, integrate the remote commits and push normally. On your own branch after a rebase, use `git push --force-with-lease=<branch>:<expected sha> --force-if-includes`",
|
|
6262
|
+
"git.block.not": "the same effect through another git command, an alias, a script or a nested shell",
|
|
6263
|
+
"git.block.human": "Stopped a git command that could lose work or rewrite shared history.",
|
|
6264
|
+
"git.block.lease_not_own.claim": "`{command}` forces a push onto {subject}, which is not the branch you are working on or is protected",
|
|
6265
|
+
"git.block.lease_not_own.requires": "A forced push is only for your own branch, with an explicit lease",
|
|
6266
|
+
"git.block.push_delete.claim": "`{command}` deletes {subject} on the remote",
|
|
6267
|
+
"git.block.push_delete.requires": "Deleting a remote branch is for the person to do",
|
|
6268
|
+
"git.block.push_mirror.claim": "`{command}` overwrites every remote ref and would publish the backup refs",
|
|
6269
|
+
"git.block.push_mirror.requires": "Push the branch you need by name",
|
|
6270
|
+
"git.block.clean.claim": "`{command}` deletes untracked files for good; they are in no commit",
|
|
6271
|
+
"git.block.clean.requires": "Run `git clean -n` to see the list, then move what should go into .finitemonkey/trash/ or ask the person",
|
|
6272
|
+
"git.block.stash_drop.claim": "`{command}` throws away stashed work that exists nowhere else",
|
|
6273
|
+
"git.block.stash_drop.requires": "Apply it with `git stash apply` or leave it; dropping a stash is for the person to do",
|
|
6274
|
+
"git.block.branch_unmerged.claim": "`{command}` deletes {subject}, whose commits are neither in its upstream nor in the default branch",
|
|
6275
|
+
"git.block.branch_unmerged.requires": "Push or merge it first; `git branch -d` works once it is merged",
|
|
6276
|
+
"git.block.worktree_force.claim": "`{command}` removes a worktree even with uncommitted changes",
|
|
6277
|
+
"git.block.worktree_force.requires": "Commit or archive its work first; plain `git worktree remove` refuses a dirty tree on purpose",
|
|
6278
|
+
"git.block.rm_worktree.claim": "`{command}` deletes {subject}, which is a git worktree or repository; uncommitted work in it would be lost",
|
|
6279
|
+
"git.block.rm_worktree.requires": "Commit or archive it, then use `git worktree remove` without --force",
|
|
6280
|
+
"git.block.rm_root.claim": "`{command}` recursively deletes {subject}, a root or home directory",
|
|
6281
|
+
"git.block.rm_root.requires": "Name the exact folder to remove",
|
|
6282
|
+
"git.block.rebase_protected.claim": "`{command}` rewrites {subject}, a protected branch",
|
|
6283
|
+
"git.block.rebase_protected.requires": "Change it through a pull request",
|
|
6284
|
+
"git.block.rebase_shared.claim": "`{command}` rewrites {subject}, which already has someone else's commits on the remote",
|
|
6285
|
+
"git.block.rebase_shared.requires": "Merge the base into it instead of rebasing",
|
|
6286
|
+
"git.block.merge_side.claim": "`{command}` resolves conflicts by taking one side whole ({subject}), which silently drops the other side's changes",
|
|
6287
|
+
"git.block.merge_side.requires": "Resolve each conflict by hand and run `finitemonkey merge verify` before committing",
|
|
6288
|
+
"git.block.history.claim": "`{command}` deletes history or reflog entries that undo and rescue depend on",
|
|
6289
|
+
"git.block.history.requires": "Rewriting history is for the person to do",
|
|
6290
|
+
"git.block.protected_commit.claim": "`{command}` would commit straight onto {subject}, a protected branch",
|
|
6291
|
+
"git.block.protected_commit.requires": "Create a branch with `git switch -c <type>/<name>` and open a pull request",
|
|
6292
|
+
"git.block.protected_push.claim": "`{command}` pushes to {subject}, a protected branch",
|
|
6293
|
+
"git.block.protected_push.requires": "Push your own branch and open a pull request",
|
|
6294
|
+
"git.block.foreign.claim": "`{command}` would discard changes this session did not make: {files}",
|
|
6295
|
+
"git.block.foreign.requires": "Undo only your own lines with Edit",
|
|
6217
6296
|
"git.foreign.before": "{path} (had changes before you started)",
|
|
6218
6297
|
"git.foreign.other": "{path} (changed outside this session)",
|
|
6219
|
-
"git.block.unknown": "
|
|
6220
|
-
"git.block.
|
|
6298
|
+
"git.block.unknown.claim": "`{command}` discards changes, and `git status` failed, so there is no telling whose they are",
|
|
6299
|
+
"git.block.unknown.requires": "Fix the repository and try again",
|
|
6300
|
+
"git.block.snapshot_failed.claim": "`{command}` is risky and the safety snapshot before it failed ({detail}), so it did not run",
|
|
6301
|
+
"git.block.snapshot_failed.requires": "Fix the cause and try again",
|
|
6221
6302
|
"git.snapshot.context": "finitemonkey saved a snapshot before `{command}`: {ref}. `finitemonkey undo {ref}` brings the previous state back.",
|
|
6222
|
-
"prod.block.effect": "
|
|
6223
|
-
"prod.block.
|
|
6303
|
+
"prod.block.effect.claim": "`{command}` changes production ({target}) by hand, and a server edited by hand drifts from the repository",
|
|
6304
|
+
"prod.block.effect.requires": "Change it through the deploy path ({deploy}): commit, open a pull request and let the deploy run",
|
|
6305
|
+
"prod.block.not": "the same change through another tool, a script or a nested shell",
|
|
6306
|
+
"prod.block.human": "Stopped a hand edit to production; changes go through the deploy.",
|
|
6307
|
+
"prod.block.interactive.claim": "`{command}` opens an interactive session on production ({target}), where nothing typed can be checked first",
|
|
6308
|
+
"prod.block.interactive.requires": "Run one read-only command at a time, such as `ssh {target} docker ps`",
|
|
6224
6309
|
"prod.deploy.unknown": "the project's declared deploy",
|
|
6225
6310
|
"git.snapshot.done": "snapshot saved: {ref} ({commit}). `finitemonkey undo {ref}` restores it.",
|
|
6226
6311
|
"git.undo.list_title": "{count, plural, one {# snapshot:} other {# snapshots, newest first:}}",
|
|
@@ -6347,7 +6432,11 @@ var en_default = {
|
|
|
6347
6432
|
"gate.look.allow_ignored": "exception ignored, its decision is not recorded: {entry}",
|
|
6348
6433
|
"gate.look.unopened": "{count, plural, one {# capture} other {# captures}} not opened after the last edit to a screen file",
|
|
6349
6434
|
"gate.look.open": "open with Read: {file}",
|
|
6350
|
-
"gate.look.ok": "{count, plural, one {# capture} other {# captures}}, no failure, all opened"
|
|
6435
|
+
"gate.look.ok": "{count, plural, one {# capture} other {# captures}}, no failure, all opened",
|
|
6436
|
+
"reason.label.blocked": "blocked",
|
|
6437
|
+
"reason.label.requires": "requires",
|
|
6438
|
+
"reason.label.not": "does not count",
|
|
6439
|
+
"reason.human.generic": "Blocked a tool call; the reason went to Claude."
|
|
6351
6440
|
};
|
|
6352
6441
|
|
|
6353
6442
|
// src/i18n/es.json
|
|
@@ -6396,6 +6485,7 @@ var es_default = {
|
|
|
6396
6485
|
"i18n.problem.placeholder": "marcadores distintos (esperado: {expected}; encontrado: {actual})",
|
|
6397
6486
|
"i18n.problem.plural": "faltan ramas de plural (necesita: {expected}; encontradas: {actual})",
|
|
6398
6487
|
"i18n.problem.status": "sin estado de revisión (use: {expected})",
|
|
6488
|
+
"i18n.problem.release_hint": "instrucción de liberación en texto que lee el modelo ({actual}); muévela a una clave que lee la persona",
|
|
6399
6489
|
"i18n.problem.empty": "texto vacío",
|
|
6400
6490
|
"i18n.problem.not_string": "el valor no es texto",
|
|
6401
6491
|
"doctor.title": "finitemonkey doctor ({version})",
|
|
@@ -6522,12 +6612,20 @@ var es_default = {
|
|
|
6522
6612
|
"secrets.where.line": "línea {line}, columna {column}",
|
|
6523
6613
|
"secrets.where.file": "{file}:{line}:{column}",
|
|
6524
6614
|
"secrets.where.new_text": "{file} (línea {line} del texto nuevo)",
|
|
6525
|
-
"secrets.block.write": "
|
|
6526
|
-
"secrets.block.
|
|
6527
|
-
"secrets.block.
|
|
6528
|
-
"secrets.block.
|
|
6529
|
-
"secrets.block.
|
|
6530
|
-
"secrets.block.
|
|
6615
|
+
"secrets.block.write.claim": "el texto nuevo de {file} tiene una credencial ({found})",
|
|
6616
|
+
"secrets.block.write.requires": "No se escribió nada. Deja el valor en .env (fuera de git) y léelo por el nombre de la variable. Si la clave es real, trátala como expuesta y rótala",
|
|
6617
|
+
"secrets.block.not": "una copia codificada, partida, comentada o renombrada del mismo valor",
|
|
6618
|
+
"secrets.block.human": "Mantuve una credencial fuera de un archivo, comando o commit.",
|
|
6619
|
+
"secrets.block.bash.claim": "este comando tiene una credencial ({found}) y no se ejecutó",
|
|
6620
|
+
"secrets.block.bash.requires": "Lee el valor de una variable de entorno en lugar de escribirlo en el comando. Si la clave es real, trátala como expuesta y rótala",
|
|
6621
|
+
"secrets.block.commit.claim": "los cambios preparados tienen una credencial ({found}), así que el commit no se ejecutó",
|
|
6622
|
+
"secrets.block.commit.requires": "Quítala de los archivos preparados, déjala en .env (fuera de git) y rótala si es real",
|
|
6623
|
+
"secrets.block.read.claim": "{target} guarda secretos, y leerlo pondría sus valores en la conversación",
|
|
6624
|
+
"secrets.block.read.requires": "Pide a la persona los nombres de las variables, o lee .env.example",
|
|
6625
|
+
"secrets.block.env_dump.claim": "`{command}` imprime todas las variables de entorno, secretos incluidos",
|
|
6626
|
+
"secrets.block.env_dump.requires": 'Imprime solo la variable que necesitas por su nombre, o comprueba que existe con `test -n "$NAME"`',
|
|
6627
|
+
"secrets.block.person_only.claim": "`{command}` es una decisión de la persona, no del modelo",
|
|
6628
|
+
"secrets.block.person_only.requires": "Pide a la persona que lo ejecute en su propia terminal",
|
|
6531
6629
|
"secrets.block.prompt": "tu mensaje no se envió al modelo: tiene una credencial ({found}). Si esta clave se pegó en otro lugar, trátala como expuesta y rótala. Para usarla, ponla en .env y dime solo el nombre de la variable. Nunca pegues claves en el chat. Incidente: {incident}.",
|
|
6532
6630
|
"secrets.post.context": "Finite Monkey: la salida de {tool} contenía una credencial ({found}). El incidente {incident} está abierto; rotar la clave es decisión de la persona. La salida de Finite Monkey nunca repite el valor.",
|
|
6533
6631
|
"secrets.incident.unsaved": "no registrado ({detail})",
|
|
@@ -6720,16 +6818,27 @@ var es_default = {
|
|
|
6720
6818
|
"gate.config.disabled": "Finite Monkey: este cambio activa disableAllHooks en {file}; no se aplicó.",
|
|
6721
6819
|
"gate.config.human": "Mantuve los hooks de Finite Monkey en {file}. Si fue a propósito, escriba en una línea: finitemonkey: allow config <motivo>",
|
|
6722
6820
|
"gate.config.released": "Cambio de config en {file} aceptado por su liberación.",
|
|
6723
|
-
"gate.guard.bypass.no_verify": "
|
|
6724
|
-
"gate.guard.bypass.
|
|
6725
|
-
"gate.guard.bypass.
|
|
6726
|
-
"gate.guard.bypass.
|
|
6727
|
-
"gate.guard.bypass.
|
|
6821
|
+
"gate.guard.bypass.no_verify.claim": "{detail} se salta los git hooks",
|
|
6822
|
+
"gate.guard.bypass.no_verify.requires": "los hooks corren en cada commit y push",
|
|
6823
|
+
"gate.guard.bypass.not": "el mismo interruptor con otra variable, flag, alias o script",
|
|
6824
|
+
"gate.guard.bypass.hooks_path.claim": "{detail} desvía git de los hooks del proyecto",
|
|
6825
|
+
"gate.guard.bypass.hooks_path.requires": "core.hooksPath queda como está configurado",
|
|
6826
|
+
"gate.guard.bypass.hook_env.claim": "{detail} apaga hooks o guardas",
|
|
6827
|
+
"gate.guard.bypass.hook_env.requires": "hooks y guardas quedan encendidos",
|
|
6828
|
+
"gate.guard.bypass.fm_allow.claim": "las liberaciones las hace la persona, no una llamada de herramienta",
|
|
6829
|
+
"gate.guard.bypass.fm_allow.requires": "la liberación viene de la persona escribiéndola en el prompt",
|
|
6830
|
+
"gate.guard.bypass.fm_pause.claim": "solo la persona pausa o reanuda la compuerta",
|
|
6831
|
+
"gate.guard.bypass.fm_pause.requires": "la compuerta sigue activa salvo que la persona la pause",
|
|
6728
6832
|
"gate.guard.bypass.human": "Bloqueé {detail}: apagaría la red de seguridad. Si de verdad lo quiere, escriba en una línea: finitemonkey: allow bypass <motivo>",
|
|
6729
|
-
"gate.guard.self.policy": "
|
|
6730
|
-
"gate.guard.self.
|
|
6833
|
+
"gate.guard.self.policy.claim": "{file} solo lo escribe el ejecutable finitemonkey (evidencia, política y estado)",
|
|
6834
|
+
"gate.guard.self.policy.requires": "cambiarlo con los comandos de finitemonkey",
|
|
6835
|
+
"gate.guard.self.not": "una copia, movimiento, redirección o script que escribe el mismo archivo",
|
|
6836
|
+
"gate.guard.self.allow_store.claim": "{file} registra lo que la persona liberó; ninguna herramienta lo escribe",
|
|
6837
|
+
"gate.guard.self.allow_store.requires": "dejar este archivo a la persona",
|
|
6731
6838
|
"gate.guard.self.human": "Dejé {file} fuera de alcance: el mono no corrige su propio examen.",
|
|
6732
|
-
"gate.guard.tests.
|
|
6839
|
+
"gate.guard.tests.claim": "{detail}",
|
|
6840
|
+
"gate.guard.tests.requires": "hacer que el código pase las pruebas como están",
|
|
6841
|
+
"gate.guard.tests.not": "una prueba que sigue corriendo pero ya no comprueba el comportamiento",
|
|
6733
6842
|
"gate.guard.tests.shell": "un comando de shell escribe o borra {file}",
|
|
6734
6843
|
"gate.guard.tests.human": "Bloqueado: {detail}. La prueba es el único testigo que tenemos. Corrija el código, no al testigo. Si el cambio es a propósito, escriba en una línea: finitemonkey: allow tests <motivo>",
|
|
6735
6844
|
"gate.release.allowed": "Liberé {guard} hasta {until}, a su pedido.",
|
|
@@ -6765,9 +6874,14 @@ var es_default = {
|
|
|
6765
6874
|
"prose.span": "líneas {start}-{end}: {rules}",
|
|
6766
6875
|
"prose.fix_item": "{rule}: {fix}",
|
|
6767
6876
|
"prose.warn.command": "{target} parece escrito por IA ({spans}). Reescríbelo antes de enviarlo. {fixes}. Si es texto de marca escrito a propósito, muéstrale dos alternativas a la persona.",
|
|
6768
|
-
"prose.block.command": "
|
|
6769
|
-
"prose.block.
|
|
6770
|
-
"prose.block.
|
|
6877
|
+
"prose.block.command.claim": "{target} parece escrito por IA ({spans}), y el preset de este proyecto no deja enviarlo. {fixes}",
|
|
6878
|
+
"prose.block.command.requires": "Reescríbelo y vuelve a ejecutar el comando",
|
|
6879
|
+
"prose.block.not": "el mismo texto con algunas palabras cambiadas",
|
|
6880
|
+
"prose.block.human": "Retuve un texto que parece escrito por una máquina.",
|
|
6881
|
+
"prose.block.unreadable.claim": "no se pudo leer {file} para revisar el texto ({detail})",
|
|
6882
|
+
"prose.block.unreadable.requires": "Revisa la ruta y vuelve a ejecutar el comando",
|
|
6883
|
+
"prose.block.marker.claim": "esto añadiría el marcador {marker} en {file}, y solo la persona puede ponerlo",
|
|
6884
|
+
"prose.block.marker.requires": "Reescribe el pasaje, o pide a la persona que ponga el marcador en su propio editor",
|
|
6771
6885
|
"prose.check.file": "{file}: {count, plural, one {# pasaje que parece escrito} other {# pasajes que parecen escritos}} por IA",
|
|
6772
6886
|
"prose.check.span": " {file}:{start}-{end} puntos {score}: {rules}",
|
|
6773
6887
|
"prose.check.fix": " haz en su lugar: {fix}",
|
|
@@ -6776,7 +6890,8 @@ var es_default = {
|
|
|
6776
6890
|
"prose.error.found": "{count, plural, one {# pasaje parece escrito} other {# pasajes parecen escritos}} por IA",
|
|
6777
6891
|
"prose.error.no_input": "nada que revisar: pasa archivos, --stdin, o ejecútalo dentro de un repositorio git para revisar los Markdown modificados",
|
|
6778
6892
|
"prose.error.unreadable": "no se pudo leer {file} ({detail})",
|
|
6779
|
-
"prose.block.marker_shell": "
|
|
6893
|
+
"prose.block.marker_shell.claim": "este comando escribe el marcador {marker}, y solo la persona puede ponerlo",
|
|
6894
|
+
"prose.block.marker_shell.requires": "Reescribe el pasaje, o pide a la persona que ponga el marcador en su propio editor",
|
|
6780
6895
|
"prose.rule.requester-reference": "di el motivo técnico del cambio, sin decir quién lo pidió",
|
|
6781
6896
|
"prose.rule.person-as-reason": "nombra la propiedad del cambio en lugar de la persona",
|
|
6782
6897
|
"prose.rule.origin-project": "describe la propiedad técnica, sin citar de dónde salió",
|
|
@@ -6791,30 +6906,55 @@ var es_default = {
|
|
|
6791
6906
|
"git.command.undo": "Lista las instantáneas o restaura una, por defecto en un worktree nuevo",
|
|
6792
6907
|
"git.command.rescue": "Lista commits perdidos por el reflog y el fsck, y restaura uno en una rama nueva",
|
|
6793
6908
|
"git.command.merge_verify": "Comprueba que una fusión conservó cada cambio de los dos lados",
|
|
6794
|
-
"git.block.force_push": "
|
|
6795
|
-
"git.block.
|
|
6796
|
-
"git.block.
|
|
6797
|
-
"git.block.
|
|
6798
|
-
"git.block.
|
|
6799
|
-
"git.block.
|
|
6800
|
-
"git.block.
|
|
6801
|
-
"git.block.
|
|
6802
|
-
"git.block.
|
|
6803
|
-
"git.block.
|
|
6804
|
-
"git.block.
|
|
6805
|
-
"git.block.
|
|
6806
|
-
"git.block.
|
|
6807
|
-
"git.block.
|
|
6808
|
-
"git.block.
|
|
6809
|
-
"git.block.
|
|
6810
|
-
"git.block.
|
|
6909
|
+
"git.block.force_push.claim": "`{command}` reescribe la rama remota y puede borrar commits que otra persona subió",
|
|
6910
|
+
"git.block.force_push.requires": "Trae e integra los commits remotos y sube normalmente. En tu propia rama después de un rebase, usa `git push --force-with-lease=<rama>:<sha esperado> --force-if-includes`",
|
|
6911
|
+
"git.block.not": "el mismo efecto con otro comando git, un alias, un script o un shell anidado",
|
|
6912
|
+
"git.block.human": "Detuve un comando git que podía perder trabajo o reescribir historia compartida.",
|
|
6913
|
+
"git.block.lease_not_own.claim": "`{command}` fuerza un push sobre {subject}, que no es la rama en la que trabajas o está protegida",
|
|
6914
|
+
"git.block.lease_not_own.requires": "El push forzado solo vale en tu propia rama, con lease explícito",
|
|
6915
|
+
"git.block.push_delete.claim": "`{command}` borra {subject} en el remoto",
|
|
6916
|
+
"git.block.push_delete.requires": "Borrar una rama remota le toca a la persona",
|
|
6917
|
+
"git.block.push_mirror.claim": "`{command}` sobrescribe todas las refs del remoto y publicaría las refs de respaldo",
|
|
6918
|
+
"git.block.push_mirror.requires": "Sube por nombre la rama que necesitas",
|
|
6919
|
+
"git.block.clean.claim": "`{command}` borra para siempre archivos sin seguimiento, que no están en ningún commit",
|
|
6920
|
+
"git.block.clean.requires": "Corre `git clean -n` para ver la lista y mueve lo que deba irse a .finitemonkey/trash/, o pregunta a la persona",
|
|
6921
|
+
"git.block.stash_drop.claim": "`{command}` tira trabajo guardado en el stash que no existe en otro lugar",
|
|
6922
|
+
"git.block.stash_drop.requires": "Aplícalo con `git stash apply` o déjalo; descartar un stash le toca a la persona",
|
|
6923
|
+
"git.block.branch_unmerged.claim": "`{command}` borra {subject}, cuyos commits no están en su upstream ni en la rama por defecto",
|
|
6924
|
+
"git.block.branch_unmerged.requires": "Súbela o fusiónala antes; `git branch -d` funciona cuando ya está fusionada",
|
|
6925
|
+
"git.block.worktree_force.claim": "`{command}` elimina un worktree aunque tenga cambios sin commit",
|
|
6926
|
+
"git.block.worktree_force.requires": "Haz commit o archiva su trabajo antes; `git worktree remove` sin forzar rechaza un árbol sucio a propósito",
|
|
6927
|
+
"git.block.rm_worktree.claim": "`{command}` borra {subject}, que es un worktree o repositorio git; el trabajo sin commit se perdería",
|
|
6928
|
+
"git.block.rm_worktree.requires": "Haz commit o archívalo y luego usa `git worktree remove` sin --force",
|
|
6929
|
+
"git.block.rm_root.claim": "`{command}` borra de forma recursiva {subject}, una carpeta raíz o la carpeta personal",
|
|
6930
|
+
"git.block.rm_root.requires": "Indica la carpeta exacta a eliminar",
|
|
6931
|
+
"git.block.rebase_protected.claim": "`{command}` reescribe {subject}, una rama protegida",
|
|
6932
|
+
"git.block.rebase_protected.requires": "Cámbiala con un pull request",
|
|
6933
|
+
"git.block.rebase_shared.claim": "`{command}` reescribe {subject}, que ya tiene commits de otra persona en el remoto",
|
|
6934
|
+
"git.block.rebase_shared.requires": "Fusiona la base en ella en lugar de hacer rebase",
|
|
6935
|
+
"git.block.merge_side.claim": "`{command}` resuelve conflictos tomando un lado entero ({subject}), lo que descarta en silencio los cambios del otro lado",
|
|
6936
|
+
"git.block.merge_side.requires": "Resuelve cada conflicto a mano y corre `finitemonkey merge verify` antes del commit",
|
|
6937
|
+
"git.block.history.claim": "`{command}` borra historial o entradas del reflog de las que dependen undo y rescue",
|
|
6938
|
+
"git.block.history.requires": "Reescribir el historial le toca a la persona",
|
|
6939
|
+
"git.block.protected_commit.claim": "`{command}` haría commit directo en {subject}, una rama protegida",
|
|
6940
|
+
"git.block.protected_commit.requires": "Crea una rama con `git switch -c <tipo>/<nombre>` y abre un pull request",
|
|
6941
|
+
"git.block.protected_push.claim": "`{command}` sube a {subject}, una rama protegida",
|
|
6942
|
+
"git.block.protected_push.requires": "Sube tu propia rama y abre un pull request",
|
|
6943
|
+
"git.block.foreign.claim": "`{command}` descartaría cambios que esta sesión no hizo: {files}",
|
|
6944
|
+
"git.block.foreign.requires": "Deshaz solo tus líneas con Edit",
|
|
6811
6945
|
"git.foreign.before": "{path} (tenía cambios antes de que empezaras)",
|
|
6812
6946
|
"git.foreign.other": "{path} (cambiado fuera de esta sesión)",
|
|
6813
|
-
"git.block.unknown": "
|
|
6814
|
-
"git.block.
|
|
6947
|
+
"git.block.unknown.claim": "`{command}` descarta cambios y `git status` falló, así que no hay forma de saber de quién son",
|
|
6948
|
+
"git.block.unknown.requires": "Arregla el repositorio e inténtalo de nuevo",
|
|
6949
|
+
"git.block.snapshot_failed.claim": "`{command}` es arriesgado y la instantánea de seguridad previa falló ({detail}), así que no se ejecutó",
|
|
6950
|
+
"git.block.snapshot_failed.requires": "Corrige la causa e inténtalo de nuevo",
|
|
6815
6951
|
"git.snapshot.context": "finitemonkey guardó una instantánea antes de `{command}`: {ref}. `finitemonkey undo {ref}` devuelve el estado anterior.",
|
|
6816
|
-
"prod.block.effect": "
|
|
6817
|
-
"prod.block.
|
|
6952
|
+
"prod.block.effect.claim": "`{command}` cambia producción ({target}) a mano, y un servidor editado a mano se aparta del repositorio",
|
|
6953
|
+
"prod.block.effect.requires": "Cámbialo por el camino de deploy ({deploy}): commit, pull request y que corra el deploy",
|
|
6954
|
+
"prod.block.not": "el mismo cambio con otra herramienta, un script o un shell anidado",
|
|
6955
|
+
"prod.block.human": "Detuve una edición a mano en producción; los cambios van por el despliegue.",
|
|
6956
|
+
"prod.block.interactive.claim": "`{command}` abre una sesión interactiva en producción ({target}), donde nada de lo que se escriba se revisa antes",
|
|
6957
|
+
"prod.block.interactive.requires": "Corre un comando de solo lectura a la vez, como `ssh {target} docker ps`",
|
|
6818
6958
|
"prod.deploy.unknown": "el deploy declarado del proyecto",
|
|
6819
6959
|
"git.snapshot.done": "instantánea guardada: {ref} ({commit}). `finitemonkey undo {ref}` la restaura.",
|
|
6820
6960
|
"git.undo.list_title": "{count, plural, one {# instantánea:} other {# instantáneas, de la más nueva a la más vieja:}}",
|
|
@@ -6941,7 +7081,11 @@ var es_default = {
|
|
|
6941
7081
|
"gate.look.allow_ignored": "excepción ignorada, su decisión no está registrada: {entry}",
|
|
6942
7082
|
"gate.look.unopened": "{count, plural, one {# captura sin abrir} other {# capturas sin abrir}} después de la última edición de un archivo de pantalla",
|
|
6943
7083
|
"gate.look.open": "abre con Read: {file}",
|
|
6944
|
-
"gate.look.ok": "{count, plural, one {# captura} other {# capturas}}, ningún fallo, todas abiertas"
|
|
7084
|
+
"gate.look.ok": "{count, plural, one {# captura} other {# capturas}}, ningún fallo, todas abiertas",
|
|
7085
|
+
"reason.label.blocked": "bloqueado",
|
|
7086
|
+
"reason.label.requires": "exige",
|
|
7087
|
+
"reason.label.not": "no cuenta",
|
|
7088
|
+
"reason.human.generic": "Bloqueé una llamada de herramienta; el motivo fue a Claude."
|
|
6945
7089
|
};
|
|
6946
7090
|
|
|
6947
7091
|
// src/i18n/pt-BR.json
|
|
@@ -6990,6 +7134,7 @@ var pt_BR_default = {
|
|
|
6990
7134
|
"i18n.problem.placeholder": "marcadores diferentes (esperado: {expected}; encontrado: {actual})",
|
|
6991
7135
|
"i18n.problem.plural": "faltam ramos de plural (precisa: {expected}; achados: {actual})",
|
|
6992
7136
|
"i18n.problem.status": "sem status de revisão (use: {expected})",
|
|
7137
|
+
"i18n.problem.release_hint": "instrução de liberação em texto que o modelo lê ({actual}); leve para uma chave que a pessoa lê",
|
|
6993
7138
|
"i18n.problem.empty": "texto vazio",
|
|
6994
7139
|
"i18n.problem.not_string": "valor não é texto",
|
|
6995
7140
|
"doctor.title": "finitemonkey doctor ({version})",
|
|
@@ -7116,12 +7261,20 @@ var pt_BR_default = {
|
|
|
7116
7261
|
"secrets.where.line": "linha {line}, coluna {column}",
|
|
7117
7262
|
"secrets.where.file": "{file}:{line}:{column}",
|
|
7118
7263
|
"secrets.where.new_text": "{file} (linha {line} do texto novo)",
|
|
7119
|
-
"secrets.block.write": "
|
|
7120
|
-
"secrets.block.
|
|
7121
|
-
"secrets.block.
|
|
7122
|
-
"secrets.block.
|
|
7123
|
-
"secrets.block.
|
|
7124
|
-
"secrets.block.
|
|
7264
|
+
"secrets.block.write.claim": "o texto novo de {file} tem uma credencial ({found})",
|
|
7265
|
+
"secrets.block.write.requires": "Nada foi gravado. Deixe o valor no .env (fora do git) e leia pelo nome da variável. Se a chave é real, trate como exposta e troque",
|
|
7266
|
+
"secrets.block.not": "uma cópia codificada, partida, comentada ou renomeada do mesmo valor",
|
|
7267
|
+
"secrets.block.human": "Mantive uma credencial fora de um arquivo, comando ou commit.",
|
|
7268
|
+
"secrets.block.bash.claim": "este comando tem uma credencial ({found}) e não rodou",
|
|
7269
|
+
"secrets.block.bash.requires": "Leia o valor de uma variável de ambiente em vez de escrevê-lo no comando. Se a chave é real, trate como exposta e troque",
|
|
7270
|
+
"secrets.block.commit.claim": "as mudanças preparadas têm uma credencial ({found}), então o commit não rodou",
|
|
7271
|
+
"secrets.block.commit.requires": "Tire-a dos arquivos preparados, deixe no .env (fora do git) e troque a chave se for real",
|
|
7272
|
+
"secrets.block.read.claim": "{target} guarda segredos, e lê-lo colocaria os valores na conversa",
|
|
7273
|
+
"secrets.block.read.requires": "Peça à pessoa os nomes das variáveis, ou leia o .env.example",
|
|
7274
|
+
"secrets.block.env_dump.claim": "`{command}` imprime todas as variáveis de ambiente, segredos inclusive",
|
|
7275
|
+
"secrets.block.env_dump.requires": 'Imprima só a variável que precisa, pelo nome, ou confira que ela existe com `test -n "$NAME"`',
|
|
7276
|
+
"secrets.block.person_only.claim": "`{command}` é decisão da pessoa, não do modelo",
|
|
7277
|
+
"secrets.block.person_only.requires": "Peça à pessoa que rode no terminal dela",
|
|
7125
7278
|
"secrets.block.prompt": "sua mensagem não foi enviada ao modelo: ela tem uma credencial ({found}). Se essa chave foi colada em outro lugar, trate como exposta e troque. Para usá-la, ponha no .env e me diga só o nome da variável. Nunca cole chaves na conversa. Incidente: {incident}.",
|
|
7126
7279
|
"secrets.post.context": "Finite Monkey: a saída de {tool} continha uma credencial ({found}). O incidente {incident} está aberto; trocar a chave é decisão da pessoa. A saída do Finite Monkey nunca repete o valor.",
|
|
7127
7280
|
"secrets.incident.unsaved": "não registrado ({detail})",
|
|
@@ -7314,16 +7467,27 @@ var pt_BR_default = {
|
|
|
7314
7467
|
"gate.config.disabled": "Finite Monkey: esta mudança liga disableAllHooks em {file}; ela não foi aplicada.",
|
|
7315
7468
|
"gate.config.human": "Mantive os hooks do Finite Monkey em {file}. Se foi de propósito, digite numa linha: finitemonkey: allow config <motivo>",
|
|
7316
7469
|
"gate.config.released": "Mudança de config em {file} aceita pela sua liberação.",
|
|
7317
|
-
"gate.guard.bypass.no_verify": "
|
|
7318
|
-
"gate.guard.bypass.
|
|
7319
|
-
"gate.guard.bypass.
|
|
7320
|
-
"gate.guard.bypass.
|
|
7321
|
-
"gate.guard.bypass.
|
|
7470
|
+
"gate.guard.bypass.no_verify.claim": "{detail} pula os git hooks",
|
|
7471
|
+
"gate.guard.bypass.no_verify.requires": "os hooks rodam em todo commit e push",
|
|
7472
|
+
"gate.guard.bypass.not": "a mesma chave por outra variável, flag, alias ou script",
|
|
7473
|
+
"gate.guard.bypass.hooks_path.claim": "{detail} desvia o git dos hooks do projeto",
|
|
7474
|
+
"gate.guard.bypass.hooks_path.requires": "core.hooksPath fica como está configurado",
|
|
7475
|
+
"gate.guard.bypass.hook_env.claim": "{detail} desliga hooks ou travas",
|
|
7476
|
+
"gate.guard.bypass.hook_env.requires": "hooks e travas ficam ligados",
|
|
7477
|
+
"gate.guard.bypass.fm_allow.claim": "liberação é feita pela pessoa, não por chamada de ferramenta",
|
|
7478
|
+
"gate.guard.bypass.fm_allow.requires": "a liberação vem da pessoa digitando no prompt",
|
|
7479
|
+
"gate.guard.bypass.fm_pause.claim": "só a pessoa pausa ou retoma o portão",
|
|
7480
|
+
"gate.guard.bypass.fm_pause.requires": "o portão fica ligado a menos que a pessoa o pause",
|
|
7322
7481
|
"gate.guard.bypass.human": "Barrei {detail}: desligaria a rede de proteção. Se quiser mesmo, digite numa linha: finitemonkey: allow bypass <motivo>",
|
|
7323
|
-
"gate.guard.self.policy": "
|
|
7324
|
-
"gate.guard.self.
|
|
7482
|
+
"gate.guard.self.policy.claim": "{file} só é escrito pelo executável finitemonkey (evidência, política e estado)",
|
|
7483
|
+
"gate.guard.self.policy.requires": "mudar pelos comandos do finitemonkey",
|
|
7484
|
+
"gate.guard.self.not": "uma cópia, move, redirecionamento ou script que grava o mesmo arquivo",
|
|
7485
|
+
"gate.guard.self.allow_store.claim": "{file} registra o que a pessoa liberou; ferramenta nunca escreve nele",
|
|
7486
|
+
"gate.guard.self.allow_store.requires": "deixar este arquivo para a pessoa",
|
|
7325
7487
|
"gate.guard.self.human": "Deixei {file} fora do alcance: o macaco não corrige a própria prova.",
|
|
7326
|
-
"gate.guard.tests.
|
|
7488
|
+
"gate.guard.tests.claim": "{detail}",
|
|
7489
|
+
"gate.guard.tests.requires": "fazer o código passar nos testes como estão",
|
|
7490
|
+
"gate.guard.tests.not": "um teste que ainda roda mas não confere mais o comportamento",
|
|
7327
7491
|
"gate.guard.tests.shell": "um comando de shell escreve ou apaga {file}",
|
|
7328
7492
|
"gate.guard.tests.human": "Barrado: {detail}. O teste é a única testemunha que temos. Corrija o código, não a testemunha. Se a mudança é de propósito, digite numa linha: finitemonkey: allow tests <motivo>",
|
|
7329
7493
|
"gate.release.allowed": "Liberei {guard} até {until}, a seu pedido.",
|
|
@@ -7359,9 +7523,14 @@ var pt_BR_default = {
|
|
|
7359
7523
|
"prose.span": "linhas {start}-{end}: {rules}",
|
|
7360
7524
|
"prose.fix_item": "{rule}: {fix}",
|
|
7361
7525
|
"prose.warn.command": "{target} tem cara de texto de IA ({spans}). Reescreva antes de enviar. {fixes}. Se for texto de marca escrito de propósito, mostre duas alternativas à pessoa.",
|
|
7362
|
-
"prose.block.command": "
|
|
7363
|
-
"prose.block.
|
|
7364
|
-
"prose.block.
|
|
7526
|
+
"prose.block.command.claim": "{target} tem cara de texto de IA ({spans}), e o preset deste projeto não deixa enviar. {fixes}",
|
|
7527
|
+
"prose.block.command.requires": "Reescreva e rode o comando de novo",
|
|
7528
|
+
"prose.block.not": "o mesmo texto com algumas palavras trocadas",
|
|
7529
|
+
"prose.block.human": "Segurei um texto com cara de escrito por máquina.",
|
|
7530
|
+
"prose.block.unreadable.claim": "não deu para ler {file} para conferir o texto ({detail})",
|
|
7531
|
+
"prose.block.unreadable.requires": "Confira o caminho e rode o comando de novo",
|
|
7532
|
+
"prose.block.marker.claim": "isto acrescentaria o marcador {marker} em {file}, e só a pessoa pode pôr esse marcador",
|
|
7533
|
+
"prose.block.marker.requires": "Reescreva o trecho, ou peça à pessoa que ponha o marcador no editor dela",
|
|
7365
7534
|
"prose.check.file": "{file}: {count, plural, one {# trecho} other {# trechos}} com cara de texto de IA",
|
|
7366
7535
|
"prose.check.span": " {file}:{start}-{end} pontos {score}: {rules}",
|
|
7367
7536
|
"prose.check.fix": " faça no lugar: {fix}",
|
|
@@ -7370,7 +7539,8 @@ var pt_BR_default = {
|
|
|
7370
7539
|
"prose.error.found": "{count, plural, one {# trecho} other {# trechos}} com cara de texto de IA",
|
|
7371
7540
|
"prose.error.no_input": "nada para conferir: passe arquivos, --stdin, ou rode dentro de um repositório git para conferir os Markdown alterados",
|
|
7372
7541
|
"prose.error.unreadable": "não deu para ler {file} ({detail})",
|
|
7373
|
-
"prose.block.marker_shell": "
|
|
7542
|
+
"prose.block.marker_shell.claim": "este comando escreve o marcador {marker}, e só a pessoa pode pôr esse marcador",
|
|
7543
|
+
"prose.block.marker_shell.requires": "Reescreva o trecho, ou peça à pessoa que ponha o marcador no editor dela",
|
|
7374
7544
|
"prose.rule.requester-reference": "diga o motivo técnico da mudança, sem dizer quem pediu",
|
|
7375
7545
|
"prose.rule.person-as-reason": "nomeie a propriedade da mudança no lugar da pessoa",
|
|
7376
7546
|
"prose.rule.origin-project": "descreva a propriedade técnica, sem citar de onde veio",
|
|
@@ -7385,30 +7555,55 @@ var pt_BR_default = {
|
|
|
7385
7555
|
"git.command.undo": "Lista as fotografias ou restaura uma, por padrão num worktree novo",
|
|
7386
7556
|
"git.command.rescue": "Lista commits perdidos pelo reflog e pelo fsck, e restaura um numa branch nova",
|
|
7387
7557
|
"git.command.merge_verify": "Confere que uma mescla manteve toda mudança dos dois lados",
|
|
7388
|
-
"git.block.force_push": "
|
|
7389
|
-
"git.block.
|
|
7390
|
-
"git.block.
|
|
7391
|
-
"git.block.
|
|
7392
|
-
"git.block.
|
|
7393
|
-
"git.block.
|
|
7394
|
-
"git.block.
|
|
7395
|
-
"git.block.
|
|
7396
|
-
"git.block.
|
|
7397
|
-
"git.block.
|
|
7398
|
-
"git.block.
|
|
7399
|
-
"git.block.
|
|
7400
|
-
"git.block.
|
|
7401
|
-
"git.block.
|
|
7402
|
-
"git.block.
|
|
7403
|
-
"git.block.
|
|
7404
|
-
"git.block.
|
|
7558
|
+
"git.block.force_push.claim": "`{command}` reescreve a branch remota e pode apagar commits que outra pessoa enviou",
|
|
7559
|
+
"git.block.force_push.requires": "Busque, integre os commits remotos e envie normalmente. Na sua própria branch depois de um rebase, use `git push --force-with-lease=<branch>:<sha esperado> --force-if-includes`",
|
|
7560
|
+
"git.block.not": "o mesmo efeito por outro comando git, um alias, um script ou um shell aninhado",
|
|
7561
|
+
"git.block.human": "Parei um comando git que podia perder trabalho ou reescrever histórico compartilhado.",
|
|
7562
|
+
"git.block.lease_not_own.claim": "`{command}` força um push em {subject}, que não é a branch em que você trabalha ou é protegida",
|
|
7563
|
+
"git.block.lease_not_own.requires": "Push forçado só vale na sua própria branch, com lease explícito",
|
|
7564
|
+
"git.block.push_delete.claim": "`{command}` apaga {subject} no remoto",
|
|
7565
|
+
"git.block.push_delete.requires": "Apagar branch remota é com a pessoa",
|
|
7566
|
+
"git.block.push_mirror.claim": "`{command}` sobrescreve todas as refs do remoto e publicaria as refs de backup",
|
|
7567
|
+
"git.block.push_mirror.requires": "Envie pelo nome a branch de que precisa",
|
|
7568
|
+
"git.block.clean.claim": "`{command}` apaga de vez arquivos não rastreados, que não estão em commit nenhum",
|
|
7569
|
+
"git.block.clean.requires": "Rode `git clean -n` para ver a lista e mova o que deve sair para .finitemonkey/trash/, ou pergunte à pessoa",
|
|
7570
|
+
"git.block.stash_drop.claim": "`{command}` joga fora trabalho guardado no stash que não existe em outro lugar",
|
|
7571
|
+
"git.block.stash_drop.requires": "Aplique com `git stash apply` ou deixe como está; descartar stash é com a pessoa",
|
|
7572
|
+
"git.block.branch_unmerged.claim": "`{command}` apaga {subject}, cujos commits não estão no upstream nem na branch padrão",
|
|
7573
|
+
"git.block.branch_unmerged.requires": "Envie ou mescle antes; `git branch -d` funciona depois de mesclada",
|
|
7574
|
+
"git.block.worktree_force.claim": "`{command}` remove um worktree mesmo com mudança sem commit",
|
|
7575
|
+
"git.block.worktree_force.requires": "Commite ou arquive o trabalho antes; o `git worktree remove` sem força recusa árvore suja de propósito",
|
|
7576
|
+
"git.block.rm_worktree.claim": "`{command}` apaga {subject}, que é um worktree ou repositório git; o trabalho sem commit iria junto",
|
|
7577
|
+
"git.block.rm_worktree.requires": "Commite ou arquive e depois use `git worktree remove` sem --force",
|
|
7578
|
+
"git.block.rm_root.claim": "`{command}` apaga recursivamente {subject}, uma pasta raiz ou a pasta pessoal",
|
|
7579
|
+
"git.block.rm_root.requires": "Diga a pasta exata a remover",
|
|
7580
|
+
"git.block.rebase_protected.claim": "`{command}` reescreve {subject}, uma branch protegida",
|
|
7581
|
+
"git.block.rebase_protected.requires": "Mude por pull request",
|
|
7582
|
+
"git.block.rebase_shared.claim": "`{command}` reescreve {subject}, que já tem commits de outra pessoa no remoto",
|
|
7583
|
+
"git.block.rebase_shared.requires": "Mescle a base nela em vez de fazer rebase",
|
|
7584
|
+
"git.block.merge_side.claim": "`{command}` resolve conflito escolhendo um lado inteiro ({subject}), o que descarta calado as mudanças do outro lado",
|
|
7585
|
+
"git.block.merge_side.requires": "Resolva cada conflito à mão e rode `finitemonkey merge verify` antes do commit",
|
|
7586
|
+
"git.block.history.claim": "`{command}` apaga histórico ou entradas do reflog de que o undo e o rescue dependem",
|
|
7587
|
+
"git.block.history.requires": "Reescrever histórico é com a pessoa",
|
|
7588
|
+
"git.block.protected_commit.claim": "`{command}` faria commit direto em {subject}, uma branch protegida",
|
|
7589
|
+
"git.block.protected_commit.requires": "Crie uma branch com `git switch -c <tipo>/<nome>` e abra um pull request",
|
|
7590
|
+
"git.block.protected_push.claim": "`{command}` envia para {subject}, uma branch protegida",
|
|
7591
|
+
"git.block.protected_push.requires": "Envie a sua branch e abra um pull request",
|
|
7592
|
+
"git.block.foreign.claim": "`{command}` descartaria mudanças que esta sessão não fez: {files}",
|
|
7593
|
+
"git.block.foreign.requires": "Desfaça só as suas linhas com Edit",
|
|
7405
7594
|
"git.foreign.before": "{path} (tinha mudança antes de você começar)",
|
|
7406
7595
|
"git.foreign.other": "{path} (mudado fora desta sessão)",
|
|
7407
|
-
"git.block.unknown": "
|
|
7408
|
-
"git.block.
|
|
7596
|
+
"git.block.unknown.claim": "`{command}` descarta mudanças, e o `git status` falhou, então não dá para saber de quem elas são",
|
|
7597
|
+
"git.block.unknown.requires": "Conserte o repositório e tente de novo",
|
|
7598
|
+
"git.block.snapshot_failed.claim": "`{command}` é arriscado e a fotografia de segurança antes dele falhou ({detail}), então ele não rodou",
|
|
7599
|
+
"git.block.snapshot_failed.requires": "Resolva a causa e tente de novo",
|
|
7409
7600
|
"git.snapshot.context": "o finitemonkey salvou uma fotografia antes de `{command}`: {ref}. `finitemonkey undo {ref}` traz o estado anterior de volta.",
|
|
7410
|
-
"prod.block.effect": "
|
|
7411
|
-
"prod.block.
|
|
7601
|
+
"prod.block.effect.claim": "`{command}` mexe em produção ({target}) na mão, e servidor editado na mão diverge do repositório",
|
|
7602
|
+
"prod.block.effect.requires": "Mude pelo caminho de deploy ({deploy}): commit, pull request e o deploy roda",
|
|
7603
|
+
"prod.block.not": "a mesma mudança por outra ferramenta, um script ou um shell aninhado",
|
|
7604
|
+
"prod.block.human": "Parei uma edição na mão em produção; mudança vai pelo deploy.",
|
|
7605
|
+
"prod.block.interactive.claim": "`{command}` abre sessão interativa em produção ({target}), onde nada do que for digitado passa por conferência",
|
|
7606
|
+
"prod.block.interactive.requires": "Rode um comando de leitura por vez, como `ssh {target} docker ps`",
|
|
7412
7607
|
"prod.deploy.unknown": "o deploy declarado do projeto",
|
|
7413
7608
|
"git.snapshot.done": "fotografia salva: {ref} ({commit}). `finitemonkey undo {ref}` restaura.",
|
|
7414
7609
|
"git.undo.list_title": "{count, plural, one {# fotografia:} other {# fotografias, da mais nova para a mais antiga:}}",
|
|
@@ -7535,7 +7730,11 @@ var pt_BR_default = {
|
|
|
7535
7730
|
"gate.look.allow_ignored": "exceção ignorada, a decisão não foi registrada: {entry}",
|
|
7536
7731
|
"gate.look.unopened": "{count, plural, one {# captura não aberta} other {# capturas não abertas}} depois da última edição de arquivo de tela",
|
|
7537
7732
|
"gate.look.open": "abra com Read: {file}",
|
|
7538
|
-
"gate.look.ok": "{count, plural, one {# captura} other {# capturas}}, nenhuma falha, todas abertas"
|
|
7733
|
+
"gate.look.ok": "{count, plural, one {# captura} other {# capturas}}, nenhuma falha, todas abertas",
|
|
7734
|
+
"reason.label.blocked": "bloqueado",
|
|
7735
|
+
"reason.label.requires": "exige",
|
|
7736
|
+
"reason.label.not": "não vale",
|
|
7737
|
+
"reason.human.generic": "Bloqueei uma chamada de ferramenta; o motivo foi para o Claude."
|
|
7539
7738
|
};
|
|
7540
7739
|
|
|
7541
7740
|
// src/i18n/review.json
|
|
@@ -7585,6 +7784,7 @@ var review_default = {
|
|
|
7585
7784
|
"i18n.problem.placeholder": "machine",
|
|
7586
7785
|
"i18n.problem.plural": "machine",
|
|
7587
7786
|
"i18n.problem.status": "machine",
|
|
7787
|
+
"i18n.problem.release_hint": "machine",
|
|
7588
7788
|
"i18n.problem.empty": "machine",
|
|
7589
7789
|
"i18n.problem.not_string": "machine",
|
|
7590
7790
|
"doctor.title": "machine",
|
|
@@ -7711,12 +7911,20 @@ var review_default = {
|
|
|
7711
7911
|
"secrets.where.line": "machine",
|
|
7712
7912
|
"secrets.where.file": "machine",
|
|
7713
7913
|
"secrets.where.new_text": "machine",
|
|
7714
|
-
"secrets.block.write": "machine",
|
|
7715
|
-
"secrets.block.
|
|
7716
|
-
"secrets.block.
|
|
7717
|
-
"secrets.block.
|
|
7718
|
-
"secrets.block.
|
|
7719
|
-
"secrets.block.
|
|
7914
|
+
"secrets.block.write.claim": "machine",
|
|
7915
|
+
"secrets.block.write.requires": "machine",
|
|
7916
|
+
"secrets.block.not": "machine",
|
|
7917
|
+
"secrets.block.human": "machine",
|
|
7918
|
+
"secrets.block.bash.claim": "machine",
|
|
7919
|
+
"secrets.block.bash.requires": "machine",
|
|
7920
|
+
"secrets.block.commit.claim": "machine",
|
|
7921
|
+
"secrets.block.commit.requires": "machine",
|
|
7922
|
+
"secrets.block.read.claim": "machine",
|
|
7923
|
+
"secrets.block.read.requires": "machine",
|
|
7924
|
+
"secrets.block.env_dump.claim": "machine",
|
|
7925
|
+
"secrets.block.env_dump.requires": "machine",
|
|
7926
|
+
"secrets.block.person_only.claim": "machine",
|
|
7927
|
+
"secrets.block.person_only.requires": "machine",
|
|
7720
7928
|
"secrets.block.prompt": "machine",
|
|
7721
7929
|
"secrets.post.context": "machine",
|
|
7722
7930
|
"secrets.incident.unsaved": "machine",
|
|
@@ -7909,16 +8117,27 @@ var review_default = {
|
|
|
7909
8117
|
"gate.config.disabled": "machine",
|
|
7910
8118
|
"gate.config.human": "machine",
|
|
7911
8119
|
"gate.config.released": "machine",
|
|
7912
|
-
"gate.guard.bypass.no_verify": "machine",
|
|
7913
|
-
"gate.guard.bypass.
|
|
7914
|
-
"gate.guard.bypass.
|
|
7915
|
-
"gate.guard.bypass.
|
|
7916
|
-
"gate.guard.bypass.
|
|
8120
|
+
"gate.guard.bypass.no_verify.claim": "machine",
|
|
8121
|
+
"gate.guard.bypass.no_verify.requires": "machine",
|
|
8122
|
+
"gate.guard.bypass.not": "machine",
|
|
8123
|
+
"gate.guard.bypass.hooks_path.claim": "machine",
|
|
8124
|
+
"gate.guard.bypass.hooks_path.requires": "machine",
|
|
8125
|
+
"gate.guard.bypass.hook_env.claim": "machine",
|
|
8126
|
+
"gate.guard.bypass.hook_env.requires": "machine",
|
|
8127
|
+
"gate.guard.bypass.fm_allow.claim": "machine",
|
|
8128
|
+
"gate.guard.bypass.fm_allow.requires": "machine",
|
|
8129
|
+
"gate.guard.bypass.fm_pause.claim": "machine",
|
|
8130
|
+
"gate.guard.bypass.fm_pause.requires": "machine",
|
|
7917
8131
|
"gate.guard.bypass.human": "machine",
|
|
7918
|
-
"gate.guard.self.policy": "machine",
|
|
7919
|
-
"gate.guard.self.
|
|
8132
|
+
"gate.guard.self.policy.claim": "machine",
|
|
8133
|
+
"gate.guard.self.policy.requires": "machine",
|
|
8134
|
+
"gate.guard.self.not": "machine",
|
|
8135
|
+
"gate.guard.self.allow_store.claim": "machine",
|
|
8136
|
+
"gate.guard.self.allow_store.requires": "machine",
|
|
7920
8137
|
"gate.guard.self.human": "machine",
|
|
7921
|
-
"gate.guard.tests.
|
|
8138
|
+
"gate.guard.tests.claim": "machine",
|
|
8139
|
+
"gate.guard.tests.requires": "machine",
|
|
8140
|
+
"gate.guard.tests.not": "machine",
|
|
7922
8141
|
"gate.guard.tests.shell": "machine",
|
|
7923
8142
|
"gate.guard.tests.human": "machine",
|
|
7924
8143
|
"gate.release.allowed": "machine",
|
|
@@ -7954,9 +8173,14 @@ var review_default = {
|
|
|
7954
8173
|
"prose.span": "machine",
|
|
7955
8174
|
"prose.fix_item": "machine",
|
|
7956
8175
|
"prose.warn.command": "machine",
|
|
7957
|
-
"prose.block.command": "machine",
|
|
7958
|
-
"prose.block.
|
|
7959
|
-
"prose.block.
|
|
8176
|
+
"prose.block.command.claim": "machine",
|
|
8177
|
+
"prose.block.command.requires": "machine",
|
|
8178
|
+
"prose.block.not": "machine",
|
|
8179
|
+
"prose.block.human": "machine",
|
|
8180
|
+
"prose.block.unreadable.claim": "machine",
|
|
8181
|
+
"prose.block.unreadable.requires": "machine",
|
|
8182
|
+
"prose.block.marker.claim": "machine",
|
|
8183
|
+
"prose.block.marker.requires": "machine",
|
|
7960
8184
|
"prose.check.file": "machine",
|
|
7961
8185
|
"prose.check.span": "machine",
|
|
7962
8186
|
"prose.check.fix": "machine",
|
|
@@ -7965,7 +8189,8 @@ var review_default = {
|
|
|
7965
8189
|
"prose.error.found": "machine",
|
|
7966
8190
|
"prose.error.no_input": "machine",
|
|
7967
8191
|
"prose.error.unreadable": "machine",
|
|
7968
|
-
"prose.block.marker_shell": "machine",
|
|
8192
|
+
"prose.block.marker_shell.claim": "machine",
|
|
8193
|
+
"prose.block.marker_shell.requires": "machine",
|
|
7969
8194
|
"prose.rule.requester-reference": "machine",
|
|
7970
8195
|
"prose.rule.person-as-reason": "machine",
|
|
7971
8196
|
"prose.rule.origin-project": "machine",
|
|
@@ -7980,30 +8205,55 @@ var review_default = {
|
|
|
7980
8205
|
"git.command.undo": "machine",
|
|
7981
8206
|
"git.command.rescue": "machine",
|
|
7982
8207
|
"git.command.merge_verify": "machine",
|
|
7983
|
-
"git.block.force_push": "machine",
|
|
7984
|
-
"git.block.
|
|
7985
|
-
"git.block.
|
|
7986
|
-
"git.block.
|
|
7987
|
-
"git.block.
|
|
7988
|
-
"git.block.
|
|
7989
|
-
"git.block.
|
|
7990
|
-
"git.block.
|
|
7991
|
-
"git.block.
|
|
7992
|
-
"git.block.
|
|
7993
|
-
"git.block.
|
|
7994
|
-
"git.block.
|
|
7995
|
-
"git.block.
|
|
7996
|
-
"git.block.
|
|
7997
|
-
"git.block.
|
|
7998
|
-
"git.block.
|
|
7999
|
-
"git.block.
|
|
8208
|
+
"git.block.force_push.claim": "machine",
|
|
8209
|
+
"git.block.force_push.requires": "machine",
|
|
8210
|
+
"git.block.not": "machine",
|
|
8211
|
+
"git.block.human": "machine",
|
|
8212
|
+
"git.block.lease_not_own.claim": "machine",
|
|
8213
|
+
"git.block.lease_not_own.requires": "machine",
|
|
8214
|
+
"git.block.push_delete.claim": "machine",
|
|
8215
|
+
"git.block.push_delete.requires": "machine",
|
|
8216
|
+
"git.block.push_mirror.claim": "machine",
|
|
8217
|
+
"git.block.push_mirror.requires": "machine",
|
|
8218
|
+
"git.block.clean.claim": "machine",
|
|
8219
|
+
"git.block.clean.requires": "machine",
|
|
8220
|
+
"git.block.stash_drop.claim": "machine",
|
|
8221
|
+
"git.block.stash_drop.requires": "machine",
|
|
8222
|
+
"git.block.branch_unmerged.claim": "machine",
|
|
8223
|
+
"git.block.branch_unmerged.requires": "machine",
|
|
8224
|
+
"git.block.worktree_force.claim": "machine",
|
|
8225
|
+
"git.block.worktree_force.requires": "machine",
|
|
8226
|
+
"git.block.rm_worktree.claim": "machine",
|
|
8227
|
+
"git.block.rm_worktree.requires": "machine",
|
|
8228
|
+
"git.block.rm_root.claim": "machine",
|
|
8229
|
+
"git.block.rm_root.requires": "machine",
|
|
8230
|
+
"git.block.rebase_protected.claim": "machine",
|
|
8231
|
+
"git.block.rebase_protected.requires": "machine",
|
|
8232
|
+
"git.block.rebase_shared.claim": "machine",
|
|
8233
|
+
"git.block.rebase_shared.requires": "machine",
|
|
8234
|
+
"git.block.merge_side.claim": "machine",
|
|
8235
|
+
"git.block.merge_side.requires": "machine",
|
|
8236
|
+
"git.block.history.claim": "machine",
|
|
8237
|
+
"git.block.history.requires": "machine",
|
|
8238
|
+
"git.block.protected_commit.claim": "machine",
|
|
8239
|
+
"git.block.protected_commit.requires": "machine",
|
|
8240
|
+
"git.block.protected_push.claim": "machine",
|
|
8241
|
+
"git.block.protected_push.requires": "machine",
|
|
8242
|
+
"git.block.foreign.claim": "machine",
|
|
8243
|
+
"git.block.foreign.requires": "machine",
|
|
8000
8244
|
"git.foreign.before": "machine",
|
|
8001
8245
|
"git.foreign.other": "machine",
|
|
8002
|
-
"git.block.unknown": "machine",
|
|
8003
|
-
"git.block.
|
|
8246
|
+
"git.block.unknown.claim": "machine",
|
|
8247
|
+
"git.block.unknown.requires": "machine",
|
|
8248
|
+
"git.block.snapshot_failed.claim": "machine",
|
|
8249
|
+
"git.block.snapshot_failed.requires": "machine",
|
|
8004
8250
|
"git.snapshot.context": "machine",
|
|
8005
|
-
"prod.block.effect": "machine",
|
|
8006
|
-
"prod.block.
|
|
8251
|
+
"prod.block.effect.claim": "machine",
|
|
8252
|
+
"prod.block.effect.requires": "machine",
|
|
8253
|
+
"prod.block.not": "machine",
|
|
8254
|
+
"prod.block.human": "machine",
|
|
8255
|
+
"prod.block.interactive.claim": "machine",
|
|
8256
|
+
"prod.block.interactive.requires": "machine",
|
|
8007
8257
|
"prod.deploy.unknown": "machine",
|
|
8008
8258
|
"git.snapshot.done": "machine",
|
|
8009
8259
|
"git.undo.list_title": "machine",
|
|
@@ -8130,7 +8380,11 @@ var review_default = {
|
|
|
8130
8380
|
"gate.look.allow_ignored": "machine",
|
|
8131
8381
|
"gate.look.unopened": "machine",
|
|
8132
8382
|
"gate.look.open": "machine",
|
|
8133
|
-
"gate.look.ok": "machine"
|
|
8383
|
+
"gate.look.ok": "machine",
|
|
8384
|
+
"reason.label.blocked": "machine",
|
|
8385
|
+
"reason.label.requires": "machine",
|
|
8386
|
+
"reason.label.not": "machine",
|
|
8387
|
+
"reason.human.generic": "machine"
|
|
8134
8388
|
},
|
|
8135
8389
|
es: {
|
|
8136
8390
|
"command.init.summary": "machine",
|
|
@@ -8177,6 +8431,7 @@ var review_default = {
|
|
|
8177
8431
|
"i18n.problem.placeholder": "machine",
|
|
8178
8432
|
"i18n.problem.plural": "machine",
|
|
8179
8433
|
"i18n.problem.status": "machine",
|
|
8434
|
+
"i18n.problem.release_hint": "machine",
|
|
8180
8435
|
"i18n.problem.empty": "machine",
|
|
8181
8436
|
"i18n.problem.not_string": "machine",
|
|
8182
8437
|
"doctor.title": "machine",
|
|
@@ -8303,12 +8558,20 @@ var review_default = {
|
|
|
8303
8558
|
"secrets.where.line": "machine",
|
|
8304
8559
|
"secrets.where.file": "machine",
|
|
8305
8560
|
"secrets.where.new_text": "machine",
|
|
8306
|
-
"secrets.block.write": "machine",
|
|
8307
|
-
"secrets.block.
|
|
8308
|
-
"secrets.block.
|
|
8309
|
-
"secrets.block.
|
|
8310
|
-
"secrets.block.
|
|
8311
|
-
"secrets.block.
|
|
8561
|
+
"secrets.block.write.claim": "machine",
|
|
8562
|
+
"secrets.block.write.requires": "machine",
|
|
8563
|
+
"secrets.block.not": "machine",
|
|
8564
|
+
"secrets.block.human": "machine",
|
|
8565
|
+
"secrets.block.bash.claim": "machine",
|
|
8566
|
+
"secrets.block.bash.requires": "machine",
|
|
8567
|
+
"secrets.block.commit.claim": "machine",
|
|
8568
|
+
"secrets.block.commit.requires": "machine",
|
|
8569
|
+
"secrets.block.read.claim": "machine",
|
|
8570
|
+
"secrets.block.read.requires": "machine",
|
|
8571
|
+
"secrets.block.env_dump.claim": "machine",
|
|
8572
|
+
"secrets.block.env_dump.requires": "machine",
|
|
8573
|
+
"secrets.block.person_only.claim": "machine",
|
|
8574
|
+
"secrets.block.person_only.requires": "machine",
|
|
8312
8575
|
"secrets.block.prompt": "machine",
|
|
8313
8576
|
"secrets.post.context": "machine",
|
|
8314
8577
|
"secrets.incident.unsaved": "machine",
|
|
@@ -8501,16 +8764,27 @@ var review_default = {
|
|
|
8501
8764
|
"gate.config.disabled": "machine",
|
|
8502
8765
|
"gate.config.human": "machine",
|
|
8503
8766
|
"gate.config.released": "machine",
|
|
8504
|
-
"gate.guard.bypass.no_verify": "machine",
|
|
8505
|
-
"gate.guard.bypass.
|
|
8506
|
-
"gate.guard.bypass.
|
|
8507
|
-
"gate.guard.bypass.
|
|
8508
|
-
"gate.guard.bypass.
|
|
8767
|
+
"gate.guard.bypass.no_verify.claim": "machine",
|
|
8768
|
+
"gate.guard.bypass.no_verify.requires": "machine",
|
|
8769
|
+
"gate.guard.bypass.not": "machine",
|
|
8770
|
+
"gate.guard.bypass.hooks_path.claim": "machine",
|
|
8771
|
+
"gate.guard.bypass.hooks_path.requires": "machine",
|
|
8772
|
+
"gate.guard.bypass.hook_env.claim": "machine",
|
|
8773
|
+
"gate.guard.bypass.hook_env.requires": "machine",
|
|
8774
|
+
"gate.guard.bypass.fm_allow.claim": "machine",
|
|
8775
|
+
"gate.guard.bypass.fm_allow.requires": "machine",
|
|
8776
|
+
"gate.guard.bypass.fm_pause.claim": "machine",
|
|
8777
|
+
"gate.guard.bypass.fm_pause.requires": "machine",
|
|
8509
8778
|
"gate.guard.bypass.human": "machine",
|
|
8510
|
-
"gate.guard.self.policy": "machine",
|
|
8511
|
-
"gate.guard.self.
|
|
8779
|
+
"gate.guard.self.policy.claim": "machine",
|
|
8780
|
+
"gate.guard.self.policy.requires": "machine",
|
|
8781
|
+
"gate.guard.self.not": "machine",
|
|
8782
|
+
"gate.guard.self.allow_store.claim": "machine",
|
|
8783
|
+
"gate.guard.self.allow_store.requires": "machine",
|
|
8512
8784
|
"gate.guard.self.human": "machine",
|
|
8513
|
-
"gate.guard.tests.
|
|
8785
|
+
"gate.guard.tests.claim": "machine",
|
|
8786
|
+
"gate.guard.tests.requires": "machine",
|
|
8787
|
+
"gate.guard.tests.not": "machine",
|
|
8514
8788
|
"gate.guard.tests.shell": "machine",
|
|
8515
8789
|
"gate.guard.tests.human": "machine",
|
|
8516
8790
|
"gate.release.allowed": "machine",
|
|
@@ -8546,9 +8820,14 @@ var review_default = {
|
|
|
8546
8820
|
"prose.span": "machine",
|
|
8547
8821
|
"prose.fix_item": "machine",
|
|
8548
8822
|
"prose.warn.command": "machine",
|
|
8549
|
-
"prose.block.command": "machine",
|
|
8550
|
-
"prose.block.
|
|
8551
|
-
"prose.block.
|
|
8823
|
+
"prose.block.command.claim": "machine",
|
|
8824
|
+
"prose.block.command.requires": "machine",
|
|
8825
|
+
"prose.block.not": "machine",
|
|
8826
|
+
"prose.block.human": "machine",
|
|
8827
|
+
"prose.block.unreadable.claim": "machine",
|
|
8828
|
+
"prose.block.unreadable.requires": "machine",
|
|
8829
|
+
"prose.block.marker.claim": "machine",
|
|
8830
|
+
"prose.block.marker.requires": "machine",
|
|
8552
8831
|
"prose.check.file": "machine",
|
|
8553
8832
|
"prose.check.span": "machine",
|
|
8554
8833
|
"prose.check.fix": "machine",
|
|
@@ -8557,7 +8836,8 @@ var review_default = {
|
|
|
8557
8836
|
"prose.error.found": "machine",
|
|
8558
8837
|
"prose.error.no_input": "machine",
|
|
8559
8838
|
"prose.error.unreadable": "machine",
|
|
8560
|
-
"prose.block.marker_shell": "machine",
|
|
8839
|
+
"prose.block.marker_shell.claim": "machine",
|
|
8840
|
+
"prose.block.marker_shell.requires": "machine",
|
|
8561
8841
|
"prose.rule.requester-reference": "machine",
|
|
8562
8842
|
"prose.rule.person-as-reason": "machine",
|
|
8563
8843
|
"prose.rule.origin-project": "machine",
|
|
@@ -8572,30 +8852,55 @@ var review_default = {
|
|
|
8572
8852
|
"git.command.undo": "machine",
|
|
8573
8853
|
"git.command.rescue": "machine",
|
|
8574
8854
|
"git.command.merge_verify": "machine",
|
|
8575
|
-
"git.block.force_push": "machine",
|
|
8576
|
-
"git.block.
|
|
8577
|
-
"git.block.
|
|
8578
|
-
"git.block.
|
|
8579
|
-
"git.block.
|
|
8580
|
-
"git.block.
|
|
8581
|
-
"git.block.
|
|
8582
|
-
"git.block.
|
|
8583
|
-
"git.block.
|
|
8584
|
-
"git.block.
|
|
8585
|
-
"git.block.
|
|
8586
|
-
"git.block.
|
|
8587
|
-
"git.block.
|
|
8588
|
-
"git.block.
|
|
8589
|
-
"git.block.
|
|
8590
|
-
"git.block.
|
|
8591
|
-
"git.block.
|
|
8855
|
+
"git.block.force_push.claim": "machine",
|
|
8856
|
+
"git.block.force_push.requires": "machine",
|
|
8857
|
+
"git.block.not": "machine",
|
|
8858
|
+
"git.block.human": "machine",
|
|
8859
|
+
"git.block.lease_not_own.claim": "machine",
|
|
8860
|
+
"git.block.lease_not_own.requires": "machine",
|
|
8861
|
+
"git.block.push_delete.claim": "machine",
|
|
8862
|
+
"git.block.push_delete.requires": "machine",
|
|
8863
|
+
"git.block.push_mirror.claim": "machine",
|
|
8864
|
+
"git.block.push_mirror.requires": "machine",
|
|
8865
|
+
"git.block.clean.claim": "machine",
|
|
8866
|
+
"git.block.clean.requires": "machine",
|
|
8867
|
+
"git.block.stash_drop.claim": "machine",
|
|
8868
|
+
"git.block.stash_drop.requires": "machine",
|
|
8869
|
+
"git.block.branch_unmerged.claim": "machine",
|
|
8870
|
+
"git.block.branch_unmerged.requires": "machine",
|
|
8871
|
+
"git.block.worktree_force.claim": "machine",
|
|
8872
|
+
"git.block.worktree_force.requires": "machine",
|
|
8873
|
+
"git.block.rm_worktree.claim": "machine",
|
|
8874
|
+
"git.block.rm_worktree.requires": "machine",
|
|
8875
|
+
"git.block.rm_root.claim": "machine",
|
|
8876
|
+
"git.block.rm_root.requires": "machine",
|
|
8877
|
+
"git.block.rebase_protected.claim": "machine",
|
|
8878
|
+
"git.block.rebase_protected.requires": "machine",
|
|
8879
|
+
"git.block.rebase_shared.claim": "machine",
|
|
8880
|
+
"git.block.rebase_shared.requires": "machine",
|
|
8881
|
+
"git.block.merge_side.claim": "machine",
|
|
8882
|
+
"git.block.merge_side.requires": "machine",
|
|
8883
|
+
"git.block.history.claim": "machine",
|
|
8884
|
+
"git.block.history.requires": "machine",
|
|
8885
|
+
"git.block.protected_commit.claim": "machine",
|
|
8886
|
+
"git.block.protected_commit.requires": "machine",
|
|
8887
|
+
"git.block.protected_push.claim": "machine",
|
|
8888
|
+
"git.block.protected_push.requires": "machine",
|
|
8889
|
+
"git.block.foreign.claim": "machine",
|
|
8890
|
+
"git.block.foreign.requires": "machine",
|
|
8592
8891
|
"git.foreign.before": "machine",
|
|
8593
8892
|
"git.foreign.other": "machine",
|
|
8594
|
-
"git.block.unknown": "machine",
|
|
8595
|
-
"git.block.
|
|
8893
|
+
"git.block.unknown.claim": "machine",
|
|
8894
|
+
"git.block.unknown.requires": "machine",
|
|
8895
|
+
"git.block.snapshot_failed.claim": "machine",
|
|
8896
|
+
"git.block.snapshot_failed.requires": "machine",
|
|
8596
8897
|
"git.snapshot.context": "machine",
|
|
8597
|
-
"prod.block.effect": "machine",
|
|
8598
|
-
"prod.block.
|
|
8898
|
+
"prod.block.effect.claim": "machine",
|
|
8899
|
+
"prod.block.effect.requires": "machine",
|
|
8900
|
+
"prod.block.not": "machine",
|
|
8901
|
+
"prod.block.human": "machine",
|
|
8902
|
+
"prod.block.interactive.claim": "machine",
|
|
8903
|
+
"prod.block.interactive.requires": "machine",
|
|
8599
8904
|
"prod.deploy.unknown": "machine",
|
|
8600
8905
|
"git.snapshot.done": "machine",
|
|
8601
8906
|
"git.undo.list_title": "machine",
|
|
@@ -8722,7 +9027,11 @@ var review_default = {
|
|
|
8722
9027
|
"gate.look.allow_ignored": "machine",
|
|
8723
9028
|
"gate.look.unopened": "machine",
|
|
8724
9029
|
"gate.look.open": "machine",
|
|
8725
|
-
"gate.look.ok": "machine"
|
|
9030
|
+
"gate.look.ok": "machine",
|
|
9031
|
+
"reason.label.blocked": "machine",
|
|
9032
|
+
"reason.label.requires": "machine",
|
|
9033
|
+
"reason.label.not": "machine",
|
|
9034
|
+
"reason.human.generic": "machine"
|
|
8726
9035
|
}
|
|
8727
9036
|
};
|
|
8728
9037
|
|
|
@@ -12634,7 +12943,11 @@ var isProdHostOf = (runtime, root, targets2) => memoBy((raw) => {
|
|
|
12634
12943
|
});
|
|
12635
12944
|
var blockOf = (t, hit3, command, deploy) => ({
|
|
12636
12945
|
kind: "block",
|
|
12637
|
-
reason: hit3.effect === "interactive" ? t
|
|
12946
|
+
reason: hit3.effect === "interactive" ? modelReason(t, "prod.block.interactive", { command, target: hit3.target }) : modelReason(t, "prod.block.effect", {
|
|
12947
|
+
command,
|
|
12948
|
+
target: hit3.target,
|
|
12949
|
+
deploy: deploy ?? t("prod.deploy.unknown")
|
|
12950
|
+
})
|
|
12638
12951
|
});
|
|
12639
12952
|
var prodGuard = (runtime, root, t) => {
|
|
12640
12953
|
const targets2 = memo2(() => loadProdTargets(runtime, root, loadProjectConfig(runtime, root)));
|
|
@@ -13629,7 +13942,7 @@ var RULE_KEYS = {
|
|
|
13629
13942
|
"protected-push": "git.block.protected_push"
|
|
13630
13943
|
};
|
|
13631
13944
|
var MAX_FILES2 = 8;
|
|
13632
|
-
var ruleMessage = (t, rule, command, subject2) => t
|
|
13945
|
+
var ruleMessage = (t, rule, command, subject2) => modelReason(t, RULE_KEYS[rule], { command, subject: subject2 === "" ? command : subject2 });
|
|
13633
13946
|
var fileList = (items) => {
|
|
13634
13947
|
const head = items.slice(0, MAX_FILES2).join(", ");
|
|
13635
13948
|
return items.length > MAX_FILES2 ? `${head} (+${String(items.length - MAX_FILES2)})` : head;
|
|
@@ -13640,12 +13953,12 @@ var outcomeMessage = (t, outcome2) => {
|
|
|
13640
13953
|
case "block":
|
|
13641
13954
|
return ruleMessage(t, outcome2.rule, outcome2.command, outcome2.subject);
|
|
13642
13955
|
case "foreign":
|
|
13643
|
-
return t
|
|
13956
|
+
return modelReason(t, "git.block.foreign", {
|
|
13644
13957
|
command: outcome2.command,
|
|
13645
13958
|
files: fileList(outcome2.files.map((file) => foreignLabel(t, file)))
|
|
13646
13959
|
});
|
|
13647
13960
|
case "unknown":
|
|
13648
|
-
return t
|
|
13961
|
+
return modelReason(t, "git.block.unknown", { command: outcome2.command });
|
|
13649
13962
|
case "pass":
|
|
13650
13963
|
case "snapshot":
|
|
13651
13964
|
return void 0;
|
|
@@ -13667,7 +13980,8 @@ var snapshotsOf = (input, owner, pending) => {
|
|
|
13667
13980
|
if (!taken.ok) {
|
|
13668
13981
|
return {
|
|
13669
13982
|
kind: "block",
|
|
13670
|
-
reason: input.t
|
|
13983
|
+
reason: modelReason(input.t, "git.block.snapshot_failed", { command: item2.command, detail: taken.error }),
|
|
13984
|
+
human: input.t("git.block.human")
|
|
13671
13985
|
};
|
|
13672
13986
|
}
|
|
13673
13987
|
done.set(item2.repo.root, input.t("git.snapshot.context", { command: item2.command, ref: taken.value.ref }));
|
|
@@ -13685,13 +13999,13 @@ var review = (input, commands, owner) => {
|
|
|
13685
13999
|
const chain = { branch: void 0 };
|
|
13686
14000
|
for (const command of commands) {
|
|
13687
14001
|
const removal = rmOutcome(input, command, worktrees);
|
|
13688
|
-
if (removal !== void 0) return { blocked: removal, snapshots, reads };
|
|
14002
|
+
if (removal !== void 0) return { blocked: removal, human: "git.block.human", snapshots, reads };
|
|
13689
14003
|
const decision = PROD_PROGRAMS.has(command.program) ? prod().decide(command) : void 0;
|
|
13690
|
-
if (decision?.kind === "block") return { blocked: decision.reason, snapshots, reads };
|
|
14004
|
+
if (decision?.kind === "block") return { blocked: decision.reason, human: "prod.block.human", snapshots, reads };
|
|
13691
14005
|
if (decision !== void 0) reads.push(decision);
|
|
13692
14006
|
for (const outcome2 of guardGitCommand({ runtime: input.runtime, cwd: input.cwd, owner, chain }, command)) {
|
|
13693
14007
|
const message = outcomeMessage(input.t, outcome2);
|
|
13694
|
-
if (message !== void 0) return { blocked: message, snapshots, reads };
|
|
14008
|
+
if (message !== void 0) return { blocked: message, human: "git.block.human", snapshots, reads };
|
|
13695
14009
|
if (outcome2.kind === "snapshot") snapshots.push(outcome2);
|
|
13696
14010
|
}
|
|
13697
14011
|
}
|
|
@@ -13704,7 +14018,9 @@ var gitPreToolUse = (input) => {
|
|
|
13704
14018
|
if (commands.length === 0) return ALLOW;
|
|
13705
14019
|
const owner = ownerOf2(input.payload);
|
|
13706
14020
|
const result = review(input, commands, owner);
|
|
13707
|
-
if (result.blocked !== void 0)
|
|
14021
|
+
if (result.blocked !== void 0) {
|
|
14022
|
+
return { kind: "block", reason: result.blocked, human: input.t(result.human ?? "git.block.human") };
|
|
14023
|
+
}
|
|
13708
14024
|
if (result.reads.length > 0) {
|
|
13709
14025
|
recordEvidence(
|
|
13710
14026
|
input.runtime,
|
|
@@ -13947,14 +14263,19 @@ var shown2 = (cwd, file) => {
|
|
|
13947
14263
|
};
|
|
13948
14264
|
var blocked = (input, file) => ({
|
|
13949
14265
|
kind: "block",
|
|
13950
|
-
reason: input.t
|
|
14266
|
+
reason: modelReason(input.t, "prose.block.marker", { marker: ALLOW_COMMENT, file }),
|
|
14267
|
+
human: input.t("prose.block.human")
|
|
13951
14268
|
});
|
|
13952
14269
|
var proseMarkerGuard = (input) => {
|
|
13953
14270
|
const tool = toolName2(input.payload);
|
|
13954
14271
|
const inputs = toolInput2(input.payload);
|
|
13955
14272
|
if (SHELLS2.has(tool)) {
|
|
13956
14273
|
if (!shellAddsMarker(optionalString(inputs, "command") ?? "")) return ALLOW3;
|
|
13957
|
-
return {
|
|
14274
|
+
return {
|
|
14275
|
+
kind: "block",
|
|
14276
|
+
reason: modelReason(input.t, "prose.block.marker_shell", { marker: ALLOW_COMMENT }),
|
|
14277
|
+
human: input.t("prose.block.human")
|
|
14278
|
+
};
|
|
13958
14279
|
}
|
|
13959
14280
|
const file = optionalString(inputs, "file_path") ?? optionalString(inputs, "notebook_path") ?? "";
|
|
13960
14281
|
return addsMarker(input, tool, inputs, file) ? blocked(input, shown2(input.cwd, file)) : ALLOW3;
|
|
@@ -14097,7 +14418,11 @@ var textOf2 = (input, found) => {
|
|
|
14097
14418
|
var decisionFor = (input, found, blocking2) => {
|
|
14098
14419
|
const text7 = textOf2(input, found);
|
|
14099
14420
|
if (!text7.ok) {
|
|
14100
|
-
return blocking2 ? {
|
|
14421
|
+
return blocking2 ? {
|
|
14422
|
+
kind: "block",
|
|
14423
|
+
reason: modelReason(input.t, "prose.block.unreadable", { ...text7.error }),
|
|
14424
|
+
human: input.t("prose.block.human")
|
|
14425
|
+
} : void 0;
|
|
14101
14426
|
}
|
|
14102
14427
|
const report2 = scoreProse(text7.value, { context: "record" });
|
|
14103
14428
|
if (report2.allowed || report2.spans.length === 0) return void 0;
|
|
@@ -14106,7 +14431,12 @@ var decisionFor = (input, found, blocking2) => {
|
|
|
14106
14431
|
spans: describeSpans(input.t, report2.spans),
|
|
14107
14432
|
fixes: describeFixes(input.t, report2.spans)
|
|
14108
14433
|
};
|
|
14109
|
-
if (blocking2)
|
|
14434
|
+
if (blocking2)
|
|
14435
|
+
return {
|
|
14436
|
+
kind: "block",
|
|
14437
|
+
reason: modelReason(input.t, "prose.block.command", params2),
|
|
14438
|
+
human: input.t("prose.block.human")
|
|
14439
|
+
};
|
|
14110
14440
|
const additionalContext = `finitemonkey: ${input.t("prose.warn.command", params2)}`;
|
|
14111
14441
|
return { kind: "allow", output: { hookSpecificOutput: { hookEventName: "PreToolUse", additionalContext } } };
|
|
14112
14442
|
};
|
|
@@ -14303,18 +14633,22 @@ var writeDecision = (input, tool) => {
|
|
|
14303
14633
|
ruleId: finding4.ruleId,
|
|
14304
14634
|
where: written.whole ? t("secrets.where.file", { file, line: finding4.line, column: finding4.column }) : t("secrets.where.new_text", { file, line: finding4.line })
|
|
14305
14635
|
}));
|
|
14306
|
-
return {
|
|
14636
|
+
return {
|
|
14637
|
+
kind: "block",
|
|
14638
|
+
reason: modelReason(t, "secrets.block.write", { file, found: describeFindings(t, items) }),
|
|
14639
|
+
human: t("secrets.block.human")
|
|
14640
|
+
};
|
|
14307
14641
|
}
|
|
14308
14642
|
return warningDecision(t, warnings);
|
|
14309
14643
|
};
|
|
14310
14644
|
var bashMessage = (t, finding4) => {
|
|
14311
14645
|
switch (finding4.kind) {
|
|
14312
14646
|
case "read":
|
|
14313
|
-
return t
|
|
14647
|
+
return modelReason(t, "secrets.block.read", { target: finding4.target });
|
|
14314
14648
|
case "env-dump":
|
|
14315
|
-
return t
|
|
14649
|
+
return modelReason(t, "secrets.block.env_dump", { command: finding4.command });
|
|
14316
14650
|
case "person-only":
|
|
14317
|
-
return t
|
|
14651
|
+
return modelReason(t, "secrets.block.person_only", { command: finding4.command });
|
|
14318
14652
|
}
|
|
14319
14653
|
};
|
|
14320
14654
|
var commitDecision = (input, includeUnstaged) => {
|
|
@@ -14325,7 +14659,11 @@ var commitDecision = (input, includeUnstaged) => {
|
|
|
14325
14659
|
ruleId: finding4.ruleId,
|
|
14326
14660
|
where: input.t("secrets.where.file", { file: finding4.file, line: finding4.line, column: finding4.column })
|
|
14327
14661
|
}));
|
|
14328
|
-
return {
|
|
14662
|
+
return {
|
|
14663
|
+
kind: "block",
|
|
14664
|
+
reason: modelReason(input.t, "secrets.block.commit", { found: describeFindings(input.t, items) }),
|
|
14665
|
+
human: input.t("secrets.block.human")
|
|
14666
|
+
};
|
|
14329
14667
|
};
|
|
14330
14668
|
var bashDecision = (input) => {
|
|
14331
14669
|
const command = optionalString(toolInput2(input.payload), "command") ?? "";
|
|
@@ -14336,7 +14674,11 @@ var bashDecision = (input) => {
|
|
|
14336
14674
|
const found = blocking(scanText(command));
|
|
14337
14675
|
if (found.length > 0) {
|
|
14338
14676
|
const items = found.map((finding4) => ({ ruleId: finding4.ruleId, where: lineWhere(input.t, finding4) }));
|
|
14339
|
-
return {
|
|
14677
|
+
return {
|
|
14678
|
+
kind: "block",
|
|
14679
|
+
reason: modelReason(input.t, "secrets.block.bash", { found: describeFindings(input.t, items) }),
|
|
14680
|
+
human: input.t("secrets.block.human")
|
|
14681
|
+
};
|
|
14340
14682
|
}
|
|
14341
14683
|
const commit2 = commitIntent(segments);
|
|
14342
14684
|
return commit2 === void 0 ? ALLOW5 : commitDecision(input, commit2.includeUnstaged);
|
|
@@ -14345,7 +14687,11 @@ var readDecision = (input) => {
|
|
|
14345
14687
|
const inputs = toolInput2(input.payload);
|
|
14346
14688
|
const target2 = optionalString(inputs, "file_path") ?? optionalString(inputs, "path") ?? "";
|
|
14347
14689
|
if (target2 === "" || !isSensitivePath(target2)) return ALLOW5;
|
|
14348
|
-
return {
|
|
14690
|
+
return {
|
|
14691
|
+
kind: "block",
|
|
14692
|
+
reason: modelReason(input.t, "secrets.block.read", { target: relativeFile(input.cwd, target2) }),
|
|
14693
|
+
human: input.t("secrets.block.human")
|
|
14694
|
+
};
|
|
14349
14695
|
};
|
|
14350
14696
|
var WRITERS2 = /* @__PURE__ */ new Set(["Write", "Edit", "MultiEdit", "NotebookEdit"]);
|
|
14351
14697
|
var SHELLS4 = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
|
|
@@ -14427,11 +14773,23 @@ var mergeOutputs = (left, right) => {
|
|
|
14427
14773
|
if (specific !== void 0) merged2["hookSpecificOutput"] = specific;
|
|
14428
14774
|
return merged2;
|
|
14429
14775
|
};
|
|
14776
|
+
var shaped = (input, decision) => {
|
|
14777
|
+
if (input.event !== "PreToolUse" || decision.output !== void 0) return decision;
|
|
14778
|
+
const reason = capReason(decision.reason);
|
|
14779
|
+
return {
|
|
14780
|
+
...decision,
|
|
14781
|
+
reason,
|
|
14782
|
+
output: {
|
|
14783
|
+
hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: reason },
|
|
14784
|
+
systemMessage: `finitemonkey: ${decision.human ?? input.t("reason.human.generic")}`
|
|
14785
|
+
}
|
|
14786
|
+
};
|
|
14787
|
+
};
|
|
14430
14788
|
var composeDecisions = async (input, handlers) => {
|
|
14431
14789
|
let output = {};
|
|
14432
14790
|
for (const handler of handlers) {
|
|
14433
14791
|
const decision = await handler(input);
|
|
14434
|
-
if (decision.kind === "block") return decision;
|
|
14792
|
+
if (decision.kind === "block") return shaped(input, decision);
|
|
14435
14793
|
output = mergeOutputs(output, decision.output);
|
|
14436
14794
|
}
|
|
14437
14795
|
return { kind: "allow", output };
|
|
@@ -16390,14 +16748,38 @@ var sourceProblems = (catalog) => Object.keys(catalog).sort().flatMap((key) => {
|
|
|
16390
16748
|
const value = catalog[key];
|
|
16391
16749
|
return typeof value === "string" ? pluralProblems(SOURCE_LANG, key, value, value) : [];
|
|
16392
16750
|
});
|
|
16751
|
+
var MODEL_FACING = /\.(claim|requires|not)$|^gate\.tests\.|^reason\.label\./;
|
|
16752
|
+
var RELEASE_HINTS = [
|
|
16753
|
+
/--yes\b/,
|
|
16754
|
+
/\b(finitemonkey|fm)\b[^\n]{0,20}\b(allow|off|on|trust|approve)\b/i,
|
|
16755
|
+
/\ballow\s+(bypass|tests|self|config)\b/i,
|
|
16756
|
+
/\bFINITEMONKEY_[A-Z_]+/,
|
|
16757
|
+
/\b[A-Z][A-Z0-9_]{2,}=/
|
|
16758
|
+
];
|
|
16759
|
+
var releaseHints = (text7) => RELEASE_HINTS.flatMap((pattern) => {
|
|
16760
|
+
const match = pattern.exec(text7);
|
|
16761
|
+
return match === null ? [] : [match[0]];
|
|
16762
|
+
});
|
|
16763
|
+
var hintProblems = (lang, catalog) => Object.keys(catalog).filter((key) => MODEL_FACING.test(key)).sort().flatMap((key) => {
|
|
16764
|
+
const value = catalog[key];
|
|
16765
|
+
const found = typeof value === "string" ? releaseHints(value) : [];
|
|
16766
|
+
return found.length === 0 ? [] : [{ lang, key, kind: "release_hint", actual: found }];
|
|
16767
|
+
});
|
|
16393
16768
|
var checkCatalogs = (input, review2) => {
|
|
16394
16769
|
const reference = input[SOURCE_LANG];
|
|
16395
16770
|
const problems = LANGUAGES.flatMap((lang) => {
|
|
16396
|
-
if (lang === SOURCE_LANG)
|
|
16771
|
+
if (lang === SOURCE_LANG) {
|
|
16772
|
+
return [
|
|
16773
|
+
...valueProblems(lang, input[lang], reference),
|
|
16774
|
+
...sourceProblems(reference),
|
|
16775
|
+
...hintProblems(lang, reference)
|
|
16776
|
+
];
|
|
16777
|
+
}
|
|
16397
16778
|
const statuses = review2?.[lang];
|
|
16398
16779
|
return [
|
|
16399
16780
|
...valueProblems(lang, input[lang], reference),
|
|
16400
16781
|
...parityProblems(lang, input[lang], reference),
|
|
16782
|
+
...hintProblems(lang, input[lang]),
|
|
16401
16783
|
...review2 === void 0 ? [] : statusProblems(lang, input[lang], statuses ?? {})
|
|
16402
16784
|
];
|
|
16403
16785
|
});
|