Skip to content

feat(harness): restore project navigation [Agent Map 03/15] - #822

Merged
ynadge merged 1 commit into
mainfrom
review/agent-map-03-map-navigation
Sep 6, 2026
Merged

feat(harness): restore project navigation [Agent Map 03/15]#822
ynadge merged 1 commit into
mainfrom
review/agent-map-03-map-navigation

Conversation

@ynadge

@ynadge ynadge commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Primary change type

  • Feature

Problem and motivation

Opening the project map also controlled a privileged planning conversation, coupling what the user inspected to the CLI they were operating.

Summary and scope

Select the durable map from the project name, expose ordinary project-wide session tabs, and preserve independent conversation and Canvas/Steps selection with remembered project destinations.

Make the empty-project Start session action launch a real session. Deleted or foreign map scopes show an unavailable state without offering a retry that cannot succeed.

How this increment fits

Map selection, conversation selection, and Canvas/Steps selection are independent. The initial-input-pending request field preserves startup ordering during the bootstrap transition; native first-task launch arrives in part 15.

Stack and review boundary

  • Part 03 of 15 in the Agent Map review stack; review this increment against its predecessor.
  • Base: review/agent-map-02-project-sessions.
  • Current head: cf2369c481aed15cc2985a01a9df3ddf469d7904; 5,683 changed lines across 34 files, counting additions and deletions including tests.
  • Repackages the corresponding final behavior from #804, #811. Original code and review history remain preserved.
  • Complete coworker testing branch: fix/studio-onboarding-followups.
  • The stack remains unmerged. Dependent PRs target their predecessor, so their diffs do not repeat earlier increments.

Related work

Agent Map checkpoint SAP-3147; relevant work SAP-3148. This packaging follows the maintainer-approved 15-PR split.

Validation

Root checks ran against 154c3e8a5564574eaadc407d9298b52c1d28c404. The final head changes only README terminology or commit ancestry; a complete tracked-file comparison confirms identical executable source and build inputs. The terminology gate was rerun on cf2369c481aed15cc2985a01a9df3ddf469d7904.

pnpm build — passed (exit 0)
pnpm typecheck — passed (exit 0)
pnpm lint — passed (exit 0)
pnpm test — passed (exit 0)

Tests and documentation

Regression coverage: Empty and populated projects, map/session switching, unavailable scopes, remembered destinations, sibling selection, and conversation continuity.

See part 15 for integrated browser, native CLI, and Mac journey validation. The checks above were run independently on this PR’s own commit.

Linux tests run with ordinary user filesystem permissions; the sandbox's extra ambient capabilities are dropped. Hosted CI and automated review are separate from these recorded local results.

Compatibility and release impact

  • Compatibility: Project names open maps without implicitly creating a privileged planning session. Ordinary project-wide conversation tabs replace role-specific navigation.
  • Changeset: Included: .changeset/unified-project-agents.md

Security

  • No secrets, credentials, private user data, or unsanitized logs are included.
  • This PR does not publicly disclose a suspected vulnerability.

AI assistance

  • Codex assembled the implementation, addressed reproduced defects, supplied tests and documentation, inspected the diff, and ran the checks above. Reviews are handled by hosted PR automation.

Checklist

  • Read CONTRIBUTING.md; implementation follows the requested 15-PR split.
  • Description reflects this PR's actual predecessor-relative diff.
  • Relevant tests accompany the changed behavior.
  • Root build, typecheck, lint, and test evidence matches the final implementation; any documentation-only update is identified above.
  • Release/documentation treatment is explained above.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Review — PR #822 (Agent Map 03/15)

No confidentiality findings. The changeset, README rewrite, and JSDoc read cleanly for an
anonymous npm consumer; polsia is the repo's existing public example fixture, not a new
name. The minor level and the Breaking for embedders body with its migration note are
the right call for the agentMapIdentity reshape.

Findings

1. Selecting a project with no live sessions is a dead end in the centre pane

packages/harness/web/src/App.tsx:1485,1501,1519,3235

When projectMapSelected and focusTabs is empty: conversationSession is null, so
showMapConversationEmpty is true, which suppresses showComposer (line 1505), and
newTabSource resolves to null, so onNewSession is null. SessionBar then renders
neither SessionTabs (needs sessions.length > 0) nor the standalone session-tab-new
(needs an exited activeSession). The result is the project-session-empty EmptyState with
no CTA and no +. Its body — "Select a session tab to open its conversation" — points at
tabs that are not on screen.

