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.
Files changed (68) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/README.en.md +41 -3
  3. package/README.md +41 -3
  4. package/bin/wendkeep.mjs +54 -6
  5. package/docs/en/commands/changes-and-verification.md +9 -3
  6. package/docs/en/commands/getting-started.md +7 -3
  7. package/docs/en/commands/memory.md +20 -2
  8. package/docs/en/commands/operating-profiles.md +173 -0
  9. package/docs/en/commands/sessions-and-import.md +8 -4
  10. package/docs/en/commands/verify.md +12 -6
  11. package/docs/pt-BR/commands/changes-and-verification.md +9 -4
  12. package/docs/pt-BR/commands/getting-started.md +7 -3
  13. package/docs/pt-BR/commands/memory.md +18 -2
  14. package/docs/pt-BR/commands/operating-profiles.md +171 -0
  15. package/docs/pt-BR/commands/sessions-and-import.md +7 -3
  16. package/docs/pt-BR/commands/verify.md +11 -5
  17. package/hooks/brain-core.mjs +159 -159
  18. package/hooks/brain-inject.mjs +83 -26
  19. package/hooks/brain-recall.mjs +32 -32
  20. package/hooks/brain-reindex.mjs +13 -13
  21. package/hooks/change-context.mjs +24 -10
  22. package/hooks/change-core.mjs +174 -37
  23. package/hooks/change-guard.mjs +115 -16
  24. package/hooks/change-nag.mjs +20 -5
  25. package/hooks/change-warn.mjs +27 -9
  26. package/hooks/decision-capture.mjs +1 -1
  27. package/hooks/derived-sections.mjs +1 -1
  28. package/hooks/flow-core.mjs +891 -0
  29. package/hooks/flow-protected-policy.mjs +218 -0
  30. package/hooks/frontmatter-repair.mjs +3 -1
  31. package/hooks/git-snapshot.mjs +722 -0
  32. package/hooks/import-sessions.mjs +10 -5
  33. package/hooks/memory-mode.mjs +63 -13
  34. package/hooks/memory-store.mjs +309 -69
  35. package/hooks/obsidian-common.mjs +39 -55
  36. package/hooks/operating-profile-runtime.mjs +157 -0
  37. package/hooks/plan-capture.mjs +14 -3
  38. package/hooks/sensors-core.mjs +15 -3
  39. package/hooks/session-backfill.mjs +7 -2
  40. package/hooks/session-ensure.mjs +6 -4
  41. package/hooks/session-iteration.mjs +65 -0
  42. package/hooks/session-memory-lifecycle.mjs +10 -5
  43. package/hooks/session-note-io.mjs +130 -15
  44. package/hooks/session-observability.mjs +4 -2
  45. package/hooks/session-stop.mjs +65 -19
  46. package/hooks/spec-core.mjs +91 -12
  47. package/hooks/subagent-stop.mjs +4 -1
  48. package/hooks/subagent-usage.mjs +2 -2
  49. package/hooks/task-log.mjs +3 -1
  50. package/hooks/token-usage.mjs +1 -1
  51. package/hooks/vault-health.mjs +183 -37
  52. package/hooks/vault-path-safety.mjs +558 -0
  53. package/hooks/vault-runtime-store.mjs +558 -0
  54. package/package.json +3 -3
  55. package/src/change.mjs +2 -1
  56. package/src/flow.mjs +232 -0
  57. package/src/init.mjs +26 -3
  58. package/src/memory.mjs +785 -35
  59. package/src/operating-profile.mjs +133 -0
  60. package/src/profile.mjs +224 -0
  61. package/src/project-vault.mjs +110 -5
  62. package/src/rebuild-costs.mjs +11 -4
  63. package/src/skills-seed.mjs +38 -16
  64. package/src/sync-defs.mjs +16 -7
  65. package/src/sync.mjs +9 -1
  66. package/src/taxonomy.mjs +8 -0
  67. package/src/validate-memory.mjs +21 -8
  68. package/src/verify.mjs +12 -2
@@ -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 { getVaultBase, readHookInput, writeHookOutput } from './obsidian-common.mjs';
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, { vaultBase, cwd = '.', sessionId = '' } = {}) {
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
- if (readSentinel(vaultBase, 'warn', sessionId)) return null;
27
- writeSentinel(vaultBase, 'warn', sessionId);
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 warn = warnDecision(input.tool_input?.file_path, {
39
- vaultBase: getVaultBase(input),
40
- cwd: input.cwd || '.',
41
- sessionId: input.session_id || input.sessionId || '',
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 });