Skip to content

t1k:performance

FieldValue
Modulet1k-plane
Version1.2.1
Effortlow
Tools—

Keywords: assigned hours, capacity, est hours, estimate hours, gio est, monthly hours, over capacity, performance, plane workload, thang nay lam duoc bao nhieu, utilization, workload

/t1k:performance
[--me|--user <name>] [--month YYYY-MM] [--json] [--include-cancelled]

t1k:performance — assigned estimate hours vs monthly capacity

Section titled “t1k:performance — assigned estimate hours vs monthly capacity”

Answers one question: how many estimated hours is this person carrying this month, against how many hours the month actually has? Renders as 337/168h : 200.60% — hours / capacity, then load as a percentage to two decimals.

The numerator is assigned estimate hours; the denominator is that month’s working capacity, which changes month to month (Feb 2026 = 160h, Aug 2026 = 168h, Dec 2026 = 184h). Both come from Plane, summed over every workspace the credentials reach.

Terminal window
node "$HOME/.claude/scripts/t1k-performance.cjs" # you, this month
node "$HOME/.claude/scripts/t1k-performance.cjs" --month 2026-07 # you, another month
node "$HOME/.claude/scripts/t1k-performance.cjs" --user <name> # a colleague

With no name, it reports you — identity is resolved from the configured Plane API key via /users/me/, whose id is the same UUID that appears as assignee_id on every workload row. Self mode therefore matches on that UUID, not on a display name: it survives a rename and cannot resolve to a colleague who shares a display name. Nothing needs configuring, and no person’s name is ever written into a file.

To look someone else up, name them: --user <name>, or the name as the flag (--hailh), or a bare positional. A named lookup matches on display name, which is all the caller supplied.

FlagEffect
--meYou — the API key’s owner, matched by UUID. This is the default
--user, -uLook up a colleague by display name (or pass the name as the flag)
--month, -mYYYY-MM, month validated 01–12. Default: current month
--workspace, -wComma-separated slugs. Default: every reachable workspace
--jsonFull machine-readable report
--briefJust 337/168h : 200.60% — what the status line consumes
--include-cancelledCount cancelled work too (off by default — see rule 3)
--cache-only, --max-ageRead the cache without network I/O

Exit codes: 0 ok · 1 every workspace failed (an outage, never reported as a zero) · 2 bad arguments · 3 --cache-only with no cache.

These are fixed in the script, not options. Each exists because the naive alternative produces a wrong number.

  1. Estimate hours only. Items with no estimate contribute 0. They are not silently dropped — the report carries a workspace-wide unestimated count so a low total is never mistaken for a light month.
  2. Assigned to the named person. Unassigned work is never attributed to anyone. An item assigned to two people contributes its per-assignee share, which is how Plane already splits it.
  3. State-agnostic — assignment is the trigger, not completion. Backlog, Todo, In Progress and Done all count. Cancelled is excluded by default, and that is deliberate: cancelling is the only mechanism available for removing a duplicate or dropped item from the ledger, so counting cancelled work would defeat the correction. --include-cancelled overrides it when you genuinely want the gross figure.
  4. Scheduled inside the month, by target_date alone. Plane buckets an item on its target_date, not on whether it has any date at all — an item with a start_date but no target_date still lands in Plane’s unscheduled bucket, while one with a target_date but no start_date counts normally. The report prints unscheduled hours as a separate warning line rather than dropping them, because a missing target date is a data-entry gap, not zero work.
  5. Every workspace, summed. Workspaces are discovered at runtime via /users/me/workspaces/; nothing is hardcoded. A workspace that errors is named in the output — a partial sum never passes itself off as a total.

Plane returns capacity_buckets on the workload response: working days × 8h for the queried month. The script uses that value.

A local Mon–Fri weekday count × 8 is computed independently as a fallback for when the field is absent. When both are present and disagree, the report says so and uses Plane’s — a silent preference would hide a Plane-side calendar change (holidays, a different working week) that is exactly the thing worth knowing about.

Opt-in via ~/.claude/t1k-performance.json:

{
"statusline": { "enabled": true, "ttlMinutes": 30, "includeCancelled": false, "requireKit": "cocos" }
}

No name appears here: the segment reports the API key’s owner. statusline.user (or a top-level defaultUser) may still name someone explicitly, but it is optional and only needed to watch a person other than yourself.

requireKit is an optional scope gate: the segment renders only where kit theonekit-<short> is installed, so it can follow one engine’s sessions instead of every session on the machine. It is keyed on that kit’s own t1k-config-<short>.json fragment — installed and removed with the kit, so it tracks the install rather than merely naming it — checked project-local first, then global. Omit the field (or leave it empty) and the segment renders wherever enabled is true, which is the default.

Note the consequence of scope: a kit installed globally satisfies the gate in every session on that machine, so requireKit only narrows anything for a kit installed per-project. That is the intended shape for engine kits, which rules/kit-install-scope.md puts per-project anyway.

Renders 📊 337/168h : 200.60% in the stats segment — red below 100% of capacity, green at or above it.

hooks/lib/statusline-performance.cjs never performs network I/O on the render path. It reads the cache the CLI writes; when that cache is stale it spawns one detached refresh (lock-guarded, 5-minute stale-lock expiry) whose result appears on the next render. A stale-but-shown figure is prefixed ~. With no cache at all it renders nothing — an absent segment is honest, whereas a placeholder zero reads as a real measurement.

Remove the config file, or set enabled: false, and the segment disappears with no other effect.

Read from PLANE_BASE_URL + PLANE_API_KEY when set, otherwise from the registered plane MCP server’s own env block in ~/.claude.json. The key lives in exactly one place on disk and is never written into the cache, the status line, or any log.

  • A name that matches nothing returns 0/168h, not an error. The report flags it explicitly (No assignee named "...") — check that line before believing a zero. Plane member names are what to match, not email addresses. Self mode cannot hit this, since it matches a UUID the server itself returned.
  • This is not an access control. Plane’s workload endpoint returns every assignee’s row to any member of the workspace, so a colleague with their own API key can read your hours whether or not you run this skill. Identity resolution here keeps your name out of shared config; it does not, and cannot, make the underlying numbers private. That is a Plane project-visibility question.
  • meta.zero_estimate_count on the Plane workload response is workspace-wide, not scoped to the queried assignee_ids. Two calls with identical windows, differing only in assignee_ids, return the same zero_estimate_count while issues_counted changes — it is a workspace-level diagnostic counter, not “how many of this person’s items are missing an estimate.” Do not read it as, or subtract it from, the named person’s total.
  • get_workload does NOT drop unestimated items from tasks[]. They appear there with hours: 0 and unestimated: true — a task’s absence from tasks is never explained by “it had no estimate.”
  • A missing target_date is the most common source of a total that looks too low — even when start_date is set. If the number disagrees with someone’s own tally, check the undated warning line first. An item with no target_date still appears in tasks[] and is additionally listed in the top-level unscheduled array regardless of start_date — its hours are not silently dropped, just excluded from the month total (rule 4).
  • --include-cancelled will re-add work that was cancelled precisely because it was a duplicate. Only reach for it when you want a gross figure and know why.
  • t1k-plane — work-item lifecycle, binding, state resolution by group. This skill only reads; it never mutates a work item.
  • rules/plane-workitem-workflow.md — the enforced work-item gate behind plan/cook/fix/ship.
  • rules/green-that-proves-nothing.md — why rule 5 names failed workspaces instead of quietly summing the rest.