Skip to content

Fix opencode session project path tracking in agentmemory capture plugin#999

Open
LyricsYo wants to merge 2 commits into
rohitg00:mainfrom
LyricsYo:main
Open

Fix opencode session project path tracking in agentmemory capture plugin#999
LyricsYo wants to merge 2 commits into
rohitg00:mainfrom
LyricsYo:main

Conversation

@LyricsYo

@LyricsYo LyricsYo commented Jul 2, 2026

Copy link
Copy Markdown

Problem agentmemory-capture.ts currently uses the plugin-level path:

ctx.worktree || ctx.project?.id || process.cwd()

as the project/cwd for all sessions.

In opencode desktop/server setups, that value can point to the server/worktree path instead of the actual active session directory. After switching projects, new sessions can be incorrectly assigned to the previous project scope, causing the dashboard to show the wrong session path.

Key Fix Track project paths per session:

const sessionProjects = new Map<string, string>();

Update observe() to prefer the current session’s project path instead of the global plugin path:

const project = sessionProjects.get(sessionId) || projectPath;

On session.created, read the real session directory from opencode session metadata:

const sessionProject = process.env.AGENTMEMORY_PROJECT
  || info.directory
  || projectPath
  || process.cwd();

Use that value when starting the agentmemory session:

project: sessionProject,
cwd: sessionProject,

Also keep the session project path in sync from session.updated, assistant message path.cwd, and shell.env to avoid path drift during the session.

Summary by CodeRabbit

  • New Features

    • Session activity now tracks a session-specific workspace path, improving accuracy for /observe, session start details, and system context injection.
    • Added environment-based workspace override and improved detection of the current working directory for new sessions.
  • Bug Fixes

    • Session workspace updates now respond to changes from session updates, assistant message updates, and shell environment changes.
    • Invalid or redundant workspace updates are ignored, and session tracking data is cleaned up when sessions end.

@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e16fec95-862a-43b7-8c9a-098c4c782b12

📥 Commits

Reviewing files that changed from the base of the PR and between 69b533f and 3923abb.

📒 Files selected for processing (1)
  • plugin/opencode/agentmemory-capture.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugin/opencode/agentmemory-capture.ts

📝 Walkthrough

Walkthrough

Adds per-session project and cwd tracking in the OpenCode plugin. Session events, shell environment updates, observe requests, and context injection now use session-specific values instead of a single global project path.

Changes

Per-session project tracking

Layer / File(s) Summary
sessionProjects map and update/cleanup helper
plugin/opencode/agentmemory-capture.ts
Adds the sessionProjects Map and updateSessionProject() helper, and removes stored entries during session cleanup.
projectPath initialization override
plugin/opencode/agentmemory-capture.ts
Changes initial projectPath derivation to consider ctx.directory and AGENTMEMORY_PROJECT.
Session lifecycle updates to sessionProjects
plugin/opencode/agentmemory-capture.ts
session.created stores a session-specific project value for /session/start; session.updated, message.updated, and shell.env keep sessionProjects aligned with incoming cwd values.
observe() reads per-session project
plugin/opencode/agentmemory-capture.ts
observe() and both /context call sites now resolve project from sessionProjects with projectPath as fallback.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: fixing per-session project path tracking in the opencode agentmemory capture plugin.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
plugin/opencode/agentmemory-capture.ts (2)

638-644: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

/context calls still use the stale global projectPath, bypassing per-session tracking.

chat.system.transform and experimental.session.compacting both call postJson("/context", { sessionId: sid, project: projectPath }), not the per-session value from sessionProjects. Since observe() and /session/start were updated to use sessionProjects.get(sid) || projectPath (Line 50), these two remaining call sites can still fetch context for the wrong project when multiple sessions from different projects are active in the same plugin instance — the exact class of bug this PR targets.

🐛 Proposed fix
-          const result = await postJson("/context", {
-            sessionId: sid,
-            project: projectPath,
-          });
+          const result = await postJson("/context", {
+            sessionId: sid,
+            project: sessionProjects.get(sid) || projectPath,
+          });

Apply the same change at Line 680.

