@goondocks/myco 0.2.7 → 0.2.9
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/.claude-plugin/plugin.json +1 -1
- package/CONTRIBUTING.md +1 -1
- package/commands/init.md +10 -26
- package/dist/chunk-4JML636J.js +52 -0
- package/dist/chunk-4JML636J.js.map +1 -0
- package/dist/chunk-AOMX45LH.js +8974 -0
- package/dist/chunk-AOMX45LH.js.map +1 -0
- package/dist/chunk-I7PMGO6S.js +58 -0
- package/dist/chunk-I7PMGO6S.js.map +1 -0
- package/dist/chunk-N33KUCFP.js +33 -0
- package/dist/chunk-N33KUCFP.js.map +1 -0
- package/dist/chunk-NYNEJ5QY.js +71 -0
- package/dist/chunk-NYNEJ5QY.js.map +1 -0
- package/dist/chunk-PA3VMINE.js +111 -0
- package/dist/chunk-PA3VMINE.js.map +1 -0
- package/dist/chunk-PZUWP5VK.js +44 -0
- package/dist/chunk-PZUWP5VK.js.map +1 -0
- package/dist/chunk-SVUINMDD.js +104 -0
- package/dist/chunk-SVUINMDD.js.map +1 -0
- package/dist/chunk-TH6GIBXG.js +91 -0
- package/dist/chunk-TH6GIBXG.js.map +1 -0
- package/dist/chunk-TWDS6MSU.js +354 -0
- package/dist/chunk-TWDS6MSU.js.map +1 -0
- package/dist/chunk-UIIZRTJU.js +21172 -0
- package/dist/chunk-UIIZRTJU.js.map +1 -0
- package/dist/chunk-YMYJ7FNH.js +19 -0
- package/dist/chunk-YMYJ7FNH.js.map +1 -0
- package/dist/chunk-ZJQ5G637.js +21 -0
- package/dist/chunk-ZJQ5G637.js.map +1 -0
- package/dist/chunk-ZTZVX5E6.js +421 -0
- package/dist/chunk-ZTZVX5E6.js.map +1 -0
- package/dist/cli-K5FSKLQC.js +625 -0
- package/dist/cli-K5FSKLQC.js.map +1 -0
- package/dist/client-4JMOYNKK.js +11 -0
- package/dist/client-4JMOYNKK.js.map +1 -0
- package/dist/main-5W4ADOBG.js +3224 -0
- package/dist/main-5W4ADOBG.js.map +1 -0
- package/dist/server-PIEPVUUH.js +14725 -0
- package/dist/server-PIEPVUUH.js.map +1 -0
- package/dist/session-start-2NNQHT5S.js +189 -0
- package/dist/session-start-2NNQHT5S.js.map +1 -0
- package/dist/src/cli.js +9 -582
- package/dist/src/cli.js.map +1 -1
- package/dist/src/daemon/main.js +9 -737
- package/dist/src/daemon/main.js.map +1 -1
- package/dist/src/hooks/post-tool-use.js +47 -35
- package/dist/src/hooks/post-tool-use.js.map +1 -1
- package/dist/src/hooks/session-end.js +29 -18
- package/dist/src/hooks/session-end.js.map +1 -1
- package/dist/src/hooks/session-start.js +9 -48
- package/dist/src/hooks/session-start.js.map +1 -1
- package/dist/src/hooks/stop.js +39 -30
- package/dist/src/hooks/stop.js.map +1 -1
- package/dist/src/hooks/user-prompt-submit.js +48 -40
- package/dist/src/hooks/user-prompt-submit.js.map +1 -1
- package/dist/src/mcp/server.js +9 -304
- package/dist/src/mcp/server.js.map +1 -1
- package/package.json +3 -2
- package/dist/src/agents/adapter.d.ts +0 -76
- package/dist/src/agents/adapter.d.ts.map +0 -1
- package/dist/src/agents/adapter.js +0 -124
- package/dist/src/agents/adapter.js.map +0 -1
- package/dist/src/agents/claude-code.d.ts +0 -3
- package/dist/src/agents/claude-code.d.ts.map +0 -1
- package/dist/src/agents/claude-code.js +0 -22
- package/dist/src/agents/claude-code.js.map +0 -1
- package/dist/src/agents/cursor.d.ts +0 -3
- package/dist/src/agents/cursor.d.ts.map +0 -1
- package/dist/src/agents/cursor.js +0 -154
- package/dist/src/agents/cursor.js.map +0 -1
- package/dist/src/agents/index.d.ts +0 -6
- package/dist/src/agents/index.d.ts.map +0 -1
- package/dist/src/agents/index.js +0 -5
- package/dist/src/agents/index.js.map +0 -1
- package/dist/src/agents/registry.d.ts +0 -34
- package/dist/src/agents/registry.d.ts.map +0 -1
- package/dist/src/agents/registry.js +0 -95
- package/dist/src/agents/registry.js.map +0 -1
- package/dist/src/artifacts/candidates.d.ts +0 -20
- package/dist/src/artifacts/candidates.d.ts.map +0 -1
- package/dist/src/artifacts/candidates.js +0 -84
- package/dist/src/artifacts/candidates.js.map +0 -1
- package/dist/src/artifacts/slugify.d.ts +0 -2
- package/dist/src/artifacts/slugify.d.ts.map +0 -1
- package/dist/src/artifacts/slugify.js +0 -22
- package/dist/src/artifacts/slugify.js.map +0 -1
- package/dist/src/capture/buffer.d.ts +0 -20
- package/dist/src/capture/buffer.d.ts.map +0 -1
- package/dist/src/capture/buffer.js +0 -55
- package/dist/src/capture/buffer.js.map +0 -1
- package/dist/src/capture/transcript-miner.d.ts +0 -31
- package/dist/src/capture/transcript-miner.d.ts.map +0 -1
- package/dist/src/capture/transcript-miner.js +0 -61
- package/dist/src/capture/transcript-miner.js.map +0 -1
- package/dist/src/cli.d.ts +0 -3
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/config/loader.d.ts +0 -4
- package/dist/src/config/loader.d.ts.map +0 -1
- package/dist/src/config/loader.js +0 -32
- package/dist/src/config/loader.js.map +0 -1
- package/dist/src/config/schema.d.ts +0 -83
- package/dist/src/config/schema.d.ts.map +0 -1
- package/dist/src/config/schema.js +0 -55
- package/dist/src/config/schema.js.map +0 -1
- package/dist/src/constants.d.ts +0 -73
- package/dist/src/constants.d.ts.map +0 -1
- package/dist/src/constants.js +0 -86
- package/dist/src/constants.js.map +0 -1
- package/dist/src/context/injector.d.ts +0 -18
- package/dist/src/context/injector.d.ts.map +0 -1
- package/dist/src/context/injector.js +0 -71
- package/dist/src/context/injector.js.map +0 -1
- package/dist/src/context/relevance.d.ts +0 -13
- package/dist/src/context/relevance.d.ts.map +0 -1
- package/dist/src/context/relevance.js +0 -44
- package/dist/src/context/relevance.js.map +0 -1
- package/dist/src/daemon/batch.d.ts +0 -22
- package/dist/src/daemon/batch.d.ts.map +0 -1
- package/dist/src/daemon/batch.js +0 -38
- package/dist/src/daemon/batch.js.map +0 -1
- package/dist/src/daemon/lifecycle.d.ts +0 -27
- package/dist/src/daemon/lifecycle.d.ts.map +0 -1
- package/dist/src/daemon/lifecycle.js +0 -50
- package/dist/src/daemon/lifecycle.js.map +0 -1
- package/dist/src/daemon/lineage.d.ts +0 -42
- package/dist/src/daemon/lineage.d.ts.map +0 -1
- package/dist/src/daemon/lineage.js +0 -116
- package/dist/src/daemon/lineage.js.map +0 -1
- package/dist/src/daemon/logger.d.ts +0 -33
- package/dist/src/daemon/logger.d.ts.map +0 -1
- package/dist/src/daemon/logger.js +0 -88
- package/dist/src/daemon/logger.js.map +0 -1
- package/dist/src/daemon/main.d.ts +0 -2
- package/dist/src/daemon/main.d.ts.map +0 -1
- package/dist/src/daemon/processor.d.ts +0 -44
- package/dist/src/daemon/processor.d.ts.map +0 -1
- package/dist/src/daemon/processor.js +0 -142
- package/dist/src/daemon/processor.js.map +0 -1
- package/dist/src/daemon/server.d.ts +0 -24
- package/dist/src/daemon/server.d.ts.map +0 -1
- package/dist/src/daemon/server.js +0 -117
- package/dist/src/daemon/server.js.map +0 -1
- package/dist/src/daemon/watcher.d.ts +0 -29
- package/dist/src/daemon/watcher.d.ts.map +0 -1
- package/dist/src/daemon/watcher.js +0 -67
- package/dist/src/daemon/watcher.js.map +0 -1
- package/dist/src/hooks/client.d.ts +0 -20
- package/dist/src/hooks/client.d.ts.map +0 -1
- package/dist/src/hooks/client.js +0 -111
- package/dist/src/hooks/client.js.map +0 -1
- package/dist/src/hooks/post-tool-use.d.ts +0 -2
- package/dist/src/hooks/post-tool-use.d.ts.map +0 -1
- package/dist/src/hooks/read-stdin.d.ts +0 -2
- package/dist/src/hooks/read-stdin.d.ts.map +0 -1
- package/dist/src/hooks/read-stdin.js +0 -10
- package/dist/src/hooks/read-stdin.js.map +0 -1
- package/dist/src/hooks/session-end.d.ts +0 -2
- package/dist/src/hooks/session-end.d.ts.map +0 -1
- package/dist/src/hooks/session-start.d.ts +0 -2
- package/dist/src/hooks/session-start.d.ts.map +0 -1
- package/dist/src/hooks/stop.d.ts +0 -2
- package/dist/src/hooks/stop.d.ts.map +0 -1
- package/dist/src/hooks/user-prompt-submit.d.ts +0 -2
- package/dist/src/hooks/user-prompt-submit.d.ts.map +0 -1
- package/dist/src/index/fts.d.ts +0 -16
- package/dist/src/index/fts.d.ts.map +0 -1
- package/dist/src/index/fts.js +0 -53
- package/dist/src/index/fts.js.map +0 -1
- package/dist/src/index/rebuild.d.ts +0 -4
- package/dist/src/index/rebuild.d.ts.map +0 -1
- package/dist/src/index/rebuild.js +0 -40
- package/dist/src/index/rebuild.js.map +0 -1
- package/dist/src/index/sqlite.d.ts +0 -33
- package/dist/src/index/sqlite.d.ts.map +0 -1
- package/dist/src/index/sqlite.js +0 -99
- package/dist/src/index/sqlite.js.map +0 -1
- package/dist/src/index/vectors.d.ts +0 -24
- package/dist/src/index/vectors.d.ts.map +0 -1
- package/dist/src/index/vectors.js +0 -97
- package/dist/src/index/vectors.js.map +0 -1
- package/dist/src/intelligence/anthropic.d.ts +0 -17
- package/dist/src/intelligence/anthropic.d.ts.map +0 -1
- package/dist/src/intelligence/anthropic.js +0 -36
- package/dist/src/intelligence/anthropic.js.map +0 -1
- package/dist/src/intelligence/embeddings.d.ts +0 -3
- package/dist/src/intelligence/embeddings.d.ts.map +0 -1
- package/dist/src/intelligence/embeddings.js +0 -15
- package/dist/src/intelligence/embeddings.js.map +0 -1
- package/dist/src/intelligence/llm.d.ts +0 -33
- package/dist/src/intelligence/llm.d.ts.map +0 -1
- package/dist/src/intelligence/llm.js +0 -26
- package/dist/src/intelligence/llm.js.map +0 -1
- package/dist/src/intelligence/lm-studio.d.ts +0 -20
- package/dist/src/intelligence/lm-studio.d.ts.map +0 -1
- package/dist/src/intelligence/lm-studio.js +0 -59
- package/dist/src/intelligence/lm-studio.js.map +0 -1
- package/dist/src/intelligence/ollama.d.ts +0 -22
- package/dist/src/intelligence/ollama.d.ts.map +0 -1
- package/dist/src/intelligence/ollama.js +0 -64
- package/dist/src/intelligence/ollama.js.map +0 -1
- package/dist/src/intelligence/response.d.ts +0 -29
- package/dist/src/intelligence/response.d.ts.map +0 -1
- package/dist/src/intelligence/response.js +0 -71
- package/dist/src/intelligence/response.js.map +0 -1
- package/dist/src/logs/format.d.ts +0 -6
- package/dist/src/logs/format.d.ts.map +0 -1
- package/dist/src/logs/format.js +0 -46
- package/dist/src/logs/format.js.map +0 -1
- package/dist/src/logs/reader.d.ts +0 -28
- package/dist/src/logs/reader.d.ts.map +0 -1
- package/dist/src/logs/reader.js +0 -106
- package/dist/src/logs/reader.js.map +0 -1
- package/dist/src/mcp/server.d.ts +0 -16
- package/dist/src/mcp/server.d.ts.map +0 -1
- package/dist/src/mcp/tools/consolidate.d.ts +0 -15
- package/dist/src/mcp/tools/consolidate.d.ts.map +0 -1
- package/dist/src/mcp/tools/consolidate.js +0 -49
- package/dist/src/mcp/tools/consolidate.js.map +0 -1
- package/dist/src/mcp/tools/graph.d.ts +0 -30
- package/dist/src/mcp/tools/graph.d.ts.map +0 -1
- package/dist/src/mcp/tools/graph.js +0 -106
- package/dist/src/mcp/tools/graph.js.map +0 -1
- package/dist/src/mcp/tools/logs.d.ts +0 -3
- package/dist/src/mcp/tools/logs.d.ts.map +0 -1
- package/dist/src/mcp/tools/logs.js +0 -7
- package/dist/src/mcp/tools/logs.js.map +0 -1
- package/dist/src/mcp/tools/plans.d.ts +0 -23
- package/dist/src/mcp/tools/plans.d.ts.map +0 -1
- package/dist/src/mcp/tools/plans.js +0 -63
- package/dist/src/mcp/tools/plans.js.map +0 -1
- package/dist/src/mcp/tools/recall.d.ts +0 -30
- package/dist/src/mcp/tools/recall.d.ts.map +0 -1
- package/dist/src/mcp/tools/recall.js +0 -34
- package/dist/src/mcp/tools/recall.js.map +0 -1
- package/dist/src/mcp/tools/remember.d.ts +0 -15
- package/dist/src/mcp/tools/remember.d.ts.map +0 -1
- package/dist/src/mcp/tools/remember.js +0 -18
- package/dist/src/mcp/tools/remember.js.map +0 -1
- package/dist/src/mcp/tools/search.d.ts +0 -19
- package/dist/src/mcp/tools/search.d.ts.map +0 -1
- package/dist/src/mcp/tools/search.js +0 -59
- package/dist/src/mcp/tools/search.js.map +0 -1
- package/dist/src/mcp/tools/sessions.d.ts +0 -21
- package/dist/src/mcp/tools/sessions.d.ts.map +0 -1
- package/dist/src/mcp/tools/sessions.js +0 -36
- package/dist/src/mcp/tools/sessions.js.map +0 -1
- package/dist/src/mcp/tools/supersede.d.ts +0 -14
- package/dist/src/mcp/tools/supersede.d.ts.map +0 -1
- package/dist/src/mcp/tools/supersede.js +0 -30
- package/dist/src/mcp/tools/supersede.js.map +0 -1
- package/dist/src/mcp/tools/team.d.ts +0 -16
- package/dist/src/mcp/tools/team.d.ts.map +0 -1
- package/dist/src/mcp/tools/team.js +0 -32
- package/dist/src/mcp/tools/team.js.map +0 -1
- package/dist/src/obsidian/formatter.d.ts +0 -80
- package/dist/src/obsidian/formatter.d.ts.map +0 -1
- package/dist/src/obsidian/formatter.js +0 -227
- package/dist/src/obsidian/formatter.js.map +0 -1
- package/dist/src/prompts/index.d.ts +0 -13
- package/dist/src/prompts/index.d.ts.map +0 -1
- package/dist/src/prompts/index.js +0 -75
- package/dist/src/prompts/index.js.map +0 -1
- package/dist/src/vault/frontmatter.d.ts +0 -6
- package/dist/src/vault/frontmatter.d.ts.map +0 -1
- package/dist/src/vault/frontmatter.js +0 -10
- package/dist/src/vault/frontmatter.js.map +0 -1
- package/dist/src/vault/observations.d.ts +0 -10
- package/dist/src/vault/observations.d.ts.map +0 -1
- package/dist/src/vault/observations.js +0 -33
- package/dist/src/vault/observations.js.map +0 -1
- package/dist/src/vault/reader.d.ts +0 -10
- package/dist/src/vault/reader.d.ts.map +0 -1
- package/dist/src/vault/reader.js +0 -48
- package/dist/src/vault/reader.js.map +0 -1
- package/dist/src/vault/resolve.d.ts +0 -18
- package/dist/src/vault/resolve.d.ts.map +0 -1
- package/dist/src/vault/resolve.js +0 -51
- package/dist/src/vault/resolve.js.map +0 -1
- package/dist/src/vault/session-id.d.ts +0 -16
- package/dist/src/vault/session-id.d.ts.map +0 -1
- package/dist/src/vault/session-id.js +0 -29
- package/dist/src/vault/session-id.js.map +0 -1
- package/dist/src/vault/types.d.ts +0 -88
- package/dist/src/vault/types.d.ts.map +0 -1
- package/dist/src/vault/types.js +0 -94
- package/dist/src/vault/types.js.map +0 -1
- package/dist/src/vault/writer.d.ts +0 -66
- package/dist/src/vault/writer.d.ts.map +0 -1
- package/dist/src/vault/writer.js +0 -217
- package/dist/src/vault/writer.js.map +0 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/vault/frontmatter.ts
|
|
4
|
+
function planFm(note) {
|
|
5
|
+
return note.frontmatter;
|
|
6
|
+
}
|
|
7
|
+
function sessionFm(note) {
|
|
8
|
+
return note.frontmatter;
|
|
9
|
+
}
|
|
10
|
+
function memoryFm(note) {
|
|
11
|
+
return note.frontmatter;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
planFm,
|
|
16
|
+
sessionFm,
|
|
17
|
+
memoryFm
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=chunk-YMYJ7FNH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/vault/frontmatter.ts"],"sourcesContent":["import type { IndexedNote } from '../index/sqlite.js';\nimport type { PlanFrontmatter, SessionFrontmatter, MemoryFrontmatter } from './types.js';\n\nexport function planFm(note: IndexedNote): PlanFrontmatter {\n return note.frontmatter as unknown as PlanFrontmatter;\n}\n\nexport function sessionFm(note: IndexedNote): SessionFrontmatter {\n return note.frontmatter as unknown as SessionFrontmatter;\n}\n\nexport function memoryFm(note: IndexedNote): MemoryFrontmatter {\n return note.frontmatter as unknown as MemoryFrontmatter;\n}\n"],"mappings":";;;AAGO,SAAS,OAAO,MAAoC;AACzD,SAAO,KAAK;AACd;AAEO,SAAS,UAAU,MAAuC;AAC/D,SAAO,KAAK;AACd;AAEO,SAAS,SAAS,MAAsC;AAC7D,SAAO,KAAK;AACd;","names":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
STDIN_TIMEOUT_MS
|
|
4
|
+
} from "./chunk-NYNEJ5QY.js";
|
|
5
|
+
|
|
6
|
+
// src/hooks/read-stdin.ts
|
|
7
|
+
function readStdin() {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
let data = "";
|
|
10
|
+
process.stdin.on("data", (chunk) => {
|
|
11
|
+
data += chunk;
|
|
12
|
+
});
|
|
13
|
+
process.stdin.on("end", () => resolve(data));
|
|
14
|
+
setTimeout(() => resolve(data || "{}"), STDIN_TIMEOUT_MS);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
readStdin
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=chunk-ZJQ5G637.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/read-stdin.ts"],"sourcesContent":["import { STDIN_TIMEOUT_MS } from '../constants.js';\n\nexport function readStdin(): Promise<string> {\n return new Promise((resolve) => {\n let data = '';\n process.stdin.on('data', (chunk: Buffer) => { data += chunk; });\n process.stdin.on('end', () => resolve(data));\n setTimeout(() => resolve(data || '{}'), STDIN_TIMEOUT_MS);\n });\n}\n"],"mappings":";;;;;;AAEO,SAAS,YAA6B;AAC3C,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI,OAAO;AACX,YAAQ,MAAM,GAAG,QAAQ,CAAC,UAAkB;AAAE,cAAQ;AAAA,IAAO,CAAC;AAC9D,YAAQ,MAAM,GAAG,OAAO,MAAM,QAAQ,IAAI,CAAC;AAC3C,eAAW,MAAM,QAAQ,QAAQ,IAAI,GAAG,gBAAgB;AAAA,EAC1D,CAAC;AACH;","names":[]}
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
require_dist
|
|
4
|
+
} from "./chunk-UIIZRTJU.js";
|
|
5
|
+
import {
|
|
6
|
+
__toESM
|
|
7
|
+
} from "./chunk-PZUWP5VK.js";
|
|
8
|
+
|
|
9
|
+
// src/vault/session-id.ts
|
|
10
|
+
var SESSION_PREFIX = "session-";
|
|
11
|
+
function sessionNoteId(bareId) {
|
|
12
|
+
if (bareId.startsWith(SESSION_PREFIX)) return bareId;
|
|
13
|
+
return `${SESSION_PREFIX}${bareId}`;
|
|
14
|
+
}
|
|
15
|
+
function bareSessionId(noteId) {
|
|
16
|
+
if (noteId.startsWith(SESSION_PREFIX)) return noteId.slice(SESSION_PREFIX.length);
|
|
17
|
+
return noteId;
|
|
18
|
+
}
|
|
19
|
+
function sessionWikilink(bareId) {
|
|
20
|
+
return `[[${sessionNoteId(bareId)}]]`;
|
|
21
|
+
}
|
|
22
|
+
function sessionRelativePath(bareId, date) {
|
|
23
|
+
return `sessions/${date}/${sessionNoteId(bareId)}.md`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/obsidian/formatter.ts
|
|
27
|
+
var CALLOUT_MAP = {
|
|
28
|
+
gotcha: "warning",
|
|
29
|
+
bug_fix: "bug",
|
|
30
|
+
decision: "info",
|
|
31
|
+
discovery: "tip",
|
|
32
|
+
trade_off: "question"
|
|
33
|
+
};
|
|
34
|
+
function observationCalloutType(observationType) {
|
|
35
|
+
return CALLOUT_MAP[observationType] ?? "note";
|
|
36
|
+
}
|
|
37
|
+
function callout(type, title, content) {
|
|
38
|
+
const indented = content.split("\n").map((line) => `> ${line}`).join("\n");
|
|
39
|
+
return `> [!${type}] ${title}
|
|
40
|
+
${indented}`;
|
|
41
|
+
}
|
|
42
|
+
function inlineField(key, value) {
|
|
43
|
+
return `${key}:: ${value}`;
|
|
44
|
+
}
|
|
45
|
+
function wikilink(target, display) {
|
|
46
|
+
return display ? `[[${target}|${display}]]` : `[[${target}]]`;
|
|
47
|
+
}
|
|
48
|
+
function tagNormalize(s) {
|
|
49
|
+
return s.replace(/_/g, "-");
|
|
50
|
+
}
|
|
51
|
+
function sanitizeTag(raw) {
|
|
52
|
+
const stripped = raw.startsWith("#") ? raw.slice(1) : raw;
|
|
53
|
+
return stripped.replace(/\s+/g, "/");
|
|
54
|
+
}
|
|
55
|
+
function buildTags(type, subtype, extraTags = []) {
|
|
56
|
+
const tags = [`type/${type}`];
|
|
57
|
+
if (subtype) {
|
|
58
|
+
tags.push(`${type}/${tagNormalize(subtype)}`);
|
|
59
|
+
}
|
|
60
|
+
for (const tag of extraTags) {
|
|
61
|
+
const normalized = sanitizeTag(tag);
|
|
62
|
+
if (normalized && !tags.includes(normalized)) {
|
|
63
|
+
tags.push(normalized);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return tags;
|
|
67
|
+
}
|
|
68
|
+
function footerTags(tags) {
|
|
69
|
+
return tags.map((t) => t.startsWith("#") ? t : `#${t}`).join(" ");
|
|
70
|
+
}
|
|
71
|
+
function formatSessionBody(input) {
|
|
72
|
+
const sections = [];
|
|
73
|
+
sections.push(`# ${input.title}`);
|
|
74
|
+
if (input.narrative) {
|
|
75
|
+
sections.push(callout("abstract", "Summary", input.narrative));
|
|
76
|
+
}
|
|
77
|
+
const fields = [];
|
|
78
|
+
fields.push(inlineField("Session", wikilink(sessionNoteId(input.sessionId))));
|
|
79
|
+
if (input.user) fields.push(inlineField("User", input.user));
|
|
80
|
+
if (input.started && input.ended) {
|
|
81
|
+
const duration = formatDuration(input.started, input.ended);
|
|
82
|
+
if (duration) fields.push(inlineField("Duration", duration));
|
|
83
|
+
}
|
|
84
|
+
if (input.branch) fields.push(inlineField("Branch", `\`${input.branch}\``));
|
|
85
|
+
sections.push(fields.join("\n"));
|
|
86
|
+
if (input.relatedMemories?.length) {
|
|
87
|
+
const links = input.relatedMemories.map((m) => `- ${wikilink(m.id, m.title)}`);
|
|
88
|
+
sections.push(`## Related Memories
|
|
89
|
+
${links.join("\n")}`);
|
|
90
|
+
}
|
|
91
|
+
if (input.turns.length > 0) {
|
|
92
|
+
const turnLines = [];
|
|
93
|
+
for (let i = 0; i < input.turns.length; i++) {
|
|
94
|
+
const turn = input.turns[i];
|
|
95
|
+
const turnNum = i + 1;
|
|
96
|
+
turnLines.push(`### Turn ${turnNum}`);
|
|
97
|
+
if (turn.prompt || turn.images?.length) {
|
|
98
|
+
const parts = [];
|
|
99
|
+
if (turn.prompt) parts.push(turn.prompt);
|
|
100
|
+
if (turn.images?.length) {
|
|
101
|
+
parts.push(turn.images.map((f) => `![[${f}]]`).join("\n"));
|
|
102
|
+
}
|
|
103
|
+
if (turn.toolCount > 0) parts.push(`*${turn.toolCount} tool calls*`);
|
|
104
|
+
turnLines.push(callout("user", "Prompt", parts.join("\n\n")));
|
|
105
|
+
} else if (turn.toolCount > 0) {
|
|
106
|
+
turnLines.push(callout("user", "Prompt", `*${turn.toolCount} tool calls*`));
|
|
107
|
+
}
|
|
108
|
+
if (turn.aiResponse) {
|
|
109
|
+
turnLines.push(callout("assistant", "Response", turn.aiResponse));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
sections.push(`## Conversation
|
|
113
|
+
|
|
114
|
+
${turnLines.join("\n\n")}`);
|
|
115
|
+
}
|
|
116
|
+
const allTags = buildTags("session", "ended", [
|
|
117
|
+
...input.user ? [`user/${input.user}`] : [],
|
|
118
|
+
...input.tags ?? []
|
|
119
|
+
]);
|
|
120
|
+
sections.push(footerTags(allTags));
|
|
121
|
+
return sections.join("\n\n");
|
|
122
|
+
}
|
|
123
|
+
function formatMemoryBody(input) {
|
|
124
|
+
const sections = [];
|
|
125
|
+
const calloutType = observationCalloutType(input.observationType);
|
|
126
|
+
const calloutTitle = capitalize(tagNormalize(input.observationType));
|
|
127
|
+
sections.push(`# ${input.title}`);
|
|
128
|
+
sections.push(callout(calloutType, calloutTitle, input.content));
|
|
129
|
+
const fields = [];
|
|
130
|
+
if (input.sessionId) {
|
|
131
|
+
fields.push(inlineField("Session", wikilink(sessionNoteId(input.sessionId))));
|
|
132
|
+
}
|
|
133
|
+
fields.push(inlineField("Observation", input.observationType));
|
|
134
|
+
if (fields.length > 0) sections.push(fields.join("\n"));
|
|
135
|
+
if (input.root_cause) sections.push(`## Root Cause
|
|
136
|
+
${input.root_cause}`);
|
|
137
|
+
if (input.fix) sections.push(`## Fix
|
|
138
|
+
${input.fix}`);
|
|
139
|
+
if (input.rationale) sections.push(`## Rationale
|
|
140
|
+
${input.rationale}`);
|
|
141
|
+
if (input.alternatives_rejected) sections.push(`## Alternatives Rejected
|
|
142
|
+
${input.alternatives_rejected}`);
|
|
143
|
+
if (input.gained) sections.push(`## Gained
|
|
144
|
+
${input.gained}`);
|
|
145
|
+
if (input.sacrificed) sections.push(`## Sacrificed
|
|
146
|
+
${input.sacrificed}`);
|
|
147
|
+
const allTags = buildTags("memory", input.observationType, input.tags ?? []);
|
|
148
|
+
sections.push(footerTags(allTags));
|
|
149
|
+
return sections.join("\n\n");
|
|
150
|
+
}
|
|
151
|
+
function formatPlanBody(input) {
|
|
152
|
+
const sections = [];
|
|
153
|
+
const fields = [];
|
|
154
|
+
fields.push(inlineField("Plan", wikilink(input.id)));
|
|
155
|
+
fields.push(inlineField("Status", input.status));
|
|
156
|
+
if (input.author) fields.push(inlineField("Author", input.author));
|
|
157
|
+
if (input.created) fields.push(inlineField("Created", input.created));
|
|
158
|
+
sections.push(fields.join("\n"));
|
|
159
|
+
sections.push(input.content);
|
|
160
|
+
if (input.sessions?.length) {
|
|
161
|
+
const links = input.sessions.map((s) => `- ${wikilink(sessionNoteId(s.id), s.title)}`);
|
|
162
|
+
sections.push(`## Sessions
|
|
163
|
+
${links.join("\n")}`);
|
|
164
|
+
}
|
|
165
|
+
const statusTag = tagNormalize(input.status);
|
|
166
|
+
const allTags = buildTags("plan", statusTag, input.tags ?? []);
|
|
167
|
+
sections.push(footerTags(allTags));
|
|
168
|
+
return sections.join("\n\n");
|
|
169
|
+
}
|
|
170
|
+
function formatArtifactBody(input) {
|
|
171
|
+
const sections = [];
|
|
172
|
+
const fields = [];
|
|
173
|
+
fields.push(inlineField("Artifact", wikilink(input.id)));
|
|
174
|
+
fields.push(inlineField("Source", `\`${input.source_path}\``));
|
|
175
|
+
fields.push(inlineField("Type", input.artifact_type));
|
|
176
|
+
fields.push(inlineField("Session", wikilink(sessionNoteId(input.sessionId))));
|
|
177
|
+
sections.push(fields.join("\n"));
|
|
178
|
+
sections.push(input.content);
|
|
179
|
+
const allTags = buildTags("artifact", input.artifact_type, input.tags ?? []);
|
|
180
|
+
sections.push(footerTags(allTags));
|
|
181
|
+
return sections.join("\n\n");
|
|
182
|
+
}
|
|
183
|
+
function formatTeamBody(input) {
|
|
184
|
+
const sections = [];
|
|
185
|
+
sections.push(`# ${input.user}`);
|
|
186
|
+
sections.push(callout("info", "Team Member", input.role ?? "Contributor"));
|
|
187
|
+
const fields = [];
|
|
188
|
+
fields.push(inlineField("User", input.user));
|
|
189
|
+
if (input.role) fields.push(inlineField("Role", input.role));
|
|
190
|
+
sections.push(fields.join("\n"));
|
|
191
|
+
if (input.recentSessions?.length) {
|
|
192
|
+
const links = input.recentSessions.map((s) => `- ${wikilink(sessionNoteId(s.id), s.title)}`);
|
|
193
|
+
sections.push(`## Recent Sessions
|
|
194
|
+
${links.join("\n")}`);
|
|
195
|
+
}
|
|
196
|
+
const allTags = buildTags("team", "", [`user/${input.user}`]);
|
|
197
|
+
sections.push(footerTags(allTags));
|
|
198
|
+
return sections.join("\n\n");
|
|
199
|
+
}
|
|
200
|
+
function capitalize(s) {
|
|
201
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
202
|
+
}
|
|
203
|
+
function formatDuration(started, ended) {
|
|
204
|
+
const ms = new Date(ended).getTime() - new Date(started).getTime();
|
|
205
|
+
if (isNaN(ms) || ms < 0) return "";
|
|
206
|
+
const totalMinutes = Math.floor(ms / 6e4);
|
|
207
|
+
if (totalMinutes < 1) return "<1m";
|
|
208
|
+
const hours = Math.floor(totalMinutes / 60);
|
|
209
|
+
const minutes = totalMinutes % 60;
|
|
210
|
+
if (hours === 0) return `${minutes}m`;
|
|
211
|
+
if (minutes === 0) return `${hours}h`;
|
|
212
|
+
return `${hours}h ${minutes}m`;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// src/vault/writer.ts
|
|
216
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
217
|
+
import fs from "fs";
|
|
218
|
+
import path from "path";
|
|
219
|
+
var VaultWriter = class {
|
|
220
|
+
constructor(vaultDir) {
|
|
221
|
+
this.vaultDir = vaultDir;
|
|
222
|
+
}
|
|
223
|
+
writeSession(input) {
|
|
224
|
+
const date = input.started.slice(0, 10);
|
|
225
|
+
const relativePath = sessionRelativePath(input.id, date);
|
|
226
|
+
const frontmatter = {
|
|
227
|
+
type: "session",
|
|
228
|
+
id: input.id,
|
|
229
|
+
agent: input.agent ?? "claude-code",
|
|
230
|
+
user: input.user ?? "",
|
|
231
|
+
started: input.started
|
|
232
|
+
};
|
|
233
|
+
if (input.ended) frontmatter.ended = input.ended;
|
|
234
|
+
if (input.parent) frontmatter.parent = input.parent;
|
|
235
|
+
if (input.parent_reason) frontmatter.parent_reason = input.parent_reason;
|
|
236
|
+
if (input.plans?.length) frontmatter.plans = input.plans;
|
|
237
|
+
if (input.branch) frontmatter.branch = input.branch;
|
|
238
|
+
frontmatter.tags = buildTags("session", "ended", [
|
|
239
|
+
...input.user ? [`user/${input.user}`] : [],
|
|
240
|
+
...input.tags ?? []
|
|
241
|
+
]);
|
|
242
|
+
if (input.tools_used != null) frontmatter.tools_used = input.tools_used;
|
|
243
|
+
if (input.files_changed != null) frontmatter.files_changed = input.files_changed;
|
|
244
|
+
this.writeMarkdown(relativePath, frontmatter, input.summary);
|
|
245
|
+
return relativePath;
|
|
246
|
+
}
|
|
247
|
+
writePlan(input) {
|
|
248
|
+
const relativePath = `plans/${input.id}.md`;
|
|
249
|
+
const fullPath = path.join(this.vaultDir, relativePath);
|
|
250
|
+
const status = input.status ?? "active";
|
|
251
|
+
let created = (/* @__PURE__ */ new Date()).toISOString();
|
|
252
|
+
try {
|
|
253
|
+
const existing = fs.readFileSync(fullPath, "utf-8");
|
|
254
|
+
const fmMatch = existing.match(/^---\n([\s\S]*?)\n---/);
|
|
255
|
+
if (fmMatch) {
|
|
256
|
+
const parsed = import_yaml.default.parse(fmMatch[1]);
|
|
257
|
+
if (typeof parsed.created === "string") created = parsed.created;
|
|
258
|
+
}
|
|
259
|
+
} catch {
|
|
260
|
+
}
|
|
261
|
+
const frontmatter = {
|
|
262
|
+
type: "plan",
|
|
263
|
+
id: input.id,
|
|
264
|
+
status,
|
|
265
|
+
created
|
|
266
|
+
};
|
|
267
|
+
if (input.author) frontmatter.author = input.author;
|
|
268
|
+
frontmatter.tags = buildTags("plan", status, input.tags ?? []);
|
|
269
|
+
const body = formatPlanBody({
|
|
270
|
+
id: input.id,
|
|
271
|
+
status,
|
|
272
|
+
author: input.author,
|
|
273
|
+
created,
|
|
274
|
+
content: input.content,
|
|
275
|
+
tags: input.tags
|
|
276
|
+
});
|
|
277
|
+
this.writeMarkdown(relativePath, frontmatter, body);
|
|
278
|
+
return relativePath;
|
|
279
|
+
}
|
|
280
|
+
writeMemory(input) {
|
|
281
|
+
const normalizedType = input.observation_type.replace(/_/g, "-");
|
|
282
|
+
const relativePath = `memories/${normalizedType}/${input.id}.md`;
|
|
283
|
+
const fullPath = path.join(this.vaultDir, relativePath);
|
|
284
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
285
|
+
let created = now;
|
|
286
|
+
try {
|
|
287
|
+
const existing = fs.readFileSync(fullPath, "utf-8");
|
|
288
|
+
const fmMatch = existing.match(/^---\n([\s\S]*?)\n---/);
|
|
289
|
+
if (fmMatch) {
|
|
290
|
+
const parsed = import_yaml.default.parse(fmMatch[1]);
|
|
291
|
+
if (typeof parsed.created === "string") created = parsed.created;
|
|
292
|
+
}
|
|
293
|
+
} catch {
|
|
294
|
+
}
|
|
295
|
+
const frontmatter = {
|
|
296
|
+
type: "memory",
|
|
297
|
+
id: input.id,
|
|
298
|
+
observation_type: input.observation_type,
|
|
299
|
+
created
|
|
300
|
+
};
|
|
301
|
+
if (input.session) frontmatter.session = input.session;
|
|
302
|
+
if (input.plan) frontmatter.plan = input.plan;
|
|
303
|
+
frontmatter.tags = buildTags("memory", input.observation_type, input.tags ?? []);
|
|
304
|
+
this.writeMarkdown(relativePath, frontmatter, input.content);
|
|
305
|
+
return relativePath;
|
|
306
|
+
}
|
|
307
|
+
writeArtifact(input) {
|
|
308
|
+
const relativePath = `artifacts/${input.id}.md`;
|
|
309
|
+
const fullPath = path.join(this.vaultDir, relativePath);
|
|
310
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
311
|
+
let created = now;
|
|
312
|
+
try {
|
|
313
|
+
const existing = fs.readFileSync(fullPath, "utf-8");
|
|
314
|
+
const fmMatch = existing.match(/^---\n([\s\S]*?)\n---/);
|
|
315
|
+
if (fmMatch) {
|
|
316
|
+
const parsed = import_yaml.default.parse(fmMatch[1]);
|
|
317
|
+
if (typeof parsed.created === "string") created = parsed.created;
|
|
318
|
+
}
|
|
319
|
+
} catch {
|
|
320
|
+
}
|
|
321
|
+
const frontmatter = {
|
|
322
|
+
type: "artifact",
|
|
323
|
+
id: input.id,
|
|
324
|
+
artifact_type: input.artifact_type,
|
|
325
|
+
source_path: input.source_path,
|
|
326
|
+
title: input.title,
|
|
327
|
+
last_captured_by: sessionNoteId(input.session),
|
|
328
|
+
created,
|
|
329
|
+
updated: now,
|
|
330
|
+
tags: buildTags("artifact", input.artifact_type, input.tags ?? [])
|
|
331
|
+
};
|
|
332
|
+
const body = formatArtifactBody({
|
|
333
|
+
id: input.id,
|
|
334
|
+
title: input.title,
|
|
335
|
+
artifact_type: input.artifact_type,
|
|
336
|
+
source_path: input.source_path,
|
|
337
|
+
sessionId: input.session,
|
|
338
|
+
content: input.content,
|
|
339
|
+
tags: input.tags
|
|
340
|
+
});
|
|
341
|
+
this.writeMarkdown(relativePath, frontmatter, body);
|
|
342
|
+
return relativePath;
|
|
343
|
+
}
|
|
344
|
+
writeTeamMember(input) {
|
|
345
|
+
const relativePath = `team/${input.user}.md`;
|
|
346
|
+
const frontmatter = {
|
|
347
|
+
type: "team-member",
|
|
348
|
+
user: input.user,
|
|
349
|
+
joined: (/* @__PURE__ */ new Date()).toISOString(),
|
|
350
|
+
tags: buildTags("team", "", [`user/${input.user}`])
|
|
351
|
+
};
|
|
352
|
+
if (input.role) frontmatter.role = input.role;
|
|
353
|
+
const body = formatTeamBody({
|
|
354
|
+
user: input.user,
|
|
355
|
+
role: input.role
|
|
356
|
+
});
|
|
357
|
+
this.writeMarkdown(relativePath, frontmatter, body);
|
|
358
|
+
return relativePath;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Update frontmatter fields on an existing note without touching the body.
|
|
362
|
+
* By default only adds fields that don't exist. Set overwrite=true to replace existing values.
|
|
363
|
+
* Returns true if the update was applied, false if the file doesn't exist.
|
|
364
|
+
*/
|
|
365
|
+
updateNoteFrontmatter(relativePath, fields, overwrite = false) {
|
|
366
|
+
const fullPath = path.join(this.vaultDir, relativePath);
|
|
367
|
+
let fileContent;
|
|
368
|
+
try {
|
|
369
|
+
fileContent = fs.readFileSync(fullPath, "utf-8");
|
|
370
|
+
} catch {
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
const fmMatch = fileContent.match(/^---\n([\s\S]*?)\n---/);
|
|
374
|
+
if (!fmMatch) return false;
|
|
375
|
+
const parsed = import_yaml.default.parse(fmMatch[1]);
|
|
376
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
377
|
+
if (overwrite || parsed[key] === void 0) {
|
|
378
|
+
parsed[key] = value;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
const body = fileContent.slice(fmMatch[0].length);
|
|
382
|
+
const fmYaml = import_yaml.default.stringify(parsed, { defaultStringType: "QUOTE_DOUBLE", defaultKeyType: "PLAIN" }).trim();
|
|
383
|
+
this.atomicWrite(fullPath, `---
|
|
384
|
+
${fmYaml}
|
|
385
|
+
---${body}`);
|
|
386
|
+
return true;
|
|
387
|
+
}
|
|
388
|
+
/** @deprecated Use updateNoteFrontmatter instead */
|
|
389
|
+
updateSessionFrontmatter(relativePath, fields) {
|
|
390
|
+
return this.updateNoteFrontmatter(relativePath, fields);
|
|
391
|
+
}
|
|
392
|
+
writeMarkdown(relativePath, frontmatter, content) {
|
|
393
|
+
const fullPath = path.join(this.vaultDir, relativePath);
|
|
394
|
+
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
395
|
+
const fmYaml = import_yaml.default.stringify(frontmatter, { defaultStringType: "QUOTE_DOUBLE", defaultKeyType: "PLAIN" }).trim();
|
|
396
|
+
const file = `---
|
|
397
|
+
${fmYaml}
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
${content}
|
|
401
|
+
`;
|
|
402
|
+
this.atomicWrite(fullPath, file);
|
|
403
|
+
}
|
|
404
|
+
/** Write to a temp file then rename — prevents Obsidian from seeing a truncated file mid-write. */
|
|
405
|
+
atomicWrite(fullPath, content) {
|
|
406
|
+
const tmp = `${fullPath}.tmp`;
|
|
407
|
+
fs.writeFileSync(tmp, content, "utf-8");
|
|
408
|
+
fs.renameSync(tmp, fullPath);
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
export {
|
|
413
|
+
sessionNoteId,
|
|
414
|
+
bareSessionId,
|
|
415
|
+
sessionWikilink,
|
|
416
|
+
sessionRelativePath,
|
|
417
|
+
formatSessionBody,
|
|
418
|
+
formatMemoryBody,
|
|
419
|
+
VaultWriter
|
|
420
|
+
};
|
|
421
|
+
//# sourceMappingURL=chunk-ZTZVX5E6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/vault/session-id.ts","../src/obsidian/formatter.ts","../src/vault/writer.ts"],"sourcesContent":["/**\n * Session ID convention utilities.\n *\n * The runtime session ID is a bare UUID (e.g., \"abc123\").\n * The vault stores it with a \"session-\" prefix (e.g., \"session-abc123\").\n * These helpers convert between the two forms.\n */\n\nconst SESSION_PREFIX = 'session-';\n\n/** Convert a bare session ID to a vault note ID: \"abc123\" → \"session-abc123\" */\nexport function sessionNoteId(bareId: string): string {\n if (bareId.startsWith(SESSION_PREFIX)) return bareId;\n return `${SESSION_PREFIX}${bareId}`;\n}\n\n/** Convert a vault note ID to a bare session ID: \"session-abc123\" → \"abc123\" */\nexport function bareSessionId(noteId: string): string {\n if (noteId.startsWith(SESSION_PREFIX)) return noteId.slice(SESSION_PREFIX.length);\n return noteId;\n}\n\n/** Convert a bare session ID to an Obsidian wikilink: \"abc123\" → \"[[session-abc123]]\" */\nexport function sessionWikilink(bareId: string): string {\n return `[[${sessionNoteId(bareId)}]]`;\n}\n\n/** Build the relative vault path for a session note */\nexport function sessionRelativePath(bareId: string, date: string): string {\n return `sessions/${date}/${sessionNoteId(bareId)}.md`;\n}\n","/**\n * Pure formatting functions for Obsidian-native vault notes.\n * No I/O, no external dependencies — just string transforms.\n */\nimport type { ArtifactType } from '../vault/types.js';\nimport { sessionNoteId } from '../vault/session-id.js';\n\n// Callout type mapping for observation types\nconst CALLOUT_MAP: Record<string, string> = {\n gotcha: 'warning',\n bug_fix: 'bug',\n decision: 'info',\n discovery: 'tip',\n trade_off: 'question',\n};\n\nexport function observationCalloutType(observationType: string): string {\n return CALLOUT_MAP[observationType] ?? 'note';\n}\n\nexport function callout(type: string, title: string, content: string): string {\n const indented = content.split('\\n').map((line) => `> ${line}`).join('\\n');\n return `> [!${type}] ${title}\\n${indented}`;\n}\n\nexport function inlineField(key: string, value: string): string {\n return `${key}:: ${value}`;\n}\n\nexport function wikilink(target: string, display?: string): string {\n return display ? `[[${target}|${display}]]` : `[[${target}]]`;\n}\n\n/**\n * Normalize an observation_type to a tag-safe form.\n * Frontmatter keeps underscores; tags use hyphens per Obsidian convention.\n */\nfunction tagNormalize(s: string): string {\n return s.replace(/_/g, '-');\n}\n\n/**\n * Sanitize a user/LLM-provided tag for Obsidian compatibility.\n * Obsidian tags cannot contain spaces — replace with slash (nested tag).\n * Strips leading # if present.\n */\nfunction sanitizeTag(raw: string): string {\n const stripped = raw.startsWith('#') ? raw.slice(1) : raw;\n return stripped.replace(/\\s+/g, '/');\n}\n\nexport function buildTags(type: string, subtype: string, extraTags: string[] = []): string[] {\n const tags: string[] = [`type/${type}`];\n\n if (subtype) {\n tags.push(`${type}/${tagNormalize(subtype)}`);\n }\n\n for (const tag of extraTags) {\n const normalized = sanitizeTag(tag);\n if (normalized && !tags.includes(normalized)) {\n tags.push(normalized);\n }\n }\n\n return tags;\n}\n\nexport function footerTags(tags: string[]): string {\n return tags.map((t) => (t.startsWith('#') ? t : `#${t}`)).join(' ');\n}\n\n// --- Session formatting ---\n\nexport interface SessionBodyInput {\n title: string;\n narrative: string;\n sessionId: string;\n user?: string;\n started?: string;\n ended?: string;\n branch?: string;\n relatedMemories?: Array<{ id: string; title: string }>;\n turns: Array<{\n prompt: string;\n toolCount: number;\n aiResponse?: string;\n /** Filenames of images in the vault attachments folder */\n images?: string[];\n }>;\n tags?: string[];\n}\n\nexport function formatSessionBody(input: SessionBodyInput): string {\n const sections: string[] = [];\n\n sections.push(`# ${input.title}`);\n\n if (input.narrative) {\n sections.push(callout('abstract', 'Summary', input.narrative));\n }\n\n // Inline fields\n const fields: string[] = [];\n fields.push(inlineField('Session', wikilink(sessionNoteId(input.sessionId))));\n if (input.user) fields.push(inlineField('User', input.user));\n if (input.started && input.ended) {\n const duration = formatDuration(input.started, input.ended);\n if (duration) fields.push(inlineField('Duration', duration));\n }\n if (input.branch) fields.push(inlineField('Branch', `\\`${input.branch}\\``));\n sections.push(fields.join('\\n'));\n\n // Related memories\n if (input.relatedMemories?.length) {\n const links = input.relatedMemories.map((m) => `- ${wikilink(m.id, m.title)}`);\n sections.push(`## Related Memories\\n${links.join('\\n')}`);\n }\n\n // Conversation turns — always rebuilt from the full transcript.\n // The transcript is the source of truth for the complete conversation.\n if (input.turns.length > 0) {\n const turnLines: string[] = [];\n for (let i = 0; i < input.turns.length; i++) {\n const turn = input.turns[i];\n const turnNum = i + 1;\n turnLines.push(`### Turn ${turnNum}`);\n if (turn.prompt || turn.images?.length) {\n // Build prompt content: text + images + tool count\n const parts: string[] = [];\n if (turn.prompt) parts.push(turn.prompt);\n if (turn.images?.length) {\n parts.push(turn.images.map((f) => `![[${f}]]`).join('\\n'));\n }\n if (turn.toolCount > 0) parts.push(`*${turn.toolCount} tool calls*`);\n turnLines.push(callout('user', 'Prompt', parts.join('\\n\\n')));\n } else if (turn.toolCount > 0) {\n turnLines.push(callout('user', 'Prompt', `*${turn.toolCount} tool calls*`));\n }\n if (turn.aiResponse) {\n turnLines.push(callout('assistant', 'Response', turn.aiResponse));\n }\n }\n sections.push(`## Conversation\\n\\n${turnLines.join('\\n\\n')}`);\n }\n\n // Footer tags\n const allTags = buildTags('session', 'ended', [\n ...(input.user ? [`user/${input.user}`] : []),\n ...(input.tags ?? []),\n ]);\n sections.push(footerTags(allTags));\n\n return sections.join('\\n\\n');\n}\n\n// --- Memory formatting ---\n\nexport interface MemoryBodyInput {\n title: string;\n observationType: string;\n content: string;\n sessionId?: string;\n root_cause?: string;\n fix?: string;\n rationale?: string;\n alternatives_rejected?: string;\n gained?: string;\n sacrificed?: string;\n tags?: string[];\n}\n\nexport function formatMemoryBody(input: MemoryBodyInput): string {\n const sections: string[] = [];\n const calloutType = observationCalloutType(input.observationType);\n const calloutTitle = capitalize(tagNormalize(input.observationType));\n\n sections.push(`# ${input.title}`);\n sections.push(callout(calloutType, calloutTitle, input.content));\n\n // Inline fields\n const fields: string[] = [];\n if (input.sessionId) {\n fields.push(inlineField('Session', wikilink(sessionNoteId(input.sessionId))));\n }\n fields.push(inlineField('Observation', input.observationType));\n if (fields.length > 0) sections.push(fields.join('\\n'));\n\n // Type-specific sub-sections\n if (input.root_cause) sections.push(`## Root Cause\\n${input.root_cause}`);\n if (input.fix) sections.push(`## Fix\\n${input.fix}`);\n if (input.rationale) sections.push(`## Rationale\\n${input.rationale}`);\n if (input.alternatives_rejected) sections.push(`## Alternatives Rejected\\n${input.alternatives_rejected}`);\n if (input.gained) sections.push(`## Gained\\n${input.gained}`);\n if (input.sacrificed) sections.push(`## Sacrificed\\n${input.sacrificed}`);\n\n // Footer tags\n const allTags = buildTags('memory', input.observationType, input.tags ?? []);\n sections.push(footerTags(allTags));\n\n return sections.join('\\n\\n');\n}\n\n// --- Plan formatting ---\n\nexport interface PlanBodyInput {\n id: string;\n status: string;\n author?: string;\n created?: string;\n sessions?: Array<{ id: string; title: string }>;\n content: string;\n tags?: string[];\n}\n\nexport function formatPlanBody(input: PlanBodyInput): string {\n const sections: string[] = [];\n\n // Inline fields block\n const fields: string[] = [];\n fields.push(inlineField('Plan', wikilink(input.id)));\n fields.push(inlineField('Status', input.status));\n if (input.author) fields.push(inlineField('Author', input.author));\n if (input.created) fields.push(inlineField('Created', input.created));\n sections.push(fields.join('\\n'));\n\n // User-provided content body (don't restructure)\n sections.push(input.content);\n\n // Sessions section\n if (input.sessions?.length) {\n const links = input.sessions.map((s) => `- ${wikilink(sessionNoteId(s.id), s.title)}`);\n sections.push(`## Sessions\\n${links.join('\\n')}`);\n }\n\n // Footer tags\n const statusTag = tagNormalize(input.status);\n const allTags = buildTags('plan', statusTag, input.tags ?? []);\n sections.push(footerTags(allTags));\n\n return sections.join('\\n\\n');\n}\n\n// --- Artifact formatting ---\n\nexport interface ArtifactBodyInput {\n id: string;\n title: string;\n artifact_type: ArtifactType;\n source_path: string;\n sessionId: string;\n content: string;\n tags?: string[];\n}\n\nexport function formatArtifactBody(input: ArtifactBodyInput): string {\n const sections: string[] = [];\n\n // Inline fields\n const fields: string[] = [];\n fields.push(inlineField('Artifact', wikilink(input.id)));\n fields.push(inlineField('Source', `\\`${input.source_path}\\``));\n fields.push(inlineField('Type', input.artifact_type));\n fields.push(inlineField('Session', wikilink(sessionNoteId(input.sessionId))));\n sections.push(fields.join('\\n'));\n\n // Body: full content from disk\n sections.push(input.content);\n\n // Footer tags\n const allTags = buildTags('artifact', input.artifact_type, input.tags ?? []);\n sections.push(footerTags(allTags));\n\n return sections.join('\\n\\n');\n}\n\n// --- Team formatting ---\n\nexport interface TeamBodyInput {\n user: string;\n role?: string;\n recentSessions?: Array<{ id: string; title: string }>;\n}\n\nexport function formatTeamBody(input: TeamBodyInput): string {\n const sections: string[] = [];\n\n sections.push(`# ${input.user}`);\n sections.push(callout('info', 'Team Member', input.role ?? 'Contributor'));\n\n // Inline fields\n const fields: string[] = [];\n fields.push(inlineField('User', input.user));\n if (input.role) fields.push(inlineField('Role', input.role));\n sections.push(fields.join('\\n'));\n\n // Recent sessions\n if (input.recentSessions?.length) {\n const links = input.recentSessions.map((s) => `- ${wikilink(sessionNoteId(s.id), s.title)}`);\n sections.push(`## Recent Sessions\\n${links.join('\\n')}`);\n }\n\n // Footer tags\n const allTags = buildTags('team', '', [`user/${input.user}`]);\n sections.push(footerTags(allTags));\n\n return sections.join('\\n\\n');\n}\n\n// --- Helpers ---\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction formatDuration(started: string, ended: string): string {\n const ms = new Date(ended).getTime() - new Date(started).getTime();\n if (isNaN(ms) || ms < 0) return '';\n const totalMinutes = Math.floor(ms / 60000);\n if (totalMinutes < 1) return '<1m';\n const hours = Math.floor(totalMinutes / 60);\n const minutes = totalMinutes % 60;\n if (hours === 0) return `${minutes}m`;\n if (minutes === 0) return `${hours}h`;\n return `${hours}h ${minutes}m`;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport YAML from 'yaml';\nimport { buildTags, formatTeamBody, formatPlanBody, formatArtifactBody } from '../obsidian/formatter.js';\nimport type { ArtifactType } from './types.js';\nimport { sessionNoteId, sessionRelativePath } from './session-id.js';\n\ninterface WriteSessionInput {\n id: string;\n agent?: string;\n user?: string;\n started: string;\n ended?: string;\n parent?: string;\n parent_reason?: string;\n plans?: string[];\n branch?: string;\n tags?: string[];\n tools_used?: number;\n files_changed?: number;\n summary: string;\n}\n\ninterface WritePlanInput {\n id: string;\n status?: string;\n author?: string;\n tags?: string[];\n content: string;\n}\n\ninterface WriteMemoryInput {\n id: string;\n observation_type: string;\n session?: string;\n plan?: string;\n tags?: string[];\n content: string;\n}\n\ninterface WriteArtifactInput {\n id: string;\n artifact_type: ArtifactType;\n source_path: string;\n title: string;\n session: string;\n tags?: string[];\n content: string;\n}\n\ninterface WriteTeamMemberInput {\n user: string;\n role?: string;\n}\n\nexport class VaultWriter {\n constructor(private vaultDir: string) {}\n\n writeSession(input: WriteSessionInput): string {\n const date = input.started.slice(0, 10);\n const relativePath = sessionRelativePath(input.id, date);\n\n const frontmatter: Record<string, unknown> = {\n type: 'session',\n id: input.id,\n agent: input.agent ?? 'claude-code',\n user: input.user ?? '',\n started: input.started,\n };\n if (input.ended) frontmatter.ended = input.ended;\n if (input.parent) frontmatter.parent = input.parent;\n if (input.parent_reason) frontmatter.parent_reason = input.parent_reason;\n if (input.plans?.length) frontmatter.plans = input.plans;\n if (input.branch) frontmatter.branch = input.branch;\n frontmatter.tags = buildTags('session', 'ended', [\n ...(input.user ? [`user/${input.user}`] : []),\n ...(input.tags ?? []),\n ]);\n if (input.tools_used != null) frontmatter.tools_used = input.tools_used;\n if (input.files_changed != null) frontmatter.files_changed = input.files_changed;\n\n this.writeMarkdown(relativePath, frontmatter, input.summary);\n return relativePath;\n }\n\n writePlan(input: WritePlanInput): string {\n const relativePath = `plans/${input.id}.md`;\n const fullPath = path.join(this.vaultDir, relativePath);\n\n const status = input.status ?? 'active';\n let created = new Date().toISOString();\n\n // Preserve created from existing file (idempotent)\n try {\n const existing = fs.readFileSync(fullPath, 'utf-8');\n const fmMatch = existing.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (fmMatch) {\n const parsed = YAML.parse(fmMatch[1]) as Record<string, unknown>;\n if (typeof parsed.created === 'string') created = parsed.created;\n }\n } catch {\n // File doesn't exist yet\n }\n const frontmatter: Record<string, unknown> = {\n type: 'plan',\n id: input.id,\n status,\n created,\n };\n if (input.author) frontmatter.author = input.author;\n frontmatter.tags = buildTags('plan', status, input.tags ?? []);\n\n const body = formatPlanBody({\n id: input.id,\n status,\n author: input.author,\n created,\n content: input.content,\n tags: input.tags,\n });\n\n this.writeMarkdown(relativePath, frontmatter, body);\n return relativePath;\n }\n\n writeMemory(input: WriteMemoryInput): string {\n const normalizedType = input.observation_type.replace(/_/g, '-');\n const relativePath = `memories/${normalizedType}/${input.id}.md`;\n const fullPath = path.join(this.vaultDir, relativePath);\n const now = new Date().toISOString();\n\n // Preserve created from existing file (idempotent)\n let created = now;\n try {\n const existing = fs.readFileSync(fullPath, 'utf-8');\n const fmMatch = existing.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (fmMatch) {\n const parsed = YAML.parse(fmMatch[1]) as Record<string, unknown>;\n if (typeof parsed.created === 'string') created = parsed.created;\n }\n } catch {\n // File doesn't exist yet — created = now\n }\n\n const frontmatter: Record<string, unknown> = {\n type: 'memory',\n id: input.id,\n observation_type: input.observation_type,\n created,\n };\n if (input.session) frontmatter.session = input.session;\n if (input.plan) frontmatter.plan = input.plan;\n frontmatter.tags = buildTags('memory', input.observation_type, input.tags ?? []);\n\n this.writeMarkdown(relativePath, frontmatter, input.content);\n return relativePath;\n }\n\n writeArtifact(input: WriteArtifactInput): string {\n const relativePath = `artifacts/${input.id}.md`;\n const fullPath = path.join(this.vaultDir, relativePath);\n const now = new Date().toISOString();\n\n let created = now;\n\n // Preserve created from existing file (latest-wins update)\n try {\n const existing = fs.readFileSync(fullPath, 'utf-8');\n const fmMatch = existing.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (fmMatch) {\n const parsed = YAML.parse(fmMatch[1]) as Record<string, unknown>;\n if (typeof parsed.created === 'string') created = parsed.created;\n }\n } catch {\n // File doesn't exist yet — created = now\n }\n\n const frontmatter: Record<string, unknown> = {\n type: 'artifact',\n id: input.id,\n artifact_type: input.artifact_type,\n source_path: input.source_path,\n title: input.title,\n last_captured_by: sessionNoteId(input.session),\n created,\n updated: now,\n tags: buildTags('artifact', input.artifact_type, input.tags ?? []),\n };\n\n const body = formatArtifactBody({\n id: input.id,\n title: input.title,\n artifact_type: input.artifact_type,\n source_path: input.source_path,\n sessionId: input.session,\n content: input.content,\n tags: input.tags,\n });\n\n this.writeMarkdown(relativePath, frontmatter, body);\n return relativePath;\n }\n\n writeTeamMember(input: WriteTeamMemberInput): string {\n const relativePath = `team/${input.user}.md`;\n\n const frontmatter: Record<string, unknown> = {\n type: 'team-member',\n user: input.user,\n joined: new Date().toISOString(),\n tags: buildTags('team', '', [`user/${input.user}`]),\n };\n if (input.role) frontmatter.role = input.role;\n\n const body = formatTeamBody({\n user: input.user,\n role: input.role,\n });\n\n this.writeMarkdown(relativePath, frontmatter, body);\n return relativePath;\n }\n\n /**\n * Update frontmatter fields on an existing note without touching the body.\n * By default only adds fields that don't exist. Set overwrite=true to replace existing values.\n * Returns true if the update was applied, false if the file doesn't exist.\n */\n updateNoteFrontmatter(relativePath: string, fields: Record<string, unknown>, overwrite = false): boolean {\n const fullPath = path.join(this.vaultDir, relativePath);\n let fileContent: string;\n try {\n fileContent = fs.readFileSync(fullPath, 'utf-8');\n } catch {\n return false;\n }\n\n const fmMatch = fileContent.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!fmMatch) return false;\n\n const parsed = YAML.parse(fmMatch[1]) as Record<string, unknown>;\n for (const [key, value] of Object.entries(fields)) {\n if (overwrite || parsed[key] === undefined) {\n parsed[key] = value;\n }\n }\n\n const body = fileContent.slice(fmMatch[0].length);\n const fmYaml = YAML.stringify(parsed, { defaultStringType: 'QUOTE_DOUBLE', defaultKeyType: 'PLAIN' }).trim();\n this.atomicWrite(fullPath, `---\\n${fmYaml}\\n---${body}`);\n return true;\n }\n\n /** @deprecated Use updateNoteFrontmatter instead */\n updateSessionFrontmatter(relativePath: string, fields: Record<string, unknown>): boolean {\n return this.updateNoteFrontmatter(relativePath, fields);\n }\n\n private writeMarkdown(relativePath: string, frontmatter: Record<string, unknown>, content: string): void {\n const fullPath = path.join(this.vaultDir, relativePath);\n fs.mkdirSync(path.dirname(fullPath), { recursive: true });\n\n const fmYaml = YAML.stringify(frontmatter, { defaultStringType: 'QUOTE_DOUBLE', defaultKeyType: 'PLAIN' }).trim();\n const file = `---\\n${fmYaml}\\n---\\n\\n${content}\\n`;\n this.atomicWrite(fullPath, file);\n }\n\n /** Write to a temp file then rename — prevents Obsidian from seeing a truncated file mid-write. */\n private atomicWrite(fullPath: string, content: string): void {\n const tmp = `${fullPath}.tmp`;\n fs.writeFileSync(tmp, content, 'utf-8');\n fs.renameSync(tmp, fullPath);\n }\n}\n"],"mappings":"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","names":["YAML"]}
|