Install
$ agentstack add skill-lunchpaillola-pipa-skills-pipa-time-tracking ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README — it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming — see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps — measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Pipa Time Tracking
User time-tracking req -> Pipa creds -> generic time_tracking/time_entry utility records.
CRITICAL: Use only Toggl-style time entries via generic Pipa agent utility records API. Do not use Clockify, Toggl, screenshots, payroll, invoicing, productivity scoring, passive activity reconstruction, or /v1/time-tracking/* wrapper endpoints.
Keep short todo list: mode, creds, missing question, payload validation, API call, final response.
Workflow
- Pick mode. Choose exactly one.
- Start timer: "start tracking this", "start timer for Acme", "track time on frontend fixes" -> start.
- Switch work: "switch to Acme QA" -> switch.
- Stop current timer -> stop.
- Ask what is running -> current.
- Log past time: "log 45 minutes from 9 to 9:45" -> backfill.
- Show entries / summarize time -> review.
- Update/delete/cancel/archive entry -> update/archive.
- Buy credits/top up, check credit balance, or mutating req fails with
insufficient_credits-> top-up. - Payroll, invoicing, screenshots, passive reconstruction, external tracker sync, recurring timers, auto idle detection -> explain V1 unsupported, stop.
If conversation already has successful API response and user asks about that result, answer from known response. Do not call unsupported reporting endpoints.
- Load creds. Required before API calls:
PIPA_API_BASE_URLPIPA_API_KEYPIPA_EMAILPIPA_USER_TIMEZONE
Aliases:
PIPA_FOLLOW_UP_API_KEY->PIPA_API_KEYPIPA_FOLLOW_UP_EMAIL->PIPA_EMAIL- If canonical and alias values both exist in the same source, canonical wins.
Lookup order:
- Gateway-injected values.
- Env vars.
- Repo-local
.pipa/credentials. - User-global
~/.pipa/credentials.
Hidden-path rule:
- Do not trust glob/file-search for
.pipa/credentials; hidden dirs can be skipped/mishandled. - Check explicit paths directly:
/.pipa/credentials, then~/.pipa/credentials. - Shell helper: resolve root from cwd or
git rev-parse --show-toplevel; readPath(root) / ".pipa" / "credentials". No files foundfrom glob for.pipa/credentialsis inconclusive. Direct-read before asking user for creds.
Creds file = dotenv, not JSON:
``text PIPA_API_BASE_URL=https://pailflow-chat-gateway.fly.dev PIPA_API_KEY= PIPA_EMAIL= PIPA_USER_TIMEZONE= ``
Legacy shape:
``text PIPA_API_BASE_URL=https://pailflow-chat-gateway.fly.dev PIPA_FOLLOW_UP_API_KEY= PIPA_FOLLOW_UP_EMAIL= PIPA_USER_TIMEZONE= ``
Keep API keys out of chat/logs/markdown/shell history/process args when possible. Shell helper reads creds inside script; prints only non-secret results.
If PIPA_API_BASE_URL and API key exist, continue to selected mode. If mode needs local-day interpretation and timezone missing, step 3.
- Set up missing creds only when needed. Fill smallest missing piece.
- Missing
PIPA_USER_TIMEZONE+ local dates/vague times -> ask exactly:What timezone should I use?Stop. - Missing
PIPA_API_BASE_URL-> defaulthttps://pailflow-chat-gateway.fly.devunless user named another gateway. - Missing
PIPA_API_KEYandPIPA_FOLLOW_UP_API_KEY-> ask for user's email.
Email-code setup:
- Explain email-code verification creates/replaces Pipa agent utilities key. Mention key replacement revokes prior keys only if user may already have one.
POST /v1/key/email-code/startwith productagent-utilities.- Ask for one-time email code.
POST /v1/key/email-code/verifywith challenge id, code, productagent-utilities.- Store returned key unless env ephemeral, user opted out, or write fails.
- Prefer repo-local
.pipa/credentialsfor repo-local skills;~/.pipa/credentialsfor global skills. - Before repo-local write, ensure
.pipa/gitignored. Use file mode600. - Tell user storage path. Never print key unless explicitly asked.
- Reload creds, continue selected mode.
- API contract. Use only:
GET /v1/agent-utility-recordsPOST /v1/agent-utility-recordsGET /v1/agent-utility-records/:idPATCH /v1/agent-utility-records/:idDELETE /v1/agent-utility-records/:idPOST /v1/key/email-code/startPOST /v1/key/email-code/verifyPOST /v1/topups/checkout-sessions
Credit balance:
- Do not invent a balance endpoint. Current credit balance is only known when an allowed API response includes
credits_remaining. - If the user asks for balance and the latest allowed response lacks
credits_remaining, say the skill cannot query current balance directly. - If
insufficient_creditsincludestopup_limits, use those limits in the next action. - Treat checkout URLs as user-action payment links. Do not persist them or raw-print long checkout URLs unless explicitly asked.
List query params used by this skill:
utility_typerecord_typestatusstarted_at_gtestarted_at_lt
Do not use other list filters unless the API response or docs expose them. If archived filtering is unavailable, exclude archived records after fetch.
Auth header:
``text Authorization: Bearer ${PIPA_API_KEY} ``
Time entry record:
``json { "utility_type": "time_tracking", "record_type": "time_entry", "status": "running", "title": "Work description", "started_at": "2026-06-30T13:00:00.000Z", "project_label": "optional project", "client_label": "optional client", "flex_label": "optional tag/task/phase", "rate_amount": 150, "rate_currency": "USD", "metadata": { "notes": "optional extras" } } ``
Rules:
runningrequiresstarted_at, omitsended_at.completedrequiresstarted_atandended_at.ended_atmust be >=started_at.- Only one unarchived running
time_tracking/time_entryper user. - Deletes archive. Do not claim hard-delete.
- Store exact timestamps. Round duration only in user-facing response.
- Start mode.
- Title from req. If only "start timer", use
Untitled work. - Parse obvious labels only: project, client, task/tag/phase. Do not invent labels.
GET /v1/agent-utility-records?utility_type=time_tracking&record_type=time_entry&status=running.- If running timer exists, report id/title/start. Ask exactly:
Do you want me to switch from that timer to [new title]?Stop. - If none running, create
runningrecord with current UTC ISOstarted_at. - Fresh
Idempotency-Keyfor create. - Success -> step 14 start template.
Create payload:
``json { "utility_type": "time_tracking", "record_type": "time_entry", "status": "running", "title": "Acme frontend fixes", "started_at": "2026-06-30T13:00:00.000Z", "project_label": "Acme", "client_label": "Acme Co", "flex_label": "frontend" } ``
- Switch mode.
- Fetch running timer per step 5.
- If none, create new running timer via start mode. Mention no prior timer stopped.
- If running, patch to
status=completed,ended_at=now. - After stop succeeds, create new running timer with a fresh
Idempotency-Key. - If stop succeeds but create fails, say exactly that and report no new timer running.
- Return stopped duration + new running record id.
- Stop mode.
- Fetch running timer per step 5.
- If none, say no timer currently running, stop.
- Patch running record:
status=completed,ended_at=now. - Confirm id, title, start, end, duration, labels.
Patch payload:
``json { "status": "completed", "ended_at": "2026-06-30T14:15:00.000Z" } ``
- Current mode.
- Fetch running timer per step 5.
- If none, say no timer currently running.
- If one, report id, title, start, elapsed duration, labels.
- Do not create/stop/mutate.
- Backfill mode.
- Resolve date/time range with
PIPA_USER_TIMEZONE. - Ambiguous date/time/duration/timezone -> ask one direct clarification, stop.
- Convert
started_at/ended_atto UTC ISO. - Create
completedrecord. - Return created entry confirmation.
If user says "log 45 minutes from 9:00" and timezone/date known, compute end immediately. No extra confirmation.
- Review mode.
- Resolve range to concrete
started_at_gteandstarted_at_ltUTC ISO. For "today", usePIPA_USER_TIMEZONE. GET /v1/agent-utility-recordswithutility_type=time_tracking,record_type=time_entry, range filters.- Exclude archived unless user asks archived/cancelled.
- Group/total records in response. Do not call/invent reporting endpoint.
- Include running entries separately; duration changes.
- Update/archive mode.
- Resolve record id from req, context, or short candidate list.
- Ambiguous ref -> ask one direct question, stop.
PATCH /v1/agent-utility-records/:idfor title, timestamps, labels, rate, metadata.DELETE /v1/agent-utility-records/:idonly for explicit delete/cancel/remove/archive.- Archiving running timer -> say cancelled/archived, not completed.
- Top-up mode.
Time Tracking costs 10 Pipa credits for 30 days. No auto-renewal; next mutating use after expiry charges another access pass.
Balance visibility:
- The skill cannot query current credit balance unless an allowed response includes
credits_remaining. - If the user asks how many credits they have and no current response includes
credits_remaining, say so and include the gateway URL being used.
- Use on
insufficient_creditsor buy/top-up ask. - Choose requested integer credit amount.
- No amount -> ask exactly:
How many Pipa credits do you want to buy?Stop. POST /v1/topups/checkout-sessionswith{ "credits": amount }.- Share
checkout_urlas Markdown link, e.g.[Open checkout](...), plus amount. - If checkout unavailable and API only includes
billing_url, share billing fallback. - After payment confirmation, retry original mutating req.
If insufficient_credits or invalid_topup_credits returns limits, use them. Example: 10 credits is below the minimum. Smallest top-up is 100 credits for $10. Want me to create that checkout session?
- API failures. Do smallest next action.
running_timer_exists: Fetch running timer, explain, ask whether to switch.insufficient_credits: Step 12.invalid_api_key: Explain replacement key rotates account key, step 3.started_at_required,completed_entry_requires_ended_at,running_entry_cannot_have_ended_at,ended_at_before_started_at: Fix payload; ask only if requested time ambiguous.agent_utility_record_not_found: Ask for record id, or list recent candidates if user asked about "that entry".invalid_topup_credits: Give smallest valid next action from API response. Example:10 credits is below the minimum. Smallest top-up is 100 credits for $10. Want me to create that checkout session?Do not sharebilling_urlunless checkout unavailable.failed_to_create_agent_utility_record,failed_to_patch_agent_utility_record,failed_to_archive_agent_utility_record: State whether anything changed before failure. Do not pretend timer changed.- Missing API key: Step 3.
Do not restart full workflow unless error requires it.
- Report. Crisp, operational, auditable.
Start template:
```markdown Started the timer.
- Record ID:
[id] - Title:
[title] - Started:
[started_at] - Labels:
[project/client/flex or none]
```
Stop template:
```markdown Stopped the timer.
- Record ID:
[id] - Title:
[title] - Time:
[started_at]to[ended_at] - Duration:
[rounded duration] - Labels:
[project/client/flex or none]
```
Rules:
- Ask only missing/ambiguous required info.
- Ask exactly one direct follow-up question at a time.
- Do not dump API metadata.
- Do not store secrets in skill file.
- Mention credits remaining when API returns it.
- Failures: state whether any record changed before failure.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: lunchpaillola
- Source: lunchpaillola/pipa-skills
- License: MIT
- Homepage: https://usepipa.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.