@ted-galago/wave-cli 0.1.5 → 0.1.7

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.
package/README.md CHANGED
@@ -35,6 +35,27 @@ printf '%s' '{"token":"token-value","baseUrl":"https://api.example.com","organiz
35
35
  | wave --auth-json-stdin tasks list --page 1 --per 10
36
36
  ```
37
37
 
38
+ ## Benchmark Wave vs Obsidian CLI
39
+
40
+ Run the side-by-side benchmark harness:
41
+
42
+ ```bash
43
+ npm run benchmark:cli
44
+ ```
45
+
46
+ Useful options:
47
+
48
+ ```bash
49
+ npm run benchmark:cli -- --runs 20 --warmup 3 --query "meeting notes"
50
+ npm run benchmark:cli -- --obsidian-bin /Applications/Obsidian.app/Contents/MacOS/obsidian-cli
51
+ npm run benchmark:cli -- --json-out /tmp/cli-benchmark.json
52
+ ```
53
+
54
+ Notes:
55
+
56
+ - Wave scenarios expect JSON envelopes for domain operations.
57
+ - Obsidian scenarios require the CLI to be registered and the Obsidian app available.
58
+
38
59
  ## Runtime Contract
39
60
 
40
61
  Required (from flags, stdin, or env):
@@ -82,8 +103,8 @@ wave foundation annual-objectives create --data-json '{"annual_objective":{"stra
82
103
  wave foundation quarterly-objectives create --data-json '{"quarterly_objective":{"strategic_objective_id":"7","annual_objective_id":"8","name":"Quarterly Goal"}}'
83
104
  wave lists create --data-json '{"name":"Weekly List"}'
84
105
  wave list-items create --data-json '{"list_id":"123","summary":"Follow up"}'
85
- wave todos create --data-json '{"todo_group_id":"55","name":"Send update"}'
86
- wave knowledge create --data-json '{"title":"Runbook","content":"..."}'
106
+ wave todos create --data-json '{"todo_group_id":"55","name":"Send update","status":"open"}'
107
+ wave knowledge create --data-json '{"content":{"name":"Runbook","content_type":"process","status":"draft","member_id":"67"}}'
87
108
  wave notes create-member --target-member-id 67 --name "1:1 Note" --body "Strong progress"
88
109
  wave notes create-manager --actor-member-id 67 --target-member-id 68 --name "Manager Note" --body "Coaching plan"
89
110
  wave notes create-team --actor-member-id 67 --team-id 9 --name "Team Note" --body "Team context"
@@ -94,6 +115,15 @@ wave notes list --contentable-type Member --contentable-id 67 --member-id 67 --p
94
115
  wave notes show --id 1001
95
116
  wave notes update --id 1001 --name "Updated Note" --body "Updated body" --status published
96
117
  wave notes destroy --id 1001
118
+ wave markdown-tree root --tree-view
119
+ wave markdown-tree resolve --tool-key projects --node-key tasks --parent-id 123
120
+ wave markdown-tree children --tool-key directory --node-key members --record-id 67
121
+ wave markdown-tree subtree --tool-key knowledge --node-key knowledge --content-type processes --depth 2
122
+ wave find "Ted"
123
+ wave open "Ted Martinez"
124
+ wave ls --path "directory/Members/Ted Martinez"
125
+ wave cat --path "directory/Members/Ted Martinez/Member Profile"
126
+ wave tree --path "knowledge/Processes" --depth 2
97
127
  wave pulse update --id 12 --data-json '{"status":"on_track"}'
98
128
  wave subtasks list --task-id 123 --page 1 --per 20
99
129
  wave milestones list --rock-id 234 --page 1 --per 20
@@ -116,6 +146,7 @@ These child resources enforce parent IDs at CLI validation time:
116
146
  - `issues.create` requires `issue_group_id`
117
147
  - `todos.create` requires `todo_group_id`
118
148
  - `rocks.create` requires `rock_collection_id`
149
+ - `kpis.create` requires `smart_kpi_view_id`
119
150
  - `scorecards.create` requires `measurable_group_id`
120
151
  - `subtasks.create` requires `task_id`
121
152
  - `milestones.create` requires `rock_id`
@@ -126,6 +157,139 @@ These child resources enforce parent IDs at CLI validation time:
126
157
 
127
158
  If a required parent field is missing, CLI returns JSON error with exit code `2`.
128
159
 
160
+ `kpis.create` contract notes:
161
+
162
+ - `smart_kpi.name` must be one of the backend enum values.
163
+ - If payload uses free-text `smart_kpi.name` with `measurable_group_id`, CLI routes to `create_measurable` (`scorecards.create`) instead of `create_smart_kpi`.
164
+
165
+ `meetings.create` contract notes:
166
+
167
+ - `meeting.type` is required and must be `TeamMeeting` or `OneOnOneMeeting`.
168
+ - Required fields: `member_id`, `date`, `start_time`.
169
+ - `meeting.repeats` defaults to `never` if omitted.
170
+ - For `TeamMeeting`, `teams_ids` is required.
171
+
172
+ `organizations.update` contract notes:
173
+
174
+ - `organization.workspace_name` is normalized to `organization.organization_detail_attributes.workspace_name`.
175
+
176
+ `organizations.meta-profile.update` contract notes:
177
+
178
+ - Payload must be shaped as `organization_meta_profile.profile.<section>.<field>`.
179
+ - Legacy shorthand `organization_meta_profile.title` is normalized to `profile.company_identity.one_sentence_summary`.
180
+
181
+ `organizations.key-metric-meta-profile.update` contract notes:
182
+
183
+ - Payload must be shaped as `key_metric_meta_profile.profile.<section>.<field>`.
184
+ - Legacy shorthand `key_metric_meta_profile.annual_revenue` is normalized to `profile.financial.revenue`.
185
+
186
+ `knowledge.create` contract notes:
187
+
188
+ - `content.content_type` must be one of `company`, `policy`, `process`.
189
+ - `content.status` must be `draft` or `published`.
190
+ - `content.member_id` is required.
191
+ - `content.type` is not required for create.
192
+
193
+ `news.create` contract notes:
194
+
195
+ - Requires `headline.member_id`, `headline.status`, and `headline.headline_type`.
196
+ - `headline.status` must be `active` or `completed`.
197
+ - `headline.headline_type` must be `team` or `org_wide`.
198
+
199
+ `questions.create/update` contract notes:
200
+
201
+ - Use `question.name` (legacy `summary` is normalized to `name`).
202
+ - `questions.create` requires `question.member_id` and `question.name`.
203
+ - `question.status`, when provided, must be `asked` or `answered`.
204
+ - `questions.list` supports only `asked` and `answered` filters (plus `page` / `per`).
205
+ - `questions.list` does not expose `--query-json`; unsupported filters are rejected at CLI parse time.
206
+
207
+ `pulse.create` contract notes:
208
+
209
+ - Requires `health_update.health_updatable_id`, `health_update.health_updatable_type`, `health_update.member_id`, and `health_update.status`.
210
+ - Legacy `updatable_id`/`updatable_type` are normalized to `health_updatable_id`/`health_updatable_type`.
211
+ - `health_update.status` must be `on_track`, `at_risk`, or `off_track`.
212
+
213
+ `surveys.create/update` contract notes:
214
+
215
+ - Use `survey.name` and `survey.recipient_type` (`title` is normalized to `name`).
216
+ - `survey.recipient_type` must be `member`, `team`, or `org_wide`.
217
+ - Survey results are written via `surveys.update` using nested `survey.survey_results_attributes`.
218
+ - There is no standalone `createSurveyResult` / `updateSurveyResult` CLI command.
219
+ - Valid `survey.name` values:
220
+ - `employee_net_promoter_score`
221
+ - `continuous_performance_review`
222
+ - `core_value_alignment`
223
+ - `engagement`
224
+ - `wellness_and_mental_health`
225
+ - `workspace_culture`
226
+ - `peer_review`
227
+ - `manager_review`
228
+ - `onboarding`
229
+
230
+ `feedbacks.create/update` contract notes:
231
+
232
+ - Use `feedback.name` (`title` is normalized to `name`).
233
+ - `feedbacks.create` requires `feedback.name`, `feedback.quarter`, `feedback.year`.
234
+ - `feedback.quarter` must be `q1`, `q2`, `q3`, or `q4`.
235
+
236
+ `accountability.create/update` contract notes:
237
+
238
+ - Use `responsibility.name` (`summary` is normalized to `name`).
239
+ - `accountability.create` requires `responsibility.name` and `responsibility.member_id`.
240
+
241
+ ## Markdown Tree Traversal
242
+
243
+ Thin GraphQL adapter over backend markdown-tree services.
244
+ CLI does not re-implement traversal/scope rules.
245
+
246
+ Commands:
247
+
248
+ - `wave markdown-tree root [--tree-view]`
249
+ - `wave markdown-tree resolve --tool-key <k> --node-key <k> [--parent-id <id>] [--record-id <id>] [--member-id <id>] [--team-id <id>] [--content-type <t>] [--tree-view]`
250
+ - `wave markdown-tree children --tool-key <k> --node-key <k> [--parent-id <id>] [--record-id <id>] [--member-id <id>] [--team-id <id>] [--content-type <t>] [--tree-view]`
251
+ - `wave markdown-tree subtree --tool-key <k> --node-key <k> --depth <n> [--parent-id <id>] [--record-id <id>] [--member-id <id>] [--team-id <id>] [--content-type <t>] [--tree-view]`
252
+
253
+ GraphQL mapping:
254
+
255
+ - `root` -> `markdownTreeRoot`
256
+ - `resolve` -> `markdownTreeNode`
257
+ - `children` -> `markdownTreeChildren`
258
+ - `subtree` -> `markdownTreeSubtree`
259
+
260
+ Backend error codes are surfaced explicitly from GraphQL `errors[].extensions.code`:
261
+
262
+ - `UNAUTHORIZED`
263
+ - `NOT_FOUND`
264
+ - `INVALID_SCOPE`
265
+ - `UNSUPPORTED_BRANCH`
266
+
267
+ ## Navigation Shell
268
+
269
+ Primary agent-facing discovery/navigation commands:
270
+
271
+ - `wave find "<query>" [--under <path>] [--limit <n>]`
272
+ - `wave open "<name>" [--under <path>] [--tree-view]`
273
+ - `wave ls [query] --path <path>` or `wave ls [query] --tool-key ... --node-key ...`
274
+ - `wave cat --path <path>` or `wave cat --tool-key ... --node-key ...`
275
+ - `wave tree --depth <n> --path <path>` or `wave tree --depth <n> --tool-key ... --node-key ...`
276
+
277
+ These wrap backend-owned markdown-tree primitives:
278
+
279
+ - `find` -> `markdownTreeFind`
280
+ - `open` -> `markdownTreeFind` + `markdownTreeNode`
281
+ - `ls` -> `markdownTreeChildren`
282
+ - `cat` -> `markdownTreeNode`
283
+ - `tree` -> `markdownTreeSubtree`
284
+
285
+ Discovery, ranking, canonical paths, and narrowing are backend-owned.
286
+ An empty `find` result (`candidates: []`) means no evidence for that exact query/scope, not confirmed global absence.
287
+
288
+ Ambiguity contract:
289
+
290
+ - no silent bad guesses
291
+ - returns `error.code = "ambiguous_match"` with ranked candidates in `error.details.candidates`
292
+
129
293
  ## Notes Contract
130
294
 
131
295
  The `notes` command uses exact GraphQL operation names: