You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SDK type safety: mutation option bags and projected list items are Record<string, unknown> — field typos/wrong types compile clean under strict #601
The SDK's primary programmatic surface leans on Record<string, unknown> for both mutation inputs and query outputs, so TypeScript provides almost no protection for the exact operations agents run most. Field-name typos and wrong value types compile clean under strict and fail only at runtime, and reading a listed item's id is not type-safe.
Because the base is Record<string, unknown>, the intersection accepts any key of any type:
import{create}from"@unbrained/pm-cli/sdk";awaitcreate({titel: "typo",priority: "high",nonsense: 42});// ✅ compiles under strict — all wrong
titel (typo for title), a string priority (should be number), and a garbage key all type-check. The valid fields are already known to the package — CREATE_FLAG_CONTRACTS, UPDATE_FLAG_CONTRACTS, TOOL_CREATE_OPTION_CONTRACTS, etc. are exported — but none of that shape reaches the option type.
Outputs — projected list items are untyped
// dist/sdk/query/list.d.tsexporttypeListProjectedItem=Record<string,unknown>;// :95exporttypeListResultItem=ListedItem|ListTreeItem|ListProjectedItem;// :97 — union has a bare-record arm
So (await client.list()).items[i].id is unknown (the ListProjectedItem arm poisons the union) and requires manual narrowing/casting for the single most common field access.
Impact
For an agent-integration author, the headline value of a typed SDK is "the compiler catches my field typos and wrong enums before I ship." Here it catches neither on input nor output — the two hottest paths. This is especially costly for LLM agents, which routinely emit near-miss field names (titel, desc, assignee vs assigned_to) that a real typed surface would reject at author time.
Suggested fix
Give create/update/claimNext/… typed option interfaces (title: string, priority?: number, status?: ItemStatus, tags?: string[], …) derived from the existing *_FLAG_CONTRACTS/*_OPTION_CONTRACTS constants, instead of Record<string, unknown>. Keep an escape hatch ([custom: string]: unknown) only for user-defined schema fields, so core fields still get excess-property checking.
Type ListedItem.id/ListProjectedItem so .id (and other guaranteed fields) is string, not unknown; drop the bare-Record arm from ListResultItem or gate it behind an explicit projection generic.
Confidence: high (types quoted verbatim from the shipped .d.ts; typo example type-checks under strict).
#49 - feat(schema): pm schema add-type for config-driven custom item types [closed] #466 - Expose SDK read primitives and auto PM context hint [merged] #477 - feat(sdk): expand pm primitives and lifecycle aliases [merged] #481 - Expose SDK context primitives and closed_at metadata [merged] #499 - Harden SDK schema-driven input fidelity and package preflight [merged]
📝 Issue Planner
Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.
Create Plan
🧪 Issue enrichment is currently in open beta.
You can configure auto-planning by selecting labels in the issue_enrichment configuration.
To disable automatic issue enrichment, add the following to your .coderabbit.yaml:
issue_enrichment:
auto_enrich:
enabled: false
💬 Have feedback or questions? Drop into our discord!
Activity
coderabbitai commentedon Jul 18, 2026
🔗 Related PRs
#49 - feat(schema): pm schema add-type for config-driven custom item types [closed]
#466 - Expose SDK read primitives and auto PM context hint [merged]
#477 - feat(sdk): expand pm primitives and lifecycle aliases [merged]
#481 - Expose SDK context primitives and closed_at metadata [merged]
#499 - Harden SDK schema-driven input fidelity and package preflight [merged]
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
You can configure auto-planning by selecting labels in the issue_enrichment configuration.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
unbraind commentedon Jul 19, 2026
pm tracker item: pm-x29o