monday-cli 0.4.0 → 0.5.0

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 (122) hide show
  1. package/CHANGELOG.md +368 -0
  2. package/README.md +112 -34
  3. package/dist/api/column-types.d.ts +3 -1
  4. package/dist/api/column-types.d.ts.map +1 -1
  5. package/dist/api/column-types.js +3 -1
  6. package/dist/api/column-types.js.map +1 -1
  7. package/dist/api/column-values.d.ts +5 -4
  8. package/dist/api/column-values.d.ts.map +1 -1
  9. package/dist/api/column-values.js +6 -5
  10. package/dist/api/column-values.js.map +1 -1
  11. package/dist/api/documents.d.ts +1136 -3
  12. package/dist/api/documents.d.ts.map +1 -1
  13. package/dist/api/documents.js +1828 -3
  14. package/dist/api/documents.js.map +1 -1
  15. package/dist/api/raw-write.d.ts +6 -5
  16. package/dist/api/raw-write.d.ts.map +1 -1
  17. package/dist/api/raw-write.js +7 -6
  18. package/dist/api/raw-write.js.map +1 -1
  19. package/dist/api/teams.d.ts +657 -0
  20. package/dist/api/teams.d.ts.map +1 -0
  21. package/dist/api/teams.js +880 -0
  22. package/dist/api/teams.js.map +1 -0
  23. package/dist/commands/doc/append-markdown.d.ts +117 -0
  24. package/dist/commands/doc/append-markdown.d.ts.map +1 -0
  25. package/dist/commands/doc/append-markdown.js +253 -0
  26. package/dist/commands/doc/append-markdown.js.map +1 -0
  27. package/dist/commands/doc/block-create.d.ts +114 -0
  28. package/dist/commands/doc/block-create.d.ts.map +1 -0
  29. package/dist/commands/doc/block-create.js +206 -0
  30. package/dist/commands/doc/block-create.js.map +1 -0
  31. package/dist/commands/doc/block-delete.d.ts +72 -0
  32. package/dist/commands/doc/block-delete.d.ts.map +1 -0
  33. package/dist/commands/doc/block-delete.js +161 -0
  34. package/dist/commands/doc/block-delete.js.map +1 -0
  35. package/dist/commands/doc/block-update.d.ts +75 -0
  36. package/dist/commands/doc/block-update.d.ts.map +1 -0
  37. package/dist/commands/doc/block-update.js +162 -0
  38. package/dist/commands/doc/block-update.js.map +1 -0
  39. package/dist/commands/doc/create-in-workspace.d.ts +76 -0
  40. package/dist/commands/doc/create-in-workspace.d.ts.map +1 -0
  41. package/dist/commands/doc/create-in-workspace.js +164 -0
  42. package/dist/commands/doc/create-in-workspace.js.map +1 -0
  43. package/dist/commands/doc/create-on-column.d.ts +71 -0
  44. package/dist/commands/doc/create-on-column.d.ts.map +1 -0
  45. package/dist/commands/doc/create-on-column.js +146 -0
  46. package/dist/commands/doc/create-on-column.js.map +1 -0
  47. package/dist/commands/doc/delete.d.ts +68 -0
  48. package/dist/commands/doc/delete.d.ts.map +1 -0
  49. package/dist/commands/doc/delete.js +146 -0
  50. package/dist/commands/doc/delete.js.map +1 -0
  51. package/dist/commands/doc/duplicate.d.ts +101 -0
  52. package/dist/commands/doc/duplicate.d.ts.map +1 -0
  53. package/dist/commands/doc/duplicate.js +191 -0
  54. package/dist/commands/doc/duplicate.js.map +1 -0
  55. package/dist/commands/doc/import-html.d.ts +125 -0
  56. package/dist/commands/doc/import-html.d.ts.map +1 -0
  57. package/dist/commands/doc/import-html.js +273 -0
  58. package/dist/commands/doc/import-html.js.map +1 -0
  59. package/dist/commands/doc/list.d.ts +6 -3
  60. package/dist/commands/doc/list.d.ts.map +1 -1
  61. package/dist/commands/doc/list.js +17 -48
  62. package/dist/commands/doc/list.js.map +1 -1
  63. package/dist/commands/doc/rename.d.ts +60 -0
  64. package/dist/commands/doc/rename.d.ts.map +1 -0
  65. package/dist/commands/doc/rename.js +135 -0
  66. package/dist/commands/doc/rename.js.map +1 -0
  67. package/dist/commands/index.d.ts.map +1 -1
  68. package/dist/commands/index.js +116 -0
  69. package/dist/commands/index.js.map +1 -1
  70. package/dist/commands/item/create.js +2 -2
  71. package/dist/commands/update/create.d.ts.map +1 -1
  72. package/dist/commands/update/create.js +6 -4
  73. package/dist/commands/update/create.js.map +1 -1
  74. package/dist/commands/update/edit.d.ts +4 -2
  75. package/dist/commands/update/edit.d.ts.map +1 -1
  76. package/dist/commands/update/edit.js +10 -6
  77. package/dist/commands/update/edit.js.map +1 -1
  78. package/dist/commands/update/reply.d.ts +4 -2
  79. package/dist/commands/update/reply.d.ts.map +1 -1
  80. package/dist/commands/update/reply.js +10 -6
  81. package/dist/commands/update/reply.js.map +1 -1
  82. package/dist/commands/user/_team-membership.d.ts +10 -0
  83. package/dist/commands/user/_team-membership.d.ts.map +1 -0
  84. package/dist/commands/user/_team-membership.js +88 -0
  85. package/dist/commands/user/_team-membership.js.map +1 -0
  86. package/dist/commands/user/team-add-members.d.ts +81 -0
  87. package/dist/commands/user/team-add-members.d.ts.map +1 -0
  88. package/dist/commands/user/team-add-members.js +186 -0
  89. package/dist/commands/user/team-add-members.js.map +1 -0
  90. package/dist/commands/user/team-create.d.ts +82 -0
  91. package/dist/commands/user/team-create.d.ts.map +1 -0
  92. package/dist/commands/user/team-create.js +206 -0
  93. package/dist/commands/user/team-create.js.map +1 -0
  94. package/dist/commands/user/team-delete.d.ts +56 -0
  95. package/dist/commands/user/team-delete.d.ts.map +1 -0
  96. package/dist/commands/user/team-delete.js +137 -0
  97. package/dist/commands/user/team-delete.js.map +1 -0
  98. package/dist/commands/user/team-get.d.ts +41 -0
  99. package/dist/commands/user/team-get.d.ts.map +1 -0
  100. package/dist/commands/user/team-get.js +87 -0
  101. package/dist/commands/user/team-get.js.map +1 -0
  102. package/dist/commands/user/team-list.d.ts +39 -0
  103. package/dist/commands/user/team-list.d.ts.map +1 -0
  104. package/dist/commands/user/team-list.js +90 -0
  105. package/dist/commands/user/team-list.js.map +1 -0
  106. package/dist/commands/user/team-remove-members.d.ts +71 -0
  107. package/dist/commands/user/team-remove-members.d.ts.map +1 -0
  108. package/dist/commands/user/team-remove-members.js +176 -0
  109. package/dist/commands/user/team-remove-members.js.map +1 -0
  110. package/dist/types/ids.d.ts +6 -0
  111. package/dist/types/ids.d.ts.map +1 -1
  112. package/dist/types/ids.js +46 -5
  113. package/dist/types/ids.js.map +1 -1
  114. package/dist/utils/parse-brand-list.d.ts +95 -0
  115. package/dist/utils/parse-brand-list.d.ts.map +1 -0
  116. package/dist/utils/parse-brand-list.js +96 -0
  117. package/dist/utils/parse-brand-list.js.map +1 -0
  118. package/dist/utils/source-content.d.ts +93 -0
  119. package/dist/utils/source-content.d.ts.map +1 -0
  120. package/dist/utils/source-content.js +120 -0
  121. package/dist/utils/source-content.js.map +1 -0
  122. package/package.json +1 -1
@@ -0,0 +1,176 @@
1
+ /**
2
+ * `monday user team-remove-members <tid> --users <id,...>
3
+ * [--dry-run]` — remove one or more users from a team
4
+ * (`cli-design.md` §4.3 USER section + §13 v0.5 entry;
5
+ * `v0.5-plan.md` §3 M34).
6
+ *
7
+ * **Wire shape.** Single `remove_users_from_team(team_id,
8
+ * user_ids)` round-trip via {@link removeUsersFromTeam}
9
+ * against `mutation RemoveUsersFromTeam` with `operationName:
10
+ * 'RemoveUsersFromTeam'` (R-NEW-37 W2 audit-point). Monday
11
+ * returns `ChangeTeamMembershipsResult { failed_users:
12
+ * [User!], successful_users: [User!] }` — same wire-level
13
+ * partial-success envelope as add-members. The action body
14
+ * wraps this into the §6.1 universal partial-success shape
15
+ * `data: { operation: "remove_users_from_team", team_id,
16
+ * results: [{ok, user_id, ...}] }` (D5 closure).
17
+ *
18
+ * **Argv shape.**
19
+ *
20
+ * - `<teamId>` — positional `TeamId`. Required, brand-
21
+ * validated at parse boundary.
22
+ * - `--users <id,...>` — required, comma-separated numeric
23
+ * user IDs (maps to wire `user_ids: [ID!]!`). Each entry
24
+ * brand-validated via {@link UserIdSchema} through the
25
+ * lifted {@link parseBrandedListArg} helper (R-NEW-70
26
+ * consumer #4 post-lift).
27
+ *
28
+ * **Output envelope.** Same shape as
29
+ * {@link teamAddMembersCommand} but with `operation:
30
+ * 'remove_users_from_team'` so agents that key off the
31
+ * operation literal can dispatch the right post-mutation
32
+ * recovery flow.
33
+ *
34
+ * **Wire-vs-CLI semantics asymmetry.** Same generic-
35
+ * `membership_failed`-code asymmetry as team-add-members; see
36
+ * `teamMembershipResultSchema` JSDoc in `src/api/teams.ts` for
37
+ * the canonical note + cross-link to `docs/architecture.md`'s
38
+ * "Wire-vs-CLI semantics documentation conventions" section.
39
+ *
40
+ * **Dry-run shape** per cli-design §6.4 mutation-dry-run
41
+ * variant. SINGLE planned operation entry `{operation:
42
+ * 'remove_users_from_team', team_id, user_ids: [...]}` with
43
+ * `user_ids` echoing the input argv order — Monday's wire is
44
+ * a single-shot bulk call (`remove_users_from_team(team_id,
45
+ * user_ids: [ID!]!)`), NOT a per-user fan-out like
46
+ * `monday workspace remove-users`. No preflight read fires;
47
+ * argv-derived. `meta.source: 'none'`.
48
+ *
49
+ * **Idempotent: yes** — Monday is no-op on a re-remove (the
50
+ * user already being out of the team surfaces in
51
+ * `successful_users[]` per Monday's wire convention).
52
+ *
53
+ * **Admin-permission-sensitive.** Non-admin callers surface
54
+ * `forbidden`.
55
+ *
56
+ * **Runtime body landed at v0.5-M34 IMPL.** Mirrors the
57
+ * `team-add-members` cadence verbatim modulo the `operation`
58
+ * literal — argv + `--users` parse → resolveClient → dry-run
59
+ * or live dispatch via {@link removeUsersFromTeam} → shared
60
+ * {@link projectMembershipResults} → `emitMutation`.
61
+ */
62
+ import { z } from 'zod';
63
+ import { ensureSubcommand } from '../types.js';
64
+ import { parseArgv } from '../parse-argv.js';
65
+ import { emitDryRun, emitMutation } from '../emit.js';
66
+ import { resolveClient } from '../../api/resolve-client.js';
67
+ import { TeamIdSchema, UserIdSchema } from '../../types/ids.js';
68
+ import { parseBrandedListArg } from '../../utils/parse-brand-list.js';
69
+ import { removeUsersFromTeam, teamRemoveMembersOutputSchema, } from '../../api/teams.js';
70
+ import { projectMembershipResults } from './_team-membership.js';
71
+ const inputSchema = z
72
+ .object({
73
+ teamId: TeamIdSchema,
74
+ users: z.string().min(1, '--users must not be empty'),
75
+ })
76
+ .strict();
77
+ export const teamRemoveMembersCommand = {
78
+ name: 'user.team-remove-members',
79
+ summary: 'Remove users from a team (partial-success envelope)',
80
+ examples: [
81
+ 'monday user team-remove-members 12345 --users 67890',
82
+ 'monday user team-remove-members 12345 --users 67890,67891',
83
+ 'monday user team-remove-members 12345 --users 67890 --dry-run --json',
84
+ ],
85
+ // Re-removing an already-removed user is a no-op on Monday's
86
+ // wire; mark idempotent so agents can retry on transient
87
+ // failure.
88
+ idempotent: true,
89
+ inputSchema,
90
+ outputSchema: teamRemoveMembersOutputSchema,
91
+ attach: (program, ctx) => {
92
+ const noun = ensureSubcommand(program, 'user', 'User commands');
93
+ noun
94
+ .command('team-remove-members <teamId>')
95
+ .description(teamRemoveMembersCommand.summary)
96
+ .requiredOption('--users <list>', 'Comma-separated numeric user IDs to remove (maps to wire `user_ids: [ID!]!`).')
97
+ .addHelpText('after', [
98
+ '',
99
+ 'Examples:',
100
+ ...teamRemoveMembersCommand.examples.map((e) => ` ${e}`),
101
+ '',
102
+ 'Notes:',
103
+ ' - Envelope is per-cli-design §6.1 partial-success (`results: [{user_id, ok, ...}]`).',
104
+ ' - Re-removing an absent member is a no-op (surfaces as `successful_users[]`).',
105
+ '',
106
+ ].join('\n'))
107
+ .action(async (teamIdArg, opts) => {
108
+ const parsed = parseArgv(teamRemoveMembersCommand.inputSchema, {
109
+ teamId: teamIdArg,
110
+ ...opts,
111
+ });
112
+ // Parse `--users` once at the boundary so a malformed
113
+ // user ID surfaces `usage_error` ahead of any wire call.
114
+ // Lifted helper at R-NEW-70 (consumer #4 post-lift).
115
+ const userIds = parseBrandedListArg(parsed.users, UserIdSchema, {
116
+ flagName: '--users',
117
+ entryDescription: 'numeric user ID',
118
+ hint: 'user IDs are numeric (e.g. 67890)',
119
+ emptyEntryHint: 'e.g. --users 67890,67891 — no leading, trailing, or ' +
120
+ 'duplicate commas',
121
+ });
122
+ const { client, globalFlags, apiVersion } = resolveClient(ctx, program.opts());
123
+ if (globalFlags.dryRun) {
124
+ // Minimal dry-run shape per cli-design §6.4 — single
125
+ // planned operation echoing what the live wire call
126
+ // would send. No preflight read fires; `meta.source:
127
+ // 'none'`.
128
+ emitDryRun({
129
+ ctx,
130
+ programOpts: program.opts(),
131
+ plannedChanges: [
132
+ {
133
+ operation: 'remove_users_from_team',
134
+ team_id: parsed.teamId,
135
+ user_ids: [...userIds],
136
+ },
137
+ ],
138
+ source: 'none',
139
+ cacheAgeSeconds: null,
140
+ warnings: [],
141
+ apiVersion,
142
+ });
143
+ return;
144
+ }
145
+ const result = await removeUsersFromTeam({
146
+ client,
147
+ teamId: parsed.teamId,
148
+ userIds,
149
+ });
150
+ const results = projectMembershipResults({
151
+ inputUserIds: userIds,
152
+ failedUsers: result.failedUsers,
153
+ successfulUsers: result.successfulUsers,
154
+ operation: 'remove_users_from_team',
155
+ teamId: parsed.teamId,
156
+ });
157
+ const data = {
158
+ operation: 'remove_users_from_team',
159
+ team_id: parsed.teamId,
160
+ results: [...results],
161
+ };
162
+ emitMutation({
163
+ ctx,
164
+ data,
165
+ schema: teamRemoveMembersCommand.outputSchema,
166
+ programOpts: program.opts(),
167
+ warnings: [],
168
+ source: result.source,
169
+ cacheAgeSeconds: result.cacheAgeSeconds,
170
+ complexity: result.complexity,
171
+ apiVersion,
172
+ });
173
+ });
174
+ },
175
+ };
176
+ //# sourceMappingURL=team-remove-members.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-remove-members.js","sourceRoot":"","sources":["../../../src/commands/user/team-remove-members.ts"],"names":[],"mappings":"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"}
@@ -28,8 +28,11 @@ export declare const WorkspaceIdSchema: z.core.$ZodBranded<z.ZodString, "Workspa
28
28
  export declare const UpdateIdSchema: z.core.$ZodBranded<z.ZodString, "UpdateId", "out">;
