Skip to content

Add GET /api/v1/plans/:id/snapshot endpoint for agents#95

Merged
HamptonMakes merged 3 commits intomainfrom
add-plan-snapshot-api-endpoint
Apr 21, 2026
Merged

Add GET /api/v1/plans/:id/snapshot endpoint for agents#95
HamptonMakes merged 3 commits intomainfrom
add-plan-snapshot-api-endpoint

Conversation

@HamptonMakes
Copy link
Copy Markdown
Collaborator

Summary

Adds a single "oneshot" API endpoint that returns everything an agent needs to understand and act on a plan in one request, eliminating 3-4 separate API calls.

Endpoint: GET /api/v1/plans/:id/snapshot

Response shape

{
  "id": "...",
  "title": "...",
  "status": "considering",
  "current_content": "# Plan...",
  "current_revision": 3,
  "created_by": "Alice",
  "created_by_user": { "id": "...", "name": "Alice" },
  "tags": ["infra"],
  "comment_threads": [
    {
      "id": "...",
      "status": "pending",
      "anchor_text": "...",
      "anchor_occurrence": 0,
      "created_by": "Bob",
      "created_by_user": { "id": "...", "name": "Bob" },
      "comments": [
        {
          "id": "...",
          "author_type": "human",
          "author_id": "...",
          "body_markdown": "..."
        }
      ]
    }
  ],
  "references": [...],
  "collaborators": [
    { "id": "...", "user": { "id": "...", "name": "Carol" }, "role": "reviewer" }
  ]
}

Design decisions

  • Backward compatible: created_by remains a string everywhere. New created_by_user field added as structured {id, name} object for agents that need to correlate users across sections.
  • Efficient markdown parsing: anchor_occurrence is computed by stripping markdown once for all threads, not N times.
  • N+1 prevention: Comments sorted in memory (sort_by) instead of .order() to leverage eager loading.
  • Nil-safe user_json: Returns nil for missing users instead of crashing.
  • author_id on comments: Agents can now correlate who wrote each comment.
  • No versions array: Current content/revision is included; full version history available via existing GET /api/v1/plans/:id/versions.

Testing

  • 3 new request specs (full response shape, auth required, 404 for missing plan)
  • All 690 existing tests pass

Single endpoint returning everything an agent needs: plan metadata,
current content, comment threads with comments, references, and
collaborators. Eliminates the need for agents to make 3-4 separate
API calls (show + comments + versions + references).

Key design decisions:
- Backward compatible: created_by remains a string, created_by_user
  added as structured {id, name} object across plan and thread JSON
- Efficient: strips markdown once for all threads instead of N times,
  sorts comments in memory to leverage eager loading
- anchor_occurrence included in snapshot threads for precise text targeting
- author_id added to comment JSON for agent user correlation
- user_json helper with nil safety

Amp-Thread-ID: https://ampcode.com/threads/T-019db096-9dc9-7543-ba51-f5baa78005f2
Co-authored-by: Amp <[email protected]>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0c6b4b6e00

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

end

def compute_anchor_occurrence(thread, content, stripped_data)
return nil unless thread.anchored? && content.present? && thread.anchor_start.present?
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Return fallback occurrence for unresolved anchors

For anchored threads that do not have anchor_start populated (e.g., legacy threads created before positional anchoring or records where resolution failed), compute_anchor_occurrence now returns nil immediately, so /snapshot emits anchor_occurrence: null. That regresses the existing fallback behavior in CommentThread#anchor_occurrence_index (which returns first occurrence 0 when position is missing) and can make agent-side anchor targeting non-deterministic for repeated anchor text. Please preserve the 0 fallback for anchored threads without positional data so snapshot consumers always get a usable index.

Useful? React with 👍 / 👎.

HamptonMakes and others added 2 commits April 21, 2026 12:20
- Add 'Get Plan Snapshot (Recommended)' section to API reference
- Update review workflow to use snapshot instead of separate calls
- Update typical workflow to start with snapshot

Amp-Thread-ID: https://ampcode.com/threads/T-019db096-9dc9-7543-ba51-f5baa78005f2
Co-authored-by: Amp <[email protected]>
Match CommentThread#anchor_occurrence_index behavior: return 0
(first occurrence) for anchored threads without positional data,
not nil.

Amp-Thread-ID: https://ampcode.com/threads/T-019db096-9dc9-7543-ba51-f5baa78005f2
Co-authored-by: Amp <[email protected]>
@HamptonMakes
Copy link
Copy Markdown
Collaborator Author

Re: Codex review on compute_anchor_occurrence fallback

Good catch — fixed in b546f06. Anchored threads without anchor_start now return anchor_occurrence: 0 (first occurrence) instead of nil, matching the existing CommentThread#anchor_occurrence_index fallback behavior.

@HamptonMakes HamptonMakes merged commit d1674be into main Apr 21, 2026
5 checks passed
@HamptonMakes HamptonMakes deleted the add-plan-snapshot-api-endpoint branch April 21, 2026 17:32
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