hafez 1.0.2 → 1.1.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/README.md +21 -7
- package/dist/cli/format.js +5 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/onboard.d.ts +2 -0
- package/dist/cli/onboard.js +88 -0
- package/package.json +2 -2
- package/skill/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -24,12 +24,15 @@ Set up Hafez, an agent-native knowledge vault (github.com/shrvn-r/hafez):
|
|
|
24
24
|
3. Create my vault — a git repo with entities/ and knowledge/ directories and an
|
|
25
25
|
initial commit. Suggest ~/vault but ask me where I want it first.
|
|
26
26
|
4. Register it: hafez init --register <vault-path>
|
|
27
|
-
5.
|
|
28
|
-
package ("$(npm root -g)/hafez/skill/SKILL.md") to
|
|
27
|
+
5. If you are Claude Code, install the bundled skill: copy skill/SKILL.md
|
|
28
|
+
from the installed package ("$(npm root -g)/hafez/skill/SKILL.md") to
|
|
29
|
+
~/.claude/skills/hafez/SKILL.md. Any other harness: skip this — step 7
|
|
30
|
+
covers integration.
|
|
29
31
|
6. Read hafez help --agent, then verify end-to-end: create a test capture,
|
|
30
32
|
hafez read it back, and show me hafez stats.
|
|
31
|
-
7.
|
|
32
|
-
|
|
33
|
+
7. Run hafez onboard and follow what it prints: interview me to seed the
|
|
34
|
+
vault with my current projects, then help me choose how deeply to
|
|
35
|
+
integrate Hafez into my agent setup.
|
|
33
36
|
```
|
|
34
37
|
|
|
35
38
|
From then on, just mention your projects by name in any session — the skill
|
|
@@ -54,9 +57,13 @@ cd ~/vault && git init && git commit --allow-empty -m "init vault"
|
|
|
54
57
|
hafez init --register ~/vault # remember this vault (one-time)
|
|
55
58
|
hafez init # show current vault resolution
|
|
56
59
|
|
|
57
|
-
# Claude Code
|
|
60
|
+
# Claude Code only (optional): the bundled skill
|
|
58
61
|
mkdir -p ~/.claude/skills/hafez
|
|
59
62
|
cp "$(npm root -g)/hafez/skill/SKILL.md" ~/.claude/skills/hafez/SKILL.md
|
|
63
|
+
|
|
64
|
+
# Then, in your agent — any harness: "run hafez onboard and follow it" —
|
|
65
|
+
# guided first run (seed the vault with your current projects, choose an
|
|
66
|
+
# integration level)
|
|
60
67
|
```
|
|
61
68
|
|
|
62
69
|
Prefer installing without the npm registry? The GitHub release tarball is the
|
|
@@ -131,6 +138,7 @@ Links (`parent`, `related`) are validated — they must point at slugs that exis
|
|
|
131
138
|
| `hafez changelog --since 7.days.ago` | Git-derived change history |
|
|
132
139
|
| `hafez sync` | Pull remote, push local commits (semantic merge on conflicts) |
|
|
133
140
|
| `hafez validate` / `hafez index rebuild` | Integrity check / rebuild the read index |
|
|
141
|
+
| `hafez onboard` | Agent-directed first run: seeding interview + integration setup |
|
|
134
142
|
| `hafez schema [op] [--examples]` | Machine-readable JSON schema for every operation |
|
|
135
143
|
| `hafez export --okf [--out <dir>]` | Read-only OKF v0.1 bundle export |
|
|
136
144
|
|
|
@@ -166,10 +174,16 @@ Writes are serialized through an internal mutex, so a single `Hafez` instance is
|
|
|
166
174
|
|
|
167
175
|
## Agent integration
|
|
168
176
|
|
|
169
|
-
Hafez is built to be operated by agents
|
|
177
|
+
Hafez is built to be operated by agents — any agent. The CLI is the whole
|
|
178
|
+
interface, so every harness that can run shell commands integrates the same
|
|
179
|
+
way: through its instructions file — CLAUDE.md for Claude Code, AGENTS.md
|
|
180
|
+
for everything on the [AGENTS.md standard](https://agents.md) (Codex, Cursor,
|
|
181
|
+
Copilot, …). This repo follows the same convention: `AGENTS.md` is canonical
|
|
182
|
+
and `CLAUDE.md` imports it.
|
|
170
183
|
|
|
171
|
-
-
|
|
184
|
+
- **`hafez onboard`** — an agent-directed first-run guide: a seeding interview for the empty vault, then a choice of integration level (an always-active block for the harness's global instructions file, or invoke-only).
|
|
172
185
|
- **`hafez help --agent`** — a complete API reference designed to be loaded into an agent's context.
|
|
186
|
+
- **Claude Code skill** — an optional adapter for one harness: the package bundles a skill (installed in [Setup](#setup)) covering the full session lifecycle: loading context at session start, vault ops mid-session, and a session-end digest.
|
|
173
187
|
- **`hafez schema <op> --examples`** — JSON schemas with working examples for every batch operation, so agents can self-correct.
|
|
174
188
|
- **`hafez batch`** — apply a whole session's worth of updates atomically from a single JSON payload. Validation errors report every bad op at once with did-you-mean hints.
|
|
175
189
|
- **Markdown-native output** by default, `--json` everywhere for machine consumption.
|
package/dist/cli/format.js
CHANGED
|
@@ -104,6 +104,11 @@ export function formatSearchResults(results) {
|
|
|
104
104
|
}
|
|
105
105
|
export function formatStats(stats) {
|
|
106
106
|
const lines = [];
|
|
107
|
+
const totalEntities = stats.counts.active + stats.counts.paused + stats.counts.done;
|
|
108
|
+
if (totalEntities === 0 && stats.knowledge_count === 0) {
|
|
109
|
+
lines.push('Vault is empty — run `hafez onboard` for the guided first run (seeding interview + agent integration).');
|
|
110
|
+
lines.push('');
|
|
111
|
+
}
|
|
107
112
|
lines.push('## Status Counts');
|
|
108
113
|
lines.push(`Active: ${stats.counts.active} | Paused: ${stats.counts.paused} | Done: ${stats.counts.done}`);
|
|
109
114
|
lines.push('\n## Type Counts');
|
package/dist/cli/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { HafezError } from '../types.js';
|
|
|
7
7
|
import { cmdRead, cmdQuery, cmdSearch, cmdCreate, cmdUpdate, cmdLink, cmdUnlink, cmdPromote, cmdValidate, cmdIndexRebuild, cmdBatch, cmdSync, cmdStats, cmdChangelog, cmdDigest, cmdCapture } from './commands.js';
|
|
8
8
|
import { cmdSchema } from './commands-schema.js';
|
|
9
9
|
import { renderAgentHelp } from './help-agent.js';
|
|
10
|
+
import { renderOnboard } from './onboard.js';
|
|
10
11
|
import { resolveVaultPath, noVaultMessage, cmdInit } from './resolve-vault.js';
|
|
11
12
|
const COMMANDS = {
|
|
12
13
|
read: cmdRead,
|
|
@@ -65,6 +66,7 @@ Commands:
|
|
|
65
66
|
index rebuild Rebuild the SQLite index
|
|
66
67
|
init --register <path> Register an existing vault
|
|
67
68
|
init Show current vault resolution
|
|
69
|
+
onboard Agent-directed first run: seed the vault, pick integration level
|
|
68
70
|
help --agent Full API reference for agents
|
|
69
71
|
|
|
70
72
|
Global flags:
|
|
@@ -107,6 +109,11 @@ export async function main(argv) {
|
|
|
107
109
|
process.stdout.write(USAGE);
|
|
108
110
|
return;
|
|
109
111
|
}
|
|
112
|
+
// onboard runs before vault resolution — static agent-directed text
|
|
113
|
+
if (command === 'onboard') {
|
|
114
|
+
process.stdout.write(renderOnboard());
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
110
117
|
// schema runs before vault resolution — pure Zod introspection, no vault needed.
|
|
111
118
|
if (command === 'schema') {
|
|
112
119
|
try {
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const INTEGRATION_SNIPPET = "## Hafez \u2014 Session Memory\n\n- Session start: if the first message names a project or topic, load context\n with `hafez read <slug>` (or `hafez search \"<topic>\"`). Don't load\n speculatively.\n- Mid-session: new workstream -> create an entity. Durable insight -> create\n or update a knowledge note (search first). User mentions a project by\n name -> check if it's a Hafez entity. Use `hafez batch` for 2+ mutations.\n- Session end: record a digest (`hafez digest | hafez batch`) with the\n entities touched, decisions made, and a short narrative.\n- Knowledge boundary: useful beyond this repo/session -> vault knowledge\n note. Specific to one repo's code -> that repo's own docs, not the vault.";
|
|
2
|
+
export declare function renderOnboard(): string;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// src/cli/onboard.ts
|
|
2
|
+
//
|
|
3
|
+
// `hafez onboard` — agent-directed first-run guide. Same pattern as
|
|
4
|
+
// `hafez help --agent`: plain text printed for the agent operating on the
|
|
5
|
+
// user's behalf. Covers the two things a fresh install leaves open — seeding
|
|
6
|
+
// the empty vault and choosing how deeply the agent integrates.
|
|
7
|
+
//
|
|
8
|
+
// Static by design, and deliberately NOT part of the skill: the skill loads
|
|
9
|
+
// into every session forever, this is read once. Living in the CLI also means
|
|
10
|
+
// it works before the skill is installed.
|
|
11
|
+
export const INTEGRATION_SNIPPET = `## Hafez — Session Memory
|
|
12
|
+
|
|
13
|
+
- Session start: if the first message names a project or topic, load context
|
|
14
|
+
with \`hafez read <slug>\` (or \`hafez search "<topic>"\`). Don't load
|
|
15
|
+
speculatively.
|
|
16
|
+
- Mid-session: new workstream -> create an entity. Durable insight -> create
|
|
17
|
+
or update a knowledge note (search first). User mentions a project by
|
|
18
|
+
name -> check if it's a Hafez entity. Use \`hafez batch\` for 2+ mutations.
|
|
19
|
+
- Session end: record a digest (\`hafez digest | hafez batch\`) with the
|
|
20
|
+
entities touched, decisions made, and a short narrative.
|
|
21
|
+
- Knowledge boundary: useful beyond this repo/session -> vault knowledge
|
|
22
|
+
note. Specific to one repo's code -> that repo's own docs, not the vault.`;
|
|
23
|
+
export function renderOnboard() {
|
|
24
|
+
return `# Hafez — First Run
|
|
25
|
+
|
|
26
|
+
You are an agent reading this on behalf of your user. Walk them through the
|
|
27
|
+
steps below conversationally — do not dump this document on them.
|
|
28
|
+
|
|
29
|
+
Prerequisites: \`hafez init\` resolves a vault, and you have read
|
|
30
|
+
\`hafez help --agent\` (do that now if not). The CLI is the whole interface —
|
|
31
|
+
no other pieces are required. If your harness is Claude Code, also install
|
|
32
|
+
the bundled skill — see the README Setup (github.com/shrvn-r/hafez).
|
|
33
|
+
|
|
34
|
+
## Step 1 — Seed the vault
|
|
35
|
+
|
|
36
|
+
An empty vault gives the agent nothing to trigger on, so the memory loop
|
|
37
|
+
never starts. The goal here is a small set of high-quality entries — not a
|
|
38
|
+
bulk import.
|
|
39
|
+
|
|
40
|
+
1. Interview the user: "What are you actively working on right now?" Aim for
|
|
41
|
+
3-7 projects or areas. For each one, draw out:
|
|
42
|
+
- a one-line description (\`description\`)
|
|
43
|
+
- current state / handoff context, 2-4 sentences (\`brief\`)
|
|
44
|
+
- 1-2 concrete next actions (\`add_action\`)
|
|
45
|
+
2. Offer to mine sources they already have — a repo's README, existing notes,
|
|
46
|
+
a TODO list. Read what they point you at, propose entries, and let them
|
|
47
|
+
approve before writing anything.
|
|
48
|
+
3. Anything vague, aspirational, or someday-maybe becomes a capture, not a
|
|
49
|
+
project. Captures are the inbox; promotion comes later. When in doubt,
|
|
50
|
+
capture.
|
|
51
|
+
4. Write everything in ONE \`hafez batch\` call (see
|
|
52
|
+
\`hafez schema create-entity --examples\`), then show the user
|
|
53
|
+
\`hafez stats\`.
|
|
54
|
+
|
|
55
|
+
Quality bar: every project entry should let a future agent with zero context
|
|
56
|
+
pick the work up from the brief alone. If a brief would not do that, ask one
|
|
57
|
+
more question.
|
|
58
|
+
|
|
59
|
+
## Step 2 — Choose the integration level
|
|
60
|
+
|
|
61
|
+
Ask the user how they want Hafez wired into their sessions. Recommend the
|
|
62
|
+
first option.
|
|
63
|
+
|
|
64
|
+
RECOMMENDED — always active. Add the block below to the user's global agent
|
|
65
|
+
instructions file — Claude Code: \`~/.claude/CLAUDE.md\`; any harness that
|
|
66
|
+
follows the AGENTS.md standard (Codex, Cursor, Copilot, ...): its global
|
|
67
|
+
AGENTS.md, e.g. \`~/.codex/AGENTS.md\` for Codex CLI. This makes memory
|
|
68
|
+
automatic: context loads at session start, the vault is updated as work
|
|
69
|
+
happens, and a digest records each session. Show them the block, get a yes,
|
|
70
|
+
then append it verbatim:
|
|
71
|
+
|
|
72
|
+
${INTEGRATION_SNIPPET}
|
|
73
|
+
|
|
74
|
+
FALLBACK — invoke only. If the user prefers to stay in control, add nothing.
|
|
75
|
+
Explain how invocation works: the agent touches the vault only when they
|
|
76
|
+
mention Hafez or name a project ("what am I working on?", "read <slug>").
|
|
77
|
+
Nothing is loaded or written unless asked. They can upgrade later
|
|
78
|
+
by re-running \`hafez onboard\`.
|
|
79
|
+
|
|
80
|
+
## Step 3 — Hand over
|
|
81
|
+
|
|
82
|
+
Finish with three example asks tailored to what was just seeded, e.g.:
|
|
83
|
+
|
|
84
|
+
- "What am I working on?"
|
|
85
|
+
- "Read <their-project-slug> and pick up where we left off."
|
|
86
|
+
- "Capture: <idea> — I'll triage it later."
|
|
87
|
+
`;
|
|
88
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hafez",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
20
|
"build": "rm -rf dist && tsc",
|
|
21
|
-
"install:local": "mkdir -p ~/.local/bin && ln -sf \"$(pwd)/dist/cli.js\" ~/.local/bin/hafez && rm -f ~/.claude/skills/hafez/SKILL.md && mkdir -p ~/.claude/skills/hafez && cp \"$(pwd)/skill/SKILL.md\" ~/.claude/skills/hafez/SKILL.md",
|
|
21
|
+
"install:local": "chmod +x \"$(pwd)/dist/cli.js\" && mkdir -p ~/.local/bin && ln -sf \"$(pwd)/dist/cli.js\" ~/.local/bin/hafez && rm -f ~/.claude/skills/hafez/SKILL.md && mkdir -p ~/.claude/skills/hafez && cp \"$(pwd)/skill/SKILL.md\" ~/.claude/skills/hafez/SKILL.md",
|
|
22
22
|
"pretest": "npm run build",
|
|
23
23
|
"test": "vitest run",
|
|
24
24
|
"test:watch": "vitest",
|
package/skill/SKILL.md
CHANGED
|
@@ -14,7 +14,7 @@ description: >
|
|
|
14
14
|
|
|
15
15
|
All operations use the `hafez` CLI. No file manipulation — the CLI handles reads, writes, validation, and git.
|
|
16
16
|
|
|
17
|
-
If `hafez` is not installed, or `hafez init` reports no vault, stop and follow the setup in the project README (github.com/shrvn-r/hafez) before using this skill.
|
|
17
|
+
If `hafez` is not installed, or `hafez init` reports no vault, stop and follow the setup in the project README (github.com/shrvn-r/hafez) before using this skill. If the vault exists but is empty, run `hafez onboard` and follow what it prints.
|
|
18
18
|
|
|
19
19
|
## CLI Reference
|
|
20
20
|
|