harnery 0.8.0 → 0.10.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 +2 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +8 -0
- package/dist/commands/agents.d.ts +24 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +244 -13
- package/dist/commands/backup.d.ts +5 -4
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +15 -14
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +27 -1
- package/dist/commands/claude-desktop.d.ts +19 -0
- package/dist/commands/claude-desktop.d.ts.map +1 -0
- package/dist/commands/claude-desktop.js +168 -0
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +149 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +37 -0
- package/dist/commands/eml.d.ts +32 -0
- package/dist/commands/eml.d.ts.map +1 -1
- package/dist/commands/eml.js +16 -3
- package/dist/commands/grep.d.ts +35 -2
- package/dist/commands/grep.d.ts.map +1 -1
- package/dist/commands/grep.js +427 -139
- package/dist/commands/harness.d.ts +11 -0
- package/dist/commands/harness.d.ts.map +1 -0
- package/dist/commands/harness.js +118 -0
- package/dist/commands/init.d.ts +15 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +125 -14
- package/dist/commands/presence.d.ts +9 -4
- package/dist/commands/presence.d.ts.map +1 -1
- package/dist/commands/presence.js +88 -5
- package/dist/commands/relay.d.ts +9 -0
- package/dist/commands/relay.d.ts.map +1 -0
- package/dist/commands/relay.js +143 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +5 -0
- package/dist/commands/workflow.d.ts +4 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +82 -0
- package/dist/core/agents/canonical-emit.d.ts +15 -0
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +41 -3
- package/dist/core/agents/cli.js +14 -5
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +44 -3
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +26 -1
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/claim-conflict.js +26 -1
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +4 -37
- package/dist/core/agents/rules/stop-hook.d.ts +8 -0
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +8 -0
- package/dist/core/agents/session-events.d.ts.map +1 -1
- package/dist/core/agents/session-events.js +16 -43
- package/dist/core/agents/state/heartbeat-projector.d.ts +2 -0
- package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-projector.js +24 -4
- package/dist/core/agents/state/heartbeat-writer.d.ts +16 -2
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +24 -7
- package/dist/core/agents/state/names.d.ts +38 -3
- package/dist/core/agents/state/names.d.ts.map +1 -1
- package/dist/core/agents/state/names.js +46 -7
- package/dist/core/agents/state/pidmap.d.ts +5 -1
- package/dist/core/agents/state/pidmap.d.ts.map +1 -1
- package/dist/core/agents/state/pidmap.js +58 -2
- package/dist/core/agents/state/stale-sweep.d.ts +3 -2
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +6 -6
- package/dist/core/config.d.ts +77 -11
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +210 -25
- package/dist/core/context/index.d.ts +144 -0
- package/dist/core/context/index.d.ts.map +1 -0
- package/dist/core/context/index.js +380 -0
- package/dist/core/harnesses/bench.d.ts +29 -0
- package/dist/core/harnesses/bench.d.ts.map +1 -0
- package/dist/core/harnesses/bench.js +151 -0
- package/dist/core/harnesses/index.d.ts +9 -0
- package/dist/core/harnesses/index.d.ts.map +1 -0
- package/dist/core/harnesses/index.js +4 -0
- package/dist/core/harnesses/profiles.d.ts +62 -0
- package/dist/core/harnesses/profiles.d.ts.map +1 -0
- package/dist/core/harnesses/profiles.js +115 -0
- package/dist/core/harnesses/registry.d.ts +15 -0
- package/dist/core/harnesses/registry.d.ts.map +1 -0
- package/dist/core/harnesses/registry.js +113 -0
- package/dist/core/harnesses/types.d.ts +64 -0
- package/dist/core/harnesses/types.d.ts.map +1 -0
- package/dist/core/harnesses/types.js +20 -0
- package/dist/core/hooks/cli.js +309 -66
- package/dist/core/hooks/events/schema.d.ts +42 -1
- package/dist/core/hooks/events/schema.d.ts.map +1 -1
- package/dist/core/hooks/harness/events.d.ts +7 -0
- package/dist/core/hooks/harness/events.d.ts.map +1 -1
- package/dist/core/hooks/harness/events.js +4 -0
- package/dist/core/hooks/harness/parse.d.ts +1 -1
- package/dist/core/hooks/harness/parse.d.ts.map +1 -1
- package/dist/core/hooks/harness/parse.js +4 -0
- package/dist/core/hooks/resolve/coord-root.d.ts +11 -0
- package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -1
- package/dist/core/hooks/resolve/coord-root.js +28 -6
- package/dist/core/presence/blob.d.ts +40 -0
- package/dist/core/presence/blob.d.ts.map +1 -0
- package/dist/core/presence/blob.js +91 -0
- package/dist/core/presence/git.d.ts +68 -0
- package/dist/core/presence/git.d.ts.map +1 -0
- package/dist/core/presence/git.js +173 -0
- package/dist/core/presence/index.d.ts +74 -0
- package/dist/core/presence/index.d.ts.map +1 -0
- package/dist/core/presence/index.js +224 -0
- package/dist/core/presence/relay-client.d.ts +39 -0
- package/dist/core/presence/relay-client.d.ts.map +1 -0
- package/dist/core/presence/relay-client.js +295 -0
- package/dist/core/presence/relay-protocol.d.ts +94 -0
- package/dist/core/presence/relay-protocol.d.ts.map +1 -0
- package/dist/core/presence/relay-protocol.js +169 -0
- package/dist/core/workflow/billing.d.ts +48 -0
- package/dist/core/workflow/billing.d.ts.map +1 -0
- package/dist/core/workflow/billing.js +108 -0
- package/dist/core/workflow/child-env.d.ts +30 -0
- package/dist/core/workflow/child-env.d.ts.map +1 -0
- package/dist/core/workflow/child-env.js +43 -0
- package/dist/core/workflow/engine.d.ts +21 -0
- package/dist/core/workflow/engine.d.ts.map +1 -0
- package/dist/core/workflow/engine.js +349 -0
- package/dist/core/workflow/harnesses.d.ts +17 -0
- package/dist/core/workflow/harnesses.d.ts.map +1 -0
- package/dist/core/workflow/harnesses.js +21 -0
- package/dist/core/workflow/spawn-claude.d.ts +25 -0
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -0
- package/dist/core/workflow/spawn-claude.js +103 -0
- package/dist/core/workflow/spawn-codex.d.ts +22 -0
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -0
- package/dist/core/workflow/spawn-codex.js +88 -0
- package/dist/core/workflow/spawn-cursor.d.ts +29 -0
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -0
- package/dist/core/workflow/spawn-cursor.js +91 -0
- package/dist/core/workflow/types.d.ts +152 -0
- package/dist/core/workflow/types.d.ts.map +1 -0
- package/dist/core/workflow/types.js +9 -0
- package/dist/core/workflow/validate.d.ts +15 -0
- package/dist/core/workflow/validate.d.ts.map +1 -0
- package/dist/core/workflow/validate.js +70 -0
- package/dist/lib/browser/client.d.ts +16 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +22 -0
- package/dist/lib/browser/index.d.ts +1 -0
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +1 -0
- package/dist/lib/browser/launch-args.d.ts +21 -0
- package/dist/lib/browser/launch-args.d.ts.map +1 -0
- package/dist/lib/browser/launch-args.js +32 -0
- package/dist/lib/claude-desktop.d.ts +105 -0
- package/dist/lib/claude-desktop.d.ts.map +1 -0
- package/dist/lib/claude-desktop.js +217 -0
- package/dist/lib/docs-lint.d.ts.map +1 -1
- package/dist/lib/docs-lint.js +5 -2
- package/dist/lib/identities/assume.d.ts +51 -0
- package/dist/lib/identities/assume.d.ts.map +1 -0
- package/dist/lib/identities/assume.js +274 -0
- package/dist/lib/identities/index.d.ts +7 -7
- package/dist/lib/identities/index.d.ts.map +1 -1
- package/dist/lib/identities/index.js +24 -24
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +15 -2
- package/package.json +12 -1
- package/schemas/config.schema.json +88 -19
- package/src/commander.ts +8 -0
- package/src/commands/agents.ts +280 -14
- package/src/commands/backup.ts +17 -16
- package/src/commands/browse.ts +32 -0
- package/src/commands/claude-desktop.ts +215 -0
- package/src/commands/context.ts +174 -1
- package/src/commands/doctor.ts +44 -0
- package/src/commands/eml.ts +22 -4
- package/src/commands/grep.ts +535 -142
- package/src/commands/harness.ts +147 -0
- package/src/commands/init.ts +138 -17
- package/src/commands/presence.ts +111 -5
- package/src/commands/relay.ts +160 -0
- package/src/commands/sync.ts +4 -0
- package/src/commands/workflow.ts +123 -0
- package/src/core/agents/canonical-emit.ts +41 -3
- package/src/core/agents/cli.ts +15 -6
- package/src/core/agents/render/prompt-context.ts +48 -3
- package/src/core/agents/render/session-context.ts +27 -1
- package/src/core/agents/rules/claim-conflict.ts +26 -1
- package/src/core/agents/rules/commit-conflict.ts +4 -33
- package/src/core/agents/rules/stop-hook.ts +17 -0
- package/src/core/agents/session-events.ts +15 -39
- package/src/core/agents/state/heartbeat-projector.ts +23 -2
- package/src/core/agents/state/heartbeat-writer.ts +33 -7
- package/src/core/agents/state/names.ts +68 -9
- package/src/core/agents/state/pidmap.ts +59 -2
- package/src/core/agents/state/stale-sweep.ts +6 -11
- package/src/core/config.ts +271 -24
- package/src/core/context/index.ts +575 -0
- package/src/core/harnesses/bench.ts +214 -0
- package/src/core/harnesses/index.ts +31 -0
- package/src/core/harnesses/profiles.ts +141 -0
- package/src/core/harnesses/registry.ts +140 -0
- package/src/core/harnesses/types.ts +90 -0
- package/src/core/hooks/cli.ts +361 -65
- package/src/core/hooks/events/schema.ts +72 -0
- package/src/core/hooks/harness/events.ts +11 -0
- package/src/core/hooks/harness/parse.ts +7 -1
- package/src/core/hooks/resolve/coord-root.ts +28 -6
- package/src/core/presence/blob.ts +125 -0
- package/src/core/presence/git.ts +191 -0
- package/src/core/presence/index.ts +274 -0
- package/src/core/presence/relay-client.ts +322 -0
- package/src/core/presence/relay-protocol.ts +246 -0
- package/src/core/workflow/billing.ts +152 -0
- package/src/core/workflow/child-env.ts +47 -0
- package/src/core/workflow/engine.ts +403 -0
- package/src/core/workflow/harnesses.ts +33 -0
- package/src/core/workflow/spawn-claude.ts +118 -0
- package/src/core/workflow/spawn-codex.ts +93 -0
- package/src/core/workflow/spawn-cursor.ts +108 -0
- package/src/core/workflow/types.ts +160 -0
- package/src/core/workflow/validate.ts +75 -0
- package/src/lib/browser/client.ts +37 -0
- package/src/lib/browser/index.ts +1 -0
- package/src/lib/browser/launch-args.ts +33 -0
- package/src/lib/claude-desktop.ts +293 -0
- package/src/lib/docs-lint.ts +5 -2
- package/src/lib/identities/assume.ts +363 -0
- package/src/lib/identities/index.ts +28 -24
- package/src/lib/instructions/templates.ts +16 -2
|
@@ -47,21 +47,21 @@ export interface AgentIdentity {
|
|
|
47
47
|
created_at: string;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
function identitiesDir(): string | null {
|
|
51
|
-
const root = monorepoRoot();
|
|
50
|
+
function identitiesDir(coordRoot?: string): string | null {
|
|
51
|
+
const root = coordRoot ?? monorepoRoot();
|
|
52
52
|
if (!root) return null;
|
|
53
53
|
return resolve(root, ".harnery", "identities");
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
function ensureDir(): string {
|
|
57
|
-
const dir = identitiesDir();
|
|
56
|
+
function ensureDir(coordRoot?: string): string {
|
|
57
|
+
const dir = identitiesDir(coordRoot);
|
|
58
58
|
if (!dir) throw new Error("not in an agent session; no monorepo root");
|
|
59
59
|
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
60
60
|
return dir;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
function identityPath(agentId: string): string {
|
|
64
|
-
return resolve(ensureDir(), `${agentId}.json`);
|
|
63
|
+
function identityPath(agentId: string, coordRoot?: string): string {
|
|
64
|
+
return resolve(ensureDir(coordRoot), `${agentId}.json`);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
function nowIso(): string {
|
|
@@ -94,8 +94,8 @@ export function displayName(name: string): string {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
/** Read one identity by id. Null if missing. */
|
|
97
|
-
export function lookupById(agentId: string): AgentIdentity | null {
|
|
98
|
-
const dir = identitiesDir();
|
|
97
|
+
export function lookupById(agentId: string, coordRoot?: string): AgentIdentity | null {
|
|
98
|
+
const dir = identitiesDir(coordRoot);
|
|
99
99
|
if (!dir) return null;
|
|
100
100
|
const fp = resolve(dir, `${agentId}.json`);
|
|
101
101
|
if (!existsSync(fp)) return null;
|
|
@@ -104,8 +104,8 @@ export function lookupById(agentId: string): AgentIdentity | null {
|
|
|
104
104
|
|
|
105
105
|
/** Read one identity by display name (case-insensitive on bare name).
|
|
106
106
|
* Scans the directory; O(N) on identity count. */
|
|
107
|
-
export function lookupByName(name: string): AgentIdentity | null {
|
|
108
|
-
const dir = identitiesDir();
|
|
107
|
+
export function lookupByName(name: string, coordRoot?: string): AgentIdentity | null {
|
|
108
|
+
const dir = identitiesDir(coordRoot);
|
|
109
109
|
if (!dir || !existsSync(dir)) return null;
|
|
110
110
|
const wanted = bareName(name).toLowerCase();
|
|
111
111
|
for (const f of readdirSync(dir)) {
|
|
@@ -121,8 +121,8 @@ export function lookupByName(name: string): AgentIdentity | null {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
/** All known identities, sorted by created_at ascending. */
|
|
124
|
-
export function listIdentities(): AgentIdentity[] {
|
|
125
|
-
const dir = identitiesDir();
|
|
124
|
+
export function listIdentities(coordRoot?: string): AgentIdentity[] {
|
|
125
|
+
const dir = identitiesDir(coordRoot);
|
|
126
126
|
if (!dir || !existsSync(dir)) return [];
|
|
127
127
|
const out: AgentIdentity[] = [];
|
|
128
128
|
for (const f of readdirSync(dir)) {
|
|
@@ -144,8 +144,8 @@ export function listIdentities(): AgentIdentity[] {
|
|
|
144
144
|
* surface whichever happened to be read first; the second is orphaned.
|
|
145
145
|
* For agent personas (added at human cadence) this race is theoretical.
|
|
146
146
|
*/
|
|
147
|
-
export function ensureIdentity(name: string): AgentIdentity {
|
|
148
|
-
const existing = lookupByName(name);
|
|
147
|
+
export function ensureIdentity(name: string, coordRoot?: string): AgentIdentity {
|
|
148
|
+
const existing = lookupByName(name, coordRoot);
|
|
149
149
|
if (existing) return existing;
|
|
150
150
|
const id: AgentIdentity = {
|
|
151
151
|
schema_version: IDENTITY_SCHEMA_VERSION,
|
|
@@ -154,14 +154,14 @@ export function ensureIdentity(name: string): AgentIdentity {
|
|
|
154
154
|
aliases: [],
|
|
155
155
|
created_at: nowIso(),
|
|
156
156
|
};
|
|
157
|
-
writeIdentity(id);
|
|
157
|
+
writeIdentity(id, coordRoot);
|
|
158
158
|
return id;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
/** Persist an identity (tmp + rename). Creates the dir if missing. */
|
|
162
|
-
export function writeIdentity(id: AgentIdentity): void {
|
|
163
|
-
ensureDir();
|
|
164
|
-
const fp = identityPath(id.agent_id);
|
|
162
|
+
export function writeIdentity(id: AgentIdentity, coordRoot?: string): void {
|
|
163
|
+
ensureDir(coordRoot);
|
|
164
|
+
const fp = identityPath(id.agent_id, coordRoot);
|
|
165
165
|
const tmp = `${fp}.tmp.${process.pid}`;
|
|
166
166
|
writeFileSync(tmp, `${JSON.stringify(id, null, 2)}\n`, "utf8");
|
|
167
167
|
renameSync(tmp, fp);
|
|
@@ -172,8 +172,12 @@ export function writeIdentity(id: AgentIdentity): void {
|
|
|
172
172
|
* lookup still resolves correctly. The agent_id is stable across renames,
|
|
173
173
|
* which is the whole point of the registry.
|
|
174
174
|
*/
|
|
175
|
-
export function renameIdentity(
|
|
176
|
-
|
|
175
|
+
export function renameIdentity(
|
|
176
|
+
agentId: string,
|
|
177
|
+
newName: string,
|
|
178
|
+
coordRoot?: string,
|
|
179
|
+
): AgentIdentity {
|
|
180
|
+
const existing = lookupById(agentId, coordRoot);
|
|
177
181
|
if (!existing) {
|
|
178
182
|
throw new Error(`renameIdentity: no identity matching '${agentId}'`);
|
|
179
183
|
}
|
|
@@ -184,7 +188,7 @@ export function renameIdentity(agentId: string, newName: string): AgentIdentity
|
|
|
184
188
|
name: bare,
|
|
185
189
|
aliases: [...existing.aliases, { name: existing.name, retired_at: nowIso() }],
|
|
186
190
|
};
|
|
187
|
-
writeIdentity(next);
|
|
191
|
+
writeIdentity(next, coordRoot);
|
|
188
192
|
return next;
|
|
189
193
|
}
|
|
190
194
|
|
|
@@ -197,14 +201,14 @@ export function renameIdentity(agentId: string, newName: string): AgentIdentity
|
|
|
197
201
|
* Does NOT mint. Callers that want mint-on-miss should call ensureIdentity()
|
|
198
202
|
* with a name, then use the returned agent_id.
|
|
199
203
|
*/
|
|
200
|
-
export function resolveAgentId(input: string): string | null {
|
|
204
|
+
export function resolveAgentId(input: string, coordRoot?: string): string | null {
|
|
201
205
|
const trimmed = input.trim();
|
|
202
206
|
if (!trimmed) return null;
|
|
203
207
|
// UUID shape check, relaxed; we only need the lookupById to confirm.
|
|
204
208
|
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(trimmed)) {
|
|
205
|
-
const byId = lookupById(trimmed);
|
|
209
|
+
const byId = lookupById(trimmed, coordRoot);
|
|
206
210
|
if (byId) return byId.agent_id;
|
|
207
211
|
}
|
|
208
|
-
const byName = lookupByName(trimmed);
|
|
212
|
+
const byName = lookupByName(trimmed, coordRoot);
|
|
209
213
|
return byName ? byName.agent_id : null;
|
|
210
214
|
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* Node — no `files`-field copy or package-path guesswork.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import { SCRATCH_CATEGORIES } from "../../core/scratch/index.ts";
|
|
14
15
|
import { buildOwnedSkill } from "./splice.ts";
|
|
15
16
|
|
|
16
17
|
/** Managed-region name for the AGENTS.md orientation block. */
|
|
@@ -57,6 +58,13 @@ export function renderInstructionsBlock(
|
|
|
57
58
|
const councilPointer = skills.council
|
|
58
59
|
? "The `harn-council` skill has the steward and member flow."
|
|
59
60
|
: `See \`${b} council --help\` for the steward and member flow.`;
|
|
61
|
+
// Render the scratch categories from the canonical enum so this prose can
|
|
62
|
+
// never drift from what `scratch add` actually accepts (the "note, plan…" list
|
|
63
|
+
// silently lagged the tool by two categories before this).
|
|
64
|
+
const scratchCats =
|
|
65
|
+
SCRATCH_CATEGORIES.length > 1
|
|
66
|
+
? `${SCRATCH_CATEGORIES.slice(0, -1).join(", ")}, or ${SCRATCH_CATEGORIES.at(-1)}`
|
|
67
|
+
: SCRATCH_CATEGORIES[0];
|
|
60
68
|
|
|
61
69
|
return `## harnery coordination
|
|
62
70
|
|
|
@@ -71,13 +79,19 @@ active peers and the files they've claimed; \`${b} agents set-task "<focus>"\`
|
|
|
71
79
|
declares your current focus so peers can see it. Check for peers before editing
|
|
72
80
|
widely-shared files.
|
|
73
81
|
|
|
82
|
+
**Durable role handoff.** When you are replacing a prior session in the same
|
|
83
|
+
named role, run \`${b} agents identity assume <name>\` before declaring your task.
|
|
84
|
+
It reclaims an abandoned namesake (no live process) and refuses only when another
|
|
85
|
+
live process still holds the name; never hand-edit Harnery's history, heartbeat,
|
|
86
|
+
or derived identity cache.
|
|
87
|
+
|
|
74
88
|
**Declare intent on shell commands.** Every command you run is captured to the
|
|
75
89
|
coordination ledger. Lead a shell command with a \`# intent: <why>\` comment (or set
|
|
76
90
|
the tool's description) so the recorded event carries a reason instead of
|
|
77
91
|
\`(no intent)\`.
|
|
78
92
|
|
|
79
|
-
**Scratch journal.** \`${b} scratch add <category> "<text>"\` (category =
|
|
80
|
-
|
|
93
|
+
**Scratch journal.** \`${b} scratch add <category> "<text>"\` (category = ${scratchCats})
|
|
94
|
+
leaves breadcrumbs that survive context compaction;
|
|
81
95
|
\`${b} scratch read\` reads yours, \`${b} scratch read --name <peer>\` reads a peer's.
|
|
82
96
|
Use it for anything future-you or a peer will need to pick up your thread.
|
|
83
97
|
|