portable-agent-layer 0.34.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +1 -1
  2. package/assets/skills/presentation/SKILL.md +2 -0
  3. package/assets/skills/presentation/demo/slides/004-content.md +27 -1
  4. package/assets/skills/presentation/theme-base/base.css +206 -0
  5. package/assets/skills/presentation/theme-base/skeleton.html +49 -0
  6. package/assets/skills/presentation/tools/lib/lint-rules.ts +25 -0
  7. package/assets/skills/projects/SKILL.md +0 -1
  8. package/assets/skills/telos/SKILL.md +7 -52
  9. package/assets/templates/AGENTS.md.template +2 -1
  10. package/assets/templates/PAL/ALGORITHM.md +28 -3
  11. package/assets/templates/PAL/PROJECT_LIFECYCLE.md +48 -0
  12. package/assets/templates/PAL/README.md +1 -1
  13. package/assets/templates/PAL/STEERING_RULES.md +4 -0
  14. package/assets/templates/PAL/SYSTEM_ARCHITECTURE.md +32 -17
  15. package/assets/templates/PAL/WORK_TRACKING.md +1 -1
  16. package/assets/templates/pal-settings.json +1 -3
  17. package/assets/templates/settings.claude.json +2 -1
  18. package/package.json +1 -1
  19. package/src/cli/setup-telos.ts +12 -79
  20. package/src/hooks/LoadContext.ts +22 -10
  21. package/src/hooks/handlers/context-digests.ts +74 -0
  22. package/src/hooks/handlers/session-intelligence.ts +9 -86
  23. package/src/hooks/lib/claude-md.ts +69 -14
  24. package/src/hooks/lib/context.ts +57 -139
  25. package/src/hooks/lib/relationship.ts +3 -3
  26. package/src/hooks/lib/security.ts +2 -0
  27. package/src/hooks/lib/semi-static.ts +186 -0
  28. package/src/hooks/lib/setup.ts +0 -5
  29. package/src/hooks/lib/stop.ts +3 -0
  30. package/src/targets/claude/uninstall.ts +1 -1
  31. package/src/targets/copilot/install.ts +39 -8
  32. package/src/targets/copilot/uninstall.ts +58 -17
  33. package/src/targets/cursor/install.ts +8 -0
  34. package/src/targets/cursor/uninstall.ts +18 -1
  35. package/src/targets/lib.ts +26 -0
  36. package/src/targets/opencode/install.ts +29 -1
  37. package/src/targets/opencode/plugin.ts +1 -1
  38. package/src/targets/opencode/uninstall.ts +30 -3
  39. package/src/tools/agent/handoff-note.ts +116 -0
  40. package/src/tools/agent/relationship-note.ts +51 -0
  41. package/src/tools/relationship-reflect.ts +2 -2
  42. package/src/tools/self-model.ts +4 -4
  43. package/assets/templates/telos/PROJECTS.md +0 -7
@@ -1,12 +1,22 @@
1
1
  /**
2
2
  * PAL — Copilot uninstaller
3
- * Removes pal-hooks.json, skill symlinks, agents, and copilot-instructions.md symlink.
3
+ * Removes pal-hooks.json, skill symlinks, agents, instruction files,
4
+ * and the VS Code chat.instructionsFilesLocations entry.
4
5
  */
5
6
 
6
7
  import { copyFileSync, existsSync, lstatSync, readlinkSync, unlinkSync } from "node:fs";
7
8
  import { resolve } from "node:path";
8
9
  import { platform } from "../../hooks/lib/paths";
9
- import { log, removeAgentsFromCopilot, removePalDocs, removeSkills } from "../lib";
10
+ import { copilotFilename, getSemiStaticSources } from "../../hooks/lib/semi-static";
11
+ import {
12
+ log,
13
+ readJson,
14
+ removeAgentsFromCopilot,
15
+ removePalDocs,
16
+ removeSkills,
17
+ vscodeSettingsFile,
18
+ writeJson,
19
+ } from "../lib";
10
20
 
11
21
  const COPILOT_DIR = platform.copilotDir();
12
22
  const HOOKS_FILE = resolve(COPILOT_DIR, "hooks", "pal-hooks.json");
@@ -35,26 +45,57 @@ if (removedAgents.length > 0) {
35
45
  log.success(`Removed ${removedAgents.length} agent(s): ${removedAgents.join(", ")}`);
36
46
  }
