zinkee 0.1.44 → 0.1.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +4 -0
  2. package/dist/chunk-MHEVRMDX.js +1230 -0
  3. package/dist/chunk-MHEVRMDX.js.map +1 -0
  4. package/{src/utils/examples.ts → dist/examples-67U5IRBS.js} +866 -1141
  5. package/dist/examples-67U5IRBS.js.map +1 -0
  6. package/dist/index.js +1145 -8456
  7. package/dist/index.js.map +1 -1
  8. package/package.json +6 -3
  9. package/.github/workflows/npm-publish.yml +0 -77
  10. package/.github/workflows/pr-checks.yml +0 -36
  11. package/AGENTS.md +0 -110
  12. package/docs/cli-contract.md +0 -41
  13. package/docs/npm-release.md +0 -64
  14. package/docs/superpowers/plans/2026-03-24-zinkee-cli-implementation.md +0 -837
  15. package/docs/superpowers/plans/2026-03-25-cli-backend-error-contract.md +0 -503
  16. package/docs/superpowers/plans/2026-03-26-display-freeform-create.md +0 -389
  17. package/docs/superpowers/specs/2026-03-24-zinkee-cli-backend-blockers.md +0 -172
  18. package/docs/superpowers/specs/2026-03-24-zinkee-cli-design.md +0 -1576
  19. package/docs/superpowers/specs/2026-03-24-zinkee-cli-e2e-checklist.md +0 -215
  20. package/docs/superpowers/specs/2026-03-24-zinkee-cli-e2e-design.md +0 -492
  21. package/docs/superpowers/specs/2026-03-24-zinkee-cli-e2e-status.md +0 -307
  22. package/docs/superpowers/specs/2026-07-30-cli-pr-checks-design.md +0 -37
  23. package/src/api/automations.ts +0 -404
  24. package/src/api/comments.ts +0 -51
  25. package/src/api/displays.ts +0 -337
  26. package/src/api/document-templates.ts +0 -110
  27. package/src/api/files.ts +0 -50
  28. package/src/api/formulas.test.ts +0 -65
  29. package/src/api/formulas.ts +0 -67
  30. package/src/api/logs.ts +0 -34
  31. package/src/api/navigation.ts +0 -70
  32. package/src/api/records.ts +0 -184
  33. package/src/api/schemas.ts +0 -148
  34. package/src/api/teamspace.ts +0 -110
  35. package/src/cli-examples.ts +0 -130
  36. package/src/cli-runner.ts +0 -95
  37. package/src/client.test.ts +0 -189
  38. package/src/client.ts +0 -269
  39. package/src/command-registry.ts +0 -882
  40. package/src/commands/automations.test.ts +0 -1030
  41. package/src/commands/automations.ts +0 -2102
  42. package/src/commands/comments.test.ts +0 -214
  43. package/src/commands/comments.ts +0 -303
  44. package/src/commands/config.test.ts +0 -81
  45. package/src/commands/config.ts +0 -150
  46. package/src/commands/displays.test.ts +0 -1105
  47. package/src/commands/displays.ts +0 -1442
  48. package/src/commands/document-templates.test.ts +0 -569
  49. package/src/commands/document-templates.ts +0 -563
  50. package/src/commands/files.test.ts +0 -284
  51. package/src/commands/files.ts +0 -280
  52. package/src/commands/formulas.test.ts +0 -194
  53. package/src/commands/formulas.ts +0 -243
  54. package/src/commands/logs.test.ts +0 -123
  55. package/src/commands/logs.ts +0 -159
  56. package/src/commands/navigation.test.ts +0 -211
  57. package/src/commands/navigation.ts +0 -348
  58. package/src/commands/profiles.test.ts +0 -191
  59. package/src/commands/profiles.ts +0 -303
  60. package/src/commands/records.test.ts +0 -860
  61. package/src/commands/records.ts +0 -883
  62. package/src/commands/schemas.test.ts +0 -1252
  63. package/src/commands/schemas.ts +0 -890
  64. package/src/commands/teamspace.test.ts +0 -229
  65. package/src/commands/teamspace.ts +0 -546
  66. package/src/completion/engine.test.ts +0 -138
  67. package/src/completion/engine.ts +0 -168
  68. package/src/completion/install.test.ts +0 -179
  69. package/src/completion/install.ts +0 -260
  70. package/src/completion/runtime.ts +0 -150
  71. package/src/completion/scripts.ts +0 -91
  72. package/src/config.test.ts +0 -362
  73. package/src/config.ts +0 -294
  74. package/src/index.test.ts +0 -217
  75. package/src/index.ts +0 -8
  76. package/src/parsers/expressions.test.ts +0 -95
  77. package/src/parsers/expressions.ts +0 -128
  78. package/src/parsers/kv.test.ts +0 -35
  79. package/src/parsers/kv.ts +0 -49
  80. package/src/parsers/selectors.test.ts +0 -23
  81. package/src/parsers/selectors.ts +0 -29
  82. package/src/program.ts +0 -64
  83. package/src/runtime-context.ts +0 -103
  84. package/src/types.ts +0 -76
  85. package/src/utils/argv-rewrite.test.ts +0 -149
  86. package/src/utils/argv-rewrite.ts +0 -269
  87. package/src/utils/errors.test.ts +0 -85
  88. package/src/utils/errors.ts +0 -191
  89. package/src/utils/examples.test.ts +0 -374
  90. package/src/utils/output.test.ts +0 -65
  91. package/src/utils/output.ts +0 -154
  92. package/src/utils/schema-fields.ts +0 -1016
  93. package/tsconfig.json +0 -20
  94. package/tsup.config.ts +0 -13
@@ -1,837 +0,0 @@
1
- # Zinkee CLI Implementation Plan
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Build a complete Zinkee API v2 CLI from scratch, with backward-compatible profile config, agent-friendly JSON output, and full domain coverage matching the approved design spec.
6
-
7
- **Architecture:** The CLI will follow the `store-manager` reference structure: a thin `commander` entrypoint, domain command modules in `src/commands`, REST transport modules in `src/api`, a shared runtime layer for config/output/errors/parsing, and a central command registry that powers read-only enforcement and example support. Domain implementation should proceed from core runtime outward so later domain workers can plug into stable shared contracts.
8
-
9
- **Tech Stack:** Node.js 20+, TypeScript, ESM, commander, chalk, cli-table3, tsup, tsx, vitest, native fetch, TOML parser/stringifier dependency.
10
-
11
- ---
12
-
13
- ### Task 1: Bootstrap Project Tooling
14
-
15
- **Files:**
16
- - Create: `package.json`
17
- - Create: `tsconfig.json`
18
- - Create: `tsup.config.ts`
19
- - Create: `src/index.ts`
20
- - Create: `src/types.ts`
21
- - Test: `src/index.test.ts`
22
-
23
- - [ ] **Step 1: Add the base project files and first smoke test**
24
-
25
- ```ts
26
- // src/index.test.ts
27
- import { describe, expect, it } from "vitest";
28
-
29
- describe("project bootstrap", () => {
30
- it("loads the CLI entry module", async () => {
31
- const mod = await import("./index.js");
32
- expect(mod).toBeTruthy();
33
- });
34
- });
35
- ```
36
-
37
- - [ ] **Step 2: Run the targeted bootstrap test and capture the current failure**
38
-
39
- Run: `npm test -- src/index.test.ts`
40
- Expected: failure because the package, scripts, and entrypoint do not exist yet
41
-
42
- - [ ] **Step 3: Create the package, build config, and entrypoint scaffold**
43
-
44
- ```ts
45
- // src/index.ts
46
- #!/usr/bin/env node
47
-
48
- import chalk from "chalk";
49
- import { Command } from "commander";
50
-
51
- export function buildProgram(): Command {
52
- return new Command()
53
- .name("zinkee")
54
- .description("CLI for Zinkee API v2")
55
- .showHelpAfterError();
56
- }
57
-
58
- if (import.meta.url === `file://${process.argv[1]}`) {
59
- try {
60
- await buildProgram().parseAsync(process.argv);
61
- } catch (error) {
62
- const message = error instanceof Error ? error.message : "Unknown error";
63
- process.stderr.write(`${chalk.red("Error:")} ${message}\n`);
64
- process.exitCode = 1;
65
- }
66
- }
67
- ```
68
-
69
- - [ ] **Step 4: Run bootstrap verification**
70
-
71
- Run:
72
- - `npm run build`
73
- - `npm run typecheck`
74
- - `npm test -- src/index.test.ts`
75
-
76
- Expected:
77
- - build succeeds
78
- - typecheck succeeds
79
- - bootstrap test passes
80
-
81
- - [ ] **Step 5: Commit**
82
-
83
- ```bash
84
- git add package.json tsconfig.json tsup.config.ts src/index.ts src/types.ts src/index.test.ts
85
- git commit -m "chore: bootstrap zinkee cli project"
86
- ```
87
-
88
- ### Task 2: Build Config Compatibility and Runtime Context
89
-
90
- **Files:**
91
- - Create: `src/config.ts`
92
- - Create: `src/config.test.ts`
93
- - Create: `src/runtime-context.ts`
94
- - Modify: `src/types.ts`
95
- - Modify: `src/index.ts`
96
-
97
- - [ ] **Step 1: Add tests for TOML compatibility and runtime context resolution**
98
-
99
- ```ts
100
- // src/config.test.ts
101
- import { describe, expect, it } from "vitest";
102
-
103
- import { parseConfig, resolveProfile } from "./config.js";
104
-
105
- describe("parseConfig", () => {
106
- it("reads the legacy config shape without migration", () => {
107
- const config = parseConfig(`
108
- default_profile = "prod"
109
-
110
- [profiles.prod]
111
- api_key = "token"
112
- base_url = "https://api.zinkee.com"
113
- `);
114
-
115
- expect(config.defaultProfile).toBe("prod");
116
- expect(config.profiles.prod?.apiKey).toBe("token");
117
- });
118
- });
119
-
120
- describe("resolveProfile", () => {
121
- it("prefers explicit profile over default_profile", () => {
122
- const config = {
123
- defaultProfile: "prod",
124
- profiles: {
125
- prod: { apiKey: "a" },
126
- local: { apiKey: "b", baseUrl: "http://localhost:8088" },
127
- },
128
- };
129
-
130
- expect(resolveProfile(config, { profile: "local" }).name).toBe("local");
131
- });
132
- });
133
- ```
134
-
135
- - [ ] **Step 2: Run the config test and capture the failure**
136
-
137
- Run: `npm test -- src/config.test.ts`
138
- Expected: failure because config parsing/resolution does not exist yet
139
-
140
- - [ ] **Step 3: Implement TOML-backed config reading and runtime context resolution**
141
-
142
- ```ts
143
- // src/types.ts
144
- export interface ProfileConfig {
145
- apiKey: string;
146
- baseUrl?: string;
147
- name?: string;
148
- description?: string;
149
- }
150
-
151
- export interface AppConfig {
152
- defaultProfile?: string;
153
- profiles: Record<string, ProfileConfig>;
154
- }
155
-
156
- export interface RuntimeOverrides {
157
- profile?: string;
158
- baseUrl?: string;
159
- apiKey?: string;
160
- readOnly?: boolean;
161
- json?: boolean;
162
- }
163
- ```
164
-
165
- - [ ] **Step 4: Verify config compatibility and root wiring**
166
-
167
- Run:
168
- - `npm test -- src/config.test.ts`
169
- - `npm run typecheck`
170
-
171
- Expected:
172
- - legacy TOML parsing passes
173
- - runtime context resolution is typed and working
174
-
175
- - [ ] **Step 5: Commit**
176
-
177
- ```bash
178
- git add src/config.ts src/config.test.ts src/runtime-context.ts src/types.ts src/index.ts
179
- git commit -m "feat: add config compatibility and runtime context"
180
- ```
181
-
182
- ### Task 3: Add Shared Output, Error, and Command Registry Infrastructure
183
-
184
- **Files:**
185
- - Create: `src/utils/output.ts`
186
- - Create: `src/utils/errors.ts`
187
- - Create: `src/utils/examples.ts`
188
- - Create: `src/command-registry.ts`
189
- - Create: `src/utils/output.test.ts`
190
- - Modify: `src/index.ts`
191
- - Modify: `src/types.ts`
192
-
193
- - [ ] **Step 1: Add tests for JSON envelope, error mapping, and registry lookup**
194
-
195
- ```ts
196
- // src/utils/output.test.ts
197
- import { describe, expect, it } from "vitest";
198
-
199
- import { buildJsonSuccess, buildJsonError } from "./output.js";
200
-
201
- describe("buildJsonSuccess", () => {
202
- it("wraps data in the standard success envelope", () => {
203
- expect(buildJsonSuccess([{ id: "1" }], { command: "schemas list" })).toEqual({
204
- data: [{ id: "1" }],
205
- meta: { command: "schemas list" },
206
- });
207
- });
208
- });
209
-
210
- describe("buildJsonError", () => {
211
- it("wraps error details in the standard error envelope", () => {
212
- expect(buildJsonError({ reason: "invalid_request", message: "Bad request" }, {})).toMatchObject({
213
- error: { reason: "invalid_request" },
214
- meta: {},
215
- });
216
- });
217
- });
218
- ```
219
-
220
- - [ ] **Step 2: Run the targeted shared-runtime test**
221
-
222
- Run: `npm test -- src/utils/output.test.ts`
223
- Expected: failure because the shared output/error helpers do not exist yet
224
-
225
- - [ ] **Step 3: Implement envelope rendering, exit code mapping, and command metadata**
226
-
227
- ```ts
228
- // src/command-registry.ts
229
- export type CommandAccessLevel = "read" | "write" | "destructive";
230
-
231
- export interface CommandMeta {
232
- command: string;
233
- accessLevel: CommandAccessLevel;
234
- supportsExample?: boolean;
235
- supportsRaw?: boolean;
236
- output: "table-json" | "json-only" | "binary";
237
- }
238
- ```
239
-
240
- - [ ] **Step 4: Verify the shared runtime layer**
241
-
242
- Run:
243
- - `npm test -- src/utils/output.test.ts`
244
- - `npm run typecheck`
245
-
246
- Expected:
247
- - JSON envelope helpers pass
248
- - error mapping is typed
249
- - command registry compiles and can be consumed by the root program
250
-
251
- - [ ] **Step 5: Commit**
252
-
253
- ```bash
254
- git add src/utils/output.ts src/utils/errors.ts src/utils/examples.ts src/utils/output.test.ts src/command-registry.ts src/index.ts src/types.ts
255
- git commit -m "feat: add output error and command registry runtime"
256
- ```
257
-
258
- ### Task 4: Add REST Client and Shared Parsers
259
-
260
- **Files:**
261
- - Create: `src/client.ts`
262
- - Create: `src/client.test.ts`
263
- - Create: `src/parsers/expressions.ts`
264
- - Create: `src/parsers/expressions.test.ts`
265
- - Create: `src/parsers/kv.ts`
266
- - Create: `src/parsers/kv.test.ts`
267
- - Create: `src/parsers/selectors.ts`
268
- - Create: `src/parsers/selectors.test.ts`
269
-
270
- - [ ] **Step 1: Add transport and parser tests**
271
-
272
- ```ts
273
- // src/parsers/kv.test.ts
274
- import { describe, expect, it } from "vitest";
275
-
276
- import { parseKeyValue, parseJsonAssignment } from "./kv.js";
277
-
278
- describe("parseKeyValue", () => {
279
- it("splits field=value pairs", () => {
280
- expect(parseKeyValue("status=active")).toEqual({ key: "status", value: "active" });
281
- });
282
- });
283
-
284
- describe("parseJsonAssignment", () => {
285
- it("parses field=json pairs", () => {
286
- expect(parseJsonAssignment('payload={"a":1}')).toEqual({ key: "payload", value: { a: 1 } });
287
- });
288
- });
289
- ```
290
-
291
- - [ ] **Step 2: Run parser and client checks to capture the failure**
292
-
293
- Run:
294
- - `npm test -- src/parsers/kv.test.ts`
295
- - `npm test -- src/parsers/expressions.test.ts`
296
- - `npm test -- src/client.test.ts`
297
-
298
- Expected: failures because parsers and transport do not exist yet
299
-
300
- - [ ] **Step 3: Implement the shared client and parser layer**
301
-
302
- ```ts
303
- // src/client.ts
304
- export interface ApiClientOptions {
305
- baseUrl: string;
306
- apiKey: string;
307
- timeoutMs?: number;
308
- }
309
-
310
- export class ApiClient {
311
- constructor(private readonly options: ApiClientOptions) {}
312
-
313
- async getJson<T>(path: string): Promise<T> {
314
- return this.requestJson<T>(path, { method: "GET" });
315
- }
316
-
317
- async requestJson<T>(path: string, init: RequestInit): Promise<T> {
318
- // fetch + auth header + timeout + JSON/error normalization
319
- throw new Error("not implemented");
320
- }
321
- }
322
- ```
323
-
324
- - [ ] **Step 4: Verify the transport and parser contracts**
325
-
326
- Run:
327
- - `npm test -- src/parsers/kv.test.ts`
328
- - `npm test -- src/parsers/expressions.test.ts`
329
- - `npm test -- src/parsers/selectors.test.ts`
330
- - `npm test -- src/client.test.ts`
331
- - `npm run typecheck`
332
-
333
- Expected:
334
- - assignment parsing works
335
- - expression parsing works
336
- - selector normalization works
337
- - client error handling and timeout behavior are covered
338
-
339
- - [ ] **Step 5: Commit**
340
-
341
- ```bash
342
- git add src/client.ts src/client.test.ts src/parsers/expressions.ts src/parsers/expressions.test.ts src/parsers/kv.ts src/parsers/kv.test.ts src/parsers/selectors.ts src/parsers/selectors.test.ts
343
- git commit -m "feat: add shared rest client and parsers"
344
- ```
345
-
346
- ### Task 5: Implement `profiles` and `config` Commands
347
-
348
- **Files:**
349
- - Create: `src/commands/profiles.ts`
350
- - Create: `src/commands/config.ts`
351
- - Create: `src/commands/profiles.test.ts`
352
- - Create: `src/commands/config.test.ts`
353
- - Modify: `src/index.ts`
354
- - Modify: `src/command-registry.ts`
355
-
356
- - [ ] **Step 1: Add command tests for profile and config management**
357
-
358
- ```ts
359
- // src/commands/profiles.test.ts
360
- import { describe, expect, it } from "vitest";
361
-
362
- import { buildProgram } from "../index.js";
363
-
364
- describe("profiles commands", () => {
365
- it("registers the profiles command group", () => {
366
- const program = buildProgram();
367
- expect(program.commands.some((command) => command.name() === "profiles")).toBe(true);
368
- });
369
- });
370
- ```
371
-
372
- - [ ] **Step 2: Run the profiles/config command tests**
373
-
374
- Run:
375
- - `npm test -- src/commands/profiles.test.ts`
376
- - `npm test -- src/commands/config.test.ts`
377
-
378
- Expected: failure because the command groups are not registered yet
379
-
380
- - [ ] **Step 3: Implement profile mutation commands and config inspection commands**
381
-
382
- ```ts
383
- // src/commands/config.ts
384
- export function registerConfigCommands(program: Command): void {
385
- program.command("config").description("Inspect CLI configuration");
386
- }
387
- ```
388
-
389
- - [ ] **Step 4: Verify command registration and local behavior**
390
-
391
- Run:
392
- - `npm test -- src/commands/profiles.test.ts`
393
- - `npm test -- src/commands/config.test.ts`
394
- - `npm run typecheck`
395
-
396
- Expected:
397
- - both groups are registered
398
- - read/write commands are tagged in the command registry
399
-
400
- - [ ] **Step 5: Commit**
401
-
402
- ```bash
403
- git add src/commands/profiles.ts src/commands/config.ts src/commands/profiles.test.ts src/commands/config.test.ts src/index.ts src/command-registry.ts
404
- git commit -m "feat: add profiles and config commands"
405
- ```
406
-
407
- ### Task 6: Implement `schemas` Commands and Schema API Module
408
-
409
- **Files:**
410
- - Create: `src/api/schemas.ts`
411
- - Create: `src/commands/schemas.ts`
412
- - Create: `src/commands/schemas.test.ts`
413
- - Modify: `src/index.ts`
414
- - Modify: `src/command-registry.ts`
415
-
416
- - [ ] **Step 1: Add schema command tests**
417
-
418
- ```ts
419
- // src/commands/schemas.test.ts
420
- import { describe, expect, it } from "vitest";
421
-
422
- import { normalizeUuidOrSlug } from "../parsers/selectors.js";
423
-
424
- describe("schema selector parsing", () => {
425
- it("keeps UUIDs as UUID selectors", () => {
426
- expect(normalizeUuidOrSlug("550e8400-e29b-41d4-a716-446655440000").kind).toBe("uuid");
427
- });
428
- });
429
- ```
430
-
431
- - [ ] **Step 2: Run the schemas test and capture the current failure**
432
-
433
- Run: `npm test -- src/commands/schemas.test.ts`
434
- Expected: failure because schema API and command group do not exist yet
435
-
436
- - [ ] **Step 3: Implement schema CRUD and field CRUD commands**
437
-
438
- ```ts
439
- // src/api/schemas.ts
440
- export async function listSchemas(client: ApiClient) {
441
- return client.getJson("/api/v2/schemas");
442
- }
443
- ```
444
-
445
- - [ ] **Step 4: Verify schema behavior**
446
-
447
- Run:
448
- - `npm test -- src/commands/schemas.test.ts`
449
- - `npm run typecheck`
450
-
451
- Expected:
452
- - schema selectors resolve by UUID or slug
453
- - commands register and map to `/api/v2/schemas` and `/fields`
454
-
455
- - [ ] **Step 5: Commit**
456
-
457
- ```bash
458
- git add src/api/schemas.ts src/commands/schemas.ts src/commands/schemas.test.ts src/index.ts src/command-registry.ts
459
- git commit -m "feat: add schemas command surface"
460
- ```
461
-
462
- ### Task 7: Implement `records` and `comments`
463
-
464
- **Files:**
465
- - Create: `src/api/records.ts`
466
- - Create: `src/api/comments.ts`
467
- - Create: `src/commands/records.ts`
468
- - Create: `src/commands/comments.ts`
469
- - Create: `src/commands/records.test.ts`
470
- - Create: `src/commands/comments.test.ts`
471
- - Modify: `src/index.ts`
472
- - Modify: `src/command-registry.ts`
473
-
474
- - [ ] **Step 1: Add tests for query parsing and record mutation flags**
475
-
476
- ```ts
477
- // src/commands/records.test.ts
478
- import { describe, expect, it } from "vitest";
479
-
480
- import { parseKeyValue } from "../parsers/kv.js";
481
-
482
- describe("record write flags", () => {
483
- it("parses --set assignments", () => {
484
- expect(parseKeyValue("status=active")).toEqual({ key: "status", value: "active" });
485
- });
486
- });
487
- ```
488
-
489
- - [ ] **Step 2: Run records/comments targeted tests**
490
-
491
- Run:
492
- - `npm test -- src/commands/records.test.ts`
493
- - `npm test -- src/commands/comments.test.ts`
494
-
495
- Expected: failure because records/comments command groups do not exist yet
496
-
497
- - [ ] **Step 3: Implement list/query/get/create/update/delete records and list/create comments**
498
-
499
- ```ts
500
- // src/api/records.ts
501
- export async function queryRecords(client: ApiClient, schemaId: string, body: unknown) {
502
- return client.requestJson(`/api/v2/schemas/${schemaId}/records:query`, {
503
- method: "POST",
504
- body: JSON.stringify(body),
505
- });
506
- }
507
- ```
508
-
509
- - [ ] **Step 4: Verify record and comment behavior**
510
-
511
- Run:
512
- - `npm test -- src/commands/records.test.ts`
513
- - `npm test -- src/commands/comments.test.ts`
514
- - `npm run typecheck`
515
-
516
- Expected:
517
- - `--set`, `--set-json`, and `--unset` map correctly
518
- - `records list` and `records query` share the same query model
519
- - comments stay text-first with raw fallback
520
-
521
- - [ ] **Step 5: Commit**
522
-
523
- ```bash
524
- git add src/api/records.ts src/api/comments.ts src/commands/records.ts src/commands/comments.ts src/commands/records.test.ts src/commands/comments.test.ts src/index.ts src/command-registry.ts
525
- git commit -m "feat: add records and comments commands"
526
- ```
527
-
528
- ### Task 8: Implement `files`, `navigation`, and `teamspace`
529
-
530
- **Files:**
531
- - Create: `src/api/files.ts`
532
- - Create: `src/api/navigation.ts`
533
- - Create: `src/api/teamspace.ts`
534
- - Create: `src/commands/files.ts`
535
- - Create: `src/commands/navigation.ts`
536
- - Create: `src/commands/teamspace.ts`
537
- - Create: `src/commands/files.test.ts`
538
- - Create: `src/commands/navigation.test.ts`
539
- - Create: `src/commands/teamspace.test.ts`
540
- - Modify: `src/index.ts`
541
- - Modify: `src/command-registry.ts`
542
-
543
- - [ ] **Step 1: Add command tests for binary/download rules and folder resolution**
544
-
545
- ```ts
546
- // src/commands/files.test.ts
547
- import { describe, expect, it } from "vitest";
548
-
549
- import { buildJsonError } from "../utils/output.js";
550
-
551
- describe("files download json mode", () => {
552
- it("requires --output when --json is used", () => {
553
- const result = buildJsonError({ reason: "output_required", message: "Use --output with --json." }, {});
554
- expect(result.error.reason).toBe("output_required");
555
- });
556
- });
557
- ```
558
-
559
- - [ ] **Step 2: Run the targeted tests**
560
-
561
- Run:
562
- - `npm test -- src/commands/files.test.ts`
563
- - `npm test -- src/commands/navigation.test.ts`
564
- - `npm test -- src/commands/teamspace.test.ts`
565
-
566
- Expected: failure because these domains are not implemented yet
567
-
568
- - [ ] **Step 3: Implement file, folder, move, publish, and unpublish commands**
569
-
570
- ```ts
571
- // src/api/files.ts
572
- export async function downloadFile(client: ApiClient, fileId: string) {
573
- return client.requestBinary(`/api/v2/files/${fileId}`, { method: "GET" });
574
- }
575
- ```
576
-
577
- - [ ] **Step 4: Verify organization-domain behavior**
578
-
579
- Run:
580
- - `npm test -- src/commands/files.test.ts`
581
- - `npm test -- src/commands/navigation.test.ts`
582
- - `npm test -- src/commands/teamspace.test.ts`
583
- - `npm run typecheck`
584
-
585
- Expected:
586
- - files support upload/download/delete/storage
587
- - folder selectors resolve by UUID or exact name with ambiguity failures
588
- - teamspace/resource verbs map cleanly to publish/unpublish
589
-
590
- - [ ] **Step 5: Commit**
591
-
592
- ```bash
593
- git add src/api/files.ts src/api/navigation.ts src/api/teamspace.ts src/commands/files.ts src/commands/navigation.ts src/commands/teamspace.ts src/commands/files.test.ts src/commands/navigation.test.ts src/commands/teamspace.test.ts src/index.ts src/command-registry.ts
594
- git commit -m "feat: add files navigation and teamspace commands"
595
- ```
596
-
597
- ### Task 9: Implement `displays`
598
-
599
- **Files:**
600
- - Create: `src/api/displays.ts`
601
- - Create: `src/commands/displays.ts`
602
- - Create: `src/commands/displays.test.ts`
603
- - Modify: `src/index.ts`
604
- - Modify: `src/command-registry.ts`
605
-
606
- - [ ] **Step 1: Add tests for widget flag normalization and nested subresource registration**
607
-
608
- ```ts
609
- // src/commands/displays.test.ts
610
- import { describe, expect, it } from "vitest";
611
-
612
- import { buildProgram } from "../index.js";
613
-
614
- describe("displays command group", () => {
615
- it("registers widget and variable subresources", () => {
616
- const program = buildProgram();
617
- const displays = program.commands.find((command) => command.name() === "displays");
618
- expect(displays).toBeTruthy();
619
- });
620
- });
621
- ```
622
-
623
- - [ ] **Step 2: Run the displays test**
624
-
625
- Run: `npm test -- src/commands/displays.test.ts`
626
- Expected: failure because the displays domain does not exist yet
627
-
628
- - [ ] **Step 3: Implement display, layout, tabs, variables, widgets, navigation-targets, and cross-widget-filter**
629
-
630
- ```ts
631
- // src/api/displays.ts
632
- export async function listDisplays(client: ApiClient) {
633
- return client.getJson("/api/v2/displays");
634
- }
635
- ```
636
-
637
- - [ ] **Step 4: Verify displays behavior**
638
-
639
- Run:
640
- - `npm test -- src/commands/displays.test.ts`
641
- - `npm run typecheck`
642
-
643
- Expected:
644
- - widget commands use `--type`
645
- - `--widget-read-only` does not collide with root `--read-only`
646
- - complex sections support `--raw` and JSON file helpers
647
-
648
- - [ ] **Step 5: Commit**
649
-
650
- ```bash
651
- git add src/api/displays.ts src/commands/displays.ts src/commands/displays.test.ts src/index.ts src/command-registry.ts
652
- git commit -m "feat: add displays command surface"
653
- ```
654
-
655
- ### Task 10: Implement `automations`
656
-
657
- **Files:**
658
- - Create: `src/api/automations.ts`
659
- - Create: `src/commands/automations.ts`
660
- - Create: `src/commands/automations.test.ts`
661
- - Modify: `src/index.ts`
662
- - Modify: `src/command-registry.ts`
663
-
664
- - [ ] **Step 1: Add tests for trigger/action polymorphism and flow flag parsing**
665
-
666
- ```ts
667
- // src/commands/automations.test.ts
668
- import { describe, expect, it } from "vitest";
669
-
670
- import { parseKeyValue } from "../parsers/kv.js";
671
-
672
- describe("automation action args", () => {
673
- it("parses key=value mappings for action config", () => {
674
- expect(parseKeyValue("status=active")).toEqual({ key: "status", value: "active" });
675
- });
676
- });
677
- ```
678
-
679
- - [ ] **Step 2: Run the automations test**
680
-
681
- Run: `npm test -- src/commands/automations.test.ts`
682
- Expected: failure because the automations domain does not exist yet
683
-
684
- - [ ] **Step 3: Implement folders, automations, trigger, actions, flow, webhook, plugins, and connections**
685
-
686
- ```ts
687
- // src/api/automations.ts
688
- export async function listAutomations(client: ApiClient, query: URLSearchParams) {
689
- return client.getJson(`/api/v2/automations?${query.toString()}`);
690
- }
691
- ```
692
-
693
- - [ ] **Step 4: Verify the automations domain**
694
-
695
- Run:
696
- - `npm test -- src/commands/automations.test.ts`
697
- - `npm run typecheck`
698
-
699
- Expected:
700
- - triggers and actions are modeled generically with `--type`
701
- - flow parsing supports repeated `--entry` and `--transition`
702
- - connections separate `config` and `secret` semantics
703
-
704
- - [ ] **Step 5: Commit**
705
-
706
- ```bash
707
- git add src/api/automations.ts src/commands/automations.ts src/commands/automations.test.ts src/index.ts src/command-registry.ts
708
- git commit -m "feat: add automations command surface"
709
- ```
710
-
711
- ### Task 11: Add Examples, Help Text, and Agent-Facing Docs
712
-
713
- **Files:**
714
- - Modify: `src/commands/config.ts`
715
- - Modify: `src/commands/profiles.ts`
716
- - Modify: `src/commands/schemas.ts`
717
- - Modify: `src/commands/records.ts`
718
- - Modify: `src/commands/comments.ts`
719
- - Modify: `src/commands/files.ts`
720
- - Modify: `src/commands/navigation.ts`
721
- - Modify: `src/commands/teamspace.ts`
722
- - Modify: `src/commands/displays.ts`
723
- - Modify: `src/commands/automations.ts`
724
- - Create: `README.md`
725
- - Create: `AGENTS.md`
726
- - Create: `docs/cli-contract.md`
727
-
728
- - [ ] **Step 1: Add or adjust example rendering coverage**
729
-
730
- ```ts
731
- // docs/cli-contract.md
732
- // Capture the true command contract order:
733
- // 1. live --help
734
- // 2. command modules
735
- // 3. docs
736
- ```
737
-
738
- - [ ] **Step 2: Run a help/example validation pass**
739
-
740
- Run:
741
- - `npm run build`
742
- - `node dist/index.js --help`
743
- - `node dist/index.js records query --help`
744
- - `node dist/index.js records query --example --json`
745
-
746
- Expected:
747
- - help is present
748
- - examples are realistic
749
- - JSON examples use the standard envelope
750
-
751
- - [ ] **Step 3: Implement example registration and docs**
752
-
753
- ```ts
754
- // src/utils/examples.ts
755
- export interface CommandExample {
756
- description: string;
757
- command: string;
758
- }
759
- ```
760
-
761
- - [ ] **Step 4: Verify docs/help consistency**
762
-
763
- Run:
764
- - `npm run typecheck`
765
- - `npm test`
766
-
767
- Expected:
768
- - all registered commands expose aligned help and examples
769
- - docs reflect the real command surface
770
-
771
- - [ ] **Step 5: Commit**
772
-
773
- ```bash
774
- git add src/commands/*.ts src/utils/examples.ts README.md AGENTS.md docs/cli-contract.md
775
- git commit -m "docs: add examples help text and agent docs"
776
- ```
777
-
778
- ### Task 12: Final Integration Verification
779
-
780
- **Files:**
781
- - Modify: `src/index.ts`
782
- - Modify: `src/utils/errors.ts`
783
- - Modify: `src/utils/output.ts`
784
- - Modify: `src/command-registry.ts`
785
- - Modify: `src/client.ts`
786
-
787
- - [ ] **Step 1: Add final verification coverage for root behavior**
788
-
789
- ```ts
790
- // Verify root behaviors:
791
- // - read-only blocking
792
- // - JSON-only stdout
793
- // - exit code mapping
794
- // - binary command JSON constraints
795
- ```
796
-
797
- - [ ] **Step 2: Run the full verification suite**
798
-
799
- Run:
800
- - `npm run build`
801
- - `npm run typecheck`
802
- - `npm test`
803
-
804
- Expected:
805
- - all tests pass
806
- - build succeeds
807
- - typecheck succeeds
808
-
809
- - [ ] **Step 3: Exercise representative commands locally**
810
-
811
- Run:
812
- - `node dist/index.js profiles list --json`
813
- - `node dist/index.js schemas list --json --read-only`
814
- - `node dist/index.js files storage --json`
815
-
816
- Expected:
817
- - stable JSON envelope
818
- - read-only respected
819
- - no stray stdout text in JSON mode
820
-
821
- - [ ] **Step 4: Fix any final root-contract regressions**
822
-
823
- Run:
824
- - `npm run build`
825
- - `npm run typecheck`
826
- - `npm test`
827
-
828
- Expected:
829
- - green final verification
830
-
831
- - [ ] **Step 5: Commit**
832
-
833
- ```bash
834
- git add src/index.ts src/utils/errors.ts src/utils/output.ts src/command-registry.ts src/client.ts
835
- git commit -m "test: finalize root contract verification"
836
- ```
837
-