finitemonkey 0.1.0-next.11 → 0.1.0-next.12
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 +24 -1
- package/README.md +24 -1
- package/README.pt-BR.md +24 -1
- package/dist/finitemonkey.mjs +177 -107
- package/package.json +4 -2
package/README.es.md
CHANGED
|
@@ -123,6 +123,29 @@ La comparación completa, con fuentes, está en [docs/compare.es.md](docs/compar
|
|
|
123
123
|
- **Métodos como superpowers, GSD, Spec Kit u OpenSpec** le dicen al agente cómo planificar y construir. Finite Monkey no los sustituye: comprueba el resultado al final, uses el método que uses.
|
|
124
124
|
- **Guardas sueltos como tdd-guard, cc-safety-net o dcg** hacen un trabajo cada uno, y lo hacen bien. Finite Monkey cubre cuatro daños con un control, una instalación y un `undo`. Si solo necesitas uno de esos trabajos, un guarda suelto puede ser lo más sencillo.
|
|
125
125
|
|
|
126
|
+
<!-- generated:footprint:start -->
|
|
127
|
+
## Qué lee, escribe y envía
|
|
128
|
+
|
|
129
|
+
Generado desde `src/core/footprint.ts`, la lista que los tests exigen al código. Sin telemetría. Las rutas son relativas al proyecto salvo las que empiezan con `~`.
|
|
130
|
+
|
|
131
|
+
| | Qué | Para qué |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| Lee | `stdin` | El evento que Claude Code pasa a cada hook: la llamada a la herramienta, el prompt o la petición de parada. |
|
|
134
|
+
| Lee | `.claude/settings.json`, `.claude/settings.local.json`, `~/.claude/settings.json` | La configuración de Claude Code, para comprobar que los hooks están instalados y que nada los desactiva. `$CLAUDE_CONFIG_DIR` reemplaza `~/.claude` si está definido. |
|
|
135
|
+
| Lee | `CLAUDE.md`, `.claude/CLAUDE.md`, `CLAUDE.local.md`, `AGENTS.md`, `.claude/rules/`, `.claudeignore` | Archivos de instrucciones, que `doctor` lee para señalar reglas que solo existen como texto. |
|
|
136
|
+
| Lee | `.git/` | El repositorio a través del comando `git`: estado, diffs, refs y el reflog. |
|
|
137
|
+
| Lee | `git diff` | Archivos modificados, revisados en busca de secretos, tests saltados, placeholders y patrones de prosa. |
|
|
138
|
+
| Lee | `.finitemonkey/config.yml`, `.finitemonkey/briefing.md` | La configuración del proyecto y el briefing opcional para subagentes. |
|
|
139
|
+
| Escribe | `.claude/settings.json`, `.claude/skills/verify/SKILL.md`, `AGENTS.md`, `CLAUDE.md`, `.gitignore`, `.finitemonkey/config.yml`, `.finitemonkey/lock.json`, `.finitemonkey/locks/`, `.finitemonkey/runtime/`, `.finitemonkey/backups/` | `init` y `update`: la configuración de los hooks, la skill verify, un bloque gestionado corto en `AGENTS.md` que `CLAUDE.md` importa, una línea en `.gitignore`, el runtime fijado y una copia de cada archivo que cambian. |
|
|
140
|
+
| Escribe | `.finitemonkey/tasks/`, `.finitemonkey/state.json` | Contratos de tarea y cuál tarea está activa. |
|
|
141
|
+
| Escribe | `.finitemonkey/evidence/`, `.finitemonkey/log.jsonl`, `.finitemonkey/prod-evidence.jsonl` | La evidencia de cada comprobación, ligada al hash del árbol, y el log de la puerta. |
|
|
142
|
+
| Escribe | `.finitemonkey/trust.json`, `.finitemonkey/allow/`, `.finitemonkey/cache/` | Aprobaciones y permisos escritos por la persona, y una caché breve de los pull requests abiertos. |
|
|
143
|
+
| Escribe | `.finitemonkey/findings/baseline.json`, `.finitemonkey/incidents/` | La línea base de hallazgos aceptados y los incidentes de exposición. Ambos guardan huellas y máscaras, nunca el valor de un secreto. |
|
|
144
|
+
| Escribe | `.finitemonkey/git/`, `.finitemonkey/git-journal.jsonl`, `.finitemonkey/merge-dropped.json`, `refs/finitemonkey/backup/` | Snapshots antes de comandos git destructivos, el diario que lee `undo` y las decisiones sobre líneas descartadas en merges. |
|
|
145
|
+
| Escribe | `.finitemonkey/reports/` | Informes de error enmascarados que escribe `doctor --report`, solo cuando se pide. |
|
|
146
|
+
| Envía | `api.github.com` | A través de `gh`, solo si está instalado y con sesión iniciada: el estado del pull request indicado en una tarea y tus pull requests abiertos para la línea de la sesión. El código nunca se sube. |
|
|
147
|
+
<!-- generated:footprint:end -->
|
|
148
|
+
|
|
126
149
|
## Preguntas frecuentes
|
|
127
150
|
|
|
128
151
|
Más preguntas, una por cada búsqueda real, en [docs/faq.es.md](docs/faq.es.md).
|
|
@@ -131,7 +154,7 @@ Más preguntas, una por cada búsqueda real, en [docs/faq.es.md](docs/faq.es.md)
|
|
|
131
154
|
No. Son hooks y comprobaciones que se ejecutan aunque el modelo no se acuerde.
|
|
132
155
|
|
|
133
156
|
**¿Envía mi código a algún sitio?**
|
|
134
|
-
No.
|
|
157
|
+
No. Tu código nunca sale de tu máquina y no hay telemetría. La única llamada de red es `gh` preguntando a GitHub por pull requests, y solo si `gh` tiene sesión iniciada. La lista completa está en [Qué lee, escribe y envía](#qué-lee-escribe-y-envía).
|
|
135
158
|
|
|
136
159
|
**¿Me va a ralentizar?**
|
|
137
160
|
Las tareas pequeñas no tienen ceremonia, solo el control al final. Los hooks rápidos siguen siendo rápidos; la comprobación costosa va en `Stop`. El CI rechaza un pull request que lleve un guard de `PreToolUse` por encima de 50 ms en el p95 o que agregue contexto al inicio de la sesión; los límites están en [budgets.json](budgets.json). Publicaremos los tiempos de punta a punta junto con el benchmark.
|
package/README.md
CHANGED
|
@@ -123,6 +123,29 @@ The full comparison, with sources, is in [docs/compare.md](docs/compare.md).
|
|
|
123
123
|
- **Methods like superpowers, GSD, Spec Kit or OpenSpec** tell the agent how to plan and build. Finite Monkey doesn't replace them. It checks the result at the end, whatever method you used.
|
|
124
124
|
- **Single guards like tdd-guard, cc-safety-net or dcg** each do one job well. Finite Monkey covers four damages with one gate, one install and one `undo`. If you only need one of those jobs, a single guard may be the simpler choice.
|
|
125
125
|
|
|
126
|
+
<!-- generated:footprint:start -->
|
|
127
|
+
## What it reads, writes and sends
|
|
128
|
+
|
|
129
|
+
Generated from `src/core/footprint.ts`, the list the tests hold the code to. No telemetry. Paths are relative to the project unless they start with `~`.
|
|
130
|
+
|
|
131
|
+
| | What | Why |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| Reads | `stdin` | The event Claude Code passes to each hook: the tool call, the prompt or the stop request. |
|
|
134
|
+
| Reads | `.claude/settings.json`, `.claude/settings.local.json`, `~/.claude/settings.json` | Claude Code settings, to check that the hooks are installed and nothing switches them off. `$CLAUDE_CONFIG_DIR` replaces `~/.claude` when set. |
|
|
135
|
+
| Reads | `CLAUDE.md`, `.claude/CLAUDE.md`, `CLAUDE.local.md`, `AGENTS.md`, `.claude/rules/`, `.claudeignore` | Instruction files, read by `doctor` to report rules that exist only as text. |
|
|
136
|
+
| Reads | `.git/` | The repository through the `git` command: status, diffs, refs and the reflog. |
|
|
137
|
+
| Reads | `git diff` | Changed files, scanned for secrets, test skips, placeholders and prose patterns. |
|
|
138
|
+
| Reads | `.finitemonkey/config.yml`, `.finitemonkey/briefing.md` | Project configuration and the optional briefing for subagents. |
|
|
139
|
+
| Writes | `.claude/settings.json`, `.claude/skills/verify/SKILL.md`, `AGENTS.md`, `CLAUDE.md`, `.gitignore`, `.finitemonkey/config.yml`, `.finitemonkey/lock.json`, `.finitemonkey/locks/`, `.finitemonkey/runtime/`, `.finitemonkey/backups/` | `init` and `update`: hook settings, the verify skill, a short managed block in `AGENTS.md` that `CLAUDE.md` imports, one `.gitignore` line, the pinned runtime and a backup of every file it changes. |
|
|
140
|
+
| Writes | `.finitemonkey/tasks/`, `.finitemonkey/state.json` | Task contracts and which task is active. |
|
|
141
|
+
| Writes | `.finitemonkey/evidence/`, `.finitemonkey/log.jsonl`, `.finitemonkey/prod-evidence.jsonl` | Evidence of each check, tied to the tree hash, and the gate log. |
|
|
142
|
+
| Writes | `.finitemonkey/trust.json`, `.finitemonkey/allow/`, `.finitemonkey/cache/` | Approvals and grants typed by the person, and a short-lived cache of open pull requests. |
|
|
143
|
+
| Writes | `.finitemonkey/findings/baseline.json`, `.finitemonkey/incidents/` | The accepted-findings baseline and exposure incidents. Both hold fingerprints and masks, never a secret value. |
|
|
144
|
+
| Writes | `.finitemonkey/git/`, `.finitemonkey/git-journal.jsonl`, `.finitemonkey/merge-dropped.json`, `refs/finitemonkey/backup/` | Snapshots before destructive git commands, the journal that `undo` reads and dropped-line decisions from merges. |
|
|
145
|
+
| Writes | `.finitemonkey/reports/` | Masked bug reports that `doctor --report` writes, only when asked. |
|
|
146
|
+
| Sends | `api.github.com` | Through `gh`, only when it is installed and logged in: the state of the pull request named in a task, and your open pull requests for the session line. Code is never uploaded. |
|
|
147
|
+
<!-- generated:footprint:end -->
|
|
148
|
+
|
|
126
149
|
## FAQ
|
|
127
150
|
|
|
128
151
|
More questions, one per real search, in [docs/faq.md](docs/faq.md).
|
|
@@ -131,7 +154,7 @@ More questions, one per real search, in [docs/faq.md](docs/faq.md).
|
|
|
131
154
|
No. It is hooks and checks that run whether or not the model remembers them.
|
|
132
155
|
|
|
133
156
|
**Does it send my code anywhere?**
|
|
134
|
-
No.
|
|
157
|
+
No. Your code never leaves your machine, and there is no telemetry. The one network call is `gh` asking GitHub about pull requests, and only when `gh` is logged in. The full list is in [What it reads, writes and sends](#what-it-reads-writes-and-sends).
|
|
135
158
|
|
|
136
159
|
**Will it slow me down?**
|
|
137
160
|
Small tasks get no ceremony, only the gate at the end. Fast hooks stay fast; the expensive check runs at `Stop`. CI fails a pull request that pushes a `PreToolUse` guard past 50 ms at p95 or adds context at session start; the ceilings are in [budgets.json](budgets.json). We'll publish end-to-end timings with the benchmark.
|
package/README.pt-BR.md
CHANGED
|
@@ -123,6 +123,29 @@ A comparação completa, com fontes, está em [docs/compare.pt-BR.md](docs/compa
|
|
|
123
123
|
- **Métodos como superpowers, GSD, Spec Kit ou OpenSpec** dizem ao agente como planejar e construir. O Finite Monkey não substitui nenhum deles: confere o resultado no fim, seja qual for o método.
|
|
124
124
|
- **Guardas avulsos como tdd-guard, cc-safety-net ou dcg** fazem um trabalho cada um, e bem. O Finite Monkey cobre quatro danos com um portão, uma instalação e um `undo`. Se você só precisa de um desses trabalhos, um guarda avulso pode ser a escolha mais simples.
|
|
125
125
|
|
|
126
|
+
<!-- generated:footprint:start -->
|
|
127
|
+
## O que ele lê, grava e envia
|
|
128
|
+
|
|
129
|
+
Gerado a partir de `src/core/footprint.ts`, a lista que os testes cobram do código. Sem telemetria. Caminhos são relativos ao projeto, exceto os que começam com `~`.
|
|
130
|
+
|
|
131
|
+
| | O quê | Para quê |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| Lê | `stdin` | O evento que o Claude Code passa a cada hook: a chamada de ferramenta, o prompt ou o pedido de parada. |
|
|
134
|
+
| Lê | `.claude/settings.json`, `.claude/settings.local.json`, `~/.claude/settings.json` | As configurações do Claude Code, para conferir que os hooks estão instalados e que nada os desliga. `$CLAUDE_CONFIG_DIR` substitui `~/.claude` quando definido. |
|
|
135
|
+
| Lê | `CLAUDE.md`, `.claude/CLAUDE.md`, `CLAUDE.local.md`, `AGENTS.md`, `.claude/rules/`, `.claudeignore` | Arquivos de instrução, lidos pelo `doctor` para apontar regras que só existem como texto. |
|
|
136
|
+
| Lê | `.git/` | O repositório pelo comando `git`: status, diffs, refs e o reflog. |
|
|
137
|
+
| Lê | `git diff` | Arquivos alterados, varridos atrás de segredos, testes pulados, placeholders e padrões de prosa. |
|
|
138
|
+
| Lê | `.finitemonkey/config.yml`, `.finitemonkey/briefing.md` | A configuração do projeto e o briefing opcional para subagentes. |
|
|
139
|
+
| Grava | `.claude/settings.json`, `.claude/skills/verify/SKILL.md`, `AGENTS.md`, `CLAUDE.md`, `.gitignore`, `.finitemonkey/config.yml`, `.finitemonkey/lock.json`, `.finitemonkey/locks/`, `.finitemonkey/runtime/`, `.finitemonkey/backups/` | `init` e `update`: configuração dos hooks, a skill verify, um bloco gerenciado curto no `AGENTS.md` que o `CLAUDE.md` importa, uma linha no `.gitignore`, o runtime fixado e um backup de cada arquivo que alteram. |
|
|
140
|
+
| Grava | `.finitemonkey/tasks/`, `.finitemonkey/state.json` | Contratos de tarefa e qual tarefa está ativa. |
|
|
141
|
+
| Grava | `.finitemonkey/evidence/`, `.finitemonkey/log.jsonl`, `.finitemonkey/prod-evidence.jsonl` | A evidência de cada checagem, ligada ao hash da árvore, e o log do portão. |
|
|
142
|
+
| Grava | `.finitemonkey/trust.json`, `.finitemonkey/allow/`, `.finitemonkey/cache/` | Aprovações e liberações digitadas pela pessoa, e um cache curto dos pull requests abertos. |
|
|
143
|
+
| Grava | `.finitemonkey/findings/baseline.json`, `.finitemonkey/incidents/` | A baseline de achados aceitos e os incidentes de exposição. Os dois guardam impressões e máscaras, nunca o valor de um segredo. |
|
|
144
|
+
| Grava | `.finitemonkey/git/`, `.finitemonkey/git-journal.jsonl`, `.finitemonkey/merge-dropped.json`, `refs/finitemonkey/backup/` | Snapshots antes de comandos git destrutivos, o diário que o `undo` lê e as decisões sobre linhas descartadas em merges. |
|
|
145
|
+
| Grava | `.finitemonkey/reports/` | Relatórios de bug mascarados que o `doctor --report` grava, só quando pedido. |
|
|
146
|
+
| Envia | `api.github.com` | Pelo `gh`, só quando ele está instalado e logado: o estado do pull request citado numa tarefa e os seus pull requests abertos para a linha da sessão. Código nunca é enviado. |
|
|
147
|
+
<!-- generated:footprint:end -->
|
|
148
|
+
|
|
126
149
|
## Perguntas frequentes
|
|
127
150
|
|
|
128
151
|
Mais perguntas, uma para cada busca real, em [docs/faq.pt-BR.md](docs/faq.pt-BR.md).
|
|
@@ -131,7 +154,7 @@ Mais perguntas, uma para cada busca real, em [docs/faq.pt-BR.md](docs/faq.pt-BR.
|
|
|
131
154
|
Não. São hooks e checagens que rodam lembrando o modelo ou não.
|
|
132
155
|
|
|
133
156
|
**Ele manda meu código para algum lugar?**
|
|
134
|
-
Não.
|
|
157
|
+
Não. Seu código nunca sai da sua máquina, e não há telemetria. A única chamada de rede é o `gh` perguntando ao GitHub sobre pull requests, e só quando o `gh` está logado. A lista completa está em [O que ele lê, grava e envia](#o-que-ele-lê-grava-e-envia).
|
|
135
158
|
|
|
136
159
|
**Vai me deixar mais lento?**
|
|
137
160
|
Tarefa pequena não tem cerimônia, só o portão no fim. Hook rápido continua rápido; a checagem cara roda no `Stop`. O CI reprova um pull request que leve um guard de `PreToolUse` acima de 50 ms no p95 ou que acrescente contexto no início da sessão; os limites estão em [budgets.json](budgets.json). Os tempos de ponta a ponta saem junto com o benchmark.
|
package/dist/finitemonkey.mjs
CHANGED
|
@@ -21,7 +21,7 @@ import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
|
21
21
|
|
|
22
22
|
// src/core/node-exec.ts
|
|
23
23
|
import { spawn, spawnSync } from "node:child_process";
|
|
24
|
-
import { appendFileSync, mkdirSync } from "node:fs";
|
|
24
|
+
import { appendFileSync, existsSync, mkdirSync } from "node:fs";
|
|
25
25
|
import { dirname } from "node:path";
|
|
26
26
|
|
|
27
27
|
// src/core/parsed.ts
|
|
@@ -45,6 +45,32 @@ var optionalString = (record2, key) => {
|
|
|
45
45
|
return typeof value === "string" ? value : void 0;
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
+
// src/core/windows-command.ts
|
|
49
|
+
import { win32 } from "node:path";
|
|
50
|
+
var DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD";
|
|
51
|
+
var NEEDS_SHELL = /\.(cmd|bat)$/i;
|
|
52
|
+
var NEEDS_QUOTES = /[\s"&|<>^()%!]/;
|
|
53
|
+
var envValue = (env, name) => {
|
|
54
|
+
const key = Object.keys(env).find((candidate) => candidate.toUpperCase() === name);
|
|
55
|
+
return key === void 0 ? void 0 : env[key];
|
|
56
|
+
};
|
|
57
|
+
var quoteForCmd = (arg) => arg !== "" && !NEEDS_QUOTES.test(arg) ? arg : `"${arg.replace(/"/g, '""')}"`;
|
|
58
|
+
var resolveWindowsCommand = (command, env, exists) => {
|
|
59
|
+
if (/[\\/]/.test(command) || win32.extname(command) !== "") {
|
|
60
|
+
return { command, shell: NEEDS_SHELL.test(command) };
|
|
61
|
+
}
|
|
62
|
+
const dirs = (envValue(env, "PATH") ?? "").split(";").filter((dir) => dir !== "");
|
|
63
|
+
const extensions = (envValue(env, "PATHEXT") ?? DEFAULT_PATHEXT).split(";").filter((ext) => ext !== "");
|
|
64
|
+
for (const dir of dirs) {
|
|
65
|
+
for (const ext of extensions) {
|
|
66
|
+
const candidate = win32.join(dir, `${command}${ext.toLowerCase()}`);
|
|
67
|
+
if (exists(candidate)) return { command: candidate, shell: NEEDS_SHELL.test(candidate) };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { command, shell: false };
|
|
71
|
+
};
|
|
72
|
+
var windowsCommandLine = (resolved, args) => [quoteForCmd(resolved.command), ...args.map(quoteForCmd)].join(" ");
|
|
73
|
+
|
|
48
74
|
// src/core/node-exec.ts
|
|
49
75
|
var SHELL_NOT_FOUND = /* @__PURE__ */ new Set([127, 9009]);
|
|
50
76
|
var CMD_NOT_FOUND = /is not recognized as an internal or external command|não é reconhecido como um comando interno|no se reconoce como un comando interno/i;
|
|
@@ -67,7 +93,8 @@ var nodeExec = (request) => {
|
|
|
67
93
|
Object.entries({ ...process.env, ...request.env }).filter(([name]) => !(request.unset ?? []).includes(name))
|
|
68
94
|
)
|
|
69
95
|
};
|
|
70
|
-
const
|
|
96
|
+
const resolved = process.platform === "win32" && request.shell !== true ? resolveWindowsCommand(request.command, options.env, existsSync) : void 0;
|
|
97
|
+
const result = request.shell === true ? spawnSync([request.command, ...request.args].join(" "), { ...options, shell: true }) : resolved?.shell === true ? spawnSync(windowsCommandLine(resolved, request.args), { ...options, shell: true }) : spawnSync(resolved?.command ?? request.command, [...request.args], options);
|
|
71
98
|
const code = errnoCode(result.error);
|
|
72
99
|
const exitCode = result.status;
|
|
73
100
|
const shellMissing = request.shell === true && exitCode !== null && (SHELL_NOT_FOUND.has(exitCode) || exitCode === 1 && CMD_NOT_FOUND.test(text(result.stderr)));
|
|
@@ -1132,6 +1159,12 @@ var isBundlePath = (path) => path.endsWith(".mjs");
|
|
|
1132
1159
|
|
|
1133
1160
|
// src/install/plan.ts
|
|
1134
1161
|
var CHANGING = ["create", "merge", "update"];
|
|
1162
|
+
var WSL_MOUNT = /^\/mnt\/[a-z](\/|$)/i;
|
|
1163
|
+
var SYNCED = /(OneDrive|Dropbox|iCloud ?Drive|Mobile Documents|Google ?Drive)/i;
|
|
1164
|
+
var locationOf = (root, env) => ({
|
|
1165
|
+
wslMount: WSL_MOUNT.test(root) && (env["WSL_DISTRO_NAME"] !== void 0 || env["WSL_INTEROP"] !== void 0),
|
|
1166
|
+
synced: SYNCED.test(root)
|
|
1167
|
+
});
|
|
1135
1168
|
var detect = (project, gitRoot2, input) => ({
|
|
1136
1169
|
root: project.root,
|
|
1137
1170
|
gitRoot: gitRoot2,
|
|
@@ -1140,7 +1173,8 @@ var detect = (project, gitRoot2, input) => ({
|
|
|
1140
1173
|
settings: settingsInfo(project.read(SETTINGS_FILE)),
|
|
1141
1174
|
authorities: detectAuthorities(project, input.env),
|
|
1142
1175
|
runner: chooseRunner(project, input.bin),
|
|
1143
|
-
claude: detectClaude(project.runtime.probe)
|
|
1176
|
+
claude: detectClaude(project.runtime.probe),
|
|
1177
|
+
location: locationOf(project.root, input.env)
|
|
1144
1178
|
});
|
|
1145
1179
|
var readPreviousLock = (project) => {
|
|
1146
1180
|
const text6 = project.read(LOCK_FILE);
|
|
@@ -1996,20 +2030,20 @@ var detectOs = ({ platform, env, runtime }) => {
|
|
|
1996
2030
|
const version = runtime.readText(toAbsolutePath("/proc/version"));
|
|
1997
2031
|
return version.ok && /microsoft/i.test(version.value) ? "wsl" : "linux";
|
|
1998
2032
|
};
|
|
1999
|
-
var
|
|
2000
|
-
var
|
|
2033
|
+
var WSL_MOUNT2 = /^\/mnt\/[a-z](\/|$)/i;
|
|
2034
|
+
var SYNCED2 = /(OneDrive|Dropbox|iCloud ?Drive|Mobile Documents|Google ?Drive)/i;
|
|
2001
2035
|
var NON_ASCII = /[^\x20-\x7e]/;
|
|
2002
2036
|
var pathTraits = (path) => ({
|
|
2003
2037
|
spaces: path.includes(" "),
|
|
2004
2038
|
nonAscii: NON_ASCII.test(path),
|
|
2005
|
-
synced:
|
|
2039
|
+
synced: SYNCED2.test(path)
|
|
2006
2040
|
});
|
|
2007
2041
|
var checkOs = (env) => {
|
|
2008
2042
|
const os = detectOs(env);
|
|
2009
2043
|
const findings = [
|
|
2010
2044
|
{ check: "os", status: "ok", messageKey: `doctor.os.${os}`, params: { platform: env.platform } }
|
|
2011
2045
|
];
|
|
2012
|
-
if (os === "wsl" &&
|
|
2046
|
+
if (os === "wsl" && WSL_MOUNT2.test(env.cwd)) {
|
|
2013
2047
|
findings.push({
|
|
2014
2048
|
check: "path.wsl_mount",
|
|
2015
2049
|
status: "warn",
|
|
@@ -5088,6 +5122,8 @@ var en_default = {
|
|
|
5088
5122
|
"install.plan.title": "Finite Monkey plan for {root} (preset {preset}):",
|
|
5089
5123
|
"install.warning": "warning: {message}",
|
|
5090
5124
|
"install.warn.not_git": "this folder is not inside a git repository; installing here anyway",
|
|
5125
|
+
"install.warn.wsl_mount": "{path} is on a Windows drive mounted in WSL: git and hooks run several times slower and file watching misses changes; move the project to the Linux disk (for example ~/projects) and run init there",
|
|
5126
|
+
"install.warn.synced_folder": "{path} is inside a synced folder (OneDrive, Dropbox, iCloud or Google Drive): sync can lock or rewrite files while git and hooks use them; move the project out of the synced folder",
|
|
5091
5127
|
"install.warn.fail_open": "Claude Code {version} cannot block an action when a hook crashes (needs 2.1.295 or newer); guards fail open until you update Claude Code",
|
|
5092
5128
|
"install.warn.authority": "{name} ({source}) also decides when a session may stop; Finite Monkey works alongside it and never turns it off",
|
|
5093
5129
|
"install.warn.plugin": "the finitemonkey plugin is enabled ({source}); its hooks step aside while this project has its own Finite Monkey hooks",
|
|
@@ -5375,7 +5411,9 @@ var en_default = {
|
|
|
5375
5411
|
"gate.merge.clean": "{count, plural, one {# merge checked} other {# merges checked}}, nothing lost",
|
|
5376
5412
|
"doctor.memory.lines": "{file}: {lines, plural, one {# line} other {# lines}} of {max}. Edits made during a session apply only after /clear, /compact or a restart.",
|
|
5377
5413
|
"doctor.memory.too_long": "{file}: {lines, plural, one {# line} other {# lines}}, above the ceiling of {max}; long instruction files get followed less",
|
|
5378
|
-
"doctor.memory.fix_too_long": "Move details out of {file} into docs or skills until it has at most {max} lines, or raise memory.maxLines in .finitemonkey/config.yml"
|
|
5414
|
+
"doctor.memory.fix_too_long": "Move details out of {file} into docs or skills until it has at most {max} lines, or raise memory.maxLines in .finitemonkey/config.yml",
|
|
5415
|
+
"doctor.git.autocrlf": 'git converts line endings to CRLF on checkout (core.autocrlf=true) and {file} does not pin LF; shell hooks and scripts checked out with CRLF fail with "bad interpreter"',
|
|
5416
|
+
"doctor.git.fix_autocrlf": "add `* text=auto eol=lf` to {file}, commit it, then run `git add --renormalize .`"
|
|
5379
5417
|
};
|
|
5380
5418
|
|
|
5381
5419
|
// src/i18n/es.json
|
|
@@ -5588,6 +5626,8 @@ var es_default = {
|
|
|
5588
5626
|
"install.plan.title": "Plan de Finite Monkey para {root} (preset {preset}):",
|
|
5589
5627
|
"install.warning": "aviso: {message}",
|
|
5590
5628
|
"install.warn.not_git": "esta carpeta no está dentro de un repositorio git; se instala aquí de todos modos",
|
|
5629
|
+
"install.warn.wsl_mount": "{path} está en un disco de Windows montado en WSL: git y los hooks van varias veces más lentos y la vigilancia de archivos pierde cambios; mueve el proyecto al disco de Linux (por ejemplo ~/proyectos) y ejecuta init allí",
|
|
5630
|
+
"install.warn.synced_folder": "{path} está dentro de una carpeta sincronizada (OneDrive, Dropbox, iCloud o Google Drive): la sincronización puede bloquear o reescribir archivos mientras git y los hooks los usan; saca el proyecto de la carpeta sincronizada",
|
|
5591
5631
|
"install.warn.fail_open": "Claude Code {version} no puede bloquear la acción cuando un hook falla (necesita 2.1.295 o más nueva); los guardas fallan abiertos hasta que actualices Claude Code",
|
|
5592
5632
|
"install.warn.authority": "{name} ({source}) también decide cuándo puede terminar la sesión; Finite Monkey convive con él y nunca lo desactiva",
|
|
5593
5633
|
"install.warn.plugin": "el plugin finitemonkey está habilitado ({source}); sus hooks ceden el paso mientras este proyecto tenga sus propios hooks de Finite Monkey",
|
|
@@ -5875,7 +5915,9 @@ var es_default = {
|
|
|
5875
5915
|
"gate.merge.clean": "{count, plural, one {# fusión revisada} other {# fusiones revisadas}}, no se perdió nada",
|
|
5876
5916
|
"doctor.memory.lines": "{file}: {lines, plural, one {# línea} other {# líneas}} de {max}. Los cambios hechos durante una sesión solo se aplican tras /clear, /compact o reiniciar.",
|
|
5877
5917
|
"doctor.memory.too_long": "{file}: {lines, plural, one {# línea} other {# líneas}}, por encima del techo de {max}; un archivo de instrucciones largo se sigue menos",
|
|
5878
|
-
"doctor.memory.fix_too_long": "Lleva detalles de {file} a docs o skills hasta que tenga como máximo {max} líneas, o sube memory.maxLines en .finitemonkey/config.yml"
|
|
5918
|
+
"doctor.memory.fix_too_long": "Lleva detalles de {file} a docs o skills hasta que tenga como máximo {max} líneas, o sube memory.maxLines en .finitemonkey/config.yml",
|
|
5919
|
+
"doctor.git.autocrlf": 'git convierte los saltos de línea a CRLF al hacer checkout (core.autocrlf=true) y {file} no fija LF; los hooks y scripts de shell con CRLF fallan con "bad interpreter"',
|
|
5920
|
+
"doctor.git.fix_autocrlf": "añade `* text=auto eol=lf` a {file}, haz commit y ejecuta `git add --renormalize .`"
|
|
5879
5921
|
};
|
|
5880
5922
|
|
|
5881
5923
|
// src/i18n/pt-BR.json
|
|
@@ -6088,6 +6130,8 @@ var pt_BR_default = {
|
|
|
6088
6130
|
"install.plan.title": "Plano do Finite Monkey para {root} (preset {preset}):",
|
|
6089
6131
|
"install.warning": "aviso: {message}",
|
|
6090
6132
|
"install.warn.not_git": "esta pasta não está dentro de um repositório git; instalando aqui mesmo assim",
|
|
6133
|
+
"install.warn.wsl_mount": "{path} está num disco do Windows montado no WSL: git e hooks ficam várias vezes mais lentos e a observação de arquivos perde mudanças; mova o projeto para o disco do Linux (por exemplo ~/projetos) e rode o init lá",
|
|
6134
|
+
"install.warn.synced_folder": "{path} está dentro de uma pasta sincronizada (OneDrive, Dropbox, iCloud ou Google Drive): a sincronização pode travar ou reescrever arquivos enquanto o git e os hooks os usam; tire o projeto da pasta sincronizada",
|
|
6091
6135
|
"install.warn.fail_open": "o Claude Code {version} não consegue barrar a ação quando um hook quebra (precisa da 2.1.295 ou mais nova); as travas falham abertas até você atualizar o Claude Code",
|
|
6092
6136
|
"install.warn.authority": "{name} ({source}) também decide quando a sessão pode parar; o Finite Monkey convive com ele e nunca o desliga",
|
|
6093
6137
|
"install.warn.plugin": "o plugin finitemonkey está habilitado ({source}); os hooks dele cedem a vez enquanto este projeto tiver os próprios hooks do Finite Monkey",
|
|
@@ -6375,7 +6419,9 @@ var pt_BR_default = {
|
|
|
6375
6419
|
"gate.merge.clean": "{count, plural, one {# mescla conferida} other {# mesclas conferidas}}, nada se perdeu",
|
|
6376
6420
|
"doctor.memory.lines": "{file}: {lines, plural, one {# linha} other {# linhas}} de {max}. Edições feitas durante a sessão só valem depois de /clear, /compact ou reiniciar.",
|
|
6377
6421
|
"doctor.memory.too_long": "{file}: {lines, plural, one {# linha} other {# linhas}}, acima do teto de {max}; arquivo de instruções longo é menos seguido",
|
|
6378
|
-
"doctor.memory.fix_too_long": "Leve detalhes de {file} para docs ou skills até ficar com no máximo {max} linhas, ou aumente memory.maxLines em .finitemonkey/config.yml"
|
|
6422
|
+
"doctor.memory.fix_too_long": "Leve detalhes de {file} para docs ou skills até ficar com no máximo {max} linhas, ou aumente memory.maxLines em .finitemonkey/config.yml",
|
|
6423
|
+
"doctor.git.autocrlf": 'o git converte quebras de linha para CRLF no checkout (core.autocrlf=true) e o {file} não fixa LF; hooks e scripts de shell com CRLF falham com "bad interpreter"',
|
|
6424
|
+
"doctor.git.fix_autocrlf": "acrescente `* text=auto eol=lf` ao {file}, faça commit e rode `git add --renormalize .`"
|
|
6379
6425
|
};
|
|
6380
6426
|
|
|
6381
6427
|
// src/i18n/review.json
|
|
@@ -6493,6 +6539,43 @@ var review_default = {
|
|
|
6493
6539
|
"doctor.project.fix_lockfiles": "machine",
|
|
6494
6540
|
"doctor.project.configs": "machine",
|
|
6495
6541
|
"doctor.project.fix_configs": "machine",
|
|
6542
|
+
"doctor.hooks.ok": "machine",
|
|
6543
|
+
"doctor.hooks.no_command": "machine",
|
|
6544
|
+
"doctor.hooks.not_found": "machine",
|
|
6545
|
+
"doctor.hooks.timeout": "machine",
|
|
6546
|
+
"doctor.hooks.exit": "machine",
|
|
6547
|
+
"doctor.hooks.output": "machine",
|
|
6548
|
+
"doctor.hooks.fix_broken": "machine",
|
|
6549
|
+
"doctor.hooks.fix_broken_plugin": "machine",
|
|
6550
|
+
"doctor.hooks.slow": "machine",
|
|
6551
|
+
"doctor.hooks.fix_slow": "machine",
|
|
6552
|
+
"doctor.hooks.fail_open": "machine",
|
|
6553
|
+
"doctor.hooks.fix_fail_open": "machine",
|
|
6554
|
+
"doctor.hooks.matcher": "machine",
|
|
6555
|
+
"doctor.hooks.fix_matcher": "machine",
|
|
6556
|
+
"doctor.hooks.not_fired": "machine",
|
|
6557
|
+
"doctor.hooks.fix_not_fired": "machine",
|
|
6558
|
+
"doctor.hooks.schema": "machine",
|
|
6559
|
+
"doctor.hooks.fix_schema": "machine",
|
|
6560
|
+
"doctor.hooks.plugin_disabled": "machine",
|
|
6561
|
+
"doctor.hooks.fix_plugin_disabled": "machine",
|
|
6562
|
+
"doctor.hooks.none": "machine",
|
|
6563
|
+
"doctor.hooks.fix_none": "machine",
|
|
6564
|
+
"doctor.hooks.absent": "machine",
|
|
6565
|
+
"doctor.hooks.fix_absent": "machine",
|
|
6566
|
+
"doctor.hooks.version_ok": "machine",
|
|
6567
|
+
"doctor.hooks.version_plugin": "machine",
|
|
6568
|
+
"doctor.hooks.fix_version_plugin": "machine",
|
|
6569
|
+
"doctor.hooks.version_cli": "machine",
|
|
6570
|
+
"doctor.hooks.fix_version_cli": "machine",
|
|
6571
|
+
"doctor.hooks.fix_version_cli_plugin": "machine",
|
|
6572
|
+
"doctor.fix.not_installed": "machine",
|
|
6573
|
+
"doctor.fix.nothing": "machine",
|
|
6574
|
+
"doctor.fix.would": "machine",
|
|
6575
|
+
"doctor.fix.applied": "machine",
|
|
6576
|
+
"doctor.fix.backup": "machine",
|
|
6577
|
+
"doctor.fix.manual": "machine",
|
|
6578
|
+
"doctor.report.written": "machine",
|
|
6496
6579
|
"hook.failed_closed": "machine",
|
|
6497
6580
|
"hook.failed_open": "machine",
|
|
6498
6581
|
"exit.ok": "machine",
|
|
@@ -6552,6 +6635,8 @@ var review_default = {
|
|
|
6552
6635
|
"install.plan.title": "machine",
|
|
6553
6636
|
"install.warning": "machine",
|
|
6554
6637
|
"install.warn.not_git": "machine",
|
|
6638
|
+
"install.warn.wsl_mount": "machine",
|
|
6639
|
+
"install.warn.synced_folder": "machine",
|
|
6555
6640
|
"install.warn.fail_open": "machine",
|
|
6556
6641
|
"install.warn.authority": "machine",
|
|
6557
6642
|
"install.warn.plugin": "machine",
|
|
@@ -6840,43 +6925,8 @@ var review_default = {
|
|
|
6840
6925
|
"doctor.memory.lines": "machine",
|
|
6841
6926
|
"doctor.memory.too_long": "machine",
|
|
6842
6927
|
"doctor.memory.fix_too_long": "machine",
|
|
6843
|
-
"doctor.
|
|
6844
|
-
"doctor.
|
|
6845
|
-
"doctor.hooks.not_found": "machine",
|
|
6846
|
-
"doctor.hooks.timeout": "machine",
|
|
6847
|
-
"doctor.hooks.exit": "machine",
|
|
6848
|
-
"doctor.hooks.output": "machine",
|
|
6849
|
-
"doctor.hooks.fix_broken": "machine",
|
|
6850
|
-
"doctor.hooks.fix_broken_plugin": "machine",
|
|
6851
|
-
"doctor.hooks.slow": "machine",
|
|
6852
|
-
"doctor.hooks.fix_slow": "machine",
|
|
6853
|
-
"doctor.hooks.fail_open": "machine",
|
|
6854
|
-
"doctor.hooks.fix_fail_open": "machine",
|
|
6855
|
-
"doctor.hooks.matcher": "machine",
|
|
6856
|
-
"doctor.hooks.fix_matcher": "machine",
|
|
6857
|
-
"doctor.hooks.not_fired": "machine",
|
|
6858
|
-
"doctor.hooks.fix_not_fired": "machine",
|
|
6859
|
-
"doctor.hooks.schema": "machine",
|
|
6860
|
-
"doctor.hooks.fix_schema": "machine",
|
|
6861
|
-
"doctor.hooks.plugin_disabled": "machine",
|
|
6862
|
-
"doctor.hooks.fix_plugin_disabled": "machine",
|
|
6863
|
-
"doctor.hooks.none": "machine",
|
|
6864
|
-
"doctor.hooks.fix_none": "machine",
|
|
6865
|
-
"doctor.hooks.absent": "machine",
|
|
6866
|
-
"doctor.hooks.fix_absent": "machine",
|
|
6867
|
-
"doctor.hooks.version_ok": "machine",
|
|
6868
|
-
"doctor.hooks.version_plugin": "machine",
|
|
6869
|
-
"doctor.hooks.fix_version_plugin": "machine",
|
|
6870
|
-
"doctor.hooks.version_cli": "machine",
|
|
6871
|
-
"doctor.hooks.fix_version_cli": "machine",
|
|
6872
|
-
"doctor.hooks.fix_version_cli_plugin": "machine",
|
|
6873
|
-
"doctor.fix.not_installed": "machine",
|
|
6874
|
-
"doctor.fix.nothing": "machine",
|
|
6875
|
-
"doctor.fix.would": "machine",
|
|
6876
|
-
"doctor.fix.applied": "machine",
|
|
6877
|
-
"doctor.fix.backup": "machine",
|
|
6878
|
-
"doctor.fix.manual": "machine",
|
|
6879
|
-
"doctor.report.written": "machine"
|
|
6928
|
+
"doctor.git.autocrlf": "machine",
|
|
6929
|
+
"doctor.git.fix_autocrlf": "machine"
|
|
6880
6930
|
},
|
|
6881
6931
|
es: {
|
|
6882
6932
|
"command.init.summary": "machine",
|
|
@@ -6991,6 +7041,43 @@ var review_default = {
|
|
|
6991
7041
|
"doctor.project.fix_lockfiles": "machine",
|
|
6992
7042
|
"doctor.project.configs": "machine",
|
|
6993
7043
|
"doctor.project.fix_configs": "machine",
|
|
7044
|
+
"doctor.hooks.ok": "machine",
|
|
7045
|
+
"doctor.hooks.no_command": "machine",
|
|
7046
|
+
"doctor.hooks.not_found": "machine",
|
|
7047
|
+
"doctor.hooks.timeout": "machine",
|
|
7048
|
+
"doctor.hooks.exit": "machine",
|
|
7049
|
+
"doctor.hooks.output": "machine",
|
|
7050
|
+
"doctor.hooks.fix_broken": "machine",
|
|
7051
|
+
"doctor.hooks.fix_broken_plugin": "machine",
|
|
7052
|
+
"doctor.hooks.slow": "machine",
|
|
7053
|
+
"doctor.hooks.fix_slow": "machine",
|
|
7054
|
+
"doctor.hooks.fail_open": "machine",
|
|
7055
|
+
"doctor.hooks.fix_fail_open": "machine",
|
|
7056
|
+
"doctor.hooks.matcher": "machine",
|
|
7057
|
+
"doctor.hooks.fix_matcher": "machine",
|
|
7058
|
+
"doctor.hooks.not_fired": "machine",
|
|
7059
|
+
"doctor.hooks.fix_not_fired": "machine",
|
|
7060
|
+
"doctor.hooks.schema": "machine",
|
|
7061
|
+
"doctor.hooks.fix_schema": "machine",
|
|
7062
|
+
"doctor.hooks.plugin_disabled": "machine",
|
|
7063
|
+
"doctor.hooks.fix_plugin_disabled": "machine",
|
|
7064
|
+
"doctor.hooks.none": "machine",
|
|
7065
|
+
"doctor.hooks.fix_none": "machine",
|
|
7066
|
+
"doctor.hooks.absent": "machine",
|
|
7067
|
+
"doctor.hooks.fix_absent": "machine",
|
|
7068
|
+
"doctor.hooks.version_ok": "machine",
|
|
7069
|
+
"doctor.hooks.version_plugin": "machine",
|
|
7070
|
+
"doctor.hooks.fix_version_plugin": "machine",
|
|
7071
|
+
"doctor.hooks.version_cli": "machine",
|
|
7072
|
+
"doctor.hooks.fix_version_cli": "machine",
|
|
7073
|
+
"doctor.hooks.fix_version_cli_plugin": "machine",
|
|
7074
|
+
"doctor.fix.not_installed": "machine",
|
|
7075
|
+
"doctor.fix.nothing": "machine",
|
|
7076
|
+
"doctor.fix.would": "machine",
|
|
7077
|
+
"doctor.fix.applied": "machine",
|
|
7078
|
+
"doctor.fix.backup": "machine",
|
|
7079
|
+
"doctor.fix.manual": "machine",
|
|
7080
|
+
"doctor.report.written": "machine",
|
|
6994
7081
|
"hook.failed_closed": "machine",
|
|
6995
7082
|
"hook.failed_open": "machine",
|
|
6996
7083
|
"exit.ok": "machine",
|
|
@@ -7050,6 +7137,8 @@ var review_default = {
|
|
|
7050
7137
|
"install.plan.title": "machine",
|
|
7051
7138
|
"install.warning": "machine",
|
|
7052
7139
|
"install.warn.not_git": "machine",
|
|
7140
|
+
"install.warn.wsl_mount": "machine",
|
|
7141
|
+
"install.warn.synced_folder": "machine",
|
|
7053
7142
|
"install.warn.fail_open": "machine",
|
|
7054
7143
|
"install.warn.authority": "machine",
|
|
7055
7144
|
"install.warn.plugin": "machine",
|
|
@@ -7338,43 +7427,8 @@ var review_default = {
|
|
|
7338
7427
|
"doctor.memory.lines": "machine",
|
|
7339
7428
|
"doctor.memory.too_long": "machine",
|
|
7340
7429
|
"doctor.memory.fix_too_long": "machine",
|
|
7341
|
-
"doctor.
|
|
7342
|
-
"doctor.
|
|
7343
|
-
"doctor.hooks.not_found": "machine",
|
|
7344
|
-
"doctor.hooks.timeout": "machine",
|
|
7345
|
-
"doctor.hooks.exit": "machine",
|
|
7346
|
-
"doctor.hooks.output": "machine",
|
|
7347
|
-
"doctor.hooks.fix_broken": "machine",
|
|
7348
|
-
"doctor.hooks.fix_broken_plugin": "machine",
|
|
7349
|
-
"doctor.hooks.slow": "machine",
|
|
7350
|
-
"doctor.hooks.fix_slow": "machine",
|
|
7351
|
-
"doctor.hooks.fail_open": "machine",
|
|
7352
|
-
"doctor.hooks.fix_fail_open": "machine",
|
|
7353
|
-
"doctor.hooks.matcher": "machine",
|
|
7354
|
-
"doctor.hooks.fix_matcher": "machine",
|
|
7355
|
-
"doctor.hooks.not_fired": "machine",
|
|
7356
|
-
"doctor.hooks.fix_not_fired": "machine",
|
|
7357
|
-
"doctor.hooks.schema": "machine",
|
|
7358
|
-
"doctor.hooks.fix_schema": "machine",
|
|
7359
|
-
"doctor.hooks.plugin_disabled": "machine",
|
|
7360
|
-
"doctor.hooks.fix_plugin_disabled": "machine",
|
|
7361
|
-
"doctor.hooks.none": "machine",
|
|
7362
|
-
"doctor.hooks.fix_none": "machine",
|
|
7363
|
-
"doctor.hooks.absent": "machine",
|
|
7364
|
-
"doctor.hooks.fix_absent": "machine",
|
|
7365
|
-
"doctor.hooks.version_ok": "machine",
|
|
7366
|
-
"doctor.hooks.version_plugin": "machine",
|
|
7367
|
-
"doctor.hooks.fix_version_plugin": "machine",
|
|
7368
|
-
"doctor.hooks.version_cli": "machine",
|
|
7369
|
-
"doctor.hooks.fix_version_cli": "machine",
|
|
7370
|
-
"doctor.hooks.fix_version_cli_plugin": "machine",
|
|
7371
|
-
"doctor.fix.not_installed": "machine",
|
|
7372
|
-
"doctor.fix.nothing": "machine",
|
|
7373
|
-
"doctor.fix.would": "machine",
|
|
7374
|
-
"doctor.fix.applied": "machine",
|
|
7375
|
-
"doctor.fix.backup": "machine",
|
|
7376
|
-
"doctor.fix.manual": "machine",
|
|
7377
|
-
"doctor.report.written": "machine"
|
|
7430
|
+
"doctor.git.autocrlf": "machine",
|
|
7431
|
+
"doctor.git.fix_autocrlf": "machine"
|
|
7378
7432
|
}
|
|
7379
7433
|
};
|
|
7380
7434
|
|
|
@@ -10952,11 +11006,11 @@ var withAlias = (invocation, expansion) => ({
|
|
|
10952
11006
|
|
|
10953
11007
|
// src/git/path-key.ts
|
|
10954
11008
|
import { posix as posix2 } from "node:path";
|
|
10955
|
-
var
|
|
11009
|
+
var WSL_MOUNT3 = /^\/mnt\/([a-zA-Z])(\/|$)/;
|
|
10956
11010
|
var DRIVE = /^([a-zA-Z]):(\/|$)/;
|
|
10957
11011
|
var pathKey = (path) => {
|
|
10958
11012
|
const posixPath = toPosixPath(path).replace(
|
|
10959
|
-
|
|
11013
|
+
WSL_MOUNT3,
|
|
10960
11014
|
(_match, letter, slash) => `${letter}:${slash || "/"}`
|
|
10961
11015
|
);
|
|
10962
11016
|
const drive = DRIVE.exec(posixPath);
|
|
@@ -13185,8 +13239,21 @@ var checkInstructions = (env) => {
|
|
|
13185
13239
|
];
|
|
13186
13240
|
};
|
|
13187
13241
|
|
|
13188
|
-
// src/doctor/
|
|
13242
|
+
// src/doctor/line-endings.ts
|
|
13189
13243
|
import { join as join30 } from "node:path";
|
|
13244
|
+
var LF_RULE = /^\*\s.*\beol=lf\b/m;
|
|
13245
|
+
var checkLineEndings = ({ root, runtime }) => {
|
|
13246
|
+
const autocrlf = runtime.git(["config", "--get", "core.autocrlf"], root);
|
|
13247
|
+
if (!autocrlf.ok || autocrlf.stdout.trim().toLowerCase() !== "true") return [];
|
|
13248
|
+
const attributes = runtime.readText(toAbsolutePath(join30(root, ".gitattributes")));
|
|
13249
|
+
if (attributes.ok && LF_RULE.test(attributes.value)) return [];
|
|
13250
|
+
return [
|
|
13251
|
+
finding("git.autocrlf", "warn", "doctor.git.autocrlf", { file: ".gitattributes" }, "doctor.git.fix_autocrlf")
|
|
13252
|
+
];
|
|
13253
|
+
};
|
|
13254
|
+
|
|
13255
|
+
// src/doctor/memory.ts
|
|
13256
|
+
import { join as join31 } from "node:path";
|
|
13190
13257
|
var ceilingOf = (config) => {
|
|
13191
13258
|
const value = configAt(parseConfigYaml(config ?? ""), "memory", "maxLines");
|
|
13192
13259
|
const parsed = typeof value === "string" ? Number.parseInt(value, 10) : Number.NaN;
|
|
@@ -13194,9 +13261,9 @@ var ceilingOf = (config) => {
|
|
|
13194
13261
|
};
|
|
13195
13262
|
var lineCount2 = (text6) => text6.replace(/\r?\n$/, "").split(/\r?\n/).length;
|
|
13196
13263
|
var checkAgentsFile = ({ root, runtime }) => {
|
|
13197
|
-
const text6 = runtime.readText(toAbsolutePath(
|
|
13264
|
+
const text6 = runtime.readText(toAbsolutePath(join31(root, AGENTS_FILE)));
|
|
13198
13265
|
if (!text6.ok) return [];
|
|
13199
|
-
const config = runtime.readText(toAbsolutePath(
|
|
13266
|
+
const config = runtime.readText(toAbsolutePath(join31(root, CONFIG_FILE)));
|
|
13200
13267
|
const max = ceilingOf(config.ok ? config.value : void 0);
|
|
13201
13268
|
const lines3 = lineCount2(text6.value);
|
|
13202
13269
|
const params2 = { file: AGENTS_FILE, lines: lines3, max };
|
|
@@ -13204,7 +13271,7 @@ var checkAgentsFile = ({ root, runtime }) => {
|
|
|
13204
13271
|
};
|
|
13205
13272
|
|
|
13206
13273
|
// src/doctor/project-files.ts
|
|
13207
|
-
import { join as
|
|
13274
|
+
import { join as join32 } from "node:path";
|
|
13208
13275
|
var variants = (base, extensions) => extensions.map((extension) => `${base}${extension}`);
|
|
13209
13276
|
var SCRIPT = [".js", ".cjs", ".mjs", ".ts", ".cts", ".mts"];
|
|
13210
13277
|
var DATA = ["", ".json", ".yml", ".yaml"];
|
|
@@ -13235,7 +13302,7 @@ var CONFIG_GROUPS = [
|
|
|
13235
13302
|
files: [...variants("commitlint.config", SCRIPT), ...variants(".commitlintrc", [...DATA, ".js"])]
|
|
13236
13303
|
}
|
|
13237
13304
|
];
|
|
13238
|
-
var present = (env, files) => files.filter((file) => env.runtime.stat(toAbsolutePath(
|
|
13305
|
+
var present = (env, files) => files.filter((file) => env.runtime.stat(toAbsolutePath(join32(env.root, file)))?.kind === "file");
|
|
13239
13306
|
var crowded = (env, groups, build) => groups.flatMap(({ name, files }) => {
|
|
13240
13307
|
const found = present(env, files);
|
|
13241
13308
|
return found.length > 1 ? [build(name, found.join(", "))] : [];
|
|
@@ -13273,6 +13340,7 @@ var CHECKS = [
|
|
|
13273
13340
|
checkClaudeSettings,
|
|
13274
13341
|
checkInstructions,
|
|
13275
13342
|
checkProjectFiles,
|
|
13343
|
+
checkLineEndings,
|
|
13276
13344
|
checkAgentsFile,
|
|
13277
13345
|
checkHooks
|
|
13278
13346
|
];
|
|
@@ -13800,7 +13868,7 @@ var rescueCommand = {
|
|
|
13800
13868
|
};
|
|
13801
13869
|
|
|
13802
13870
|
// src/git/undo.ts
|
|
13803
|
-
import { basename as basename3, dirname as dirname8, join as
|
|
13871
|
+
import { basename as basename3, dirname as dirname8, join as join33 } from "node:path";
|
|
13804
13872
|
var INDEX_SUBJECT = "finitemonkey index:";
|
|
13805
13873
|
var gitLine = (runtime, repo, args) => {
|
|
13806
13874
|
const result = runtime.git(args, repo.root);
|
|
@@ -13843,7 +13911,7 @@ var findSnapshot = (views, wanted) => {
|
|
|
13843
13911
|
};
|
|
13844
13912
|
var stampOf2 = (iso) => iso.replace(/[:.]/g, "-");
|
|
13845
13913
|
var worktreePath = (runtime, repo) => {
|
|
13846
|
-
const base =
|
|
13914
|
+
const base = join33(dirname8(repo.root), `${basename3(repo.root)}-undo-${stampOf2(runtime.now())}`);
|
|
13847
13915
|
return toAbsolutePath(runtime.stat(toAbsolutePath(base)) === void 0 ? base : `${base}-2`);
|
|
13848
13916
|
};
|
|
13849
13917
|
var intoWorktree = (runtime, repo, view2) => {
|
|
@@ -14032,13 +14100,13 @@ var helpCommand = {
|
|
|
14032
14100
|
};
|
|
14033
14101
|
|
|
14034
14102
|
// src/install/plugin-yield.ts
|
|
14035
|
-
import { join as
|
|
14103
|
+
import { join as join34 } from "node:path";
|
|
14036
14104
|
var PLUGIN_VIA = "plugin";
|
|
14037
14105
|
var YIELD_STDOUT = `${JSON.stringify({ continue: true })}
|
|
14038
14106
|
`;
|
|
14039
14107
|
var projectOwnsHooks = (ctx) => {
|
|
14040
14108
|
const root = ctx.env["CLAUDE_PROJECT_DIR"] ?? ctx.cwd;
|
|
14041
|
-
const text6 = ctx.runtime.readText(toAbsolutePath(
|
|
14109
|
+
const text6 = ctx.runtime.readText(toAbsolutePath(join34(root, ...SETTINGS_FILE.split("/"))));
|
|
14042
14110
|
if (!text6.ok) return false;
|
|
14043
14111
|
const parsed = parseJsonObject(text6.value);
|
|
14044
14112
|
return parsed.ok && ownHandlersIn(parsed.value) > 0;
|
|
@@ -14091,7 +14159,7 @@ var hookCommand = {
|
|
|
14091
14159
|
};
|
|
14092
14160
|
|
|
14093
14161
|
// src/commands/i18n-check.ts
|
|
14094
|
-
import { join as
|
|
14162
|
+
import { join as join35 } from "node:path";
|
|
14095
14163
|
|
|
14096
14164
|
// src/i18n/message.ts
|
|
14097
14165
|
var ARG = /^\s*([a-zA-Z][a-zA-Z0-9_]*)\s*(?:,\s*(plural|select)\s*,)?/;
|
|
@@ -14293,7 +14361,7 @@ var unreadable = (dir, file, detail) => ({
|
|
|
14293
14361
|
exitCode: ExitCode.NotConfigured
|
|
14294
14362
|
});
|
|
14295
14363
|
var readCatalog = (ctx, dir, lang) => {
|
|
14296
|
-
const file = toAbsolutePath(
|
|
14364
|
+
const file = toAbsolutePath(join35(dir, `${lang}.json`));
|
|
14297
14365
|
const text6 = ctx.runtime.readText(file);
|
|
14298
14366
|
if (!text6.ok) return reject(unreadable(dir, file, text6.error));
|
|
14299
14367
|
const parsed = parseJsonObject(text6.value);
|
|
@@ -14316,7 +14384,7 @@ var describeProblem = (ctx, problem4) => {
|
|
|
14316
14384
|
return ` ${problem4.lang} ${problem4.key} ${kind}`;
|
|
14317
14385
|
};
|
|
14318
14386
|
var loadReview = (ctx, dir) => {
|
|
14319
|
-
const text6 = ctx.runtime.readText(toAbsolutePath(
|
|
14387
|
+
const text6 = ctx.runtime.readText(toAbsolutePath(join35(dir, "review.json")));
|
|
14320
14388
|
const parsed = text6.ok ? parseJsonObject(text6.value) : void 0;
|
|
14321
14389
|
if (parsed?.ok !== true) return void 0;
|
|
14322
14390
|
const statuses = (lang) => {
|
|
@@ -14429,6 +14497,8 @@ var itemWarning = (t, item) => {
|
|
|
14429
14497
|
var planWarnings = (t, plan) => [
|
|
14430
14498
|
...plan.detection.gitRoot ? [] : [{ code: "not_git", message: t("install.warn.not_git") }],
|
|
14431
14499
|
...plan.detection.claude.failClosed ? [] : [{ code: "fail_open", message: t("install.warn.fail_open", { version: plan.detection.claude.version ?? "?" }) }],
|
|
14500
|
+
...plan.detection.location.wslMount ? [{ code: "wsl_mount", message: t("install.warn.wsl_mount", { path: plan.detection.root }) }] : [],
|
|
14501
|
+
...plan.detection.location.synced ? [{ code: "synced_folder", message: t("install.warn.synced_folder", { path: plan.detection.root }) }] : [],
|
|
14432
14502
|
...plan.detection.authorities.map((authority) => authorityWarning(t, authority)),
|
|
14433
14503
|
...plan.items.flatMap((item) => itemWarning(t, item))
|
|
14434
14504
|
];
|
|
@@ -14996,7 +15066,7 @@ var secretsScanCommand = {
|
|
|
14996
15066
|
};
|
|
14997
15067
|
|
|
14998
15068
|
// src/task/create.ts
|
|
14999
|
-
import { join as
|
|
15069
|
+
import { join as join36 } from "node:path";
|
|
15000
15070
|
|
|
15001
15071
|
// src/core/yaml/write.ts
|
|
15002
15072
|
var PLAIN_SAFE = /^[A-Za-z_./][A-Za-z0-9_./ ()-]*$/;
|
|
@@ -15080,10 +15150,10 @@ var explicitChecks = (draft) => [
|
|
|
15080
15150
|
var draftChecks = (runtime, paths, draft) => {
|
|
15081
15151
|
const disk = {
|
|
15082
15152
|
read: (relative9) => {
|
|
15083
|
-
const text6 = runtime.readText(toAbsolutePath(
|
|
15153
|
+
const text6 = runtime.readText(toAbsolutePath(join36(paths.root, relative9)));
|
|
15084
15154
|
return text6.ok ? text6.value : void 0;
|
|
15085
15155
|
},
|
|
15086
|
-
exists: (relative9) => runtime.stat(toAbsolutePath(
|
|
15156
|
+
exists: (relative9) => runtime.stat(toAbsolutePath(join36(paths.root, relative9))) !== void 0
|
|
15087
15157
|
};
|
|
15088
15158
|
const detected = detectChecks(disk);
|
|
15089
15159
|
const base = draft.runs.length > 0 || draft.tests !== void 0 ? explicitChecks(draft) : detected;
|
|
@@ -15487,7 +15557,7 @@ var REGISTRY = [
|
|
|
15487
15557
|
];
|
|
15488
15558
|
|
|
15489
15559
|
// src/i18n/lang-settings.ts
|
|
15490
|
-
import { join as
|
|
15560
|
+
import { join as join37 } from "node:path";
|
|
15491
15561
|
var read3 = (runtime, path) => {
|
|
15492
15562
|
const text6 = runtime.readText(toAbsolutePath(path));
|
|
15493
15563
|
return text6.ok ? text6.value : void 0;
|
|
@@ -15502,14 +15572,14 @@ var languageIn = (text6) => {
|
|
|
15502
15572
|
const value = parsed.ok && isRecord(parsed.value) ? parsed.value["language"] : void 0;
|
|
15503
15573
|
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
15504
15574
|
};
|
|
15505
|
-
var claudeDir = (runtime, env) => env["CLAUDE_CONFIG_DIR"] ??
|
|
15575
|
+
var claudeDir = (runtime, env) => env["CLAUDE_CONFIG_DIR"] ?? join37(runtime.homeDir(), ".claude");
|
|
15506
15576
|
var langSettings = (runtime, cwd, env, platform) => {
|
|
15507
15577
|
const root = findGitRoot(cwd, runtime) ?? cwd;
|
|
15508
|
-
const config = parseConfigYaml(read3(runtime,
|
|
15578
|
+
const config = parseConfigYaml(read3(runtime, join37(root, CONFIG_FILE)) ?? "");
|
|
15509
15579
|
const claudeFiles = [
|
|
15510
|
-
|
|
15511
|
-
|
|
15512
|
-
|
|
15580
|
+
join37(root, ".claude", "settings.local.json"),
|
|
15581
|
+
join37(root, ".claude", "settings.json"),
|
|
15582
|
+
join37(claudeDir(runtime, env), "settings.json")
|
|
15513
15583
|
];
|
|
15514
15584
|
return {
|
|
15515
15585
|
config: configText(config, "lang"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "finitemonkey",
|
|
3
|
-
"version": "0.1.0-next.
|
|
3
|
+
"version": "0.1.0-next.12",
|
|
4
4
|
"description": "Claude Code hooks that stop a coding agent from saying done before the tests pass: a machine-checked definition of done, plus guardrails for secrets, git safety and production. Pre-release.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"i18n:check": "node dist/finitemonkey.mjs i18n check --dir src/i18n",
|
|
56
56
|
"bench:startup": "node scripts/bench-startup.mjs",
|
|
57
57
|
"smoke:install": "node scripts/smoke-install.mjs",
|
|
58
|
-
"check": "npm run typecheck && npm run lint && npm run format:check && npm run check:dist && npm test && npm run i18n:check && npm run plugin:validate && npm pack --dry-run && npm run llms:check && npm run schema:check",
|
|
58
|
+
"check": "npm run typecheck && npm run lint && npm run format:check && npm run check:dist && npm test && npm run i18n:check && npm run plugin:validate && npm pack --dry-run && npm run llms:check && npm run schema:check && npm run docs:check",
|
|
59
59
|
"prepublishOnly": "npm run typecheck && npm run check:dist && npm test",
|
|
60
60
|
"prepare": "husky",
|
|
61
61
|
"gif": "tsc -p assets/scripts && node --experimental-strip-types assets/scripts/render.ts",
|
|
@@ -66,6 +66,8 @@
|
|
|
66
66
|
"schema": "tsx scripts/build-schemas.ts",
|
|
67
67
|
"schema:check": "tsx scripts/build-schemas.ts --check",
|
|
68
68
|
"budgets": "tsx scripts/budgets.ts",
|
|
69
|
+
"docs": "tsx scripts/build-docs.ts",
|
|
70
|
+
"docs:check": "tsc -p scripts && tsx scripts/build-docs.ts --check",
|
|
69
71
|
"plugin:sync": "node scripts/plugin-sync.mjs",
|
|
70
72
|
"plugin:validate": "node scripts/plugin-validate.mjs",
|
|
71
73
|
"version": "node scripts/plugin-sync.mjs"
|