hippocamp 0.1.0 → 0.1.1

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 CHANGED
@@ -227,6 +227,7 @@ Environment variables are optional for local use:
227
227
 
228
228
  - `HIPPOCAMP_GLOBAL_ROOT`: local Lagoon clone path. Default: `~/.lagoon`
229
229
  - `HIPPOCAMP_PROJECT_ROOT`: project root used to infer the current project slug. Default: current working directory
230
+ - Git worktrees, including Conductor workspaces, resolve to the main repository name so every workspace shares the same project memory.
230
231
  - `MANIFEST_BASE_URL`: OpenAI-compatible base URL used by `hippocamp dream --write`
231
232
  - `MANIFEST_API_KEY`: API key used by `hippocamp dream --write`
232
233
  - `HIPPOCAMP_DREAM_MODEL`: model used by Dream. Default: `auto`
@@ -3,6 +3,7 @@ name: Hippocamp Dream
3
3
  on:
4
4
  schedule:
5
5
  - cron: "17 3 * * *"
6
+ workflow_dispatch:
6
7
 
7
8
  permissions:
8
9
  contents: write
@@ -91,36 +92,36 @@ jobs:
91
92
  git push --force-with-lease origin "$branch"
92
93
 
93
94
  node - "$project" "/tmp/hippocamp-dream-${project}.json" > "/tmp/hippocamp-dream-${project}.md" <<'NODE'
94
- const fs = require("node:fs");
95
- const project = process.argv[2];
96
- const payload = JSON.parse(fs.readFileSync(process.argv[3], "utf8"));
97
- const result = payload.results[0];
98
- const lines = [
99
- `Dream compacted \`${project}\` curated memory.`,
100
- "",
101
- "Before:",
102
- `- wake_up: ${result.wakeUpChars} chars`,
103
- `- current_state.md: ${result.files["current_state.md"]} bytes`,
104
- `- open_threads.md: ${result.files["open_threads.md"]} bytes`,
105
- "",
106
- "Context:",
107
- `- open threads found: ${result.context.openThreads}`,
108
- `- threads with event evidence: ${result.context.threadsWithEvidence}`,
109
- `- event evidence snippets: ${result.context.evidenceItems}`,
110
- `- evidence budget used: ${result.context.evidenceChars}/${result.context.evidenceBudgetChars} chars`,
111
- "",
112
- "After:",
113
- `- wake_up: ${result.afterWakeUpChars} chars`,
114
- `- current_state.md + open_threads.md: ${result.afterBytes} bytes`,
115
- "",
116
- "Policy:",
117
- "- touched only `current_state.md` and `open_threads.md`",
118
- "- used bounded cue-indexed event evidence for thread decisions",
119
- "- did not modify append-only events or cue indexes",
120
- "- moved historical detail out of wake-up context",
121
- ];
122
- console.log(lines.join("\n"));
123
- NODE
95
+ const fs = require("node:fs");
96
+ const project = process.argv[2];
97
+ const payload = JSON.parse(fs.readFileSync(process.argv[3], "utf8"));
98
+ const result = payload.results[0];
99
+ const lines = [
100
+ `Dream compacted \`${project}\` curated memory.`,
101
+ "",
102
+ "Before:",
103
+ `- wake_up: ${result.wakeUpChars} chars`,
104
+ `- current_state.md: ${result.files["current_state.md"]} bytes`,
105
+ `- open_threads.md: ${result.files["open_threads.md"]} bytes`,
106
+ "",
107
+ "Context:",
108
+ `- open threads found: ${result.context.openThreads}`,
109
+ `- threads with event evidence: ${result.context.threadsWithEvidence}`,
110
+ `- event evidence snippets: ${result.context.evidenceItems}`,
111
+ `- evidence budget used: ${result.context.evidenceChars}/${result.context.evidenceBudgetChars} chars`,
112
+ "",
113
+ "After:",
114
+ `- wake_up: ${result.afterWakeUpChars} chars`,
115
+ `- current_state.md + open_threads.md: ${result.afterBytes} bytes`,
116
+ "",
117
+ "Policy:",
118
+ "- touched only `current_state.md` and `open_threads.md`",
119
+ "- used bounded cue-indexed event evidence for thread decisions",
120
+ "- did not modify append-only events or cue indexes",
121
+ "- moved historical detail out of wake-up context",
122
+ ];
123
+ console.log(lines.join("\n"));
124
+ NODE
124
125
 
125
126
  existing="$(gh pr list --head "$branch" --state open --json number --jq '.[0].number // empty')"
126
127
  title="Dream compact ${project} memory"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hippocamp",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "private": false,
5
5
  "description": "Local Git-backed memory for AI agents.",
6
6
  "license": "MIT",
@@ -69,6 +69,36 @@ function findGitRootSync(startPath) {
69
69
  }
70
70
  }
71
71
 
72
+ function findRepositoryRootSync(startPath) {
73
+ const gitRoot = findGitRootSync(startPath);
74
+
75
+ if (!gitRoot) {
76
+ return null;
77
+ }
78
+
79
+ const gitFile = path.join(gitRoot, ".git");
80
+
81
+ if (!fsSync.statSync(gitFile).isFile()) {
82
+ return gitRoot;
83
+ }
84
+
85
+ const match = fsSync.readFileSync(gitFile, "utf8").trim().match(/^gitdir:\s*(.+)$/i);
86
+
87
+ if (!match) {
88
+ return gitRoot;
89
+ }
90
+
91
+ const gitDir = path.resolve(gitRoot, match[1]);
92
+ const commonDirFile = path.join(gitDir, "commondir");
93
+
94
+ if (!fsSync.existsSync(commonDirFile)) {
95
+ return gitRoot;
96
+ }
97
+
98
+ const commonDir = path.resolve(gitDir, fsSync.readFileSync(commonDirFile, "utf8").trim());
99
+ return path.basename(commonDir) === ".git" ? path.dirname(commonDir) : gitRoot;
100
+ }
101
+
72
102
  function slugifyProjectName(value) {
73
103
  const slug = value
74
104
  .toLowerCase()
@@ -80,8 +110,8 @@ function slugifyProjectName(value) {
80
110
 
81
111
  function getProjectSlug(projectRoot) {
82
112
  const resolvedProjectRoot = getProjectRoot(projectRoot);
83
- const gitRoot = findGitRootSync(resolvedProjectRoot);
84
- return slugifyProjectName(path.basename(gitRoot || resolvedProjectRoot));
113
+ const repositoryRoot = findRepositoryRootSync(resolvedProjectRoot);
114
+ return slugifyProjectName(path.basename(repositoryRoot || resolvedProjectRoot));
85
115
  }
86
116
 
87
117
  function getScopeRoot(scope, projectRoot) {