- Workspace config generation — sync workspace metadata (columns, users, lists, pipelines, stages) into a local config
- Clean, enriched output — resolve all UUIDs (custom fields, select options, owners, stages, etc.) to human-readable names; output processable by humans and LLMs
- No hardcoded values — enrichment driven by workspace config, not hardcoded field names
- TDD: write tests first, then implement, iterate until green, commit
- Incremental steps — each step is independently testable and committable
- Rewrite
index.tsinto focused modules instead of one monolith
Goal: Extract cache logic into its own module with proper types, file I/O, error handling.
src/cache.ts—loadCache(),saveCache(),getWorkspace(), cache typessrc/types.ts— shared interfaces (WorkspaceCache,GlobalCache,ColumnDef, etc.)- Tests: load/save roundtrip, missing file handling, workspace creation, schema validation
- No enrichment yet, no CLI wiring
Goal: Fetch column definitions from the raw CLI and store them with full type info.
src/sync.ts—syncColumns(rawCli)function- Stores column
type,name,entity, andoptions(with key→name mapping) - Tests: mock raw CLI output → verify cache contains correct column definitions; verify select/multiselect options are stored; verify different column types are preserved
- Depends on: Step 1
Goal: Fetch workspace names and bootstrap user/list context.
- Extend
src/sync.ts—syncWorkspaces(),syncContext()(users, lists from contacts/deals) - Store workspace names, user id→name, list id→name
- Tests: mock workspace list → verify names cached; mock contacts with owners/lists → verify user and list caches populated; handle empty responses gracefully
- Depends on: Steps 1–2
Goal: Resolve custom object UUIDs to human-readable names using column type.
src/enrich.ts—enrichObject(obj, cache, options)- Column UUID keys → column names
select/multiselectoption key UUIDs → option display namesuser-type columns → user names from cache- Tests: custom field with select option → resolved; multiselect → all resolved; user-type column → resolved to name; unknown UUID → left as-is; nested objects handled
- Depends on: Steps 1–2
Goal: Resolve common ID fields across all entity types.
- Extend
src/enrich.ts ownerIds→ user names,listIds→ list names,createdById/updatedById→ user names,assignedToIds→ user names- Derive enrichable fields from column
typemetadata (not hardcoded field names) where possible --hide-nullssupport- Tests: ownerIds array → names; createdById string → name; listIds → names; unknown IDs → left as-is; hide-nulls removes null values
- Depends on: Steps 1–4
Goal: Resolve deal-specific UUIDs (stage, pipelineId).
- Extend sync to capture pipeline/stage names from deal responses
- Extend enrichment to resolve
stageandpipelineId - Tests: deal with stage UUID → resolved to stage name; pipeline UUID → name; uncached stage → left as UUID
- Depends on: Steps 1–5
Goal: Clean the API response envelope so output is the useful data, not the wrapper.
src/output.ts—formatOutput(response, options)- Unwrap
body.dataordataarrays/objects - Include
totalas metadata when relevant - Tests: wrapped response → unwrapped; single record → just the record; list → array with total; already-flat response → unchanged
- Depends on: Steps 4–6
Goal: Rewrite the main entry point to use the new modules.
src/cli.ts— main entry point- Wire up: arg parsing → sync (if needed) → raw CLI call → parse → enrich → format → output
columns synccommand → calls sync engineconfig showcommand → dumps current cached config--syncflag → sync before command--hide-nullsflag → passed to enrichment- Tests: end-to-end with mocked raw CLI; verify enriched output for contacts, companies, deals; verify
config showoutputs cache; verify passthrough for login/logout/help - Depends on: Steps 1–7
Goal: Let users inspect their workspace configuration.
config show— dump full workspace config (columns, users, lists, stages)config show --workspace <id>— single workspaceconfig show --columns— just columns- Tests: show outputs JSON with all cached data; workspace filter works; columns filter works
- Depends on: Steps 1–3, 8
Goal: Full end-to-end tests against the compiled binary.
- Test each resource type (contacts, companies, deals, notes, tasks) with
--curlto validate command generation - Test enrichment end-to-end with a pre-populated cache file
- Update README with correct command syntax
- Clean up any remaining issues
- Depends on: All prior steps
src/
types.ts — shared interfaces
cache.ts — cache load/save/access
sync.ts — workspace config sync engine
enrich.ts — UUID → name enrichment
output.ts — response unwrapping + formatting
cli.ts — main entry point (replaces index.ts)
raw.ts — raw CLI binary path resolution + execution
tests/
cache.test.ts
sync.test.ts
enrich.test.ts
output.test.ts
cli.test.ts — end-to-end tests
docs/ — API reference (already created)
| Step | Description | Status |
|---|---|---|
| 1 | Module scaffold + cache layer | done |
| 2 | Sync engine — columns | done |
| 3 | Sync engine — workspaces + context | done |
| 4 | Enrichment — custom fields | done |
| 5 | Enrichment — standard ID fields | done |
| 6 | Enrichment — deals (stage/pipeline) | done |
| 7 | Response unwrapping | done |
| 8 | CLI wiring — replace index.ts | done |
| 9 | Config show/inspect commands | done |
| 10 | Integration tests + cleanup | done |