29
29
  export declare const WebhookIdSchema: z.core.$ZodBranded<z.ZodString, "WebhookId", "out">;
30
30
  export declare const DocIdSchema: z.core.$ZodBranded<z.ZodString, "DocId", "out">;
31
+ export declare const TeamIdSchema: z.core.$ZodBranded<z.ZodString, "TeamId", "out">;
32
+ export declare const DocFolderIdSchema: z.core.$ZodBranded<z.ZodString, "DocFolderId", "out">;
31
33
  export declare const ColumnIdSchema: z.core.$ZodBranded<z.ZodString, "ColumnId", "out">;
32
34
  export declare const GroupIdSchema: z.core.$ZodBranded<z.ZodString, "GroupId", "out">;
35
+ export declare const DocBlockIdSchema: z.core.$ZodBranded<z.ZodString, "DocBlockId", "out">;
33
36
  export type BoardId = z.infer<typeof BoardIdSchema>;
34
37
  export type ItemId = z.infer<typeof ItemIdSchema>;
35
38
  export type ColumnId = z.infer<typeof ColumnIdSchema>;
@@ -39,4 +42,7 @@ export type WorkspaceId = z.infer<typeof WorkspaceIdSchema>;
39
42
  export type UpdateId = z.infer<typeof UpdateIdSchema>;
40
43
  export type WebhookId = z.infer<typeof WebhookIdSchema>;
41
44
  export type DocId = z.infer<typeof DocIdSchema>;
45
+ export type TeamId = z.infer<typeof TeamIdSchema>;
46
+ export type DocFolderId = z.infer<typeof DocFolderIdSchema>;
47
+ export type DocBlockId = z.infer<typeof DocBlockIdSchema>;
42
48
  //# sourceMappingURL=ids.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/types/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAuBxB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,uBAAuB,QAAoB,CAAC;AAEzD,eAAO,MAAM,aAAa,mDAAqC,CAAC;AAChE,eAAO,MAAM,YAAY,kDAAoC,CAAC;AAC9D,eAAO,MAAM,YAAY,kDAAoC,CAAC;AAC9D,eAAO,MAAM,iBAAiB,uDAAyC,CAAC;AACxE,eAAO,MAAM,cAAc,oDAAsC,CAAC;AAClE,eAAO,MAAM,eAAe,qDAAuC,CAAC;AAOpE,eAAO,MAAM,WAAW,iDAAmC,CAAC;AAI5D,eAAO,MAAM,cAAc,oDAAmC,CAAC;AAC/D,eAAO,MAAM,aAAa,mDAAkC,CAAC;AAE7D,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AACpD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AACpD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AACxD,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC"}