Also applies to: 678-681

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugin/opencode/agentmemory-capture.ts` around lines 638 - 644, The remaining
/context calls in chat.system.transform and experimental.session.compacting
still pass the global projectPath instead of the per-session project. Update
those postJson("/context", { sessionId: sid, project: ... }) calls to use the
same session-scoped lookup already used in observe() and /session/start, namely
sessionProjects.get(sid) || projectPath, so each sid resolves context against
the correct project.

94-104: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

sessionProjects needs cleanup on session.deleted
pruneSessionMaps() is defined but never called in this file, and the deletion handler only clears the other session maps. Add sessionProjects.delete(sid) there, or call pruneSessionMaps(sid) and remove the duplicated deletes, so dead sessions don't keep accumulating state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugin/opencode/agentmemory-capture.ts` around lines 94 - 104, The session
cleanup path is leaving stale entries behind in sessionProjects. Update the
session.deleted handling to either call pruneSessionMaps(sid) or explicitly add
sessionProjects.delete(sid) alongside the other map clears, and remove any
duplicated deletions if you switch to the helper. Use the existing
pruneSessionMaps and updateSessionProject symbols in agentmemory-capture.ts to
keep dead sessions from retaining state.
🧹 Nitpick comments (1)
plugin/opencode/agentmemory-capture.ts (1)

193-259: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated AGENTMEMORY_PROJECT/session-project update logic across three call sites.

The AGENTMEMORY_PROJECT || <derived value> pattern is repeated at session.created, session.updated, and assistant message.updated instead of routing through a shared helper. Consider extending updateSessionProject() (once it also honors AGENTMEMORY_PROJECT, per the prior comment) and calling it from all these sites to keep the precedence rule in one place.

Also applies to: 320-323

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugin/opencode/agentmemory-capture.ts` around lines 193 - 259, The session
project selection logic is duplicated across session.created, session.updated,
and assistant message.updated. Move the AGENTMEMORY_PROJECT-or-derived-path
precedence into the shared updateSessionProject() helper and call that helper
from each of these event handlers so the rule lives in one place and stays
consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugin/opencode/agentmemory-capture.ts`:
- Around line 208-212: The session title fallback in the agent memory capture
flow is using a raw filesystem path, which can expose local details in the
dashboard. Update the title assignment in agentmemory-capture’s session payload
so it does not default to sessionProject; instead, keep a human-readable
placeholder or null when info?.title is absent, while leaving the rest of the
captured fields unchanged.
- Around line 101-105: updateSessionProject() is bypassing the
AGENTMEMORY_PROJECT override and can overwrite the chosen project with
shell.cwd. Update updateSessionProject() in agentmemory-capture.ts to resolve
the project path the same way session.created, session.updated, and
message.updated do: prefer process.env.AGENTMEMORY_PROJECT when present,
otherwise fall back to cwd. Keep the existing guards and sessionProjects.set
logic, and make sure the shell.env handler path uses this consistent precedence.
- Around line 180-181: The fallback chain in agentmemory-capture.ts is broken
because currentDirectory always resolves to a truthy value, making
ctx.project?.id and ctx.worktree unreachable in the projectPath assignment.
Update the precedence logic in the agentmemory capture flow so the order is
truly directory → project id → worktree → cwd, and avoid pre-falling back
currentDirectory to process.cwd() before the full chain is evaluated.

---

Outside diff comments:
In `@plugin/opencode/agentmemory-capture.ts`:
- Around line 638-644: The remaining /context calls in chat.system.transform and
experimental.session.compacting still pass the global projectPath instead of the
per-session project. Update those postJson("/context", { sessionId: sid,
project: ... }) calls to use the same session-scoped lookup already used in
observe() and /session/start, namely sessionProjects.get(sid) || projectPath, so
each sid resolves context against the correct project.
- Around line 94-104: The session cleanup path is leaving stale entries behind
in sessionProjects. Update the session.deleted handling to either call
pruneSessionMaps(sid) or explicitly add sessionProjects.delete(sid) alongside
the other map clears, and remove any duplicated deletions if you switch to the
helper. Use the existing pruneSessionMaps and updateSessionProject symbols in
agentmemory-capture.ts to keep dead sessions from retaining state.

---

Nitpick comments:
In `@plugin/opencode/agentmemory-capture.ts`:
- Around line 193-259: The session project selection logic is duplicated across
session.created, session.updated, and assistant message.updated. Move the
AGENTMEMORY_PROJECT-or-derived-path precedence into the shared
updateSessionProject() helper and call that helper from each of these event
handlers so the rule lives in one place and stays consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e31d0610-7a26-41a0-b452-c6a6b2af3bd5

📥 Commits

Reviewing files that changed from the base of the PR and between 93ae9bc and 69b533f.

📒 Files selected for processing (1)
  • plugin/opencode/agentmemory-capture.ts