37
47
 
38
- // --- Remove copilot-instructions.md symlink (only if it points to AGENTS.md) ---
39
- const instructionsPath = resolve(COPILOT_DIR, "copilot-instructions.md");
40
- if (existsSync(instructionsPath)) {
48
+ // --- Remove PAL docs ---
49
+ removePalDocs();
50
+
51
+ // --- Remove ~/.copilot/instructions/pal-*.instructions.md ---
52
+ for (const src of getSemiStaticSources()) {
53
+ try {
54
+ unlinkSync(resolve(COPILOT_DIR, "instructions", copilotFilename(src)));
55
+ } catch {
56
+ /* gone */
57
+ }
58
+ }
59
+ // pal-session.instructions.md is written by LoadContext (not a semi-static source)
60
+ try {
61
+ unlinkSync(resolve(COPILOT_DIR, "instructions", "pal-session.instructions.md"));
62
+ } catch {
63
+ /* gone */
64
+ }
65
+ log.success("Removed ~/.copilot/instructions/pal-*.instructions.md");
66
+
67
+ // --- Backward compat: remove old copilot-instructions.md symlink if present ---
68
+ const legacyPath = resolve(COPILOT_DIR, "copilot-instructions.md");
69
+ if (existsSync(legacyPath)) {
41
70
  try {
42
- const stat = lstatSync(instructionsPath);
43
- if (stat.isSymbolicLink()) {
44
- const target = readlinkSync(instructionsPath);
45
- if (target.includes("AGENTS.md")) {
46
- unlinkSync(instructionsPath);
47
- log.success("Removed copilot-instructions.md symlink");
48
- } else {
49
- log.info("copilot-instructions.md is not a PAL symlink — leaving it");
50
- }
71
+ if (
72
+ lstatSync(legacyPath).isSymbolicLink() &&
73
+ readlinkSync(legacyPath).includes("AGENTS.md")
74
+ ) {
75
+ unlinkSync(legacyPath);
76
+ log.success("Removed legacy copilot-instructions.md symlink");
51
77
  }
52
78
  } catch {
53
- // ignore
79
+ /* ignore */
54
80
  }
55
81
  }
56
82
 
57
- // --- Remove PAL docs ---
58
- removePalDocs();
83
+ // --- Remove ~/.copilot/instructions entry from VS Code settings ---
84
+ const vsSettingsPath = vscodeSettingsFile();
85
+ if (vsSettingsPath && existsSync(vsSettingsPath)) {
86
+ const settings = readJson<Record<string, unknown>>(vsSettingsPath, {});
87
+ const locs = settings["chat.instructionsFilesLocations"];
88
+ if (typeof locs === "object" && locs !== null) {
89
+ const obj = locs as Record<string, unknown>;
90
+ delete obj["~/.copilot/instructions"];
91
+ if (Object.keys(obj).length === 0) {
92
+ delete settings["chat.instructionsFilesLocations"];
93
+ } else {
94
+ settings["chat.instructionsFilesLocations"] = obj;
95
+ }
96
+ writeJson(vsSettingsPath, settings);
97
+ log.success("Removed ~/.copilot/instructions from VS Code settings");
98
+ }
99
+ }
59
100
 
60
101
  log.success("Copilot uninstall complete");
@@ -6,6 +6,7 @@
6
6
 
7
7
  import { copyFileSync, existsSync, mkdirSync } from "node:fs";
8
8
  import { resolve } from "node:path";
9
+ import { writeContextDigests } from "../../hooks/handlers/context-digests";
9
10
  import { regenerateIfNeeded } from "../../hooks/lib/claude-md";
10
11
  import { assets, palPkg, platform } from "../../hooks/lib/paths";
11
12
  import {
@@ -64,6 +65,13 @@ scaffoldPalSettings();
64
65
  regenerateIfNeeded();
65
66
  log.success("Generated AGENTS.md");
66
67
 
68
+ // --- Write ~/.cursor/rules/pal-*.mdc ---
69
+ mkdirSync(resolve(CURSOR_DIR, "rules"), { recursive: true });
70
+ writeContextDigests();
71
+ log.success(
72
+ "Written ~/.cursor/rules/pal-self-model.mdc + pal-wisdom.mdc + pal-opinions.mdc"
73
+ );
74
+
67
75
  log.success("Cursor installation complete");
68
76
  console.log("");
69
77
  log.info(`Skills: ${countSkills()}`);
@@ -4,9 +4,10 @@
4
4
  * Removes PAL skill symlinks.
5
5
  */
6
6
 
7
- import { copyFileSync, existsSync } from "node:fs";
7
+ import { copyFileSync, existsSync, unlinkSync } from "node:fs";
8
8
  import { resolve } from "node:path";
9
9
  import { assets, palPkg, platform } from "../../hooks/lib/paths";
10
+ import { cursorFilename, getSemiStaticSources } from "../../hooks/lib/semi-static";
10
11
  import {
11
12
  loadCursorHooksTemplate,
12
13
  log,
@@ -56,4 +57,20 @@ if (removedAgents.length > 0) {
56
57
  // --- Remove PAL system docs ---
57
58
  removePalDocs();
58
59
 
60
+ // --- Remove ~/.cursor/rules/pal-*.mdc ---
61
+ for (const src of getSemiStaticSources()) {
62
+ try {
63
+ unlinkSync(resolve(CURSOR_DIR, "rules", cursorFilename(src)));
64
+ } catch {
65
+ /* gone */
66
+ }
67
+ }
68
+ // Backward compat: remove legacy merged file if present
69
+ try {
70
+ unlinkSync(resolve(CURSOR_DIR, "rules", "pal-context.mdc"));
71
+ } catch {
72
+ /* gone */
73
+ }
74
+ log.success("Removed ~/.cursor/rules/pal-*.mdc");
75
+
59
76
  log.success("Cursor uninstall complete");
@@ -14,6 +14,7 @@ import {
14
14
  unlinkSync,
15
15
  writeFileSync,
16
16
  } from "node:fs";
17
+ import { homedir } from "node:os";
17
18
  import { resolve } from "node:path";
18
19
  import { assets, palHome, platform } from "../hooks/lib/paths";
19
20
 
@@ -41,6 +42,31 @@ export function writeJson(path: string, data: unknown): void {
41
42
  writeFileSync(path, `${JSON.stringify(data, null, 2)}\n`, "utf-8");
42
43
  }
43
44
 
45
+ /** Resolve the VS Code user settings.json path cross-platform. Returns null on unknown platforms. */
46
+ export function vscodeSettingsFile(): string | null {
47
+ const h = homedir();
48
+ if (process.platform === "darwin") {
49
+ return resolve(h, "Library", "Application Support", "Code", "User", "settings.json");
50
+ }
51
+ if (process.platform === "linux") {
52
+ return resolve(
53
+ process.env.XDG_CONFIG_HOME ?? resolve(h, ".config"),
54
+ "Code",
55
+ "User",
56
+ "settings.json"
57
+ );
58
+ }
59
+ if (process.platform === "win32") {
60
+ return resolve(
61
+ process.env.APPDATA ?? resolve(h, "AppData", "Roaming"),
62
+ "Code",
63
+ "User",
64
+ "settings.json"
65
+ );
66
+ }
67
+ return null;
68
+ }
69
+
44
70
  // --- Settings template merge/unmerge ---
45
71
 
46
72
  type HookEntry = { matcher?: string; hooks?: Array<{ type: string; command: string }> };
@@ -3,10 +3,18 @@
3
3
  * Deploys plugin, installs skills, generates AGENTS.md.
4
4
  */
5
5
 
6
- import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
6
+ import {
7
+ existsSync,
8
+ mkdirSync,
9
+ readFileSync,
10
+ statSync,
11
+ unlinkSync,
12
+ writeFileSync,
13
+ } from "node:fs";
7
14
  import { resolve } from "node:path";
8
15
  import { regenerateIfNeeded } from "../../hooks/lib/claude-md";
9
16
  import { palPkg, platform } from "../../hooks/lib/paths";
17
+ import { getSemiStaticSources } from "../../hooks/lib/semi-static";
10
18
  import {
11
19
  copyAgentsForOpencode,
12
20
  copyPalDocs,
@@ -70,6 +78,26 @@ log.success(`Installed ${palDocsCount} PAL docs to ~/.pal/docs/`);
70
78
  regenerateIfNeeded();
71
79
  log.success("Generated ~/.config/opencode/AGENTS.md");
72
80
 
81
+ // --- 7. Add semi-static digest files to instructions[] in config.json ---
82
+ const configPath = resolve(OC_GLOBAL_DIR, "config.json");
83
+ const staticFiles = getSemiStaticSources().map((s) => s.path);
84
+ let ocConfig: Record<string, unknown> = {};
85
+ if (existsSync(configPath) && statSync(configPath).size > 0) {
86
+ try {
87
+ ocConfig = JSON.parse(readFileSync(configPath, "utf-8"));
88
+ } catch {
89
+ /* start fresh */
90
+ }
91
+ }
92
+ const existingInstructions = Array.isArray(ocConfig.instructions)
93
+ ? (ocConfig.instructions as string[])
94
+ : [];
95
+ ocConfig.instructions = [...new Set([...existingInstructions, ...staticFiles])];
96
+ writeFileSync(configPath, `${JSON.stringify(ocConfig, null, 2)}\n`, "utf-8");
97
+ log.success(
98
+ `Updated config.json: ${(ocConfig.instructions as string[]).length} instructions`
99
+ );
100
+
73
101
  log.success("opencode installation complete");
74
102
  console.log("");
75
103
  log.info(`Plugin: ${pluginDst}`);
@@ -74,7 +74,7 @@ const PALPlugin: Plugin = async ({ directory, client }: PluginInput) => {
74
74
  return {
75
75
  // --- Per-message: Inject dynamic system reminder ---
76
76
  "experimental.chat.system.transform": async (_input, output) => {
77
- const reminder = buildSystemReminder();
77
+ const reminder = buildSystemReminder({ agent: "opencode" });
78
78
  if (reminder) output.system.push(reminder);
79
79
  },
80
80
 
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * PAL — opencode uninstaller (TypeScript)
3
- * Removes plugin and AGENTS.md.
3
+ * Removes plugin, AGENTS.md, and PAL entries from config.json.
4
4
  */
5
5
 
6
- import { unlinkSync } from "node:fs";
6
+ import { existsSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
7
7
  import { resolve } from "node:path";
8
8
  import { platform } from "../../hooks/lib/paths";
9
+ import { getSemiStaticSources } from "../../hooks/lib/semi-static";
9
10
  import { log, removeAgentsFromOpencode, removePalDocs, removeSkills } from "../lib";
10
11
 
11
12
  const OC_GLOBAL_DIR = platform.opencodeDir() || "";
@@ -41,7 +42,7 @@ if (removedAgents.length > 0)
41
42
  // --- Remove PAL system docs ---
42
43
  removePalDocs();
43
44
 
44
- // --- Remove AGENTS.md and CLAUDE.md symlink ---
45
+ // --- Remove AGENTS.md and CLAUDE.md ---
45
46
  const agentsMd = resolve(OC_GLOBAL_DIR, "AGENTS.md");
46
47
  const claudeMd = resolve(PAL_CLAUDE_DIR, "CLAUDE.md");
47
48
  try {
@@ -57,4 +58,30 @@ try {
57
58
  /* gone */
58
59
  }
59
60
 
61
+ // --- Remove PAL entries from config.json instructions[] ---
62
+ const configPath = resolve(OC_GLOBAL_DIR, "config.json");
63
+ if (existsSync(configPath) && statSync(configPath).size > 0) {
64
+ try {
65
+ const ocConfig = JSON.parse(readFileSync(configPath, "utf-8")) as Record<
66
+ string,
67
+ unknown
68
+ >;
69
+ if (Array.isArray(ocConfig.instructions)) {
70
+ const palFiles = new Set(getSemiStaticSources().map((s) => s.path));
71
+ const filtered = (ocConfig.instructions as string[]).filter(
72
+ (p) => !palFiles.has(p)
73
+ );
74
+ if (filtered.length === 0) {
75
+ delete ocConfig.instructions;
76
+ } else {
77
+ ocConfig.instructions = filtered;
78
+ }
79
+ writeFileSync(configPath, `${JSON.stringify(ocConfig, null, 2)}\n`, "utf-8");
80
+ log.success("Removed PAL entries from config.json instructions[]");
81
+ }
82
+ } catch {
83
+ log.warn("Could not clean config.json instructions[] — check manually");
84
+ }
85
+ }
86
+
60
87
  log.success("opencode uninstall complete");
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * HandoffNote — Write or clear a handoff note for the current project.
4
+ *
5
+ * Called in the ALGORITHM LEARN phase when work is unfinished.
6
+ * Written by Claude in-session — no inference call needed.
7
+ *
8
+ * Usage:
9
+ * bun ~/.pal/tools/handoff-note.ts --title "what we were doing" --text "what remains + next steps"
10
+ * bun ~/.pal/tools/handoff-note.ts --done # mark completed, suppress next-session injection
11
+ */
12
+
13
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
14
+ import { resolve } from "node:path";
15
+ import { parseArgs } from "node:util";
16
+ import { ensureDir, paths } from "../../hooks/lib/paths";
17
+
18
+ interface HandoffEntry {
19
+ timestamp: string;
20
+ title: string;
21
+ status: "in-progress" | "completed";
22
+ handoff: string;
23
+ artifacts: string[];
24
+ }
25
+
26
+ function handoffPath(): string {
27
+ return resolve(ensureDir(paths.state()), "last-handoff.json");
28
+ }
29
+
30
+ function readHandoffs(): Record<string, HandoffEntry> {
31
+ const p = handoffPath();
32
+ if (!existsSync(p)) return {};
33
+ try {
34
+ return JSON.parse(readFileSync(p, "utf-8"));
35
+ } catch {
36
+ return {};
37
+ }
38
+ }
39
+
40
+ function writeHandoffs(handoffs: Record<string, HandoffEntry>): void {
41
+ const entries = Object.entries(handoffs);
42
+ const trimmed = entries.length > 20 ? Object.fromEntries(entries.slice(-20)) : handoffs;
43
+ writeFileSync(handoffPath(), JSON.stringify(trimmed, null, 2), "utf-8");
44
+ }
45
+
46
+ export function writeHandoffNote(
47
+ cwd: string,
48
+ title: string,
49
+ text: string,
50
+ done: boolean
51
+ ): { success: boolean; message: string } {
52
+ const handoffs = readHandoffs();
53
+ handoffs[cwd] = {
54
+ timestamp: new Date().toISOString(),
55
+ title,
56
+ status: done ? "completed" : "in-progress",
57
+ handoff: text,
58
+ artifacts: [],
59
+ };
60
+ writeHandoffs(handoffs);
61
+ return {
62
+ success: true,
63
+ message: done ? "Handoff cleared (marked completed)" : "Handoff note written",
64
+ };
65
+ }
66
+
67
+ function run() {
68
+ const { values } = parseArgs({
69
+ args: Bun.argv.slice(2),
70
+ options: {
71
+ title: { type: "string" },
72
+ text: { type: "string" },
73
+ done: { type: "boolean" },
74
+ help: { type: "boolean", short: "h" },
75
+ },
76
+ });
77
+
78
+ if (values.help) {
79
+ console.log(`
80
+ HandoffNote — Write a handoff note for the current project
81
+
82
+ Usage:
83
+ bun ~/.pal/tools/handoff-note.ts --title "what we were doing" --text "what remains"
84
+ bun ~/.pal/tools/handoff-note.ts --done # mark session completed
85
+
86
+ Arguments:
87
+ --title Brief title of what was being worked on (5-10 words)
88
+ --text What remains unfinished — decisions made, next steps, blockers
89
+ --done Mark as completed; suppresses "pick up where you left off" injection
90
+
91
+ Output: writes to memory/state/last-handoff.json keyed by cwd
92
+ `);
93
+ process.exit(0);
94
+ }
95
+
96
+ if (values.done) {
97
+ const result = writeHandoffNote(
98
+ process.cwd(),
99
+ values.title || "session",
100
+ values.text || "",
101
+ true
102
+ );
103
+ console.log(JSON.stringify(result, null, 2));
104
+ process.exit(0);
105
+ }
106
+
107
+ if (!values.title || !values.text) {
108
+ console.error("Required: --title and --text (or --done to close)");
109
+ process.exit(1);
110
+ }
111
+
112
+ const result = writeHandoffNote(process.cwd(), values.title, values.text, false);
113
+ console.log(JSON.stringify(result, null, 2));
114
+ }
115
+
116
+ if (import.meta.main) run();
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * RelationshipNote — Write a B entry to today's relationship log.
4
+ *
5
+ * Called in the ALGORITHM LEARN phase. Claude writes the B entry directly
6
+ * from full session context — no inference call needed.
7
+ *
8
+ * Usage:
9
+ * bun ~/.pal/tools/relationship-note.ts --b "what I did this session"
10
+ */
11
+
12
+ import { parseArgs } from "node:util";
13
+ import { appendNotes } from "../../hooks/lib/relationship";
14
+
15
+ function run() {
16
+ const { values } = parseArgs({
17
+ args: Bun.argv.slice(2),
18
+ options: {
19
+ b: { type: "string" },
20
+ help: { type: "boolean", short: "h" },
21
+ },
22
+ });
23
+
24
+ if (values.help) {
25
+ console.log(`
26
+ RelationshipNote — Append a B entry to today's relationship log
27
+
28
+ Usage:
29
+ bun ~/.pal/tools/relationship-note.ts --b "description"
30
+
31
+ Arguments:
32
+ --b What happened this session (1-2 sentences, first-person, specific)
33
+
34
+ Output: appends to memory/relationship/YYYY-MM/YYYY-MM-DD.md
35
+ `);
36
+ process.exit(0);
37
+ }
38
+
39
+ if (!values.b) {
40
+ console.error("Required: --b");
41
+ process.exit(1);
42
+ }
43
+
44
+ appendNotes([{ type: "Session", text: values.b }]);
45
+
46
+ console.log(
47
+ JSON.stringify({ success: true, message: "Relationship note written" }, null, 2)
48
+ );
49
+ }
50
+
51
+ if (import.meta.main) run();
@@ -37,7 +37,7 @@ interface Rating {
37
37
  }
38
38
 
39
39
  interface ParsedNote {
40
- type: "W" | "O" | "B";
40
+ type: "W" | "O" | "Session";
41
41
  text: string;
42
42
  confidence?: number;
43
43
  date: string;
@@ -94,7 +94,7 @@ export function loadNotes(daysBack: number): ParsedNote[] {
94
94
  const obMatch = line.match(/^- ([OB])\(c=([\d.]+)\):\s*(.+)$/);
95
95
  if (obMatch) {
96
96
  notes.push({
97
- type: obMatch[1] as "O" | "B",
97
+ type: obMatch[1] as "O" | "Session",
98
98
  confidence: Number.parseFloat(obMatch[2]),
99
99
  text: obMatch[3],
100
100
  date: dateStr,
@@ -71,7 +71,7 @@ interface AlgorithmReflection {
71
71
  }
72
72
 
73
73
  interface RelationshipNote {
74
- type: "O" | "W" | "B";
74
+ type: "O" | "W" | "Session";
75
75
  content: string;
76
76
  confidence?: number;
77
77
  date: string;
@@ -292,9 +292,9 @@ function readRelationshipNotes(since: Date): RelationshipNote[] {
292
292
  continue;
293
293
  }
294
294
 
295
- const behaviorMatch = noteContent.match(/^B:\s*(.+)$/);
295
+ const behaviorMatch = noteContent.match(/^Session:\s*(.+)$/);
296
296
  if (behaviorMatch) {
297
- notes.push({ type: "B", content: behaviorMatch[1], date: dateStr });
297
+ notes.push({ type: "Session", content: behaviorMatch[1], date: dateStr });
298
298
  }
299
299
  }
300
300
  }
@@ -376,7 +376,7 @@ function gatherData(days: number): SelfModelData {
376
376
  wisdomFrames,
377
377
  graduated,
378
378
  reflections,
379
- behaviorNotes: relNotes.filter((n) => n.type === "B").map((n) => n.content),
379
+ behaviorNotes: relNotes.filter((n) => n.type === "Session").map((n) => n.content),
380
380
  wisdomNotes: relNotes.filter((n) => n.type === "W").map((n) => n.content),
381
381
  selfObservations: reflections.map((r) => r.q1).filter(Boolean),
382
382
  algorithmObservations: reflections.map((r) => r.q2).filter(Boolean),
@@ -1,7 +0,0 @@
1
- # Projects
2
-
3
- <!-- Current projects, their status, and how they relate to each other. -->
4
-
5
- | Project | Status | Priority | Notes |
6
- |---------|--------|----------|-------|
7
- | | | | |