1
+ {"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/types/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiCxB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,uBAAuB,QAAoB,CAAC;AAEzD,eAAO,MAAM,aAAa,mDAAqC,CAAC;AAChE,eAAO,MAAM,YAAY,kDAAoC,CAAC;AAC9D,eAAO,MAAM,YAAY,kDAAoC,CAAC;AAC9D,eAAO,MAAM,iBAAiB,uDAAyC,CAAC;AACxE,eAAO,MAAM,cAAc,oDAAsC,CAAC;AAClE,eAAO,MAAM,eAAe,qDAAuC,CAAC;AAOpE,eAAO,MAAM,WAAW,iDAAmC,CAAC;AAQ5D,eAAO,MAAM,YAAY,kDAAoC,CAAC;AAS9D,eAAO,MAAM,iBAAiB,uDAAyC,CAAC;AAIxE,eAAO,MAAM,cAAc,oDAAmC,CAAC;AAC/D,eAAO,MAAM,aAAa,mDAAkC,CAAC;AAc7D,eAAO,MAAM,gBAAgB,sDAAqC,CAAC;AAEnE,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AACpD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AACpD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AACxD,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAChD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
package/dist/types/ids.js CHANGED
@@ -1,16 +1,26 @@
1
1
  import { z } from 'zod';
2
2
  /**
3
- * Branded zod schemas for the nine ID kinds Monday surfaces (M32
4
- * adds `DocId` alongside the eight v0.1+M27 brands). Brands make
3
+ * Branded zod schemas for the twelve ID kinds Monday surfaces
4
+ * (v0.5-M36 adds `DocBlockId` alongside the v0.5-M35 `DocFolderId`,
5
+ * the v0.5-M34 `TeamId`, and nine v0.1+M27+M32 brands). Brands make
5
6
  * `BoardId`/`ItemId`/etc. nominally distinct at the type level even
6
- * though they're all numeric strings on the wire — passing a
7
- * `BoardId` where an `ItemId` is wanted becomes a compile error,
8
- * which is the whole point.
7
+ * though most are numeric strings on the wire — passing a `BoardId`
8
+ * where an `ItemId` is wanted becomes a compile error, which is the
9
+ * whole point.
9
10
  *
10
11
  * Monday's numeric IDs exceed `Number.MAX_SAFE_INTEGER` for older
11
12
  * accounts, so we keep them as decimal strings everywhere — argv
12
13
  * already arrives as strings, GraphQL responses already arrive as
13
14
  * strings, and the wire format stays stable through the CLI.
15
+ *
16
+ * Three ID kinds are non-numeric (opaque string IDs): `ColumnId`,
17
+ * `GroupId`, and `DocBlockId`. These use a non-empty-string base
18
+ * regex (`slugIdSchema`) rather than the numeric `^\d+$` regex.
19
+ * Column IDs and group IDs are lower-snake-case slugs (`status_4`,
20
+ * `topics`); doc-block IDs are opaque strings minted by Monday's
21
+ * workdocs surface — pin only "non-empty" at the brand boundary so
22
+ * the type system catches absence without mis-matching Monday's
23
+ * actual character class (UUID, base62, or any other future shape).
14
24
  */
15
25
  const numericIdSchema = z
16
26
  .string()
@@ -53,8 +63,39 @@ export const WebhookIdSchema = numericIdSchema.brand();
53
63
  // `BoardId`/`ItemId`/etc. so the type system catches an `--workspace
54
64
  // <did>` slip at compile time.
55
65
  export const DocIdSchema = numericIdSchema.brand();
66
+ // M34 (v0.5) — team writer surface (`monday user team-*`). Monday's
67
+ // `Team.id` is `ID!` on the wire (numeric on every observed account
68
+ // at API `2026-01`; empirical probe at `scripts/probe/v0.5-team-
69
+ // mutations.ts` 2026-05-15). Brand keeps `TeamId` distinct from
70
+ // `UserId` so the type system catches a `--users <tid>` slip at
71
+ // compile time (an easy mistake to make against `team-add-members
72
+ // <tid> --users <id,...>` where both args are numeric).
73
+ export const TeamIdSchema = numericIdSchema.brand();
74
+ // M35 (v0.5) — doc-level CRUD surface (`monday doc create-in-
75
+ // workspace --folder <fid>`). Monday's `Document.doc_folder_id` is
76
+ // `ID, nullable` on the wire (M32 probe) + `CreateDocWorkspaceInput.
77
+ // folder_id` accepts the same `ID` shape. Brand keeps `DocFolderId`
78
+ // distinct from `WorkspaceId` so the type system catches a slip at
79
+ // the `create-in-workspace --workspace <wid> --folder <fid>` call
80
+ // site at compile time (both args are numeric IDs but address
81
+ // distinct Monday entities — workspace vs nested-folder).
82
+ export const DocFolderIdSchema = numericIdSchema.brand();
56
83
  // Column and group IDs are stable lower-snake-case slugs ("status_4",
57
84
  // "topics") — not numeric. Validate as non-empty strings only.
58
85
  export const ColumnIdSchema = slugIdSchema.brand();
59
86
  export const GroupIdSchema = slugIdSchema.brand();
87
+ // M36 (v0.5) — per-block CRUD surface (`monday doc block-create` /
88
+ // `block-update` / `block-delete`). Monday's `DocumentBlock.id` is
89
+ // `String!` on the wire (NOT `ID` — empirical probe at
90
+ // `scripts/probe/v0.5-doc-mutations.ts` + `v0.5-inputs-and-results.ts`
91
+ // 2026-05-15; the same `String!` shape applies to the `block_id`
92
+ // arg slot on `update_doc_block` / `delete_doc_block` and to
93
+ // `DocumentBlockIdOnly.id`). The block IDs Monday mints are opaque
94
+ // — UUID-shaped in practice today, but the wire contract pins only
95
+ // "non-empty string", so the brand uses `slugIdSchema` like
96
+ // `ColumnId` / `GroupId` rather than the numeric `^\d+$` regex.
97
+ // Distinct from `DocId` (numeric — wire `ID!`) so the type system
98
+ // catches a `--parent <did>` slip at compile time (e.g.
99
+ // `block-create <docId> --parent <bidNotDid>`).
100
+ export const DocBlockIdSchema = slugIdSchema.brand();
60
101
  //# sourceMappingURL=ids.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ids.js","sourceRoot":"","sources":["../../src/types/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;GAYG;AACH,MAAM,eAAe,GAAG,CAAC;KACtB,MAAM,EAAE;KACR,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAEzD,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE;IACrC,OAAO,EAAE,yBAAyB;CACnC,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAEzD,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC,KAAK,EAAa,CAAC;AAChE,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,EAAY,CAAC;AAC9D,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,EAAY,CAAC;AAC9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC,KAAK,EAAiB,CAAC;AACxE,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAC,KAAK,EAAc,CAAC;AAClE,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,EAAe,CAAC;AACpE,uEAAuE;AACvE,gEAAgE;AAChE,mEAAmE;AACnE,0DAA0D;AAC1D,qEAAqE;AACrE,+BAA+B;AAC/B,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC,KAAK,EAAW,CAAC;AAE5D,sEAAsE;AACtE,+DAA+D;AAC/D,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,EAAc,CAAC;AAC/D,MAAM,CAAC,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,EAAa,CAAC"}
1
+ {"version":3,"file":"ids.js","sourceRoot":"","sources":["../../src/types/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,eAAe,GAAG,CAAC;KACtB,MAAM,EAAE;KACR,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAEzD,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE;IACrC,OAAO,EAAE,yBAAyB;CACnC,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAEzD,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC,KAAK,EAAa,CAAC;AAChE,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,EAAY,CAAC;AAC9D,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,EAAY,CAAC;AAC9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC,KAAK,EAAiB,CAAC;AACxE,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAC,KAAK,EAAc,CAAC;AAClE,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,EAAe,CAAC;AACpE,uEAAuE;AACvE,gEAAgE;AAChE,mEAAmE;AACnE,0DAA0D;AAC1D,qEAAqE;AACrE,+BAA+B;AAC/B,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC,KAAK,EAAW,CAAC;AAC5D,oEAAoE;AACpE,oEAAoE;AACpE,iEAAiE;AACjE,gEAAgE;AAChE,gEAAgE;AAChE,kEAAkE;AAClE,wDAAwD;AACxD,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,EAAY,CAAC;AAC9D,8DAA8D;AAC9D,mEAAmE;AACnE,qEAAqE;AACrE,oEAAoE;AACpE,mEAAmE;AACnE,kEAAkE;AAClE,8DAA8D;AAC9D,0DAA0D;AAC1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC,KAAK,EAAiB,CAAC;AAExE,sEAAsE;AACtE,+DAA+D;AAC/D,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,EAAc,CAAC;AAC/D,MAAM,CAAC,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,EAAa,CAAC;AAC7D,mEAAmE;AACnE,mEAAmE;AACnE,uDAAuD;AACvD,uEAAuE;AACvE,iEAAiE;AACjE,6DAA6D;AAC7D,mEAAmE;AACnE,mEAAmE;AACnE,4DAA4D;AAC5D,gEAAgE;AAChE,kEAAkE;AAClE,wDAAwD;AACxD,gDAAgD;AAChD,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,KAAK,EAAgB,CAAC"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Comma-separated branded-ID list argv parser (R-NEW-70 lift,
3
+ * v0.5-M34 pre-flight kickoff — ahead-of-feat per R-NEW-29 M25
4
+ * cadence; `v0.5-plan.md` §22 R-NEW-70 entry).
5
+ *
6
+ * Three sites in `src/commands/*` consume a `--<flag> <id,...>`
7
+ * comma-separated list of branded IDs at the argv-parse boundary +
8
+ * reject malformed entries as `usage_error`:
9
+ *
10
+ * - `monday workspace add-users` / `workspace remove-users` /
11
+ * `board add-users` already use the mixed numeric-or-email
12
+ * {@link parseUsersArg} helper (different shape — accepts
13
+ * emails + numeric IDs; NOT a consumer of this helper).
14
+ * - `monday doc list --workspace <wid,...>`
15
+ * (`src/commands/doc/list.ts`, M32 pre-flight — 1st pure-brand-list
16
+ * consumer; pre-lift `parseWorkspaceListArg` inline copy).
17
+ * - `monday user team-create --users <id,...>` / `team-add-members
18
+ * <tid> --users <id,...>` / `team-remove-members <tid> --users
19
+ * <id,...>` (`src/commands/user/team-*.ts`, M34 pre-flight —
20
+ * 3rd-5th consumers; would each duplicate the ~35-line inline
21
+ * pattern without this lift).
22
+ *
23
+ * Each pre-lift site shared the outer-split + trim + empty-entry +
24
+ * per-entry brand-validation outline; the per-call sites carried
25
+ * verb-specific error-message strings + detail keys + hint text. M34
26
+ * pre-flight pushed the count to 4 (1 migrated + 3 new), crossing the
27
+ * R7/R8 3-consumer threshold; this lift ships AHEAD of the M34
28
+ * pre-flight feat commit mirroring R-NEW-29's M25 cadence (lift
29
+ * commit lands first, feat commit consumes the lifted helper, Codex
30
+ * review then sees the lifted shape).
31
+ *
32
+ * **Why this is NOT folded into {@link parseUsersArg}.** The mixed
33
+ * numeric-or-email shape inflates the helper's signature with an
34
+ * `email_kind` discriminator + a directory-cache leg's source-
35
+ * aggregator coupling that's load-bearing in the fan-out path but
36
+ * irrelevant to a pure brand-list parse. Keeping the two shapes as
37
+ * sibling helpers keeps the pure-brand-list call sites readable and
38
+ * the mixed-mode fan-out call sites tightly typed.
39
+ */
40
+ import type { z } from 'zod';
41
+ export interface ParseBrandedListArgOptions {
42
+ /**
43
+ * The argv flag name including the leading dashes (e.g.
44
+ * `'--workspace'`, `'--users'`). Surfaces verbatim into
45
+ * `error.message` so the agent sees which flag rejected.
46
+ */
47
+ readonly flagName: string;
48
+ /**
49
+ * Short noun phrase describing one entry (e.g. `'numeric workspace
50
+ * ID'`, `'numeric user ID'`). Surfaces into the per-entry
51
+ * rejection message: `"--<flag> entry "<token>" is not a
52
+ * <entryDescription>"`.
53
+ */
54
+ readonly entryDescription: string;
55
+ /**
56
+ * Free-form hint surfaced into `error.details.hint` on per-entry
57
+ * brand-validation failure (e.g. `'workspace IDs are numeric
58
+ * (e.g. 12345)'`). Same hint used for both the empty-entry
59
+ * rejection (where it falls back to a generic "no leading,
60
+ * trailing, or duplicate commas" message if {@link emptyEntryHint}
61
+ * is unset) and the per-entry rejection.
62
+ */
63
+ readonly hint: string;
64
+ /**
65
+ * Optional hint override for the empty-entry rejection path
66
+ * (trailing comma / leading comma / double comma). Defaults to
67
+ * `"e.g. ${flagName} <id-or-token>,<id-or-token> — no leading,
68
+ * trailing, or duplicate commas"` when unset, which matches the
69
+ * pre-lift `parseWorkspaceListArg` shape verbatim.
70
+ */
71
+ readonly emptyEntryHint?: string;
72
+ }
73
+ /**
74
+ * Splits a comma-separated argv string into an array of brand-
75
+ * validated typed IDs. Whitespace around commas is trimmed. Empty
76
+ * entries (trailing comma, leading comma, double comma) reject
77
+ * with `usage_error.details.hint`; non-conforming entries reject
78
+ * via the supplied zod brand schema (`details.issues[]` carries
79
+ * the per-issue path/message + `details.argv_value` echoes the
80
+ * raw input so agents can correlate retries against the original
81
+ * argv).
82
+ *
83
+ * The brand-validation step uses `safeParse` so the zod error
84
+ * doesn't bubble through the runner's catch-all as
85
+ * `internal_error` (per `validation.md`'s "Never bubble raw
86
+ * ZodError out of a parse boundary" rule). Caller wraps with the
87
+ * verb's outer `parseArgv` for the rest of the argv surface.
88
+ *
89
+ * Empty input strings (`raw === ''`) reject at the per-verb input
90
+ * schema's `.min(1)` check BEFORE reaching this helper — the
91
+ * helper assumes a non-empty raw string. The empty-`raw` defensive
92
+ * branch is c8-ignored as unreachable from production.
93
+ */
94
+ export declare const parseBrandedListArg: <T>(raw: string, brandSchema: z.ZodType<T>, options: ParseBrandedListArgOptions) => readonly T[];
95
+ //# sourceMappingURL=parse-brand-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-brand-list.d.ts","sourceRoot":"","sources":["../../src/utils/parse-brand-list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAG7B,MAAM,WAAW,0BAA0B;IACzC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,EACnC,KAAK,MAAM,EACX,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EACzB,SAAS,0BAA0B,KAClC,SAAS,CAAC,EAwCZ,CAAC"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Comma-separated branded-ID list argv parser (R-NEW-70 lift,
3
+ * v0.5-M34 pre-flight kickoff — ahead-of-feat per R-NEW-29 M25
4
+ * cadence; `v0.5-plan.md` §22 R-NEW-70 entry).
5
+ *
6
+ * Three sites in `src/commands/*` consume a `--<flag> <id,...>`
7
+ * comma-separated list of branded IDs at the argv-parse boundary +
8
+ * reject malformed entries as `usage_error`:
9
+ *
10
+ * - `monday workspace add-users` / `workspace remove-users` /
11
+ * `board add-users` already use the mixed numeric-or-email
12
+ * {@link parseUsersArg} helper (different shape — accepts
13
+ * emails + numeric IDs; NOT a consumer of this helper).
14
+ * - `monday doc list --workspace <wid,...>`
15
+ * (`src/commands/doc/list.ts`, M32 pre-flight — 1st pure-brand-list
16
+ * consumer; pre-lift `parseWorkspaceListArg` inline copy).
17
+ * - `monday user team-create --users <id,...>` / `team-add-members
18
+ * <tid> --users <id,...>` / `team-remove-members <tid> --users
19
+ * <id,...>` (`src/commands/user/team-*.ts`, M34 pre-flight —
20
+ * 3rd-5th consumers; would each duplicate the ~35-line inline
21
+ * pattern without this lift).
22
+ *
23
+ * Each pre-lift site shared the outer-split + trim + empty-entry +
24
+ * per-entry brand-validation outline; the per-call sites carried
25
+ * verb-specific error-message strings + detail keys + hint text. M34
26
+ * pre-flight pushed the count to 4 (1 migrated + 3 new), crossing the
27
+ * R7/R8 3-consumer threshold; this lift ships AHEAD of the M34
28
+ * pre-flight feat commit mirroring R-NEW-29's M25 cadence (lift
29
+ * commit lands first, feat commit consumes the lifted helper, Codex
30
+ * review then sees the lifted shape).
31
+ *
32
+ * **Why this is NOT folded into {@link parseUsersArg}.** The mixed
33
+ * numeric-or-email shape inflates the helper's signature with an
34
+ * `email_kind` discriminator + a directory-cache leg's source-
35
+ * aggregator coupling that's load-bearing in the fan-out path but
36
+ * irrelevant to a pure brand-list parse. Keeping the two shapes as
37
+ * sibling helpers keeps the pure-brand-list call sites readable and
38
+ * the mixed-mode fan-out call sites tightly typed.
39
+ */
40
+ import { UsageError } from './errors.js';
41
+ /**
42
+ * Splits a comma-separated argv string into an array of brand-
43
+ * validated typed IDs. Whitespace around commas is trimmed. Empty
44
+ * entries (trailing comma, leading comma, double comma) reject
45
+ * with `usage_error.details.hint`; non-conforming entries reject
46
+ * via the supplied zod brand schema (`details.issues[]` carries
47
+ * the per-issue path/message + `details.argv_value` echoes the
48
+ * raw input so agents can correlate retries against the original
49
+ * argv).
50
+ *
51
+ * The brand-validation step uses `safeParse` so the zod error
52
+ * doesn't bubble through the runner's catch-all as
53
+ * `internal_error` (per `validation.md`'s "Never bubble raw
54
+ * ZodError out of a parse boundary" rule). Caller wraps with the
55
+ * verb's outer `parseArgv` for the rest of the argv surface.
56
+ *
57
+ * Empty input strings (`raw === ''`) reject at the per-verb input
58
+ * schema's `.min(1)` check BEFORE reaching this helper — the
59
+ * helper assumes a non-empty raw string. The empty-`raw` defensive
60
+ * branch is c8-ignored as unreachable from production.
61
+ */
62
+ export const parseBrandedListArg = (raw, brandSchema, options) => {
63
+ const tokens = raw.split(',').map((t) => t.trim());
64
+ const ids = [];
65
+ for (const token of tokens) {
66
+ if (token === '') {
67
+ throw new UsageError(`${options.flagName} contains an empty entry (trailing comma ` +
68
+ `or double comma); pass a comma-separated list of ` +
69
+ `${options.entryDescription}s.`, {
70
+ details: {
71
+ hint: options.emptyEntryHint ??
72
+ `e.g. ${options.flagName} <id>,<id> — no leading, ` +
73
+ `trailing, or duplicate commas`,
74
+ argv_value: raw,
75
+ },
76
+ });
77
+ }
78
+ const parsed = brandSchema.safeParse(token);
79
+ if (!parsed.success) {
80
+ throw new UsageError(`${options.flagName} entry ${JSON.stringify(token)} is not a ${options.entryDescription}`, {
81
+ cause: parsed.error,
82
+ details: {
83
+ issues: parsed.error.issues.map((i) => ({
84
+ path: i.path.map((p) => String(p)).join('.'),
85
+ message: i.message,
86
+ })),
87
+ argv_value: raw,
88
+ hint: options.hint,
89
+ },
90
+ });
91
+ }
92
+ ids.push(parsed.data);
93
+ }
94
+ return ids;
95
+ };
96
+ //# sourceMappingURL=parse-brand-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-brand-list.js","sourceRoot":"","sources":["../../src/utils/parse-brand-list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAmCzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,GAAW,EACX,WAAyB,EACzB,OAAmC,EACrB,EAAE;IAChB,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnD,MAAM,GAAG,GAAQ,EAAE,CAAC;IACpB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,UAAU,CAClB,GAAG,OAAO,CAAC,QAAQ,2CAA2C;gBAC5D,mDAAmD;gBACnD,GAAG,OAAO,CAAC,gBAAgB,IAAI,EACjC;gBACE,OAAO,EAAE;oBACP,IAAI,EACF,OAAO,CAAC,cAAc;wBACtB,QAAQ,OAAO,CAAC,QAAQ,2BAA2B;4BACjD,+BAA+B;oBACnC,UAAU,EAAE,GAAG;iBAChB;aACF,CACF,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,UAAU,CAClB,GAAG,OAAO,CAAC,QAAQ,UAAU,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,OAAO,CAAC,gBAAgB,EAAE,EACzF;gBACE,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE;oBACP,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBACtC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;wBAC5C,OAAO,EAAE,CAAC,CAAC,OAAO;qBACnB,CAAC,CAAC;oBACH,UAAU,EAAE,GAAG;oBACf,IAAI,EAAE,OAAO,CAAC,IAAI;iBACnB;aACF,CACF,CAAC;QACJ,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Generic file-or-stdin-or-inline-string source-content reader
3
+ * (R-v0.5-NEW-18 lift, v0.5-M37 IMPL kickoff — ahead-of-feat per
4
+ * R-NEW-29 M25 + R-NEW-70 M34 cadence; `v0.5-plan.md` §22 R-v0.5-NEW-18
5
+ * entry).
6
+ *
7
+ * Five sites consume the same shape post-lift:
8
+ *
9
+ * - `src/commands/update/create.ts` (M13; `--body <md>` /
10
+ * `--body-file <path|->`).
11
+ * - `src/commands/update/reply.ts` (M13).
12
+ * - `src/commands/update/edit.ts` (M13).
13
+ * - `src/commands/doc/import-html.ts` (M37; `--html-string <s>` /
14
+ * `--html <file|->`).
15
+ * - `src/commands/doc/append-markdown.ts` (M37; `--markdown-string
16
+ * <s>` / `--markdown <file|->`).
17
+ *
18
+ * All five materialise a content payload from one of three mutually-
19
+ * exclusive sources:
20
+ *
21
+ * 1. `inline` — literal content via an inline-string flag (e.g.
22
+ * `--body <md>`, `--html-string <s>`, `--markdown-string <s>`).
23
+ * 2. `file` — file path via a file-source flag (e.g.
24
+ * `--body-file <path>`, `--html <file>`, `--markdown <file>`).
25
+ * 3. `file === '-'` — stdin (requires the `stdin` slot wired by
26
+ * the runner).
27
+ *
28
+ * Mutex of (1) vs (2) is typically enforced at the parse boundary via
29
+ * a cross-field `.refine()` on the argv schema (see R-v0.5-NEW-20);
30
+ * the helper rejects the both-set case defensively. Inline byte-length
31
+ * cap is enforced at the parse boundary via `.refine()` (see
32
+ * R-v0.5-NEW-21); when {@link ReadSourceContentInputs.maxBytes} is
33
+ * supplied here, the same cap is applied at the runtime read boundary
34
+ * for the file / stdin path (file content size isn't known at argv-
35
+ * parse time).
36
+ *
37
+ * Throws `UsageError` for:
38
+ * - Both `inline` and `file` set (pre-parse-boundary drift).
39
+ * - Neither set (no source).
40
+ * - `file === '-'` with no `stdin` (programmer wiring bug).
41
+ * - Empty (or whitespace-only) result after read.
42
+ * - File-read failure (ENOENT / EACCES / etc.) wrapped with the
43
+ * underlying error message.
44
+ * - Oversized payload (when `maxBytes` is set) with
45
+ * `details.size_bytes` + `details.limit_bytes` + `details.source`
46
+ * ('inline' / 'file' / 'stdin') for agent introspection.
47
+ */
48
+ export interface ReadSourceContentInputs {
49
+ /** Inline-string flag value (e.g. `--body <md>` / `--html-string`). */
50
+ readonly inline: string | undefined;
51
+ /** File-source flag value (e.g. `--body-file <path>` / `--html <file>`). */
52
+ readonly file: string | undefined;
53
+ /** stdin slot wired by the runner — required for `<file-flag> -`. */
54
+ readonly stdin: NodeJS.ReadableStream | undefined;
55
+ /**
56
+ * Inline-flag display name for error messages (e.g. `'--body'`,
57
+ * `'--html-string'`). Surfaces verbatim into `error.message`.
58
+ */
59
+ readonly inlineFlagName: string;
60
+ /**
61
+ * File-source flag display name for error messages (e.g.
62
+ * `'--body-file'`, `'--html'`).
63
+ */
64
+ readonly fileFlagName: string;
65
+ /**
66
+ * Verb-specific "neither set" error message. Omit for a generic
67
+ * `${inlineFlagName} or ${fileFlagName}` phrasing. Callers usually
68
+ * supply a verb-named hint (e.g. "monday update create requires
69
+ * either --body <md> or --body-file <path>. Use --body-file - to
70
+ * read from stdin.").
71
+ */
72
+ readonly verbHint?: string;
73
+ /**
74
+ * Optional UTF-8 byte-length cap applied to the resolved content.
75
+ * When set, the helper rejects oversized payloads as `usage_error`
76
+ * with structured `details.size_bytes` / `details.limit_bytes` /
77
+ * `details.source`. M37 supplies `MAX_DOC_IMPORT_PAYLOAD_BYTES`
78
+ * (`256_000`) per D13 closure; M13 supplies nothing (no wire-side
79
+ * cap on `update` body payloads).
80
+ */
81
+ readonly maxBytes?: number;
82
+ /**
83
+ * Trim trailing whitespace from file / stdin content. Default
84
+ * `true` (matches M13 behaviour — a trailing newline from `cat
85
+ * foo.md` doesn't surface as a literal `\n` in the posted
86
+ * comment / doc payload). Inline content is always returned
87
+ * verbatim (post empty-trim rejection); the parameter only
88
+ * affects file / stdin paths.
89
+ */
90
+ readonly trimTrailingWhitespace?: boolean;
91
+ }
92
+ export declare const readSourceContent: (inputs: ReadSourceContentInputs) => Promise<string>;
93
+ //# sourceMappingURL=source-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-content.d.ts","sourceRoot":"","sources":["../../src/utils/source-content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAKH,MAAM,WAAW,uBAAuB;IACtC,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,qEAAqE;IACrE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,GAAG,SAAS,CAAC;IAClD;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAC3C;AA8BD,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,uBAAuB,KAC9B,OAAO,CAAC,MAAM,CA+EhB,CAAC"}