@ted-galago/wave-cli 0.1.4 → 0.1.5

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
@@ -84,7 +84,25 @@ wave lists create --data-json '{"name":"Weekly List"}'
84
84
  wave list-items create --data-json '{"list_id":"123","summary":"Follow up"}'
85
85
  wave todos create --data-json '{"todo_group_id":"55","name":"Send update"}'
86
86
  wave knowledge create --data-json '{"title":"Runbook","content":"..."}'
87
+ wave notes create-member --target-member-id 67 --name "1:1 Note" --body "Strong progress"
88
+ wave notes create-manager --actor-member-id 67 --target-member-id 68 --name "Manager Note" --body "Coaching plan"
89
+ wave notes create-team --actor-member-id 67 --team-id 9 --name "Team Note" --body "Team context"
90
+ wave notes create-project --actor-member-id 67 --project-id 80 --name "Project Note" --body "Project context"
91
+ wave notes create-customer --actor-member-id 67 --customer-id 30 --name "Customer Note" --body "Customer context"
92
+ wave notes create-contact --actor-member-id 67 --contact-id 31 --name "Contact Note" --body "Contact context"
93
+ wave notes list --contentable-type Member --contentable-id 67 --member-id 67 --page 1 --per 20
94
+ wave notes show --id 1001
95
+ wave notes update --id 1001 --name "Updated Note" --body "Updated body" --status published
96
+ wave notes destroy --id 1001
87
97
  wave pulse update --id 12 --data-json '{"status":"on_track"}'
98
+ wave subtasks list --task-id 123 --page 1 --per 20
99
+ wave milestones list --rock-id 234 --page 1 --per 20
100
+ wave subitems list --list-item-id 345 --page 1 --per 20
101
+ wave subtodos list --todo-id 456 --page 1 --per 20
102
+ wave subissues list --issue-id 567 --page 1 --per 20
103
+ wave talking-points list --meeting-id 678 --page 1 --per 20
104
+ wave subtasks create --data-json '{"subtask":{"task_id":"123","member_id":"67","name":"Subtask name","description":"Subtask description"}}'
105
+ wave subissues destroy --id 999
88
106
  ```
89
107
 
90
108
  All commands require organization context via `--organization-id` or `WAVE_ORGANIZATION_ID`.
@@ -99,9 +117,56 @@ These child resources enforce parent IDs at CLI validation time:
99
117
  - `todos.create` requires `todo_group_id`
100
118
  - `rocks.create` requires `rock_collection_id`
101
119
  - `scorecards.create` requires `measurable_group_id`
120
+ - `subtasks.create` requires `task_id`
121
+ - `milestones.create` requires `rock_id`
122
+ - `subitems.create` requires `list_item_id`
123
+ - `subtodos.create` requires `todo_id`
124
+ - `subissues.create` requires `issue_id`
125
+ - `talking-points.create` requires `meeting_id`
102
126
 
103
127
  If a required parent field is missing, CLI returns JSON error with exit code `2`.
104
128
 
129
+ ## Notes Contract
130
+
131
+ The `notes` command uses exact GraphQL operation names:
132
+
133
+ - `CreateContent`
134
+ - `UpdateContent`
135
+ - `DestroyContent`
136
+ - `ContentShow`
137
+ - `ContentsIndex`
138
+
139
+ Placement rules enforced by command shape:
140
+
141
+ - `notes create-member`
142
+ - `contentable_type: "Member"`
143
+ - `contentable_id: TARGET_MEMBER_ID`
144
+ - `member_id: TARGET_MEMBER_ID`
145
+ - `focus_member_id: null`
146
+ - `focus_team_id: null`
147
+ - `notes create-manager`
148
+ - `contentable_type: "Member"`
149
+ - `contentable_id: ACTOR_MEMBER_ID`
150
+ - `member_id: ACTOR_MEMBER_ID`
151
+ - `focus_member_id: TARGET_MEMBER_ID`
152
+ - `notes create-team`
153
+ - `contentable_type: "Team"`
154
+ - `contentable_id: TEAM_ID`
155
+ - `member_id: ACTOR_MEMBER_ID`
156
+ - `focus_team_id: TEAM_ID`
157
+ - `notes create-project`
158
+ - `contentable_type: "Project"`
159
+ - `contentable_id: PROJECT_ID`
160
+ - `member_id: ACTOR_MEMBER_ID`
161
+ - `notes create-customer`
162
+ - `contentable_type: "Customer"`
163
+ - `contentable_id: CUSTOMER_ID`
164
+ - `member_id: ACTOR_MEMBER_ID`
165
+ - `notes create-contact`
166
+ - `contentable_type: "Contact"`
167
+ - `contentable_id: CONTACT_ID`
168
+ - `member_id: ACTOR_MEMBER_ID`
169
+
105
170
  ## JSON Envelope
106
171
 
107
172
  Success:
package/dist/index.cjs CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  // src/index.ts
5
5
  var import_commander2 = require("commander");
6
- var import_zod12 = require("zod");
6
+ var import_zod14 = require("zod");
7
7
 
8
8
  // src/cli.ts
9
9
  var import_commander = require("commander");
@@ -252,7 +252,7 @@ function normalizeGraphqlVariables(variables) {
252
252
  function buildGraphqlBody(input) {
253
253
  const graphqlField = toCamelCase(input.field);
254
254
  const graphqlVariables = normalizeGraphqlVariables(input.variables);
255
- const operationName = graphqlOperationName(input.command);
255
+ const operationName = input.operationName ?? graphqlOperationName(input.command);
256
256
  const variableEntries = Object.entries(graphqlVariables).filter(([, value]) => value !== void 0);
257
257
  const variableDecl = variableEntries.map(([name, value]) => `$${name}: ${withNonNull(graphqlTypeForVariable(name, value))}`).join(", ");
258
258
  const fieldArgs = variableEntries.map(([name]) => `${name}: $${name}`).join(", ");
@@ -490,12 +490,21 @@ async function runGraphqlQueryCommand(input) {
490
490
  const result = await graphqlRequest({
491
491
  config,
492
492
  command: input.command,
493
+ operationName: input.operationName,
493
494
  operationType: "query",
494
495
  field: input.field,
495
496
  variables: input.variables ?? {},
496
497
  selectionSet: input.selectionSet ?? defaultQuerySelectionSet(input.field, Boolean(input.isList)),
497
498
  isShow: input.isShow
498
499
  });
500
+ if (result.envelope.ok && input.transformData && result.envelope.data) {
501
+ const dataRecord = result.envelope.data;
502
+ const transformed = input.transformData(dataRecord[input.field]);
503
+ result.envelope.data = {
504
+ ...dataRecord,
505
+ [input.field]: transformed
506
+ };
507
+ }
499
508
  printEnvelopeAndExit(result);
500
509
  } catch (error) {
501
510
  if (error instanceof CliError) {
@@ -528,6 +537,7 @@ async function runGraphqlMutationCommand(input) {
528
537
  const result = await graphqlRequest({
529
538
  config,
530
539
  command: input.command,
540
+ operationName: input.operationName,
531
541
  operationType: "mutation",
532
542
  field: input.field,
533
543
  variables: input.variables ?? {},
@@ -2541,6 +2551,480 @@ function registerFoundationCommands(program) {
2541
2551
  });
2542
2552
  }
2543
2553
 
2554
+ // src/commands/childEntities.ts
2555
+ var import_zod12 = require("zod");
2556
+ var idSchema11 = import_zod12.z.string().min(1);
2557
+ var jsonObjectSchema = import_zod12.z.record(import_zod12.z.string(), import_zod12.z.unknown());
2558
+ function parseJsonObject2(raw) {
2559
+ try {
2560
+ const parsed = JSON.parse(raw);
2561
+ return jsonObjectSchema.parse(parsed);
2562
+ } catch (error) {
2563
+ throw new CliError({
2564
+ message: error instanceof Error ? `Invalid --data-json: ${error.message}` : "Invalid --data-json.",
2565
+ kind: "invalid_args",
2566
+ status: 400,
2567
+ exitCode: EXIT_CODES.invalidArgs
2568
+ });
2569
+ }
2570
+ }
2571
+ function normalizeBody2(raw, rootKey) {
2572
+ const payload = parseJsonObject2(raw);
2573
+ const rooted = payload[rootKey];
2574
+ if (rooted && typeof rooted === "object" && !Array.isArray(rooted)) {
2575
+ return payload;
2576
+ }
2577
+ return { [rootKey]: payload };
2578
+ }
2579
+ function assertRequiredParent(body, rootKey, parentKey) {
2580
+ const entity = body[rootKey];
2581
+ if (!entity || typeof entity !== "object" || Array.isArray(entity)) {
2582
+ throw new CliError({
2583
+ message: `Invalid payload. Expected object at "${rootKey}".`,
2584
+ kind: "invalid_args",
2585
+ status: 400,
2586
+ exitCode: EXIT_CODES.invalidArgs
2587
+ });
2588
+ }
2589
+ const value = entity[parentKey];
2590
+ if (!(typeof value === "string" && value.trim().length > 0)) {
2591
+ throw new CliError({
2592
+ message: `Missing required create field for ${rootKey}: ${parentKey}.`,
2593
+ kind: "invalid_args",
2594
+ status: 400,
2595
+ exitCode: EXIT_CODES.invalidArgs
2596
+ });
2597
+ }
2598
+ }
2599
+ function attrValue(attrs, keys) {
2600
+ if (!attrs || typeof attrs !== "object" || Array.isArray(attrs)) {
2601
+ return void 0;
2602
+ }
2603
+ const record = attrs;
2604
+ for (const key of keys) {
2605
+ if (record[key] !== void 0 && record[key] !== null && `${record[key]}`.trim() !== "") {
2606
+ return record[key];
2607
+ }
2608
+ }
2609
+ return void 0;
2610
+ }
2611
+ function normalizePlacementRow(row, parentKind, parentIdFallback, parentTypedField) {
2612
+ const typedParent = parentTypedField ? row[parentTypedField] : void 0;
2613
+ const parentId = (typeof typedParent === "string" && typedParent.trim().length > 0 ? typedParent : void 0) ?? parentIdFallback ?? null;
2614
+ const attrs = row.attributes;
2615
+ const memberId = (typeof row.memberId === "string" ? row.memberId : void 0) ?? attrValue(attrs, ["memberId", "member_id"]) ?? null;
2616
+ const creatorId = (typeof row.creatorId === "string" ? row.creatorId : void 0) ?? attrValue(attrs, ["creatorId", "creator_id"]) ?? null;
2617
+ const ownerRaw = attrValue(attrs, ["memberId", "member_id", "creatorId", "creator_id"]) ?? null;
2618
+ const description = (typeof row.description === "string" && row.description.length > 0 ? row.description : attrValue(attrs, ["description"])) ?? null;
2619
+ return {
2620
+ id: row.id ?? null,
2621
+ type: row.type ?? null,
2622
+ parent: {
2623
+ kind: parentKind,
2624
+ id: parentId
2625
+ },
2626
+ owner: {
2627
+ memberId,
2628
+ creatorId,
2629
+ raw: ownerRaw
2630
+ },
2631
+ description,
2632
+ attributes: attrs ?? {}
2633
+ };
2634
+ }
2635
+ function normalizeListPayload(payload, parentKind, parentIdFallback, parentTypedField) {
2636
+ const record = payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
2637
+ const rows = Array.isArray(record.data) ? record.data : [];
2638
+ const normalizedRows = rows.map(
2639
+ (row) => normalizePlacementRow(
2640
+ row,
2641
+ parentKind,
2642
+ parentIdFallback,
2643
+ parentTypedField
2644
+ )
2645
+ );
2646
+ return {
2647
+ data: normalizedRows,
2648
+ count: record.count ?? normalizedRows.length,
2649
+ currentPage: record.currentPage ?? 1,
2650
+ totalPages: record.totalPages ?? 1
2651
+ };
2652
+ }
2653
+ function registerChildCommands(program, config) {
2654
+ const command = program.command(config.command).description(config.description);
2655
+ command.command("list").requiredOption(`--${config.parentFlag} <${config.parentFlag}>`).option("--page <page>").option("--per <per>").action(async (opts, cmd) => {
2656
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2657
+ const organizationId = resolveOrganizationId(context.organizationId);
2658
+ const parentId = idSchema11.parse(opts[config.parentFlag.replace(/-([a-z])/g, (_, c) => c.toUpperCase())]);
2659
+ await runGraphqlQueryCommand({
2660
+ command: `${config.command}.list`,
2661
+ operationName: config.listOperationName,
2662
+ runtimeOptions: context.runtimeOptions,
2663
+ field: config.listField,
2664
+ variables: {
2665
+ organization_id: organizationId,
2666
+ [config.parentFlag.replace(/-/g, "_")]: parentId,
2667
+ page: opts.page,
2668
+ per: opts.per
2669
+ },
2670
+ isList: true,
2671
+ selectionSet: config.listSelectionSet,
2672
+ transformData: (payload) => normalizeListPayload(
2673
+ payload,
2674
+ config.parentKind,
2675
+ parentId,
2676
+ config.listParentTypedField
2677
+ )
2678
+ });
2679
+ });
2680
+ command.command("create").requiredOption("--data-json <dataJson>").action(async (opts, cmd) => {
2681
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2682
+ const organizationId = resolveOrganizationId(context.organizationId);
2683
+ const body = normalizeBody2(String(opts.dataJson), config.rootKey);
2684
+ assertRequiredParent(body, config.rootKey, config.parentFlag.replace(/-/g, "_"));
2685
+ await runGraphqlMutationCommand({
2686
+ command: `${config.command}.create`,
2687
+ operationName: config.createOperationName,
2688
+ runtimeOptions: context.runtimeOptions,
2689
+ field: config.createField,
2690
+ variables: {
2691
+ organization_id: organizationId,
2692
+ params: body
2693
+ }
2694
+ });
2695
+ });
2696
+ command.command("update").requiredOption("--id <id>").requiredOption("--data-json <dataJson>").action(async (opts, cmd) => {
2697
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2698
+ const organizationId = resolveOrganizationId(context.organizationId);
2699
+ const id = idSchema11.parse(opts.id);
2700
+ const body = normalizeBody2(String(opts.dataJson), config.rootKey);
2701
+ await runGraphqlMutationCommand({
2702
+ command: `${config.command}.update`,
2703
+ operationName: config.updateOperationName,
2704
+ runtimeOptions: context.runtimeOptions,
2705
+ field: config.updateField,
2706
+ variables: {
2707
+ organization_id: organizationId,
2708
+ [config.idVariable]: id,
2709
+ params: body
2710
+ }
2711
+ });
2712
+ });
2713
+ command.command("destroy").requiredOption("--id <id>").action(async (opts, cmd) => {
2714
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2715
+ const organizationId = resolveOrganizationId(context.organizationId);
2716
+ const id = idSchema11.parse(opts.id);
2717
+ await runGraphqlMutationCommand({
2718
+ command: `${config.command}.destroy`,
2719
+ operationName: config.destroyOperationName,
2720
+ runtimeOptions: context.runtimeOptions,
2721
+ field: config.destroyField,
2722
+ variables: {
2723
+ organization_id: organizationId,
2724
+ [config.idVariable]: id
2725
+ }
2726
+ });
2727
+ });
2728
+ }
2729
+ function registerChildEntityCommands(program) {
2730
+ registerChildCommands(program, {
2731
+ command: "subtasks",
2732
+ description: "Subtask operations",
2733
+ parentFlag: "task-id",
2734
+ parentKind: "task",
2735
+ rootKey: "subtask",
2736
+ listField: "subtasks",
2737
+ createField: "create_subtask",
2738
+ updateField: "update_subtask",
2739
+ destroyField: "destroy_subtask",
2740
+ idVariable: "subtask_id",
2741
+ listOperationName: "SubtasksForTask",
2742
+ createOperationName: "CreateSubtask",
2743
+ updateOperationName: "UpdateSubtask",
2744
+ destroyOperationName: "DestroySubtask",
2745
+ listSelectionSet: "{ data { id type name status taskId attributes } count currentPage totalPages }",
2746
+ listParentTypedField: "taskId"
2747
+ });
2748
+ registerChildCommands(program, {
2749
+ command: "milestones",
2750
+ description: "Milestone operations",
2751
+ parentFlag: "rock-id",
2752
+ parentKind: "rock",
2753
+ rootKey: "milestone",
2754
+ listField: "milestones",
2755
+ createField: "create_milestone",
2756
+ updateField: "update_milestone",
2757
+ destroyField: "destroy_milestone",
2758
+ idVariable: "milestone_id",
2759
+ listOperationName: "MilestonesForRock",
2760
+ createOperationName: "CreateMilestone",
2761
+ updateOperationName: "UpdateMilestone",
2762
+ destroyOperationName: "DestroyMilestone",
2763
+ listSelectionSet: "{ data { id type name slug status attributes } count currentPage totalPages }"
2764
+ });
2765
+ registerChildCommands(program, {
2766
+ command: "subitems",
2767
+ description: "Subitem operations",
2768
+ parentFlag: "list-item-id",
2769
+ parentKind: "listItem",
2770
+ rootKey: "subitem",
2771
+ listField: "subitems",
2772
+ createField: "create_subitem",
2773
+ updateField: "update_subitem",
2774
+ destroyField: "destroy_subitem",
2775
+ idVariable: "subitem_id",
2776
+ listOperationName: "SubitemsForListItem",
2777
+ createOperationName: "CreateSubitem",
2778
+ updateOperationName: "UpdateSubitem",
2779
+ destroyOperationName: "DestroySubitem",
2780
+ listSelectionSet: "{ data { id type name status listItemId attributes } count currentPage totalPages }",
2781
+ listParentTypedField: "listItemId"
2782
+ });
2783
+ registerChildCommands(program, {
2784
+ command: "subtodos",
2785
+ description: "Subtodo operations",
2786
+ parentFlag: "todo-id",
2787
+ parentKind: "todo",
2788
+ rootKey: "sub_todo",
2789
+ listField: "sub_todos",
2790
+ createField: "create_sub_todo",
2791
+ updateField: "update_sub_todo",
2792
+ destroyField: "destroy_sub_todo",
2793
+ idVariable: "sub_todo_id",
2794
+ listOperationName: "SubtodosForTodo",
2795
+ createOperationName: "CreateSubTodo",
2796
+ updateOperationName: "UpdateSubTodo",
2797
+ destroyOperationName: "DestroySubTodo",
2798
+ listSelectionSet: "{ data { id type name status todoId attributes } count currentPage totalPages }",
2799
+ listParentTypedField: "todoId"
2800
+ });
2801
+ registerChildCommands(program, {
2802
+ command: "subissues",
2803
+ description: "Subissue operations",
2804
+ parentFlag: "issue-id",
2805
+ parentKind: "issue",
2806
+ rootKey: "sub_issue",
2807
+ listField: "sub_issues",
2808
+ createField: "create_sub_issue",
2809
+ updateField: "update_sub_issue",
2810
+ destroyField: "destroy_sub_issue",
2811
+ idVariable: "sub_issue_id",
2812
+ listOperationName: "SubissuesForIssue",
2813
+ createOperationName: "CreateSubIssue",
2814
+ updateOperationName: "UpdateSubIssue",
2815
+ destroyOperationName: "DestroySubIssue",
2816
+ listSelectionSet: "{ data { id type name status issueId attributes } count currentPage totalPages }",
2817
+ listParentTypedField: "issueId"
2818
+ });
2819
+ registerChildCommands(program, {
2820
+ command: "talking-points",
2821
+ description: "Talking point operations",
2822
+ parentFlag: "meeting-id",
2823
+ parentKind: "meeting",
2824
+ rootKey: "talking_point",
2825
+ listField: "talking_points",
2826
+ createField: "create_talking_point",
2827
+ updateField: "update_talking_point",
2828
+ destroyField: "destroy_talking_point",
2829
+ idVariable: "talking_point_id",
2830
+ listOperationName: "TalkingPointsForMeeting",
2831
+ createOperationName: "CreateTalkingPoint",
2832
+ updateOperationName: "UpdateTalkingPoint",
2833
+ destroyOperationName: "DestroyTalkingPoint",
2834
+ listSelectionSet: "{ data { id type name description status priority rank dueDate memberId creatorId meetingId attributes } count currentPage totalPages }",
2835
+ listParentTypedField: "meetingId"
2836
+ });
2837
+ }
2838
+
2839
+ // src/commands/notes.ts
2840
+ var import_zod13 = require("zod");
2841
+ var idSchema12 = import_zod13.z.string().min(1);
2842
+ var nonEmptyString = import_zod13.z.string().min(1);
2843
+ function assertUpdateFields(params) {
2844
+ if (!params.name && !params.content && !params.status) {
2845
+ throw new CliError({
2846
+ message: "notes update requires at least one of --name, --body, or --status.",
2847
+ kind: "invalid_args",
2848
+ status: 400,
2849
+ exitCode: EXIT_CODES.invalidArgs
2850
+ });
2851
+ }
2852
+ }
2853
+ async function createContent(command, cmd, payload) {
2854
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2855
+ const organizationId = resolveOrganizationId(context.organizationId);
2856
+ return runGraphqlMutationCommand({
2857
+ command,
2858
+ operationName: "CreateContent",
2859
+ runtimeOptions: context.runtimeOptions,
2860
+ field: "create_content",
2861
+ variables: normalizeGraphqlVariables2({
2862
+ organization_id: organizationId,
2863
+ params: {
2864
+ content: payload
2865
+ }
2866
+ })
2867
+ });
2868
+ }
2869
+ function registerNoteCommands(program) {
2870
+ const notes = program.command("notes").description("Content note operations");
2871
+ notes.command("list").option("--contentable-type <contentableType>").option("--contentable-id <contentableId>").option("--member-id <memberId>").option("--focus-member-id <focusMemberId>").option("--focus-team-id <focusTeamId>").option("--page <page>").option("--per <per>").action(async (opts, cmd) => {
2872
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2873
+ const organizationId = resolveOrganizationId(context.organizationId);
2874
+ await runGraphqlQueryCommand({
2875
+ command: "notes.list",
2876
+ operationName: "ContentsIndex",
2877
+ runtimeOptions: context.runtimeOptions,
2878
+ field: "contents",
2879
+ variables: normalizeGraphqlVariables2({
2880
+ organization_id: organizationId,
2881
+ contentable_type: opts.contentableType,
2882
+ contentable_id: opts.contentableId,
2883
+ member_id: opts.memberId,
2884
+ focus_member_id: opts.focusMemberId,
2885
+ focus_team_id: opts.focusTeamId,
2886
+ page: opts.page,
2887
+ per: opts.per
2888
+ }),
2889
+ isList: true,
2890
+ selectionSet: "{ count currentPage totalPages data { id type name contentableType contentableId memberId focusMemberId focusTeamId attributes } }"
2891
+ });
2892
+ });
2893
+ notes.command("show").requiredOption("--id <id>").action(async (opts, cmd) => {
2894
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2895
+ const organizationId = resolveOrganizationId(context.organizationId);
2896
+ const id = idSchema12.parse(opts.id);
2897
+ await runGraphqlQueryCommand({
2898
+ command: "notes.show",
2899
+ operationName: "ContentShow",
2900
+ runtimeOptions: context.runtimeOptions,
2901
+ field: "content",
2902
+ variables: normalizeGraphqlVariables2({
2903
+ organization_id: organizationId,
2904
+ id
2905
+ }),
2906
+ isShow: true,
2907
+ selectionSet: "{ id type name contentableType contentableId memberId focusMemberId focusTeamId attributes }"
2908
+ });
2909
+ });
2910
+ notes.command("update").requiredOption("--id <id>").option("--name <name>").option("--body <body>").option("--status <status>").action(async (opts, cmd) => {
2911
+ assertUpdateFields({
2912
+ name: opts.name,
2913
+ content: opts.body,
2914
+ status: opts.status
2915
+ });
2916
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2917
+ const organizationId = resolveOrganizationId(context.organizationId);
2918
+ const contentId = idSchema12.parse(opts.id);
2919
+ await runGraphqlMutationCommand({
2920
+ command: "notes.update",
2921
+ operationName: "UpdateContent",
2922
+ runtimeOptions: context.runtimeOptions,
2923
+ field: "update_content",
2924
+ variables: normalizeGraphqlVariables2({
2925
+ organization_id: organizationId,
2926
+ content_id: contentId,
2927
+ params: {
2928
+ content: normalizeGraphqlVariables2({
2929
+ name: opts.name,
2930
+ content: opts.body,
2931
+ status: opts.status
2932
+ })
2933
+ }
2934
+ })
2935
+ });
2936
+ });
2937
+ notes.command("destroy").requiredOption("--id <id>").action(async (opts, cmd) => {
2938
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2939
+ const organizationId = resolveOrganizationId(context.organizationId);
2940
+ const contentId = idSchema12.parse(opts.id);
2941
+ await runGraphqlMutationCommand({
2942
+ command: "notes.destroy",
2943
+ operationName: "DestroyContent",
2944
+ runtimeOptions: context.runtimeOptions,
2945
+ field: "destroy_content",
2946
+ variables: normalizeGraphqlVariables2({
2947
+ organization_id: organizationId,
2948
+ content_id: contentId
2949
+ })
2950
+ });
2951
+ });
2952
+ notes.command("create-member").requiredOption("--target-member-id <targetMemberId>").requiredOption("--name <name>").requiredOption("--body <body>").option("--status <status>", "draft").action(async (opts, cmd) => {
2953
+ const targetMemberId = nonEmptyString.parse(opts.targetMemberId);
2954
+ await createContent("notes.create-member", cmd, {
2955
+ type: "WrittenContent",
2956
+ name: nonEmptyString.parse(opts.name),
2957
+ content: nonEmptyString.parse(opts.body),
2958
+ status: String(opts.status ?? "draft"),
2959
+ contentable_type: "Member",
2960
+ contentable_id: targetMemberId,
2961
+ member_id: targetMemberId,
2962
+ focus_member_id: null,
2963
+ focus_team_id: null
2964
+ });
2965
+ });
2966
+ notes.command("create-manager").requiredOption("--actor-member-id <actorMemberId>").requiredOption("--target-member-id <targetMemberId>").requiredOption("--name <name>").requiredOption("--body <body>").option("--status <status>", "draft").action(async (opts, cmd) => {
2967
+ const actorMemberId = nonEmptyString.parse(opts.actorMemberId);
2968
+ await createContent("notes.create-manager", cmd, {
2969
+ type: "WrittenContent",
2970
+ name: nonEmptyString.parse(opts.name),
2971
+ content: nonEmptyString.parse(opts.body),
2972
+ status: String(opts.status ?? "draft"),
2973
+ contentable_type: "Member",
2974
+ contentable_id: actorMemberId,
2975
+ member_id: actorMemberId,
2976
+ focus_member_id: nonEmptyString.parse(opts.targetMemberId)
2977
+ });
2978
+ });
2979
+ notes.command("create-team").requiredOption("--actor-member-id <actorMemberId>").requiredOption("--team-id <teamId>").requiredOption("--name <name>").requiredOption("--body <body>").option("--status <status>", "draft").action(async (opts, cmd) => {
2980
+ const actorMemberId = nonEmptyString.parse(opts.actorMemberId);
2981
+ const teamId = nonEmptyString.parse(opts.teamId);
2982
+ await createContent("notes.create-team", cmd, {
2983
+ type: "WrittenContent",
2984
+ name: nonEmptyString.parse(opts.name),
2985
+ content: nonEmptyString.parse(opts.body),
2986
+ status: String(opts.status ?? "draft"),
2987
+ contentable_type: "Team",
2988
+ contentable_id: teamId,
2989
+ member_id: actorMemberId,
2990
+ focus_team_id: teamId
2991
+ });
2992
+ });
2993
+ notes.command("create-project").requiredOption("--actor-member-id <actorMemberId>").requiredOption("--project-id <projectId>").requiredOption("--name <name>").requiredOption("--body <body>").option("--status <status>", "draft").action(async (opts, cmd) => {
2994
+ await createContent("notes.create-project", cmd, {
2995
+ type: "WrittenContent",
2996
+ name: nonEmptyString.parse(opts.name),
2997
+ content: nonEmptyString.parse(opts.body),
2998
+ status: String(opts.status ?? "draft"),
2999
+ contentable_type: "Project",
3000
+ contentable_id: nonEmptyString.parse(opts.projectId),
3001
+ member_id: nonEmptyString.parse(opts.actorMemberId)
3002
+ });
3003
+ });
3004
+ notes.command("create-customer").requiredOption("--actor-member-id <actorMemberId>").requiredOption("--customer-id <customerId>").requiredOption("--name <name>").requiredOption("--body <body>").option("--status <status>", "draft").action(async (opts, cmd) => {
3005
+ await createContent("notes.create-customer", cmd, {
3006
+ type: "WrittenContent",
3007
+ name: nonEmptyString.parse(opts.name),
3008
+ content: nonEmptyString.parse(opts.body),
3009
+ status: String(opts.status ?? "draft"),
3010
+ contentable_type: "Customer",
3011
+ contentable_id: nonEmptyString.parse(opts.customerId),
3012
+ member_id: nonEmptyString.parse(opts.actorMemberId)
3013
+ });
3014
+ });
3015
+ notes.command("create-contact").requiredOption("--actor-member-id <actorMemberId>").requiredOption("--contact-id <contactId>").requiredOption("--name <name>").requiredOption("--body <body>").option("--status <status>", "draft").action(async (opts, cmd) => {
3016
+ await createContent("notes.create-contact", cmd, {
3017
+ type: "WrittenContent",
3018
+ name: nonEmptyString.parse(opts.name),
3019
+ content: nonEmptyString.parse(opts.body),
3020
+ status: String(opts.status ?? "draft"),
3021
+ contentable_type: "Contact",
3022
+ contentable_id: nonEmptyString.parse(opts.contactId),
3023
+ member_id: nonEmptyString.parse(opts.actorMemberId)
3024
+ });
3025
+ });
3026
+ }
3027
+
2544
3028
  // src/cli.ts
2545
3029
  function buildCli() {
2546
3030
  const program = new import_commander.Command();
@@ -2573,6 +3057,8 @@ function buildCli() {
2573
3057
  registerIssueCommands(program);
2574
3058
  registerSystemToolCommands(program);
2575
3059
  registerFoundationCommands(program);
3060
+ registerChildEntityCommands(program);
3061
+ registerNoteCommands(program);
2576
3062
  return program;
2577
3063
  }
2578
3064
 
@@ -2621,13 +3107,13 @@ main().catch((error) => {
2621
3107
  exitCode: EXIT_CODES.invalidArgs
2622
3108
  });
2623
3109
  }
2624
- if (error instanceof import_zod12.ZodError || error instanceof import_commander2.InvalidArgumentError) {
3110
+ if (error instanceof import_zod14.ZodError || error instanceof import_commander2.InvalidArgumentError) {
2625
3111
  printCliFailure({
2626
3112
  status: 400,
2627
3113
  code: "invalid_args",
2628
3114
  message: "Invalid command arguments.",
2629
3115
  details: {
2630
- issues: error instanceof import_zod12.ZodError ? error.issues : [{ message: error.message, code: "invalid_argument" }]
3116
+ issues: error instanceof import_zod14.ZodError ? error.issues : [{ message: error.message, code: "invalid_argument" }]
2631
3117
  },
2632
3118
  exitCode: EXIT_CODES.invalidArgs
2633
3119
  });
package/dist/index.js CHANGED
@@ -251,7 +251,7 @@ function normalizeGraphqlVariables(variables) {
251
251
  function buildGraphqlBody(input) {
252
252
  const graphqlField = toCamelCase(input.field);
253
253
  const graphqlVariables = normalizeGraphqlVariables(input.variables);
254
- const operationName = graphqlOperationName(input.command);
254
+ const operationName = input.operationName ?? graphqlOperationName(input.command);
255
255
  const variableEntries = Object.entries(graphqlVariables).filter(([, value]) => value !== void 0);
256
256
  const variableDecl = variableEntries.map(([name, value]) => `$${name}: ${withNonNull(graphqlTypeForVariable(name, value))}`).join(", ");
257
257
  const fieldArgs = variableEntries.map(([name]) => `${name}: $${name}`).join(", ");
@@ -489,12 +489,21 @@ async function runGraphqlQueryCommand(input) {
489
489
  const result = await graphqlRequest({
490
490
  config,
491
491
  command: input.command,
492
+ operationName: input.operationName,
492
493
  operationType: "query",
493
494
  field: input.field,
494
495
  variables: input.variables ?? {},
495
496
  selectionSet: input.selectionSet ?? defaultQuerySelectionSet(input.field, Boolean(input.isList)),
496
497
  isShow: input.isShow
497
498
  });
499
+ if (result.envelope.ok && input.transformData && result.envelope.data) {
500
+ const dataRecord = result.envelope.data;
501
+ const transformed = input.transformData(dataRecord[input.field]);
502
+ result.envelope.data = {
503
+ ...dataRecord,
504
+ [input.field]: transformed
505
+ };
506
+ }
498
507
  printEnvelopeAndExit(result);
499
508
  } catch (error) {
500
509
  if (error instanceof CliError) {
@@ -527,6 +536,7 @@ async function runGraphqlMutationCommand(input) {
527
536
  const result = await graphqlRequest({
528
537
  config,
529
538
  command: input.command,
539
+ operationName: input.operationName,
530
540
  operationType: "mutation",
531
541
  field: input.field,
532
542
  variables: input.variables ?? {},
@@ -2540,6 +2550,480 @@ function registerFoundationCommands(program) {
2540
2550
  });
2541
2551
  }
2542
2552
 
2553
+ // src/commands/childEntities.ts
2554
+ import { z as z12 } from "zod";
2555
+ var idSchema11 = z12.string().min(1);
2556
+ var jsonObjectSchema = z12.record(z12.string(), z12.unknown());
2557
+ function parseJsonObject2(raw) {
2558
+ try {
2559
+ const parsed = JSON.parse(raw);
2560
+ return jsonObjectSchema.parse(parsed);
2561
+ } catch (error) {
2562
+ throw new CliError({
2563
+ message: error instanceof Error ? `Invalid --data-json: ${error.message}` : "Invalid --data-json.",
2564
+ kind: "invalid_args",
2565
+ status: 400,
2566
+ exitCode: EXIT_CODES.invalidArgs
2567
+ });
2568
+ }
2569
+ }
2570
+ function normalizeBody2(raw, rootKey) {
2571
+ const payload = parseJsonObject2(raw);
2572
+ const rooted = payload[rootKey];
2573
+ if (rooted && typeof rooted === "object" && !Array.isArray(rooted)) {
2574
+ return payload;
2575
+ }
2576
+ return { [rootKey]: payload };
2577
+ }
2578
+ function assertRequiredParent(body, rootKey, parentKey) {
2579
+ const entity = body[rootKey];
2580
+ if (!entity || typeof entity !== "object" || Array.isArray(entity)) {
2581
+ throw new CliError({
2582
+ message: `Invalid payload. Expected object at "${rootKey}".`,
2583
+ kind: "invalid_args",
2584
+ status: 400,
2585
+ exitCode: EXIT_CODES.invalidArgs
2586
+ });
2587
+ }
2588
+ const value = entity[parentKey];
2589
+ if (!(typeof value === "string" && value.trim().length > 0)) {
2590
+ throw new CliError({
2591
+ message: `Missing required create field for ${rootKey}: ${parentKey}.`,
2592
+ kind: "invalid_args",
2593
+ status: 400,
2594
+ exitCode: EXIT_CODES.invalidArgs
2595
+ });
2596
+ }
2597
+ }
2598
+ function attrValue(attrs, keys) {
2599
+ if (!attrs || typeof attrs !== "object" || Array.isArray(attrs)) {
2600
+ return void 0;
2601
+ }
2602
+ const record = attrs;
2603
+ for (const key of keys) {
2604
+ if (record[key] !== void 0 && record[key] !== null && `${record[key]}`.trim() !== "") {
2605
+ return record[key];
2606
+ }
2607
+ }
2608
+ return void 0;
2609
+ }
2610
+ function normalizePlacementRow(row, parentKind, parentIdFallback, parentTypedField) {
2611
+ const typedParent = parentTypedField ? row[parentTypedField] : void 0;
2612
+ const parentId = (typeof typedParent === "string" && typedParent.trim().length > 0 ? typedParent : void 0) ?? parentIdFallback ?? null;
2613
+ const attrs = row.attributes;
2614
+ const memberId = (typeof row.memberId === "string" ? row.memberId : void 0) ?? attrValue(attrs, ["memberId", "member_id"]) ?? null;
2615
+ const creatorId = (typeof row.creatorId === "string" ? row.creatorId : void 0) ?? attrValue(attrs, ["creatorId", "creator_id"]) ?? null;
2616
+ const ownerRaw = attrValue(attrs, ["memberId", "member_id", "creatorId", "creator_id"]) ?? null;
2617
+ const description = (typeof row.description === "string" && row.description.length > 0 ? row.description : attrValue(attrs, ["description"])) ?? null;
2618
+ return {
2619
+ id: row.id ?? null,
2620
+ type: row.type ?? null,
2621
+ parent: {
2622
+ kind: parentKind,
2623
+ id: parentId
2624
+ },
2625
+ owner: {
2626
+ memberId,
2627
+ creatorId,
2628
+ raw: ownerRaw
2629
+ },
2630
+ description,
2631
+ attributes: attrs ?? {}
2632
+ };
2633
+ }
2634
+ function normalizeListPayload(payload, parentKind, parentIdFallback, parentTypedField) {
2635
+ const record = payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
2636
+ const rows = Array.isArray(record.data) ? record.data : [];
2637
+ const normalizedRows = rows.map(
2638
+ (row) => normalizePlacementRow(
2639
+ row,
2640
+ parentKind,
2641
+ parentIdFallback,
2642
+ parentTypedField
2643
+ )
2644
+ );
2645
+ return {
2646
+ data: normalizedRows,
2647
+ count: record.count ?? normalizedRows.length,
2648
+ currentPage: record.currentPage ?? 1,
2649
+ totalPages: record.totalPages ?? 1
2650
+ };
2651
+ }
2652
+ function registerChildCommands(program, config) {
2653
+ const command = program.command(config.command).description(config.description);
2654
+ command.command("list").requiredOption(`--${config.parentFlag} <${config.parentFlag}>`).option("--page <page>").option("--per <per>").action(async (opts, cmd) => {
2655
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2656
+ const organizationId = resolveOrganizationId(context.organizationId);
2657
+ const parentId = idSchema11.parse(opts[config.parentFlag.replace(/-([a-z])/g, (_, c) => c.toUpperCase())]);
2658
+ await runGraphqlQueryCommand({
2659
+ command: `${config.command}.list`,
2660
+ operationName: config.listOperationName,
2661
+ runtimeOptions: context.runtimeOptions,
2662
+ field: config.listField,
2663
+ variables: {
2664
+ organization_id: organizationId,
2665
+ [config.parentFlag.replace(/-/g, "_")]: parentId,
2666
+ page: opts.page,
2667
+ per: opts.per
2668
+ },
2669
+ isList: true,
2670
+ selectionSet: config.listSelectionSet,
2671
+ transformData: (payload) => normalizeListPayload(
2672
+ payload,
2673
+ config.parentKind,
2674
+ parentId,
2675
+ config.listParentTypedField
2676
+ )
2677
+ });
2678
+ });
2679
+ command.command("create").requiredOption("--data-json <dataJson>").action(async (opts, cmd) => {
2680
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2681
+ const organizationId = resolveOrganizationId(context.organizationId);
2682
+ const body = normalizeBody2(String(opts.dataJson), config.rootKey);
2683
+ assertRequiredParent(body, config.rootKey, config.parentFlag.replace(/-/g, "_"));
2684
+ await runGraphqlMutationCommand({
2685
+ command: `${config.command}.create`,
2686
+ operationName: config.createOperationName,
2687
+ runtimeOptions: context.runtimeOptions,
2688
+ field: config.createField,
2689
+ variables: {
2690
+ organization_id: organizationId,
2691
+ params: body
2692
+ }
2693
+ });
2694
+ });
2695
+ command.command("update").requiredOption("--id <id>").requiredOption("--data-json <dataJson>").action(async (opts, cmd) => {
2696
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2697
+ const organizationId = resolveOrganizationId(context.organizationId);
2698
+ const id = idSchema11.parse(opts.id);
2699
+ const body = normalizeBody2(String(opts.dataJson), config.rootKey);
2700
+ await runGraphqlMutationCommand({
2701
+ command: `${config.command}.update`,
2702
+ operationName: config.updateOperationName,
2703
+ runtimeOptions: context.runtimeOptions,
2704
+ field: config.updateField,
2705
+ variables: {
2706
+ organization_id: organizationId,
2707
+ [config.idVariable]: id,
2708
+ params: body
2709
+ }
2710
+ });
2711
+ });
2712
+ command.command("destroy").requiredOption("--id <id>").action(async (opts, cmd) => {
2713
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2714
+ const organizationId = resolveOrganizationId(context.organizationId);
2715
+ const id = idSchema11.parse(opts.id);
2716
+ await runGraphqlMutationCommand({
2717
+ command: `${config.command}.destroy`,
2718
+ operationName: config.destroyOperationName,
2719
+ runtimeOptions: context.runtimeOptions,
2720
+ field: config.destroyField,
2721
+ variables: {
2722
+ organization_id: organizationId,
2723
+ [config.idVariable]: id
2724
+ }
2725
+ });
2726
+ });
2727
+ }
2728
+ function registerChildEntityCommands(program) {
2729
+ registerChildCommands(program, {
2730
+ command: "subtasks",
2731
+ description: "Subtask operations",
2732
+ parentFlag: "task-id",
2733
+ parentKind: "task",
2734
+ rootKey: "subtask",
2735
+ listField: "subtasks",
2736
+ createField: "create_subtask",
2737
+ updateField: "update_subtask",
2738
+ destroyField: "destroy_subtask",
2739
+ idVariable: "subtask_id",
2740
+ listOperationName: "SubtasksForTask",
2741
+ createOperationName: "CreateSubtask",
2742
+ updateOperationName: "UpdateSubtask",
2743
+ destroyOperationName: "DestroySubtask",
2744
+ listSelectionSet: "{ data { id type name status taskId attributes } count currentPage totalPages }",
2745
+ listParentTypedField: "taskId"
2746
+ });
2747
+ registerChildCommands(program, {
2748
+ command: "milestones",
2749
+ description: "Milestone operations",
2750
+ parentFlag: "rock-id",
2751
+ parentKind: "rock",
2752
+ rootKey: "milestone",
2753
+ listField: "milestones",
2754
+ createField: "create_milestone",
2755
+ updateField: "update_milestone",
2756
+ destroyField: "destroy_milestone",
2757
+ idVariable: "milestone_id",
2758
+ listOperationName: "MilestonesForRock",
2759
+ createOperationName: "CreateMilestone",
2760
+ updateOperationName: "UpdateMilestone",
2761
+ destroyOperationName: "DestroyMilestone",
2762
+ listSelectionSet: "{ data { id type name slug status attributes } count currentPage totalPages }"
2763
+ });
2764
+ registerChildCommands(program, {
2765
+ command: "subitems",
2766
+ description: "Subitem operations",
2767
+ parentFlag: "list-item-id",
2768
+ parentKind: "listItem",
2769
+ rootKey: "subitem",
2770
+ listField: "subitems",
2771
+ createField: "create_subitem",
2772
+ updateField: "update_subitem",
2773
+ destroyField: "destroy_subitem",
2774
+ idVariable: "subitem_id",
2775
+ listOperationName: "SubitemsForListItem",
2776
+ createOperationName: "CreateSubitem",
2777
+ updateOperationName: "UpdateSubitem",
2778
+ destroyOperationName: "DestroySubitem",
2779
+ listSelectionSet: "{ data { id type name status listItemId attributes } count currentPage totalPages }",
2780
+ listParentTypedField: "listItemId"
2781
+ });
2782
+ registerChildCommands(program, {
2783
+ command: "subtodos",
2784
+ description: "Subtodo operations",
2785
+ parentFlag: "todo-id",
2786
+ parentKind: "todo",
2787
+ rootKey: "sub_todo",
2788
+ listField: "sub_todos",
2789
+ createField: "create_sub_todo",
2790
+ updateField: "update_sub_todo",
2791
+ destroyField: "destroy_sub_todo",
2792
+ idVariable: "sub_todo_id",
2793
+ listOperationName: "SubtodosForTodo",
2794
+ createOperationName: "CreateSubTodo",
2795
+ updateOperationName: "UpdateSubTodo",
2796
+ destroyOperationName: "DestroySubTodo",
2797
+ listSelectionSet: "{ data { id type name status todoId attributes } count currentPage totalPages }",
2798
+ listParentTypedField: "todoId"
2799
+ });
2800
+ registerChildCommands(program, {
2801
+ command: "subissues",
2802
+ description: "Subissue operations",
2803
+ parentFlag: "issue-id",
2804
+ parentKind: "issue",
2805
+ rootKey: "sub_issue",
2806
+ listField: "sub_issues",
2807
+ createField: "create_sub_issue",
2808
+ updateField: "update_sub_issue",
2809
+ destroyField: "destroy_sub_issue",
2810
+ idVariable: "sub_issue_id",
2811
+ listOperationName: "SubissuesForIssue",
2812
+ createOperationName: "CreateSubIssue",
2813
+ updateOperationName: "UpdateSubIssue",
2814
+ destroyOperationName: "DestroySubIssue",
2815
+ listSelectionSet: "{ data { id type name status issueId attributes } count currentPage totalPages }",
2816
+ listParentTypedField: "issueId"
2817
+ });
2818
+ registerChildCommands(program, {
2819
+ command: "talking-points",
2820
+ description: "Talking point operations",
2821
+ parentFlag: "meeting-id",
2822
+ parentKind: "meeting",
2823
+ rootKey: "talking_point",
2824
+ listField: "talking_points",
2825
+ createField: "create_talking_point",
2826
+ updateField: "update_talking_point",
2827
+ destroyField: "destroy_talking_point",
2828
+ idVariable: "talking_point_id",
2829
+ listOperationName: "TalkingPointsForMeeting",
2830
+ createOperationName: "CreateTalkingPoint",
2831
+ updateOperationName: "UpdateTalkingPoint",
2832
+ destroyOperationName: "DestroyTalkingPoint",
2833
+ listSelectionSet: "{ data { id type name description status priority rank dueDate memberId creatorId meetingId attributes } count currentPage totalPages }",
2834
+ listParentTypedField: "meetingId"
2835
+ });
2836
+ }
2837
+
2838
+ // src/commands/notes.ts
2839
+ import { z as z13 } from "zod";
2840
+ var idSchema12 = z13.string().min(1);
2841
+ var nonEmptyString = z13.string().min(1);
2842
+ function assertUpdateFields(params) {
2843
+ if (!params.name && !params.content && !params.status) {
2844
+ throw new CliError({
2845
+ message: "notes update requires at least one of --name, --body, or --status.",
2846
+ kind: "invalid_args",
2847
+ status: 400,
2848
+ exitCode: EXIT_CODES.invalidArgs
2849
+ });
2850
+ }
2851
+ }
2852
+ async function createContent(command, cmd, payload) {
2853
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2854
+ const organizationId = resolveOrganizationId(context.organizationId);
2855
+ return runGraphqlMutationCommand({
2856
+ command,
2857
+ operationName: "CreateContent",
2858
+ runtimeOptions: context.runtimeOptions,
2859
+ field: "create_content",
2860
+ variables: normalizeGraphqlVariables2({
2861
+ organization_id: organizationId,
2862
+ params: {
2863
+ content: payload
2864
+ }
2865
+ })
2866
+ });
2867
+ }
2868
+ function registerNoteCommands(program) {
2869
+ const notes = program.command("notes").description("Content note operations");
2870
+ notes.command("list").option("--contentable-type <contentableType>").option("--contentable-id <contentableId>").option("--member-id <memberId>").option("--focus-member-id <focusMemberId>").option("--focus-team-id <focusTeamId>").option("--page <page>").option("--per <per>").action(async (opts, cmd) => {
2871
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2872
+ const organizationId = resolveOrganizationId(context.organizationId);
2873
+ await runGraphqlQueryCommand({
2874
+ command: "notes.list",
2875
+ operationName: "ContentsIndex",
2876
+ runtimeOptions: context.runtimeOptions,
2877
+ field: "contents",
2878
+ variables: normalizeGraphqlVariables2({
2879
+ organization_id: organizationId,
2880
+ contentable_type: opts.contentableType,
2881
+ contentable_id: opts.contentableId,
2882
+ member_id: opts.memberId,
2883
+ focus_member_id: opts.focusMemberId,
2884
+ focus_team_id: opts.focusTeamId,
2885
+ page: opts.page,
2886
+ per: opts.per
2887
+ }),
2888
+ isList: true,
2889
+ selectionSet: "{ count currentPage totalPages data { id type name contentableType contentableId memberId focusMemberId focusTeamId attributes } }"
2890
+ });
2891
+ });
2892
+ notes.command("show").requiredOption("--id <id>").action(async (opts, cmd) => {
2893
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2894
+ const organizationId = resolveOrganizationId(context.organizationId);
2895
+ const id = idSchema12.parse(opts.id);
2896
+ await runGraphqlQueryCommand({
2897
+ command: "notes.show",
2898
+ operationName: "ContentShow",
2899
+ runtimeOptions: context.runtimeOptions,
2900
+ field: "content",
2901
+ variables: normalizeGraphqlVariables2({
2902
+ organization_id: organizationId,
2903
+ id
2904
+ }),
2905
+ isShow: true,
2906
+ selectionSet: "{ id type name contentableType contentableId memberId focusMemberId focusTeamId attributes }"
2907
+ });
2908
+ });
2909
+ notes.command("update").requiredOption("--id <id>").option("--name <name>").option("--body <body>").option("--status <status>").action(async (opts, cmd) => {
2910
+ assertUpdateFields({
2911
+ name: opts.name,
2912
+ content: opts.body,
2913
+ status: opts.status
2914
+ });
2915
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2916
+ const organizationId = resolveOrganizationId(context.organizationId);
2917
+ const contentId = idSchema12.parse(opts.id);
2918
+ await runGraphqlMutationCommand({
2919
+ command: "notes.update",
2920
+ operationName: "UpdateContent",
2921
+ runtimeOptions: context.runtimeOptions,
2922
+ field: "update_content",
2923
+ variables: normalizeGraphqlVariables2({
2924
+ organization_id: organizationId,
2925
+ content_id: contentId,
2926
+ params: {
2927
+ content: normalizeGraphqlVariables2({
2928
+ name: opts.name,
2929
+ content: opts.body,
2930
+ status: opts.status
2931
+ })
2932
+ }
2933
+ })
2934
+ });
2935
+ });
2936
+ notes.command("destroy").requiredOption("--id <id>").action(async (opts, cmd) => {
2937
+ const context = await resolveCommandContext(cmd.optsWithGlobals());
2938
+ const organizationId = resolveOrganizationId(context.organizationId);
2939
+ const contentId = idSchema12.parse(opts.id);
2940
+ await runGraphqlMutationCommand({
2941
+ command: "notes.destroy",
2942
+ operationName: "DestroyContent",
2943
+ runtimeOptions: context.runtimeOptions,
2944
+ field: "destroy_content",
2945
+ variables: normalizeGraphqlVariables2({
2946
+ organization_id: organizationId,
2947
+ content_id: contentId
2948
+ })
2949
+ });
2950
+ });
2951
+ notes.command("create-member").requiredOption("--target-member-id <targetMemberId>").requiredOption("--name <name>").requiredOption("--body <body>").option("--status <status>", "draft").action(async (opts, cmd) => {
2952
+ const targetMemberId = nonEmptyString.parse(opts.targetMemberId);
2953
+ await createContent("notes.create-member", cmd, {
2954
+ type: "WrittenContent",
2955
+ name: nonEmptyString.parse(opts.name),
2956
+ content: nonEmptyString.parse(opts.body),
2957
+ status: String(opts.status ?? "draft"),
2958
+ contentable_type: "Member",
2959
+ contentable_id: targetMemberId,
2960
+ member_id: targetMemberId,
2961
+ focus_member_id: null,
2962
+ focus_team_id: null
2963
+ });
2964
+ });
2965
+ notes.command("create-manager").requiredOption("--actor-member-id <actorMemberId>").requiredOption("--target-member-id <targetMemberId>").requiredOption("--name <name>").requiredOption("--body <body>").option("--status <status>", "draft").action(async (opts, cmd) => {
2966
+ const actorMemberId = nonEmptyString.parse(opts.actorMemberId);
2967
+ await createContent("notes.create-manager", cmd, {
2968
+ type: "WrittenContent",
2969
+ name: nonEmptyString.parse(opts.name),
2970
+ content: nonEmptyString.parse(opts.body),
2971
+ status: String(opts.status ?? "draft"),
2972
+ contentable_type: "Member",
2973
+ contentable_id: actorMemberId,
2974
+ member_id: actorMemberId,
2975
+ focus_member_id: nonEmptyString.parse(opts.targetMemberId)
2976
+ });
2977
+ });
2978
+ notes.command("create-team").requiredOption("--actor-member-id <actorMemberId>").requiredOption("--team-id <teamId>").requiredOption("--name <name>").requiredOption("--body <body>").option("--status <status>", "draft").action(async (opts, cmd) => {
2979
+ const actorMemberId = nonEmptyString.parse(opts.actorMemberId);
2980
+ const teamId = nonEmptyString.parse(opts.teamId);
2981
+ await createContent("notes.create-team", cmd, {
2982
+ type: "WrittenContent",
2983
+ name: nonEmptyString.parse(opts.name),
2984
+ content: nonEmptyString.parse(opts.body),
2985
+ status: String(opts.status ?? "draft"),
2986
+ contentable_type: "Team",
2987
+ contentable_id: teamId,
2988
+ member_id: actorMemberId,
2989
+ focus_team_id: teamId
2990
+ });
2991
+ });
2992
+ notes.command("create-project").requiredOption("--actor-member-id <actorMemberId>").requiredOption("--project-id <projectId>").requiredOption("--name <name>").requiredOption("--body <body>").option("--status <status>", "draft").action(async (opts, cmd) => {
2993
+ await createContent("notes.create-project", cmd, {
2994
+ type: "WrittenContent",
2995
+ name: nonEmptyString.parse(opts.name),
2996
+ content: nonEmptyString.parse(opts.body),
2997
+ status: String(opts.status ?? "draft"),
2998
+ contentable_type: "Project",
2999
+ contentable_id: nonEmptyString.parse(opts.projectId),
3000
+ member_id: nonEmptyString.parse(opts.actorMemberId)
3001
+ });
3002
+ });
3003
+ notes.command("create-customer").requiredOption("--actor-member-id <actorMemberId>").requiredOption("--customer-id <customerId>").requiredOption("--name <name>").requiredOption("--body <body>").option("--status <status>", "draft").action(async (opts, cmd) => {
3004
+ await createContent("notes.create-customer", cmd, {
3005
+ type: "WrittenContent",
3006
+ name: nonEmptyString.parse(opts.name),
3007
+ content: nonEmptyString.parse(opts.body),
3008
+ status: String(opts.status ?? "draft"),
3009
+ contentable_type: "Customer",
3010
+ contentable_id: nonEmptyString.parse(opts.customerId),
3011
+ member_id: nonEmptyString.parse(opts.actorMemberId)
3012
+ });
3013
+ });
3014
+ notes.command("create-contact").requiredOption("--actor-member-id <actorMemberId>").requiredOption("--contact-id <contactId>").requiredOption("--name <name>").requiredOption("--body <body>").option("--status <status>", "draft").action(async (opts, cmd) => {
3015
+ await createContent("notes.create-contact", cmd, {
3016
+ type: "WrittenContent",
3017
+ name: nonEmptyString.parse(opts.name),
3018
+ content: nonEmptyString.parse(opts.body),
3019
+ status: String(opts.status ?? "draft"),
3020
+ contentable_type: "Contact",
3021
+ contentable_id: nonEmptyString.parse(opts.contactId),
3022
+ member_id: nonEmptyString.parse(opts.actorMemberId)
3023
+ });
3024
+ });
3025
+ }
3026
+
2543
3027
  // src/cli.ts
2544
3028
  function buildCli() {
2545
3029
  const program = new Command();
@@ -2572,6 +3056,8 @@ function buildCli() {
2572
3056
  registerIssueCommands(program);
2573
3057
  registerSystemToolCommands(program);
2574
3058
  registerFoundationCommands(program);
3059
+ registerChildEntityCommands(program);
3060
+ registerNoteCommands(program);
2575
3061
  return program;
2576
3062
  }
2577
3063
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ted-galago/wave-cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "wave": "dist/index.js"