Skip to content

feat: add event receipt retrieval skill - #152

Open
shrey150 wants to merge 7 commits into
mainfrom
shrey/gro-2198-fetch-event-receipts
Open

feat: add event receipt retrieval skill#152
shrey150 wants to merge 7 commits into
mainfrom
shrey/gro-2198-fetch-event-receipts

Conversation

@shrey150

@shrey150 shrey150 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a deterministic fetch-event-receipts runner for the DoorDash-to-Ramp demo
  • accept conversational date and approximate-amount prompts through a thin skill entrypoint
  • keep the authenticated Browserbase session, DoorDash PDF print, optional Ramp upload, and cleanup in one foreground process
  • emit five concise milestones plus clickable Ramp and Browserbase session links
  • use a private operator-owned registry for demo targets without publishing live identifiers

Why

A freeform command-by-command run made the host agent responsible for shell state, CLI response parsing, retries, and narration. The deterministic runner keeps those mechanics in one process, while the skill stays small and the visible demo remains easy to follow.

E2E Test Matrix

Command / flow Observed output Confidence / sufficiency
node scripts/validate-skills.mjs --skill fetch-event-receipts 1 skill(s) checked: 1 passed, 0 failed, 0 error(s), 0 warning(s) Proves the skill metadata, eval schema, license, and referenced files satisfy the repository validator.
bash -n <demo runner> && shellcheck <demo runner> Both checks passed with no diagnostics. Proves shell syntax and static correctness; it does not call live services.
node --check <live-view helper> && node --check <print helper> Both helpers parsed successfully. Proves JavaScript syntax; it does not exercise the live services.
Local viewer smoke: launch with a private empty session-ID file, wait for readiness, call /health, then stop the owned process /health returned { "ok": true }; the viewer stopped cleanly. Proves the branded loopback viewer starts and stops independently.
Recorded Browserbase context → exact DoorDash order → CDP print-to-PDF The saved context authenticated, the configured completed order opened, and print-to-PDF produced a private PDF below the upload limit. Proves the real authenticated retrieval and PDF path against a demo account.
Ramp production receipt upload with the printed PDF Ramp returned data[0].attached_to_transaction: true with a receipt UUID, and the Ramp UI rendered the receipt under the agent identity. Proves the real write path and the nested response shape used by the runner. Live identifiers are intentionally omitted.

Live validation boundary

The live run covers one configured demo target. The private target registry and credentials are operator-owned local configuration and are not part of this public diff.


Note

Medium Risk
Touches production Ramp receipt writes and authenticated Browserbase sessions, but scope is demo-only with transaction verification, duplicate guards, and isolated agent config rather than general automation.

Overview
Adds a new fetch-event-receipts skill that runs a single deterministic demo: match a configured DoorDash order to a Ramp card transaction, pull the receipt PDF from an authenticated Browserbase session, and optionally attach it via a standalone Ramp agent identity.

The agent entrypoint is intentionally thin: it normalizes conversational date/amount hints and invokes scripts/run-demo.sh once (with --attach only on explicit request), relaying five milestones instead of improvising browse/ramp CLI steps. The runner resolves targets from a private local registry, verifies the Ramp transaction before any browser work, blocks duplicate receipt uploads, spins up a token-gated loopback live viewer (debugger URLs stay server-side), uses the shared catering-agent context for DoorDash navigation, prints the order page to PDF via CDP/Stagehand, and cleans up sessions on exit.

Also ships setup references for Browserbase context and Ramp agent provisioning, eval assertions for runner behavior, branded viewer assets, and a README skills-table row.

Reviewed by Cursor Bugbot for commit 864b270. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread skills/fetch-event-receipts/SKILL.md Outdated
Comment thread skills/fetch-event-receipts/SKILL.md Outdated
Comment thread skills/fetch-event-receipts/references/doordash.md Outdated
Comment thread skills/fetch-event-receipts/references/doordash.md Outdated
Comment thread skills/fetch-event-receipts/references/doordash.md Outdated
Comment thread skills/fetch-event-receipts/references/doordash.md Outdated
{ media: "screen" },
).catch(() => {});
}
await stagehandContext?.close().catch(() => {});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Print helper closes remote session

High Severity

The print helper always calls stagehandContext.close() in finally. That context is the live Browserbase session the browse CLI still owns, so a successful print or a failed target check closes the DoorDash tab, blanks the live viewer, and can prevent --persist from saving login state.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6744702. Configure here.

Comment thread skills/fetch-event-receipts/SKILL.md Outdated
--file_content_base64 "$receipt_base64" \
--transaction_uuid "$transaction_uuid" \
--rationale 'Attach the matched DoorDash receipt to the verified Ramp transaction.' \
| sed -n '/^[[:space:]]*{/,$p')"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Upload drops size and dry-run guards

High Severity

The runbook now base64-encodes the full-page PDF and passes it straight to ramp receipts upload as --file_content_base64. That drops the deleted helper's MIME/size/ARG_MAX checks, redaction, and default --dry_run, so typical printToPDF output hits argument list too long, writes without a dry run, and leaks receipt bytes in process listings.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6744702. Configure here.

Comment thread skills/fetch-event-receipts/SKILL.md Outdated
browse stop --session "$driver_session"
browse cloud sessions update "$browserbase_session_id" --status REQUEST_RELEASE
: >"$session_id_file"
kill "$viewer_pid"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cleanup skips persist completion wait

High Severity

Cleanup issues REQUEST_RELEASE and immediately clears the session file and viewer. It never polls for COMPLETED, which is the only state that proves the remote session released and the --persist catering-agent context finished saving.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6744702. Configure here.

Comment thread skills/fetch-event-receipts/SKILL.md Outdated

```bash
driver_status="$(browse status --session "$driver_session")"
target_id="$(jq -er '.selectedTargetId' <<<"$driver_status")"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Status JSON is not banner-stripped

Medium Severity

browse status is piped straight into jq for selectedTargetId, unlike session create and Ramp calls that strip CLI banners with sed. An update notice before the JSON object makes target lookup fail and skips PDF generation.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6744702. Configure here.

Comment thread skills/fetch-event-receipts/SKILL.md Outdated

Do not display either private value. If this branch is unavailable, search
cleared Ramp transactions for `DOORDASH` on the normalized date and keep only
amounts inside the stated range. Never choose the closest candidate.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fallback never sets the order URL

Medium Severity

When the private demo registry is missing, the runbook says to search Ramp and use the DoorDash Orders UI, but later still runs browse open "$doordash_order_url". That variable is only assigned in the registry branch, so the non-demo path opens an empty URL.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6744702. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

There are 7 total unresolved issues (including 5 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 864b270. Configure here.

session_json="$(last_json <<<"$session_raw")"
browserbase_session_id="$(jq -er '.id' <<<"$session_json")"
connect_url="$(jq -er '.connectUrl | select(test("^wss?://"))' <<<"$session_json")"
printf '%s\n' "$browserbase_session_id" >"$session_id_file"; chmod 600 "$session_id_file"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Runner skips shared context lock

Medium Severity

The new runner creates a --persist catering-agent session without taking the atomic lock that setup treats as required for normal skill runs. Because the skill now forbids reconstructing the workflow, nothing serializes a fetch against context setup or a second run, so overlapping persist sessions can clobber the shared DoorDash login.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 864b270. Configure here.

((exit_code == 0)) || printf 'Stopped at %s. No automatic retry was attempted.\n' "$stage" >&2
exit "$exit_code"
}
trap cleanup EXIT ERR INT TERM

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Interrupt cleanup reports success

Medium Severity

The INT and TERM trap reuse $? from the last command, which is often 0 when the process is signaled. Cleanup then exits successfully and skips the stopped-stage message, so an interrupted run can look complete even though no final result was emitted.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 864b270. Configure here.

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