The code this replaces did offer a way forward here (planner-session-ended had a "New
planning session" button). The rail's project-row + still works, so this is a dead end in
the centre pane rather than in the app, but the user is told to click something that does
not exist.

web/e2e/project-map-navigation.spec.ts:99 asserts the empty state's text and does not
assert any affordance, so the gap is uncovered. Either give the EmptyState a "Start a
session in " CTA, or drop !showMapConversationEmpty from showComposer when
focusTabs.length === 0 so the ordinary composer stands in.

2. Live public REST routes lost their documentation without a deprecation

packages/harness/README.md, packages/harness/src/server/agent-map.ts:362,387,416

The README section documenting POST /api/projects/:projectId/planner-sessions,
.../messages, and .../greeting/retry is deleted, but all three routes are still
registered and served. The changeset does not mention them either. A consumer that wired up
the documented project-scoped planner surface now gets silence: no @deprecated, no
changelog line, no statement of when they go away. Either keep a short "deprecated,
replaced by the generic session routes in a later release" paragraph, or say so in the
changeset body.

3. CreateSessionRequest.initialUserInputPending ships as an inert public field

packages/harness/src/shared/types.ts:1092, packages/harness/src/server/rest.ts:89

The field is added to the exported request type, accepted by the strict zod schema, and
forwarded into sessionManager.create — which never reads it (no reference anywhere under
src/ outside the type, the schema, and the test that asserts the forward). This is a
contract commitment in a published minor whose only observable behaviour is "accepted and
discarded". The JSDoc's "Bootstrap consumes this hint when activated" is the closest thing
to a warning, and it is too oblique for a stranger reading the types. Say explicitly that it
is a no-op until the bootstrap coordinator lands, or hold the field until slot 7 — the web
callers that set it (App.tsx:1782, 1864, 1954, 2139, 2495) get nothing from it today.

4. AgentMapEntryState.unavailable is now computed but never read

packages/harness/web/src/lib/use-agent-map-entry.ts:41

The hook still sets unavailable for missing/deleted/foreign projects, and its JSDoc still
claims it exists "so the renderer can present the right recovery copy". App.tsx no longer
reads it — agentMapUnavailable, the agent-map-unavailable EmptyState, and retryAll
were all removed. A project that has been deleted out from under the selection now renders
the generic map-read error with a Retry that can never succeed. Either restore a distinct
rendering for it or delete the field and its comment; keeping both is how the next reader
concludes the recovery path works.

Nit

  • MockApi.studioSession (web/src/lib/api.ts:2211) hand-rolls nearest-scope resolution
    with cwd.length depth, while the code it is mirroring (mostSpecificStudioScope
    resolveProjectRootForPath) now uses pathSegmentDepth and a fail-closed tie rule. Since
    every Studio e2e case runs against this fixture, the two can disagree without any test
    noticing. Call resolveProjectRootForPath from the mock too.

Verdict

Request changes — finding 1 is a user-visible dead end introduced by this PR, and findings 2
and 3 are published-surface hygiene that are cheapest to fix before the tarball goes out.
Nothing here blocks the stack's direction; the identity/navigation split itself is coherent
and well covered by the new project-map-navigation suite.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Review — PR #822, round 2 (delta since 3da297c)

Fixed since last round: #1 (project-start-session CTA on the empty state) and #4
(unavailable is now read — AgentMapPane renders agent-map-project-unavailable with no
dead Retry). The workspaceKey dedup in server/index.ts:2506 is correct: both catalogs are
LocalWorkspaceScopeCatalog, whose key is sha256(canonicalGraphPath(root)), and
canonicalGraphPath realpaths — so symlink aliases genuinely collapse. No confidentiality
findings in the new copy.

New

1. The empty-state body promises affordances that the unavailable path removes

packages/harness/web/src/App.tsx:3234

project-session-empty always reads "Start a session or select a tab to open its
conversation." When the map load fails, the CTA is gated off
(workspace.status === "ready") and there are no tabs, so the centre pane instructs the user
to click two things that are not on screen — the same dead end finding 1 described, now
narrowed to the unavailable/error path. The new
web/e2e/project-map-empty-recovery.spec.ts:33-35 asserts exactly this state
(project-start-session count 0) without asserting any way forward. The map pane's "Select
another project to continue" is the only guidance; make the body match when
workspace.status !== "ready".

Not fixed from round 1

  • update SDKs to use payment protocol data #2/api/projects/:projectId/planner-sessions{,/messages,/greeting/retry} are still
    registered (src/server/agent-map.ts:361,387,416) with their README section deleted, no
    @deprecated, and no changeset line.
  • langchain SDK config cleanup #3CreateSessionRequest.initialUserInputPending is still accepted, forwarded, and
    read by nothing under src/.
  • NitMockApi.studioSession (web/src/lib/api.ts:2226) still ranks scopes by
    cwd.length instead of calling resolveProjectRootForPath.

Nit

  • The changeset's new AgentMapToolEvent.role paragraph addresses consumers who cannot reach
    that type: agent-map-mcp-tools.ts is not re-exported from src/index.ts. Permanent
    CHANGELOG noise; drop it or export the type.

Verdict

Request changes — finding 1 is a smaller residue of round 1's dead end, but findings 2 and 3
are published-surface commitments that are still cheapest to settle before the tarball ships.

@ynadge
ynadge force-pushed the review/agent-map-03-map-navigation branch from 154c3e8 to cf2369c Compare September 5, 2026 12:17
Base automatically changed from review/agent-map-02-project-sessions to main September 6, 2026 22:20
@ynadge
ynadge merged commit 8462081 into main Sep 6, 2026
2 checks passed
@ynadge
ynadge deleted the review/agent-map-03-map-navigation branch September 6, 2026 22:20
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