osborn 0.9.23 → 0.9.25

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/dist/config.js CHANGED
@@ -649,11 +649,30 @@ export async function listAllClaudeSessions(limit = 100) {
649
649
  ]);
650
650
  if (preview.messageCount < 2)
651
651
  continue;
652
+ // SLUG-FIRST for both `cwd` (routing) and `projectPath` (display).
653
+ //
654
+ // The workspace root (the agent's cwd, e.g. `/workspace` on fly) is
655
+ // the base layer. Projects are subdirectories beneath it — a session
656
+ // started in `/workspace/instagram` gets slug `-workspace-instagram`,
657
+ // and slugToPath turns that back into `/workspace/instagram`. The
658
+ // dashboard groups by this path → "instagram" naturally becomes a
659
+ // project card. Sessions started at the workspace root collapse into
660
+ // one "General" / "Workspace" card.
661
+ //
662
+ // Why NOT prefer the content cwd: the JSONL records whatever cwd
663
+ // existed when the session was recorded — for migrated sessions that
664
+ // can be a path that no longer exists on this host (e.g.
665
+ // `/workspaces/codespaces-blank` from someone's Codespace). Using
666
+ // file LOCATION as the source of truth keeps grouping aligned with
667
+ // where the data actually lives and where Claude Code's --resume
668
+ // will look. Content cwd is kept as a last-resort fallback for the
669
+ // rare case where slugToPath reversal fails.
670
+ const slugPath = slugToPath(c.slug);
652
671
  sessions.push({
653
672
  sessionId: c.sessionId,
654
673
  projectSlug: c.slug,
655
- projectPath: cwd || slugToPath(c.slug),
656
- cwd: cwd || slugToPath(c.slug),
674
+ projectPath: slugPath || cwd,
675
+ cwd: slugPath || cwd,
657
676
  timestamp: c.mtime,
658
677
  lastMessage: preview.lastMessage,
659
678
  messageCount: preview.messageCount,
package/dist/index.js CHANGED
@@ -164,6 +164,14 @@ function startApiServer(workingDir, port) {
164
164
  const limit = parseInt(url.searchParams.get('limit') || '100', 10);
165
165
  const sessions = await listAllClaudeSessions(limit);
166
166
  const payload = {
167
+ // The agent's working directory at launch — the BASE LAYER of all
168
+ // project organization. The dashboard groups sessions relative to
169
+ // this path: a session whose cwd === baseCwd is a "Workspace"
170
+ // session (the base); a session at `${baseCwd}/<name>` is a
171
+ // project called "<name>". Replaces the dashboard's previously-
172
+ // hardcoded base-path list — agent self-describes its base so
173
+ // the UI doesn't have to keep a sync'd copy.
174
+ baseCwd: workingDir,
167
175
  sessions: sessions.map(s => ({
168
176
  sessionId: s.sessionId,
169
177
  projectSlug: s.projectSlug,
@@ -3100,6 +3108,11 @@ async function main() {
3100
3108
  const sessions = await listAllClaudeSessions(100);
3101
3109
  await sendToFrontend({
3102
3110
  type: 'sessions_list',
3111
+ // See `/sessions` HTTP handler — baseCwd is the agent's
3112
+ // workingDir, the base layer the dashboard groups against.
3113
+ // Sent here too so the in-chat session list grouping stays
3114
+ // consistent with the dashboard's grouping.
3115
+ baseCwd: workingDir,
3103
3116
  sessions: sessions.map(s => ({
3104
3117
  sessionId: s.sessionId,
3105
3118
  projectSlug: s.projectSlug,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "osborn",
3
- "version": "0.9.23",
3
+ "version": "0.9.25",
4
4
  "description": "Voice AI coding assistant - local agent that connects to Osborn frontend",
5
5
  "type": "module",
6
6
  "bin": {