Comment on lines +101 to 105
async function updateSessionProject(sessionId: string, cwd: unknown): Promise<void> {
if (typeof cwd !== "string" || cwd.length === 0) return;
if (sessionProjects.get(sessionId) === cwd) return;
sessionProjects.set(sessionId, cwd);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

updateSessionProject() ignores AGENTMEMORY_PROJECT, unlike every other update site.

session.created (193-197), session.updated (257-259), and assistant message.updated (320-323) all prefer process.env.AGENTMEMORY_PROJECT before the discovered path. updateSessionProject() — the only function invoked by the new shell.env handler (Lines 604-608) — writes cwd unconditionally, so a shell command's directory can silently clobber a user's explicit AGENTMEMORY_PROJECT override. This reintroduces the "wrong project directory picked up" failure mode this PR is fixing.

🐛 Proposed fix
 async function updateSessionProject(sessionId: string, cwd: unknown): Promise<void> {
   if (typeof cwd !== "string" || cwd.length === 0) return;
-  if (sessionProjects.get(sessionId) === cwd) return;
-  sessionProjects.set(sessionId, cwd);
+  const resolved = process.env.AGENTMEMORY_PROJECT || cwd;
+  if (sessionProjects.get(sessionId) === resolved) return;
+  sessionProjects.set(sessionId, resolved);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function updateSessionProject(sessionId: string, cwd: unknown): Promise<void> {
if (typeof cwd !== "string" || cwd.length === 0) return;
if (sessionProjects.get(sessionId) === cwd) return;
sessionProjects.set(sessionId, cwd);
}
async function updateSessionProject(sessionId: string, cwd: unknown): Promise<void> {
if (typeof cwd !== "string" || cwd.length === 0) return;
const resolved = process.env.AGENTMEMORY_PROJECT || cwd;
if (sessionProjects.get(sessionId) === resolved) return;
sessionProjects.set(sessionId, resolved);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugin/opencode/agentmemory-capture.ts` around lines 101 - 105,
updateSessionProject() is bypassing the AGENTMEMORY_PROJECT override and can
overwrite the chosen project with shell.cwd. Update updateSessionProject() in
agentmemory-capture.ts to resolve the project path the same way session.created,
session.updated, and message.updated do: prefer process.env.AGENTMEMORY_PROJECT
when present, otherwise fall back to cwd. Keep the existing guards and
sessionProjects.set logic, and make sure the shell.env handler path uses this
consistent precedence.

Comment on lines +180 to +181
const currentDirectory = (ctx as any).directory || process.cwd();
projectPath = process.env.AGENTMEMORY_PROJECT || currentDirectory || ctx.project?.id || ctx.worktree || process.cwd();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Broken fallback precedence — ctx.project?.id/ctx.worktree become unreachable dead code.

currentDirectory already falls back to process.cwd() when ctx.directory is absent, so it's always truthy. That means in line 181, ctx.project?.id || ctx.worktree can never be evaluated — the intended precedence order (directory → project id → worktree → cwd) is silently broken.

🐛 Proposed fix
-  const currentDirectory = (ctx as any).directory || process.cwd();
-  projectPath = process.env.AGENTMEMORY_PROJECT || currentDirectory || ctx.project?.id || ctx.worktree || process.cwd();
+  projectPath = process.env.AGENTMEMORY_PROJECT || (ctx as any).directory || ctx.project?.id || ctx.worktree || process.cwd();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const currentDirectory = (ctx as any).directory || process.cwd();
projectPath = process.env.AGENTMEMORY_PROJECT || currentDirectory || ctx.project?.id || ctx.worktree || process.cwd();
projectPath = process.env.AGENTMEMORY_PROJECT || (ctx as any).directory || ctx.project?.id || ctx.worktree || process.cwd();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugin/opencode/agentmemory-capture.ts` around lines 180 - 181, The fallback
chain in agentmemory-capture.ts is broken because currentDirectory always
resolves to a truthy value, making ctx.project?.id and ctx.worktree unreachable
in the projectPath assignment. Update the precedence logic in the agentmemory
capture flow so the order is truly directory → project id → worktree → cwd, and
avoid pre-falling back currentDirectory to process.cwd() before the full chain
is evaluated.

Comment on lines +208 to +212
title: info?.title ?? sessionProject,
parentID: info?.parentID ?? null,
version: info?.version ?? null,
project: projectPath,
cwd: projectPath,
project: sessionProject,
cwd: sessionProject,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Session title now defaults to a raw filesystem path.

title: info?.title ?? sessionProject means, absent a real title, the dashboard will display an absolute local path (potentially containing a username, e.g. /Users/jdoe/...) as the session title instead of a human-readable placeholder or null.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugin/opencode/agentmemory-capture.ts` around lines 208 - 212, The session
title fallback in the agent memory capture flow is using a raw filesystem path,
which can expose local details in the dashboard. Update the title assignment in
agentmemory-capture’s session payload so it does not default to sessionProject;
instead, keep a human-readable placeholder or null when info?.title is absent,
while leaving the rest of the captured fields unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant