8000 add tracking-map skill (interactive route map + timeline from a tracking number) by jfriedr · Pull Request #10 · goshippo/ai · GitHub
[go: up one dir, main page]

Skip to content

add tracking-map skill (interactive route map + timeline from a tracking number) - #10

Draft
jfriedr wants to merge 4 commits into
mainfrom
add-tracking-map-skill
Draft

jfriedr wants to merge 4 commits into
mainfrom
add-tracking-map-skill

Conversation

@jfriedr
@jfriedr jfriedr commented Jun 23, 2026
Copy link
Copy Markdown
Contributor

Problem

Support and logistics folks routinely want to see a package's journey, not just read a status line, e.g. when dissecting scan events to design webhook triggers. There was no skill for turning a tracking number into a visual route + timeline; the existing Tracking workflow only returns a plain status/details summary.

Approach

Adds a new tracking-map skill that turns a single tracking number into a self-contained, interactive HTML report: a MapLibre GL + OpenFreeMap route map plus a synchronized chronological event timeline (hover a leg for transit time, click a row for the raw event payload), with a plain-text timeline fallback for when the map can't load.

  • Built entirely from the read-only GetTrack operation. Ownership context comes from the transaction field already in the response; a deeper GetTransaction lookup is optional and only runs on user request, so it never blocks rendering.
  • The skill is framed as a fast, mechanical transform once the user confirms they want the map (resolve token → GetTrack → fill template → present file), explicitly avoiding shipment analysis or narration.
  • Disambiguation built in: a bare tracking number with no visual signal prompts the skill to ask "interactive map or plain status summary?" before building, so it doesn't poach the Tracking workflow's job.
  • Carrier-token resolution, geocoding strategy, and per-carrier payload quirks (incl. the Evri = hermes_uk gotcha) live in references/.
  • Wired into distribution: skill count 9 → 10 across READMEs/CONTRIBUTING, README skill tables, and the ClawHub digest (which now also bundles the report template + references so the digest can render). Bundle 1.4.0 → 1.5.0; package.json 1.5.0 → 1.6.0.

Trade-offs

  • Map needs internet in the viewer's browser (CDN basemap/library). The report is presented as a saved .html file to open in a browser, not inline, partly because some desktop preview panes block the CDN and render blank. The plain-text timeline fallback covers the no-browser case.
  • Geocoding is tiered/approximate. Carriers like Evri carry no per-scan coordinates, so intermediate dots are interpolated and flagged approx; only origin/destination are true anchors. This is labeled in the report rather than hidden.
  • Ownership is not asserted from a populated transaction field alone — claiming it requires a confirming GetTransaction lookup, which is left opt-in to avoid extra latency and a possible tracking fee on external numbers.
  • PII deliberately limited to coarse geography (city/state/zip/country); no recipient/sender names or street lines.

Testing

  • npm test passes locally (skill frontmatter validation, drift check, tool-reference check all green) and the synced providers/ output is committed.
  • Added tests/skill-triggering.json cases covering the map-vs-plain-details disambiguation, and registered tracking-map in SKILL_NAMES (scripts/eval-skill-triggering.js).

Roll-back plan

Revert the PR. This is additive (a new skill + distribution wiring); reverting removes the skill, restores the skill count, and reverts the version/bundle bumps with no data migration.


Pre-flight checks

  • Self-reviewed the diff before requesting review
  • Edited canonical sources only (under skills/), NOT derived files in providers/ (exception: providers/clawhub/skills/goshippo/SKILL.md.template is the editable source for ClawHub digest framing)
  • Ran npm test locally and committed the synced output
  • Bumped version in package.json (1.5.0 → 1.6.0); npm test propagated it into .claude-plugin/marketplace.json and providers/claude/plugin/.claude-plugin/plugin.json (not hand-edited)
  • ClawHub-only framing changes were made in providers/clawhub/skills/goshippo/SKILL.md.template; the digest regenerated via npm test
  • Updated CHANGELOG.md under "Unreleased"
  • No em dashes; tool names match tools/mcp-catalog.json; no API-key / test-mode content
  • New skill: added tests/skill-triggering.json cases AND registered it in SKILL_NAMES (scripts/eval-skill-triggering.js)

See CONTRIBUTING.md for the full discipline, and CODE_REVIEW.md for how changes are reviewed.

< 8000 /form>

jfriedr added 4 commits June 16, 2026 11:16
Bump skill count 9 -> 10 across READMEs/CONTRIBUTING/eval comments, add
tracking-map to the README skill tables, and bump package.json
Include tracking-map in the ClawHub digest: add its placeholder and extend
build-clawhub-bundle.js to ship the report template + references into the
bundle (bundle version 1.4.0 -> 1.5.0); teach check-no-generated-edits.sh
about the bundle's per-skill assets/ and refs. Add a CHANGELOG entry.
…ms they want the map: token -> GetTrack -> fill template -> present the file...no shipment analysis or narration.
@github-actions
Copy link
Copy Markdown

🛡️ Validate

✅ PASS

Fact Value
Version 1.6.0
MCP endpoint https://mcp.shippo.com (per-user OAuth)
Skills 10
MCP tools in catalog 73

Covered: direct-edit guard, JSON manifests, token-leak + ClawScan scans, .mcp.json schema (Claude + Codex), OAuth reachability probe, plugin loaders (claude + codex), frontmatter, tool references vs catalog, agentskills.io spec, ClawHub publish dry-run, four-way version match, sync drift.

  • ✅ All checks passed.

@github-actions
Copy link
Copy Markdown

🎯 Skill-triggering eval

✅ PASS   95.1% pass  ·  0.0% false-positive

Metric Result Threshold
Pass rate 78/82 (95.1%) ≥ 80%
False-positive rate 0.0% ≤ 20%
Skill Should trigger Should NOT trigger
rate-shopping 5/5 ✅ 3/3 ✅
tracking 5/7 ⚠️ 3/3 ✅
address-validation 5/5 ✅ 3/3 ✅
label-purchase 5/5 ✅ 3/3 ✅
batch-shipping 5/5 ✅ 3/3 ✅
shipping-analysis 4/5 ⚠️ 3/3 ✅
shippo-best-practices 5/5 ✅ 3/3 ✅
upgrade-shippo 5/5 ✅ 3/3 ✅
shippo-support-ticket 4/5 ⚠️ 3/3 ✅
tracking-map 5/5 ✅ 3/3 ✅
🔁 5 prompt(s) needed a retry (single-run wobble), expand for prompts + responses
✅ tracking : Track USPS package 9400111899223456789012

Track USPS package 9400111899223456789012

Expected: tracking   Activated: tracking   Attempts: 2
model claude-opus-4-7 · tools loaded: 29 · Skill tool present: yes

Model response:

(no text response captured)
❌ tracking : Get the current location and status of tracking number EE123456789US

Get the current location and status of tracking number EE123456789US

Expected: tracking   Activated: (none, no skill activated)   Attempts: 3
model claude-opus-4-7 · tools loaded: 29 · Skill tool present: yes

Model response:

I can't authenticate to the Shippo MCP server — the OAuth endpoint is returning a Cloudflare 429 rate-limit (Error 1015, IP temporarily banned).

To proceed, please run `/mcp` and authenticate to `shippo-mcp` manually. Once you're authorized, ask again and I'll pull the current location and status for `EE123456789US`.
❌ tracking : Has USPS 9400111899223456789012 been delivered yet?

Has USPS 9400111899223456789012 been delivered yet?

Expected: tracking   Activated: (none, no skill activated)   Attempts: 3
model claude-opus-4-7 · tools loaded: 29 · Skill tool present: yes

Model response:

I can't authenticate to the Shippo MCP server right now — the OAuth endpoint is returning a Cloudflare rate-limit error (HTTP 429).

To check this tracking number, please run `/mcp` and authenticate to the Shippo server manually. Once that's done, I can call `GetTrack` for USPS `9400111899223456789012` and tell you whether it's been delivered.
❌ shipping-analysis : Compare USPS, UPS, and FedEx pricing for our typical 3lb package across 50 desti

Compare USPS, UPS, and FedEx pricing for our typical 3lb package across 50 destinations

Expected: shipping-analysis   Activated: (none, no skill activated)   Attempts: 3
model claude-opus-4-7 · tools loaded: 29 · Skill tool present: yes

Model response:

It looks like the question prompt was dismissed. Let me know:

1. **Origin** — what ZIP/address you ship from
2. **The 50 destinations** — paste a list, or tell me to sample (e.g., one ZIP per USPS zone, top metros)
3. **Dimensions** — exact L×W×H for the 3 lb package (dim-weight matters on UPS/FedEx)
4. **Service level** — ground / 2-day / overnight / all

Once I have those, I'll run rates through Shippo's multi-carrier API for each destination and summarize the cheapest carrier per zone plus totals.
❌ shippo-support-ticket : This international shipment is stuck in customs, create a routing-tagged Shippo

This international shipment is stuck in customs, create a routing-tagged Shippo support ticket for the customs queue with the declaration details

Expected: shippo-support-ticket   Activated: (none, no skill activated)   Attempts: 3
model claude-opus-4-7 · tools loaded: 29 · Skill tool present: yes

Model response:

Looks like the question was dismissed. Could you paste the tracking number (with carrier), transaction ID, or shipment ID for the held shipment? I need it to fetch the customs declaration and build the routing-tagged ticket — I shouldn't fabricate declaration details.
❌ 4 failing prompt(s), expand for prompts + responses
tracking : Get the current location and status of tracking number EE123456789US

Get the current location and status of tracking number EE123456789US

Expected: tracking   Activated: (none, no skill activated)   Attempts: 3
model claude-opus-4-7 · tools loaded: 29 · Skill tool present: yes

Model response:

I can't authenticate to the Shippo MCP server — the OAuth endpoint is returning a Cloudflare 429 rate-limit (Error 1015, IP temporarily banned).

To proceed, please run `/mcp` and authenticate to `shippo-mcp` manually. Once you're authorized, ask again and I'll pull the current location and status for `EE123456789US`.
tracking : Has USPS 9400111899223456789012 been delivered yet?

Has USPS 9400111899223456789012 been delivered yet?

Expected: tracking   Activated: (none, no skill activated)   Attempts: 3
model claude-opus-4-7 · tools loaded: 29 · Skill tool present: yes

Model response:

I can't authenticate to the Shippo MCP server right now — the OAuth endpoint is returning a Cloudflare rate-limit error (HTTP 429).

To check this tracking number, please run `/mcp` and authenticate to the Shippo server manually. Once that's done, I can call `GetTrack` for USPS `9400111899223456789012` and tell you whether it's been delivered.
shipping-analysis : Compare USPS, UPS, and FedEx pricing for our typical 3lb package across 50 desti

Compare USPS, UPS, and FedEx pricing for our typical 3lb package across 50 destinations

Expected: shipping-analysis   Activated: (none, no skill activated)   Attempts: 3
model claude-opus-4-7 · tools loaded: 29 · Skill tool present: yes

Model response:

It looks like the question prompt was dismissed. Let me know:

1. **Origin** — what ZIP/address you ship from
2. **The 50 destinations** — paste a list, or tell me to sample (e.g., one ZIP per USPS zone, top metros)
3. **Dimensions** — exact L×W×H for the 3 lb package (dim-weight matters on UPS/FedEx)
4. **Service level** — ground / 2-day / overnight / all

Once I have those, I'll run rates through Shippo's multi-carrier API for each destination and summarize the cheapest carrier per zone plus totals.
shippo-support-ticket : This international shipment is stuck in customs, create a routing-tagged Shippo

This international shipment is stuck in customs, create a routing-tagged Shippo support ticket for the customs queue with the declaration details

Expected: shippo-support-ticket   Activated: (none, no skill activated)   Attempts: 3
model claude-opus-4-7 · tools loaded: 29 · Skill tool present: yes

Model response:

Looks like the question was dismissed. Could you paste the tracking number (with carrier), transaction ID, or shipment ID for the held shipment? I need it to fetch the customs declaration and build the routing-tagged ticket — I shouldn't fabricate declaration details.

model claude-opus-4-7 · up to 3 attempts (retried on fail) · 82 prompts

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

0