wendkeep 0.58.1 → 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 +120 -0
- package/README.en.md +70 -40
- package/README.md +70 -40
- package/bin/wendkeep.mjs +54 -6
- package/docs/en/commands/changes-and-verification.md +85 -0
- package/docs/en/commands/costs-and-observability.md +65 -0
- package/docs/en/commands/getting-started.md +86 -0
- package/docs/en/commands/maintenance-and-diagnostics.md +77 -0
- package/docs/en/commands/memory-migration.md +73 -0
- package/docs/en/commands/memory.md +102 -0
- package/docs/en/commands/notes-and-knowledge.md +70 -0
- package/docs/en/commands/operating-profiles.md +173 -0
- package/docs/en/commands/retroactive-import.md +67 -0
- package/docs/en/commands/sessions-and-import.md +89 -0
- package/docs/en/commands/verify.md +92 -0
- package/docs/pt-BR/commands/changes-and-verification.md +85 -0
- package/docs/pt-BR/commands/costs-and-observability.md +65 -0
- package/docs/pt-BR/commands/getting-started.md +87 -0
- package/docs/pt-BR/commands/maintenance-and-diagnostics.md +77 -0
- package/docs/pt-BR/commands/memory-migration.md +73 -0
- package/docs/pt-BR/commands/memory.md +99 -0
- package/docs/pt-BR/commands/notes-and-knowledge.md +69 -0
- package/docs/pt-BR/commands/operating-profiles.md +171 -0
- package/docs/pt-BR/commands/retroactive-import.md +67 -0
- package/docs/pt-BR/commands/sessions-and-import.md +89 -0
- package/docs/pt-BR/commands/verify.md +93 -0
- 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 +119 -84
- 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 +21 -12
- package/hooks/session-iteration.mjs +65 -0
- package/hooks/session-memory-lifecycle.mjs +335 -0
- package/hooks/session-note-io.mjs +130 -15
- package/hooks/session-observability.mjs +4 -2
- package/hooks/session-stop.mjs +181 -59
- 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 +268 -25
- package/hooks/vault-path-safety.mjs +558 -0
- package/hooks/vault-runtime-store.mjs +558 -0
- package/package.json +5 -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 +9 -0
- package/src/validate-memory.mjs +21 -8
- package/src/verify.mjs +12 -2
package/src/sync-defs.mjs
CHANGED
|
@@ -58,14 +58,23 @@ function renderAgentsSection(skills, sourceHash = '') {
|
|
|
58
58
|
const list = skills.map((s) => `- **${s.name}** — ${s.description}`).join('\n');
|
|
59
59
|
return `${AG_START}
|
|
60
60
|
<!-- wendkeep-version: ${WENDKEEP_VERSION}; skills-sha256: ${sourceHash} -->
|
|
61
|
-
## wendkeep —
|
|
61
|
+
## wendkeep — Keep Core & operating profiles
|
|
62
62
|
|
|
63
|
-
This project uses the [wendkeep](https://github.com/rogersialves/wendkeep) harness.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
This project uses the [wendkeep](https://github.com/rogersialves/wendkeep) harness. **Keep Core is always active**
|
|
64
|
+
in every profile: Vault, session, identity, memory, lessons, and persistence integrations.
|
|
65
|
+
The effective profile is selected explicitly; missing or invalid configuration uses **GOVERN as the default**.
|
|
66
|
+
|
|
67
|
+
Route work by the effective profile:
|
|
68
|
+
- **OFF** — Wend Runtime is disabled and governance belongs to the native LLM harness; Keep Core stays active.
|
|
69
|
+
- **FLOW** — Execute → Validate through \`wendkeep flow start/finish\`, without creating a change.
|
|
70
|
+
- **GUIDE** — Plan → Execute → Validate through a compact change.
|
|
71
|
+
- **GOVERN** — the default a2 loop: \`wendkeep change new <slug>\` → review → implement tasks test-first
|
|
72
|
+
(tag proof \`[sensor:id]\` and requirement \`[req:ID]\`) → \`wendkeep verify\` →
|
|
73
|
+
\`wendkeep verify --deep\` + independent read-only verdict → \`wendkeep change archive\`.
|
|
74
|
+
- **ASSURE** — GOVERN plus explicit confirmation and handoff.
|
|
75
|
+
|
|
76
|
+
Inspect with \`wendkeep profile status\` / \`wendkeep change status\` /
|
|
77
|
+
\`spec effective --change <slug>\` / \`sensors list\`. Author specs only in
|
|
69
78
|
\`08-Mudanças/<slug>/specs/\`; \`07-Specs\` is generated and must not be edited directly.
|
|
70
79
|
|
|
71
80
|
Process skills (full text in \`.claude/skills/\`, \`.agents/skills/\`, and the vault's \`.brain/skills/\`):
|
package/src/sync.mjs
CHANGED
|
@@ -22,6 +22,9 @@ const step = (n, label) => process.stdout.write(`\n[${n}/3] ${label}\n`);
|
|
|
22
22
|
export async function runSync(argv) {
|
|
23
23
|
const projectRaw = opt(argv, '--project');
|
|
24
24
|
const vaultRaw = opt(argv, '--vault');
|
|
25
|
+
const hasProfile = argv.includes('--profile') || argv.some((a) => a.startsWith('--profile='));
|
|
26
|
+
const profileRaw = opt(argv, '--profile');
|
|
27
|
+
const profileArgs = hasProfile ? ['--profile', profileRaw] : [];
|
|
25
28
|
const projectPath = resolve(projectRaw && !projectRaw.startsWith('--') ? projectRaw : process.cwd());
|
|
26
29
|
const passthrough = argv.filter((a) => a === '--yes' || a === '-y' || a === '--force');
|
|
27
30
|
|
|
@@ -29,7 +32,12 @@ export async function runSync(argv) {
|
|
|
29
32
|
step(1, 'init');
|
|
30
33
|
const { runInit } = await import('./init.mjs');
|
|
31
34
|
try {
|
|
32
|
-
await runInit([
|
|
35
|
+
await runInit([
|
|
36
|
+
'--project', projectPath,
|
|
37
|
+
...(vaultRaw ? ['--vault', vaultRaw] : []),
|
|
38
|
+
...profileArgs,
|
|
39
|
+
...passthrough,
|
|
40
|
+
]);
|
|
33
41
|
} catch (error) {
|
|
34
42
|
process.stderr.write(`wendkeep sync: init falhou — ${error.message}\n`);
|
|
35
43
|
return 1;
|
package/src/taxonomy.mjs
CHANGED
|
@@ -37,6 +37,15 @@ export const HOOK_FILES = [
|
|
|
37
37
|
'memory-schema.mjs',
|
|
38
38
|
'memory-store.mjs',
|
|
39
39
|
'memory-handoff.mjs',
|
|
40
|
+
'session-memory-lifecycle.mjs',
|
|
41
|
+
'session-note-io.mjs',
|
|
42
|
+
'operating-profile-runtime.mjs',
|
|
43
|
+
'git-snapshot.mjs',
|
|
44
|
+
'flow-protected-policy.mjs',
|
|
45
|
+
'session-iteration.mjs',
|
|
46
|
+
'vault-path-safety.mjs',
|
|
47
|
+
'vault-runtime-store.mjs',
|
|
48
|
+
'flow-core.mjs',
|
|
40
49
|
'change-core.mjs',
|
|
41
50
|
'spec-core.mjs',
|
|
42
51
|
'sensors-core.mjs',
|
package/src/validate-memory.mjs
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { validateMemoryEvent, validateSharedMemory } from '../hooks/memory-schema.mjs';
|
|
4
|
+
import { assertVaultPathSafe } from '../hooks/vault-path-safety.mjs';
|
|
4
5
|
import { validateCore } from './validate-core.mjs';
|
|
5
6
|
|
|
6
7
|
function failedComponent(errors, extra = {}) {
|
|
7
8
|
return { ok: false, errors: Array.isArray(errors) ? errors : [errors], warnings: [], ...extra };
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
function readRequired(path, label) {
|
|
11
|
-
|
|
11
|
+
function readRequired(vaultBase, path, label) {
|
|
12
|
+
let checked;
|
|
12
13
|
try {
|
|
13
|
-
|
|
14
|
+
checked = assertVaultPathSafe(vaultBase, path, {
|
|
15
|
+
expectedType: 'file', label: `artefato ${label}`,
|
|
16
|
+
});
|
|
17
|
+
} catch (error) {
|
|
18
|
+
return { ok: false, error: `${label} inseguro: ${error?.message || error}` };
|
|
19
|
+
}
|
|
20
|
+
if (!checked.exists) return { ok: false, error: `${label} ausente: ${path}` };
|
|
21
|
+
try {
|
|
22
|
+
// Deliberately adjacent to the open performed by readFileSync.
|
|
23
|
+
checked = assertVaultPathSafe(vaultBase, checked.target, {
|
|
24
|
+
allowMissing: false, expectedType: 'file', label: `artefato ${label}`,
|
|
25
|
+
});
|
|
26
|
+
return { ok: true, content: readFileSync(checked.target, 'utf8') };
|
|
14
27
|
} catch (error) {
|
|
15
28
|
return { ok: false, error: `${label} ilegível: ${error?.message || error}` };
|
|
16
29
|
}
|
|
@@ -18,7 +31,7 @@ function readRequired(path, label) {
|
|
|
18
31
|
|
|
19
32
|
export function readProjectForValidation(vaultBase) {
|
|
20
33
|
const path = join(vaultBase, '.brain', 'PROJECT.json');
|
|
21
|
-
const read = readRequired(path, 'PROJECT.json');
|
|
34
|
+
const read = readRequired(vaultBase, path, 'PROJECT.json');
|
|
22
35
|
if (!read.ok) return failedComponent(read.error, { projectId: '', path });
|
|
23
36
|
try {
|
|
24
37
|
const marker = JSON.parse(read.content);
|
|
@@ -34,7 +47,7 @@ export function readProjectForValidation(vaultBase) {
|
|
|
34
47
|
/** Read and validate the append-only JSONL authority without repairing or mutating it. */
|
|
35
48
|
export function readLedgerForValidation(vaultBase, { projectId } = {}) {
|
|
36
49
|
const path = join(vaultBase, '.brain', 'MEMORY_EVENTS.jsonl');
|
|
37
|
-
const read = readRequired(path, 'MEMORY_EVENTS.jsonl');
|
|
50
|
+
const read = readRequired(vaultBase, path, 'MEMORY_EVENTS.jsonl');
|
|
38
51
|
if (!read.ok) return failedComponent(read.error, { events: [], eventIds: new Set(), path });
|
|
39
52
|
|
|
40
53
|
const errors = [];
|
|
@@ -79,14 +92,14 @@ export function readLedgerForValidation(vaultBase, { projectId } = {}) {
|
|
|
79
92
|
|
|
80
93
|
function validateCoreArtifact(vaultBase) {
|
|
81
94
|
const path = join(vaultBase, '.brain', 'CORE.md');
|
|
82
|
-
const read = readRequired(path, 'CORE.md');
|
|
95
|
+
const read = readRequired(vaultBase, path, 'CORE.md');
|
|
83
96
|
if (!read.ok) return failedComponent(read.error, { lineCount: 0, path });
|
|
84
97
|
return { ...validateCore(read.content), path, content: read.content };
|
|
85
98
|
}
|
|
86
99
|
|
|
87
100
|
function validateSharedArtifact(vaultBase, eventIds) {
|
|
88
101
|
const path = join(vaultBase, '.brain', 'SHARED_MEMORY.md');
|
|
89
|
-
const read = readRequired(path, 'SHARED_MEMORY.md');
|
|
102
|
+
const read = readRequired(vaultBase, path, 'SHARED_MEMORY.md');
|
|
90
103
|
if (!read.ok) return failedComponent(read.error, { path });
|
|
91
104
|
return { ...validateSharedMemory(read.content, { eventIds }), path, content: read.content };
|
|
92
105
|
}
|
package/src/verify.mjs
CHANGED
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
import { readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
5
5
|
import { isAbsolute, join, resolve } from 'node:path';
|
|
6
6
|
import { parseTasks, activeChange, appendFixTasks, healSpecBacklinks } from '../hooks/change-core.mjs';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
loadSensorsDetailed,
|
|
9
|
+
findProjectRoot,
|
|
10
|
+
requiredSensors,
|
|
11
|
+
runSensors,
|
|
12
|
+
evaluateGate,
|
|
13
|
+
sensorProcessEnv,
|
|
14
|
+
} from '../hooks/sensors-core.mjs';
|
|
8
15
|
import {
|
|
9
16
|
buildEffectiveRequirementPackage,
|
|
10
17
|
captureSpecBaseline,
|
|
@@ -54,7 +61,10 @@ export function runVerify(argv) {
|
|
|
54
61
|
process.stderr.write(`wendkeep verify: wendkeep.sensors.json não encontrado em ${loaded.path} — rode da raiz do projeto ou use --project <raiz>\n`);
|
|
55
62
|
}
|
|
56
63
|
const sensors = loaded.sensors;
|
|
57
|
-
const evidence = runSensors(sensors, ids, {
|
|
64
|
+
const evidence = runSensors(sensors, ids, {
|
|
65
|
+
cwd: projectRoot,
|
|
66
|
+
env: sensorProcessEnv(vaultBase),
|
|
67
|
+
});
|
|
58
68
|
writeFileSync(join(changeDir, 'evidencia.json'), `${JSON.stringify(evidence, null, 2)}\n`, 'utf8');
|
|
59
69
|
// Freshness seal: bind this evidence to the tarefas.md it was produced against, so the archive
|
|
60
70
|
// gate can reject evidence gone stale (a sensor task added after this verify run).
|