wendkeep 0.58.3 → 0.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +73 -0
- package/README.en.md +41 -3
- package/README.md +41 -3
- package/bin/wendkeep.mjs +54 -6
- package/docs/en/commands/changes-and-verification.md +9 -3
- package/docs/en/commands/getting-started.md +7 -3
- package/docs/en/commands/memory.md +20 -2
- package/docs/en/commands/operating-profiles.md +173 -0
- package/docs/en/commands/sessions-and-import.md +8 -4
- package/docs/en/commands/verify.md +12 -6
- package/docs/pt-BR/commands/changes-and-verification.md +9 -4
- package/docs/pt-BR/commands/getting-started.md +7 -3
- package/docs/pt-BR/commands/memory.md +18 -2
- package/docs/pt-BR/commands/operating-profiles.md +171 -0
- package/docs/pt-BR/commands/sessions-and-import.md +7 -3
- package/docs/pt-BR/commands/verify.md +11 -5
- package/hooks/brain-core.mjs +159 -159
- package/hooks/brain-inject.mjs +83 -26
- package/hooks/brain-recall.mjs +32 -32
- package/hooks/brain-reindex.mjs +13 -13
- package/hooks/change-context.mjs +24 -10
- package/hooks/change-core.mjs +174 -37
- package/hooks/change-guard.mjs +115 -16
- package/hooks/change-nag.mjs +20 -5
- package/hooks/change-warn.mjs +27 -9
- package/hooks/decision-capture.mjs +1 -1
- package/hooks/derived-sections.mjs +1 -1
- package/hooks/flow-core.mjs +891 -0
- package/hooks/flow-protected-policy.mjs +218 -0
- package/hooks/frontmatter-repair.mjs +3 -1
- package/hooks/git-snapshot.mjs +722 -0
- package/hooks/import-sessions.mjs +10 -5
- package/hooks/memory-mode.mjs +63 -13
- package/hooks/memory-store.mjs +309 -69
- package/hooks/obsidian-common.mjs +39 -55
- package/hooks/operating-profile-runtime.mjs +157 -0
- package/hooks/plan-capture.mjs +14 -3
- package/hooks/sensors-core.mjs +15 -3
- package/hooks/session-backfill.mjs +7 -2
- package/hooks/session-ensure.mjs +6 -4
- package/hooks/session-iteration.mjs +65 -0
- package/hooks/session-memory-lifecycle.mjs +10 -5
- package/hooks/session-note-io.mjs +130 -15
- package/hooks/session-observability.mjs +4 -2
- package/hooks/session-stop.mjs +65 -19
- package/hooks/spec-core.mjs +91 -12
- package/hooks/subagent-stop.mjs +4 -1
- package/hooks/subagent-usage.mjs +2 -2
- package/hooks/task-log.mjs +3 -1
- package/hooks/token-usage.mjs +1 -1
- package/hooks/vault-health.mjs +183 -37
- package/hooks/vault-path-safety.mjs +558 -0
- package/hooks/vault-runtime-store.mjs +558 -0
- package/package.json +3 -3
- package/src/change.mjs +2 -1
- package/src/flow.mjs +232 -0
- package/src/init.mjs +26 -3
- package/src/memory.mjs +785 -35
- package/src/operating-profile.mjs +133 -0
- package/src/profile.mjs +224 -0
- package/src/project-vault.mjs +110 -5
- package/src/rebuild-costs.mjs +11 -4
- package/src/skills-seed.mjs +38 -16
- package/src/sync-defs.mjs +16 -7
- package/src/sync.mjs +9 -1
- package/src/taxonomy.mjs +8 -0
- package/src/validate-memory.mjs +21 -8
- package/src/verify.mjs +12 -2
package/hooks/change-warn.mjs
CHANGED
|
@@ -4,8 +4,14 @@
|
|
|
4
4
|
// bloqueia — mudança trivial pode seguir. Ignora edições no vault e em .claude/.agent/.brain.
|
|
5
5
|
import { isAbsolute, resolve } from 'node:path';
|
|
6
6
|
import { pathToFileURL } from 'node:url';
|
|
7
|
-
import {
|
|
7
|
+
import { readHookInput, writeHookOutput } from './obsidian-common.mjs';
|
|
8
|
+
import { profileRuntimeError } from './brain-inject.mjs';
|
|
8
9
|
import { activeChange, readSentinel, writeSentinel } from './change-core.mjs';
|
|
10
|
+
import {
|
|
11
|
+
hookProfilePolicy,
|
|
12
|
+
profileSentinelId,
|
|
13
|
+
resolveHookOperatingProfile,
|
|
14
|
+
} from './operating-profile-runtime.mjs';
|
|
9
15
|
|
|
10
16
|
const CODE_EXT = /\.(ts|tsx|js|jsx|mjs|cjs|py|prisma|sql|go|rs|java|cs)$/i;
|
|
11
17
|
|
|
@@ -16,15 +22,23 @@ export function isCodeFile(p) {
|
|
|
16
22
|
const norm = (p) => String(p || '').replace(/\\/g, '/');
|
|
17
23
|
|
|
18
24
|
// Retorna o additionalContext do aviso, ou null (caso comum).
|
|
19
|
-
export function warnDecision(filePath, {
|
|
25
|
+
export function warnDecision(filePath, {
|
|
26
|
+
vaultBase,
|
|
27
|
+
cwd = '.',
|
|
28
|
+
sessionId = '',
|
|
29
|
+
profile = 'GOVERN',
|
|
30
|
+
} = {}) {
|
|
31
|
+
const policy = hookProfilePolicy(profile);
|
|
32
|
+
if (!policy.requiresChange) return null;
|
|
20
33
|
if (!filePath || !isCodeFile(filePath)) return null;
|
|
21
34
|
if (activeChange(vaultBase)) return null;
|
|
22
35
|
const abs = norm(isAbsolute(filePath) ? filePath : resolve(cwd, filePath));
|
|
23
36
|
// Dentro do vault (NTFS é case-insensitive) ou em dirs de config de agente: não é código do projeto.
|
|
24
37
|
if (abs.toLowerCase().startsWith(`${norm(resolve(vaultBase)).toLowerCase()}/`)) return null;
|
|
25
38
|
if (/\/(\.claude|\.agent|\.brain)\//.test(`${abs}/`)) return null;
|
|
26
|
-
|
|
27
|
-
|
|
39
|
+
const sentinelId = profileSentinelId(sessionId, profile);
|
|
40
|
+
if (readSentinel(vaultBase, 'warn', sentinelId)) return null;
|
|
41
|
+
writeSentinel(vaultBase, 'warn', sentinelId);
|
|
28
42
|
return [
|
|
29
43
|
'<change_warn>',
|
|
30
44
|
`Você editou código (${filePath}) sem change ativa. Para trabalho não-trivial, roteie pelo processo: \`wendkeep change new <slug>\` e preencha proposta/design/tarefas (skill wk-workflow). Ignore se for um ajuste trivial — este aviso não repete nesta sessão.`,
|
|
@@ -35,11 +49,15 @@ export function warnDecision(filePath, { vaultBase, cwd = '.', sessionId = '' }
|
|
|
35
49
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
36
50
|
try {
|
|
37
51
|
const input = readHookInput();
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
const runtime = resolveHookOperatingProfile({ input });
|
|
53
|
+
const warn = runtime.bindingError
|
|
54
|
+
? profileRuntimeError(runtime.bindingError)
|
|
55
|
+
: warnDecision(input.tool_input?.file_path, {
|
|
56
|
+
vaultBase: runtime.vaultBase,
|
|
57
|
+
cwd: input.cwd || '.',
|
|
58
|
+
sessionId: input.session_id || input.sessionId || '',
|
|
59
|
+
profile: runtime.profile,
|
|
60
|
+
});
|
|
43
61
|
if (!warn) { writeHookOutput({}); }
|
|
44
62
|
else writeHookOutput({ hookSpecificOutput: { hookEventName: 'PostToolUse', additionalContext: warn } });
|
|
45
63
|
} catch {
|
|
@@ -212,7 +212,7 @@ export function captureDecision(vaultBase, input) {
|
|
|
212
212
|
session = anchor === -1 ? `${session.trimEnd()}${section}` : `${session.slice(0, anchor).trimEnd()}${section}${session.slice(anchor)}`;
|
|
213
213
|
}
|
|
214
214
|
return session;
|
|
215
|
-
});
|
|
215
|
+
}, { vaultBase });
|
|
216
216
|
} catch { /* backlink auxiliar nunca derruba a captura */ }
|
|
217
217
|
}
|
|
218
218
|
return { rel, skipped: false };
|
|
@@ -178,7 +178,7 @@ export function repairDerivedSections(vaultBase, { apply = false, lockTimeoutMs
|
|
|
178
178
|
const outcome = mutateSessionNote(
|
|
179
179
|
abs,
|
|
180
180
|
(original) => applyDerivedSections(original, mergedForNote(entry)),
|
|
181
|
-
lockTimeoutMs ? { timeoutMs: lockTimeoutMs } : {},
|
|
181
|
+
{ ...(lockTimeoutMs ? { timeoutMs: lockTimeoutMs } : {}), vaultBase },
|
|
182
182
|
);
|
|
183
183
|
if (!outcome.written) { skipped.push({ file: rel, reason: `gravação não ocorreu (${outcome.reason})` }); continue; }
|
|
184
184
|
repaired.push({ file: rel, missing });
|