@parall/cli 1.34.0 → 1.36.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.
@@ -0,0 +1,19 @@
1
+ import type { ExternalConnection } from '@parall/sdk';
2
+ import type { Command } from 'commander';
3
+ export declare const EXTERNAL_TRIGGERS_FLAG = "external-triggers";
4
+ type ExternalTriggerFeatureFlagClient = {
5
+ getFeatureFlags(orgId: string): Promise<{
6
+ flags: Record<string, boolean | string | number>;
7
+ }>;
8
+ };
9
+ type IngressTokenOutputOptions = {
10
+ tokenFile?: string;
11
+ showToken?: boolean;
12
+ };
13
+ export declare function isFeatureFlagEnabled(value: boolean | string | number | undefined): boolean;
14
+ export declare function requireExternalTriggersEnabled(client: ExternalTriggerFeatureFlagClient, orgId: string): Promise<void>;
15
+ export declare function validateIngressTokenOutputOptions(opts: IngressTokenOutputOptions): void;
16
+ export declare function connectionTokenOutput(connection: ExternalConnection, opts: IngressTokenOutputOptions): Promise<ExternalConnection | Record<string, unknown>>;
17
+ export declare function registerExternalTriggerCommands(program: Command): void;
18
+ export {};
19
+ //# sourceMappingURL=external-triggers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-triggers.d.ts","sourceRoot":"","sources":["../../src/commands/external-triggers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,kBAAkB,EAInB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,eAAO,MAAM,sBAAsB,sBAAsB,CAAC;AAE1D,KAAK,gCAAgC,GAAG;IACtC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC,CAAA;KAAE,CAAC,CAAC;CAC/F,CAAC;AAEF,KAAK,yBAAyB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAsDF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAM1F;AAED,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,gCAAgC,EACxC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAKf;AAQD,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,CAKvF;AAED,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,kBAAkB,EAC9B,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAqBvD;AAkBD,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,OAAO,QAqZ/D"}
@@ -0,0 +1,488 @@
1
+ import { chmod, readFile, writeFile } from 'node:fs/promises';
2
+ import { resolveCredentials } from '../lib/client.js';
3
+ import { printError, printJson, printRefHint, stripPrllScheme } from '../lib/output.js';
4
+ const connectionStatuses = ['active', 'disabled'];
5
+ const triggerStatuses = ['active', 'paused'];
6
+ export const EXTERNAL_TRIGGERS_FLAG = 'external-triggers';
7
+ function stripUndefined(obj) {
8
+ return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined));
9
+ }
10
+ function parseIds(value, flag) {
11
+ const ids = value
12
+ .split(',')
13
+ .map((s) => stripPrllScheme(s.trim()))
14
+ .filter(Boolean);
15
+ if (ids.length === 0) {
16
+ throw new Error(`${flag} must include at least one ID.`);
17
+ }
18
+ return ids;
19
+ }
20
+ function parsePositiveInt(value, flag) {
21
+ if (value === undefined)
22
+ return undefined;
23
+ const normalized = value.trim();
24
+ const parsed = Number(normalized);
25
+ if (normalized === '' || !Number.isInteger(parsed) || parsed <= 0) {
26
+ throw new Error(`${flag} must be a positive integer.`);
27
+ }
28
+ return parsed;
29
+ }
30
+ function parseEnum(value, allowed, flag) {
31
+ if (value === undefined)
32
+ return undefined;
33
+ if (allowed.includes(value))
34
+ return value;
35
+ throw new Error(`${flag} must be one of: ${allowed.join(', ')}.`);
36
+ }
37
+ function parseJsonObject(value, flag) {
38
+ if (value === undefined)
39
+ return undefined;
40
+ let parsed;
41
+ try {
42
+ parsed = JSON.parse(value);
43
+ }
44
+ catch {
45
+ throw new Error(`${flag} must be a valid JSON object.`);
46
+ }
47
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
48
+ throw new Error(`${flag} must be a JSON object.`);
49
+ }
50
+ return parsed;
51
+ }
52
+ export function isFeatureFlagEnabled(value) {
53
+ return (value === true ||
54
+ (typeof value === 'string' && value !== '') ||
55
+ (typeof value === 'number' && value !== 0));
56
+ }
57
+ export async function requireExternalTriggersEnabled(client, orgId) {
58
+ const res = await client.getFeatureFlags(orgId);
59
+ if (!isFeatureFlagEnabled(res.flags[EXTERNAL_TRIGGERS_FLAG])) {
60
+ throw new Error('External Triggers are disabled for this organization.');
61
+ }
62
+ }
63
+ async function resolveExternalTriggerCommandContext() {
64
+ const ctx = resolveCredentials();
65
+ await requireExternalTriggersEnabled(ctx.client, ctx.orgId);
66
+ return ctx;
67
+ }
68
+ export function validateIngressTokenOutputOptions(opts) {
69
+ const count = [opts.tokenFile, opts.showToken].filter(Boolean).length;
70
+ if (count !== 1) {
71
+ throw new Error('Choose exactly one token output mode: --token-file <path> or --show-token.');
72
+ }
73
+ }
74
+ export async function connectionTokenOutput(connection, opts) {
75
+ validateIngressTokenOutputOptions(opts);
76
+ if (!connection.ingress_token) {
77
+ throw new Error('Server did not return an ingress token.');
78
+ }
79
+ if (opts.showToken)
80
+ return connection;
81
+ if (!opts.tokenFile) {
82
+ throw new Error('Choose exactly one token output mode: --token-file <path> or --show-token.');
83
+ }
84
+ await writeFile(opts.tokenFile, connection.ingress_token, { mode: 0o600 });
85
+ await chmod(opts.tokenFile, 0o600);
86
+ const redacted = { ...connection };
87
+ delete redacted.ingress_token;
88
+ delete redacted.ingress_url;
89
+ return {
90
+ ...redacted,
91
+ ingress_token_redacted: true,
92
+ ingress_url_redacted: true,
93
+ ingress_token_file: opts.tokenFile,
94
+ };
95
+ }
96
+ async function resolveTemplate(opts) {
97
+ if (opts.template !== undefined && opts.templateFile !== undefined) {
98
+ throw new Error('Do not pass --template together with --template-file.');
99
+ }
100
+ if (opts.templateFile !== undefined) {
101
+ return readFile(opts.templateFile, 'utf8');
102
+ }
103
+ if (opts.template !== undefined)
104
+ return opts.template;
105
+ if (opts.required)
106
+ throw new Error('Provide --template or --template-file.');
107
+ return undefined;
108
+ }
109
+ export function registerExternalTriggerCommands(program) {
110
+ const externalTriggers = program
111
+ .command('external-triggers')
112
+ .description('Manage External Triggers (incoming platform triggers for agents)');
113
+ externalTriggers
114
+ .command('connections')
115
+ .description('List External Trigger Connections in the organization')
116
+ .option('--limit <n>', 'Maximum number of connections to return', '50')
117
+ .option('--cursor <cursor>', 'Pagination cursor')
118
+ .action(async (opts) => {
119
+ try {
120
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
121
+ const result = await client.listExternalConnections(orgId, stripUndefined({
122
+ limit: parsePositiveInt(opts.limit, '--limit'),
123
+ cursor: opts.cursor,
124
+ }));
125
+ printJson(result);
126
+ }
127
+ catch (err) {
128
+ printError(err);
129
+ }
130
+ });
131
+ externalTriggers
132
+ .command('create-connection')
133
+ .description('Create an External Trigger Connection and return its incoming endpoint')
134
+ .requiredOption('--name <name>', 'Connection display name')
135
+ .option('--token-file <path>', 'Write the one-time token to a file with mode 0600')
136
+ .option('--show-token', 'Print the one-time token to stdout')
137
+ .action(async (opts) => {
138
+ try {
139
+ validateIngressTokenOutputOptions(opts);
140
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
141
+ const result = await client.createExternalConnection(orgId, {
142
+ display_name: opts.name,
143
+ });
144
+ printJson(await connectionTokenOutput(result, opts));
145
+ printRefHint(result.id);
146
+ }
147
+ catch (err) {
148
+ printError(err);
149
+ }
150
+ });
151
+ externalTriggers
152
+ .command('connection')
153
+ .description('Get an External Trigger Connection by ID')
154
+ .argument('<connectionId>', 'External Trigger Connection ID')
155
+ .action(async (connectionId) => {
156
+ try {
157
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
158
+ const result = await client.getExternalConnection(orgId, stripPrllScheme(connectionId));
159
+ printJson(result);
160
+ }
161
+ catch (err) {
162
+ printError(err);
163
+ }
164
+ });
165
+ externalTriggers
166
+ .command('update-connection')
167
+ .description('Update an External Trigger Connection')
168
+ .argument('<connectionId>', 'External Trigger Connection ID')
169
+ .option('--name <name>', 'Connection display name')
170
+ .option('--status <status>', 'active | disabled')
171
+ .action(async (connectionId, opts) => {
172
+ try {
173
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
174
+ const patch = stripUndefined({
175
+ display_name: opts.name,
176
+ status: parseEnum(opts.status, connectionStatuses, '--status'),
177
+ });
178
+ if (Object.keys(patch).length === 0) {
179
+ printError(new Error('No fields to update. Provide at least one option.'));
180
+ return;
181
+ }
182
+ const result = await client.updateExternalConnection(orgId, stripPrllScheme(connectionId), patch);
183
+ printJson(result);
184
+ }
185
+ catch (err) {
186
+ printError(err);
187
+ }
188
+ });
189
+ externalTriggers
190
+ .command('regenerate-connection-token')
191
+ .description('Regenerate a connection ingress token; old webhook URLs stop working')
192
+ .argument('<connectionId>', 'External Trigger Connection ID')
193
+ .option('--token-file <path>', 'Write the one-time token to a file with mode 0600')
194
+ .option('--show-token', 'Print the one-time token to stdout')
195
+ .action(async (connectionId, opts) => {
196
+ try {
197
+ validateIngressTokenOutputOptions(opts);
198
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
199
+ const result = await client.regenerateExternalConnectionIngressToken(orgId, stripPrllScheme(connectionId));
200
+ printJson(await connectionTokenOutput(result, opts));
201
+ printRefHint(result.id, 'Regenerated');
202
+ }
203
+ catch (err) {
204
+ printError(err);
205
+ }
206
+ });
207
+ externalTriggers
208
+ .command('delete-connection')
209
+ .description('Archive an External Trigger Connection')
210
+ .argument('<connectionId>', 'External Trigger Connection ID')
211
+ .action(async (connectionId) => {
212
+ try {
213
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
214
+ await client.deleteExternalConnection(orgId, stripPrllScheme(connectionId));
215
+ printJson({ ok: true });
216
+ }
217
+ catch (err) {
218
+ printError(err);
219
+ }
220
+ });
221
+ externalTriggers
222
+ .command('schema')
223
+ .description('Inspect CEL/template variables supported by a connection')
224
+ .argument('<connectionId>', 'External Trigger Connection ID')
225
+ .action(async (connectionId) => {
226
+ try {
227
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
228
+ const result = await client.getExternalTriggerSchema(orgId, stripPrllScheme(connectionId));
229
+ printJson(result);
230
+ }
231
+ catch (err) {
232
+ printError(err);
233
+ }
234
+ });
235
+ externalTriggers
236
+ .command('list')
237
+ .description('List External Triggers in the organization')
238
+ .option('--connection <connectionId>', 'Filter by External Trigger Connection ID')
239
+ .option('--creator-id <id>', 'Filter by creator user ID')
240
+ .option('--limit <n>', 'Maximum number of triggers to return', '50')
241
+ .option('--cursor <cursor>', 'Pagination cursor')
242
+ .action(async (opts) => {
243
+ try {
244
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
245
+ const result = await client.listExternalTriggers(orgId, stripUndefined({
246
+ connection_id: opts.connection ? stripPrllScheme(opts.connection) : undefined,
247
+ creator_id: opts.creatorId ? stripPrllScheme(opts.creatorId) : undefined,
248
+ limit: parsePositiveInt(opts.limit, '--limit'),
249
+ cursor: opts.cursor,
250
+ }));
251
+ printJson(result);
252
+ }
253
+ catch (err) {
254
+ printError(err);
255
+ }
256
+ });
257
+ externalTriggers
258
+ .command('create')
259
+ .description('Create an External Trigger targeting one or more agents')
260
+ .requiredOption('--connection <connectionId>', 'External Trigger Connection ID')
261
+ .requiredOption('--name <name>', 'Trigger name')
262
+ .requiredOption('--target-ids <ids>', 'Comma-separated target agent user IDs')
263
+ .option('--description <text>', 'Human-facing trigger description')
264
+ .option('--attached-to-uri <uri>', 'Attach to a prll:// resource URI')
265
+ .option('--filter <expr>', 'CEL filter expression', 'true')
266
+ .option('--filter-metadata-json <json>', 'JSON object with UI/display metadata for the filter')
267
+ .option('--template <text>', 'Liquid template for the agent input body')
268
+ .option('--template-file <path>', 'Read the Liquid template from a file')
269
+ .option('--max-runs <n>', 'Maximum delivered runs before the trigger auto-archives')
270
+ .option('--expires-at <ts>', 'Expiration time (RFC3339)')
271
+ .option('--client-context-json <json>', 'JSON object stored with the trigger')
272
+ .action(async (opts) => {
273
+ try {
274
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
275
+ const agentInputTemplate = await resolveTemplate({ ...opts, required: true });
276
+ const data = {
277
+ connection_id: stripPrllScheme(opts.connection),
278
+ name: opts.name,
279
+ target_agent_ids: parseIds(opts.targetIds, '--target-ids'),
280
+ filter_expr: opts.filter,
281
+ agent_input_template: agentInputTemplate ?? '',
282
+ ...stripUndefined({
283
+ description: opts.description,
284
+ attached_to_uri: opts.attachedToUri,
285
+ filter_display_metadata: parseJsonObject(opts.filterMetadataJson, '--filter-metadata-json'),
286
+ max_runs: parsePositiveInt(opts.maxRuns, '--max-runs'),
287
+ expires_at: opts.expiresAt,
288
+ client_context: parseJsonObject(opts.clientContextJson, '--client-context-json'),
289
+ }),
290
+ };
291
+ const result = await client.createExternalTrigger(orgId, data);
292
+ printJson(result);
293
+ printRefHint(result.id);
294
+ }
295
+ catch (err) {
296
+ printError(err);
297
+ }
298
+ });
299
+ externalTriggers
300
+ .command('get')
301
+ .description('Get an External Trigger by ID')
302
+ .argument('<triggerId>', 'External Trigger ID')
303
+ .action(async (triggerId) => {
304
+ try {
305
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
306
+ const result = await client.getExternalTrigger(orgId, stripPrllScheme(triggerId));
307
+ printJson(result);
308
+ }
309
+ catch (err) {
310
+ printError(err);
311
+ }
312
+ });
313
+ externalTriggers
314
+ .command('update')
315
+ .description('Update an External Trigger')
316
+ .argument('<triggerId>', 'External Trigger ID')
317
+ .option('--name <name>', 'Trigger name')
318
+ .option('--description <text>', 'Human-facing trigger description')
319
+ .option('--status <status>', 'active | paused')
320
+ .option('--target-ids <ids>', 'Comma-separated target agent user IDs')
321
+ .option('--attached-to-uri <uri>', 'Attach to a prll:// resource URI')
322
+ .option('--clear-attached-to', 'Explicitly clear attached_to_uri')
323
+ .option('--filter <expr>', 'CEL filter expression')
324
+ .option('--filter-metadata-json <json>', 'JSON object with UI/display metadata for the filter')
325
+ .option('--template <text>', 'Liquid template for the agent input body')
326
+ .option('--template-file <path>', 'Read the Liquid template from a file')
327
+ .option('--max-runs <n>', 'Maximum delivered runs before the trigger auto-archives')
328
+ .option('--clear-max-runs', 'Explicitly clear max_runs')
329
+ .option('--expires-at <ts>', 'Expiration time (RFC3339)')
330
+ .option('--clear-expires-at', 'Explicitly clear expires_at')
331
+ .option('--client-context-json <json>', 'JSON object stored with the trigger')
332
+ .action(async (triggerId, opts) => {
333
+ try {
334
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
335
+ const conflicts = [
336
+ [opts.attachedToUri, opts.clearAttachedTo, '--attached-to-uri', '--clear-attached-to'],
337
+ [opts.maxRuns, opts.clearMaxRuns, '--max-runs', '--clear-max-runs'],
338
+ [opts.expiresAt, opts.clearExpiresAt, '--expires-at', '--clear-expires-at'],
339
+ ];
340
+ for (const [value, clear, valueFlag, clearFlag] of conflicts) {
341
+ if (value !== undefined && clear) {
342
+ printError(new Error(`Do not pass ${valueFlag} together with ${clearFlag}.`));
343
+ return;
344
+ }
345
+ }
346
+ const agentInputTemplate = await resolveTemplate(opts);
347
+ const patch = stripUndefined({
348
+ name: opts.name,
349
+ description: opts.description,
350
+ status: parseEnum(opts.status, triggerStatuses, '--status'),
351
+ target_agent_ids: opts.targetIds !== undefined ? parseIds(opts.targetIds, '--target-ids') : undefined,
352
+ attached_to_uri: opts.attachedToUri,
353
+ attached_to_uri_clear: opts.clearAttachedTo || undefined,
354
+ filter_expr: opts.filter,
355
+ filter_display_metadata: parseJsonObject(opts.filterMetadataJson, '--filter-metadata-json'),
356
+ agent_input_template: agentInputTemplate,
357
+ max_runs: parsePositiveInt(opts.maxRuns, '--max-runs'),
358
+ max_runs_clear: opts.clearMaxRuns || undefined,
359
+ expires_at: opts.expiresAt,
360
+ expires_at_clear: opts.clearExpiresAt || undefined,
361
+ client_context: parseJsonObject(opts.clientContextJson, '--client-context-json'),
362
+ });
363
+ if (Object.keys(patch).length === 0) {
364
+ printError(new Error('No fields to update. Provide at least one option.'));
365
+ return;
366
+ }
367
+ const result = await client.updateExternalTrigger(orgId, stripPrllScheme(triggerId), patch);
368
+ printJson(result);
369
+ }
370
+ catch (err) {
371
+ printError(err);
372
+ }
373
+ });
374
+ externalTriggers
375
+ .command('pause')
376
+ .description('Pause an External Trigger')
377
+ .argument('<triggerId>', 'External Trigger ID')
378
+ .action(async (triggerId) => {
379
+ try {
380
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
381
+ const result = await client.updateExternalTrigger(orgId, stripPrllScheme(triggerId), {
382
+ status: 'paused',
383
+ });
384
+ printJson(result);
385
+ }
386
+ catch (err) {
387
+ printError(err);
388
+ }
389
+ });
390
+ externalTriggers
391
+ .command('resume')
392
+ .description('Resume a paused External Trigger')
393
+ .argument('<triggerId>', 'External Trigger ID')
394
+ .action(async (triggerId) => {
395
+ try {
396
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
397
+ const result = await client.updateExternalTrigger(orgId, stripPrllScheme(triggerId), {
398
+ status: 'active',
399
+ });
400
+ printJson(result);
401
+ }
402
+ catch (err) {
403
+ printError(err);
404
+ }
405
+ });
406
+ externalTriggers
407
+ .command('delete')
408
+ .description('Archive an External Trigger')
409
+ .argument('<triggerId>', 'External Trigger ID')
410
+ .action(async (triggerId) => {
411
+ try {
412
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
413
+ await client.deleteExternalTrigger(orgId, stripPrllScheme(triggerId));
414
+ printJson({ ok: true });
415
+ }
416
+ catch (err) {
417
+ printError(err);
418
+ }
419
+ });
420
+ externalTriggers
421
+ .command('runs')
422
+ .description('List run history for an External Trigger')
423
+ .argument('<triggerId>', 'External Trigger ID')
424
+ .option('--limit <n>', 'Maximum number of runs to return', '50')
425
+ .option('--cursor <cursor>', 'Pagination cursor')
426
+ .action(async (triggerId, opts) => {
427
+ try {
428
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
429
+ const result = await client.listExternalTriggerRuns(orgId, stripUndefined({
430
+ trigger_id: stripPrllScheme(triggerId),
431
+ limit: parsePositiveInt(opts.limit, '--limit'),
432
+ cursor: opts.cursor,
433
+ }));
434
+ printJson(result);
435
+ }
436
+ catch (err) {
437
+ printError(err);
438
+ }
439
+ });
440
+ externalTriggers
441
+ .command('run')
442
+ .description('Get a single External Trigger run')
443
+ .argument('<runId>', 'External Trigger Run ID (xrn_...)')
444
+ .action(async (runId) => {
445
+ try {
446
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
447
+ const result = await client.getExternalTriggerRun(orgId, stripPrllScheme(runId));
448
+ printJson(result);
449
+ }
450
+ catch (err) {
451
+ printError(err);
452
+ }
453
+ });
454
+ externalTriggers
455
+ .command('events')
456
+ .description('List incoming events received by External Trigger Connections')
457
+ .option('--connection <connectionId>', 'Filter by External Trigger Connection ID')
458
+ .option('--limit <n>', 'Maximum number of events to return', '50')
459
+ .option('--cursor <cursor>', 'Pagination cursor')
460
+ .action(async (opts) => {
461
+ try {
462
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
463
+ const result = await client.listExternalIngressEvents(orgId, stripUndefined({
464
+ connection_id: opts.connection ? stripPrllScheme(opts.connection) : undefined,
465
+ limit: parsePositiveInt(opts.limit, '--limit'),
466
+ cursor: opts.cursor,
467
+ }));
468
+ printJson(result);
469
+ }
470
+ catch (err) {
471
+ printError(err);
472
+ }
473
+ });
474
+ externalTriggers
475
+ .command('event')
476
+ .description('Get a single incoming event by ID')
477
+ .argument('<eventId>', 'External Trigger Event ID (xin_...)')
478
+ .action(async (eventId) => {
479
+ try {
480
+ const { client, orgId } = await resolveExternalTriggerCommandContext();
481
+ const result = await client.getExternalIngressEvent(orgId, stripPrllScheme(eventId));
482
+ printJson(result);
483
+ }
484
+ catch (err) {
485
+ printError(err);
486
+ }
487
+ });
488
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/commands/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAoSpD"}
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/commands/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAqTpD"}
@@ -148,6 +148,21 @@ export function registerTaskCommands(program) {
148
148
  printError(err);
149
149
  }
150
150
  });
151
+ tasks
152
+ .command('assigned')
153
+ .description("List pending tasks (todo + in_progress) on a member's plate, including subtasks assigned to them")
154
+ .argument('[memberId]', 'Member user ID (defaults to the authenticated user)')
155
+ .action(async (memberId) => {
156
+ try {
157
+ const { client, orgId } = resolveCredentials();
158
+ const targetId = memberId ? stripPrllScheme(memberId) : (await client.getMe()).id;
159
+ const result = await client.getMemberTasksAll(orgId, targetId);
160
+ printJson(result);
161
+ }
162
+ catch (err) {
163
+ printError(err);
164
+ }
165
+ });
151
166
  // ---- Comments subgroup ----
152
167
  const comments = tasks.command('comments').description('Manage task comments');
153
168
  comments
@@ -1 +1 @@
1
- {"version":3,"file":"wiki.d.ts","sourceRoot":"","sources":["../../src/commands/wiki.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAq2BpD"}
1
+ {"version":3,"file":"wiki.d.ts","sourceRoot":"","sources":["../../src/commands/wiki.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAk/BpD"}