@kivel.io/cli 0.10.1 → 0.11.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @kivel.io/cli
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - e137d14: Add email search filters, resumable wait cursors and checkpoints before triggering new mail. Add message inspection, triage and email forwarding history.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [e137d14]
12
+ - @kivel.io/sdk@0.11.0
13
+
3
14
  ## 0.10.1
4
15
 
5
16
  ### Patch Changes
@@ -9,7 +9,8 @@ export function needsInput(args) {
9
9
  (args[0] === 'credential' && ['save', 'update'].includes(args[1] ?? '')) ||
10
10
  (args[0] === 'approval' && args[1] === 'ask') ||
11
11
  (args[0] === 'monitor' && args[1] === 'create') ||
12
- (args[0] === 'email' && ['draft-create', 'draft-submit'].includes(args[1] ?? '')) ||
12
+ (args[0] === 'email' &&
13
+ ['draft-create', 'draft-submit', 'message-update'].includes(args[1] ?? '')) ||
13
14
  (args[0] === 'event' && args[1] === 'wait') ||
14
15
  (['oauth', 'mock', 'mcp-server', 'status-page', 'job'].includes(args[0] ?? '') &&
15
16
  ['create', 'update'].includes(args[1] ?? '')) ||
@@ -54,6 +55,24 @@ export async function agentCommand(client, args, input) {
54
55
  allowed.add('--after');
55
56
  allowed.add('--timeout-seconds');
56
57
  }
58
+ if (group === 'email' && ['messages', 'wait'].includes(action ?? '')) {
59
+ for (const flag of [
60
+ '--from',
61
+ '--mail-from',
62
+ '--subject',
63
+ '--text',
64
+ '--has-code',
65
+ '--has-link',
66
+ '--has-attachment',
67
+ '--read',
68
+ '--label',
69
+ '--cursor',
70
+ '--limit',
71
+ ])
72
+ allowed.add(flag);
73
+ if (action === 'wait')
74
+ allowed.add('--checkpoint');
75
+ }
57
76
  if (group === 'email' && action === 'threads') {
58
77
  allowed.add('--cursor');
59
78
  allowed.add('--limit');
@@ -86,7 +105,7 @@ export async function agentCommand(client, args, input) {
86
105
  throw new Error(`Unknown option: ${value}`);
87
106
  if (flags.has(value))
88
107
  throw new Error(`Duplicate option: ${value}`);
89
- if (value === '--persistent')
108
+ if (value === '--persistent' || value === '--checkpoint')
90
109
  flags.set(value, 'true');
91
110
  else {
92
111
  const next = tail[++i];
@@ -122,6 +141,28 @@ export async function agentCommand(client, args, input) {
122
141
  const idempotencyKey = take('--idempotency-key');
123
142
  const emailSettings = { activeDays: number('--active-days'), localPart: take('--local-part') };
124
143
  const threadPage = { cursor: take('--cursor'), limit: number('--limit') };
144
+ const boolean = (key) => {
145
+ const value = take(key);
146
+ if (value === undefined)
147
+ return undefined;
148
+ if (value === 'true' || value === 'false')
149
+ return value === 'true';
150
+ throw new Error(`Use true or false for ${key}.`);
151
+ };
152
+ const emailSearch = {
153
+ ...threadPage,
154
+ token,
155
+ from: take('--from'),
156
+ mailFrom: take('--mail-from'),
157
+ subject: take('--subject'),
158
+ text: take('--text'),
159
+ hasCode: boolean('--has-code'),
160
+ hasLink: boolean('--has-link'),
161
+ hasAttachment: boolean('--has-attachment'),
162
+ read: boolean('--read'),
163
+ label: take('--label'),
164
+ };
165
+ const checkpoint = boolean('--checkpoint');
125
166
  const approvalId = take('--approval-id');
126
167
  const passwordLength = number('--length');
127
168
  if (flags.size)
@@ -381,6 +422,8 @@ export async function agentCommand(client, args, input) {
381
422
  return client.inboxDeliveries(id(), token);
382
423
  }
383
424
  if (group === 'email') {
425
+ if (action === 'deliveries')
426
+ return client.emailDeliveries(id());
384
427
  if (action === 'threads') {
385
428
  if (positional.length > 1)
386
429
  throw new Error('Provide at most one inbox ID.');
@@ -424,10 +467,17 @@ export async function agentCommand(client, args, input) {
424
467
  exact(0);
425
468
  return client.createEmailInbox(emailSettings);
426
469
  }
470
+ if (action === 'message' || action === 'message-update') {
471
+ exact(2);
472
+ const [inboxId, messageId] = positional;
473
+ return action === 'message'
474
+ ? client.emailMessage(inboxId, messageId, token)
475
+ : client.updateEmailMessage(inboxId, messageId, json());
476
+ }
427
477
  if (action === 'messages')
428
- return client.emails(id(), token);
478
+ return client.emails(id(), emailSearch);
429
479
  if (action === 'wait')
430
- return client.waitForEmail(id(), wait);
480
+ return client.waitForEmail(id(), { ...wait, ...emailSearch, checkpoint });
431
481
  }
432
482
  if (group === 'mock' || group === 'mcp-server') {
433
483
  if (action === 'create') {
@@ -1,4 +1,4 @@
1
1
  export { needsInput } from './agent-commands.js';
2
2
  import type { Kivel } from '@kivel.io/sdk';
3
- export declare const help = "kivel tools | usage | resources\nkivel --version\nkivel plans | activity\nkivel agent login <name> [--client <client>]\nkivel agent token < login.json\nkivel agent trial <name> [--human-email <email>] [--client <client>]\nkivel agent list\nkivel authenticator add < authenticator.json\nkivel authenticator list|code|delete [id]\nkivel authenticator rename <id> <name>\nkivel email attachment|download-attachment <inbox-id> <message-id> <attachment-id>\nkivel email create [--active-days <1-7>] [--local-part <paid-address>]\nkivel email list\nkivel email clear <id>\nkivel email forward <id> [--token <token>] < forwarding.json\nkivel email send <id> --idempotency-key <unique-key> < message.json\nkivel event wait [--timeout-seconds <1-30>] < sources.json\nkivel test-wallet create|list|inspect|update|delete [id]\nkivel test-wallet balance|transactions <id>\nkivel test-wallet pay|top-up <id> < test-payment.json\nkivel test-paywall create|list|inspect|update|delete [id]\nkivel test-checkout create|list|inspect|update|delete [id]\nkivel test-checkout complete|confirm <id> < test-checkout.json\nTest payments use fake units only. Create/update read JSON from stdin. Agent keys cannot set wallet limits; only a human owner/admin can. Resume approval with the same payment idempotencyKey.\nkivel credential save < credential.json\nkivel credential list\nkivel credential inspect|delete <id>\nkivel credential update <id> < changes.json\nkivel credential reveal <id> [--approval-id <id>]\nkivel password generate [--length <n>]\nkivel email threads [inbox-id] [--cursor <cursor>] [--limit <n>]\nkivel email thread <inbox-id> <thread-id>\nkivel email drafts|rules <inbox-id>\nkivel email draft-create <inbox-id> < content.json\nkivel email draft-inspect|draft-delete <draft-id>\nkivel email draft-submit <draft-id> [< settings.json]\nkivel email messages|wait <id> [--token <token>] [--after <id>] [--timeout-seconds <n>]\nkivel memory set <namespace> <key> [--ttl-seconds <n>] < value.json\nkivel memory get|delete <namespace> <key>\nkivel memory list <namespace> [--prefix <prefix>]\nkivel monitor create < monitor.json\nkivel monitor list|inspect|pause|resume|delete [id]\nkivel monitor ping|fail <ping-token>\nkivel monitor accept-dns <id>\nkivel job create [--ttl-seconds <n>] < job.json\nkivel job list|inspect|cancel [id]\nkivel status-page create|update [id] < page.json\nkivel smtp create [--ttl-seconds <n>]\nkivel smtp rotate <id>\nkivel phone available [US-area-code]\nkivel phone create <E.164-number> --idempotency-key <unique-key>\nkivel phone list|release|messages|wait [id] [--after <id>] [--timeout-seconds <n>]\nkivel approval ask < question.json\nkivel approval list|pending|inspect|wait [id] [--timeout-seconds <n>]\nkivel inbox requests|wait|deliveries <id> [--token <token>]\nkivel inbox response|forward <id> [--token <token>] < settings.json\nkivel oauth create [--ttl-seconds <n>] < provider.json\nkivel oauth update <id> < provider.json\nkivel oauth list|inspect|calls|renew|delete [id]\nkivel mock create|update [id] < config.json\nkivel mock calls|reset <id> [--token <token>]\nkivel mcp-server create < config.json\nkivel inbox|email|mock|mcp-server|file inspect|delete|renew <id> [--token <token>]\nkivel inbox|mock|mcp-server|file sharing <id> --visibility private|public [--token <token>]\nkivel describe <tool-id>\nkivel run <tool-id> [--file <filename>] [--options '{\"action\":\"minify\"}'] < input.txt\nkivel inbox create [--visibility private|public]\nkivel listen <inbox-id> [--token <inspection-token>] [--forward http://localhost:3000] [--all]\nkivel api <GET|HEAD|OPTIONS|POST|PUT|PATCH|DELETE> /api/path-or-/mock/path [--token <resource-token>] < body.json\nkivel upload <filename> [--visibility private|public] [--max-downloads 1] < file.bin\nkivel download <file-id> [--access-token token] > file.bin\n\nSet KIVEL_URL and KIVEL_API_KEY. Commands output JSON; downloads output binary; help is plain text. Mutations are never retried. Authenticators are only for accounts your human asked you to create or operate. Attachment downloads output untrusted binary files; attachment links expire in two minutes.\nCreation also accepts --ttl-seconds <n> and --persistent. Webhook receiving is public by default; inspection always needs workspace credentials or the inspection token. Use inbox create --visibility private only when senders can add X-Access-Token. Other resources default to private.";
3
+ export declare const help = "kivel tools | usage | resources\nkivel --version\nkivel plans | activity\nkivel agent login <name> [--client <client>]\nkivel agent token < login.json\nkivel agent trial <name> [--human-email <email>] [--client <client>]\nkivel agent list\nkivel authenticator add < authenticator.json\nkivel authenticator list|code|delete [id]\nkivel authenticator rename <id> <name>\nkivel email attachment|download-attachment <inbox-id> <message-id> <attachment-id>\nkivel email create [--active-days <1-7>] [--local-part <paid-address>]\nkivel email list\nkivel email clear <id>\nkivel email forward <id> [--token <token>] < forwarding.json\nkivel email send <id> --idempotency-key <unique-key> < message.json\nkivel event wait [--timeout-seconds <1-30>] < sources.json\nkivel test-wallet create|list|inspect|update|delete [id]\nkivel test-wallet balance|transactions <id>\nkivel test-wallet pay|top-up <id> < test-payment.json\nkivel test-paywall create|list|inspect|update|delete [id]\nkivel test-checkout create|list|inspect|update|delete [id]\nkivel test-checkout complete|confirm <id> < test-checkout.json\nTest payments use fake units only. Create/update read JSON from stdin. Agent keys cannot set wallet limits; only a human owner/admin can. Resume approval with the same payment idempotencyKey.\nkivel credential save < credential.json\nkivel credential list\nkivel credential inspect|delete <id>\nkivel credential update <id> < changes.json\nkivel credential reveal <id> [--approval-id <id>]\nkivel password generate [--length <n>]\nkivel email message <inbox-id> <message-id>\nkivel email message-update <inbox-id> <message-id> < update.json\nkivel email deliveries <inbox-id>\nkivel email threads [inbox-id] [--cursor <cursor>] [--limit <n>]\nkivel email thread <inbox-id> <thread-id>\nkivel email drafts|rules <inbox-id>\nkivel email draft-create <inbox-id> < content.json\nkivel email draft-inspect|draft-delete <draft-id>\nkivel email draft-submit <draft-id> [< settings.json]\nkivel email messages|wait <id> [--cursor <cursor>] [--limit <n>] [--from <address>] [--mail-from <address>] [--subject <text>] [--text <text>] [--has-code true|false] [--has-link true|false] [--has-attachment true|false] [--read true|false] [--label <label>]\nkivel email wait <id> [--checkpoint] [--after <id>] [--timeout-seconds <n>] [--token <token>]\nkivel memory set <namespace> <key> [--ttl-seconds <n>] < value.json\nkivel memory get|delete <namespace> <key>\nkivel memory list <namespace> [--prefix <prefix>]\nkivel monitor create < monitor.json\nkivel monitor list|inspect|pause|resume|delete [id]\nkivel monitor ping|fail <ping-token>\nkivel monitor accept-dns <id>\nkivel job create [--ttl-seconds <n>] < job.json\nkivel job list|inspect|cancel [id]\nkivel status-page create|update [id] < page.json\nkivel smtp create [--ttl-seconds <n>]\nkivel smtp rotate <id>\nkivel phone available [US-area-code]\nkivel phone create <E.164-number> --idempotency-key <unique-key>\nkivel phone list|release|messages|wait [id] [--after <id>] [--timeout-seconds <n>]\nkivel approval ask < question.json\nkivel approval list|pending|inspect|wait [id] [--timeout-seconds <n>]\nkivel inbox requests|wait|deliveries <id> [--token <token>]\nkivel inbox response|forward <id> [--token <token>] < settings.json\nkivel oauth create [--ttl-seconds <n>] < provider.json\nkivel oauth update <id> < provider.json\nkivel oauth list|inspect|calls|renew|delete [id]\nkivel mock create|update [id] < config.json\nkivel mock calls|reset <id> [--token <token>]\nkivel mcp-server create < config.json\nkivel inbox|email|mock|mcp-server|file inspect|delete|renew <id> [--token <token>]\nkivel inbox|mock|mcp-server|file sharing <id> --visibility private|public [--token <token>]\nkivel describe <tool-id>\nkivel run <tool-id> [--file <filename>] [--options '{\"action\":\"minify\"}'] < input.txt\nkivel inbox create [--visibility private|public]\nkivel listen <inbox-id> [--token <inspection-token>] [--forward http://localhost:3000] [--all]\nkivel api <GET|HEAD|OPTIONS|POST|PUT|PATCH|DELETE> /api/path-or-/mock/path [--token <resource-token>] < body.json\nkivel upload <filename> [--visibility private|public] [--max-downloads 1] < file.bin\nkivel download <file-id> [--access-token token] > file.bin\n\nSet KIVEL_URL and KIVEL_API_KEY. Commands output JSON; downloads output binary; help is plain text. Mutations are never retried. Authenticators are only for accounts your human asked you to create or operate. Attachment downloads output untrusted binary files; attachment links expire in two minutes.\nCreation also accepts --ttl-seconds <n> and --persistent. Webhook receiving is public by default; inspection always needs workspace credentials or the inspection token. Use inbox create --visibility private only when senders can add X-Access-Token. Other resources default to private.";
4
4
  export declare function command(client: Kivel, args: string[], input?: Uint8Array): Promise<unknown>;
package/dist/commands.js CHANGED
@@ -31,13 +31,17 @@ kivel credential inspect|delete <id>
31
31
  kivel credential update <id> < changes.json
32
32
  kivel credential reveal <id> [--approval-id <id>]
33
33
  kivel password generate [--length <n>]
34
+ kivel email message <inbox-id> <message-id>
35
+ kivel email message-update <inbox-id> <message-id> < update.json
36
+ kivel email deliveries <inbox-id>
34
37
  kivel email threads [inbox-id] [--cursor <cursor>] [--limit <n>]
35
38
  kivel email thread <inbox-id> <thread-id>
36
39
  kivel email drafts|rules <inbox-id>
37
40
  kivel email draft-create <inbox-id> < content.json
38
41
  kivel email draft-inspect|draft-delete <draft-id>
39
42
  kivel email draft-submit <draft-id> [< settings.json]
40
- kivel email messages|wait <id> [--token <token>] [--after <id>] [--timeout-seconds <n>]
43
+ kivel email messages|wait <id> [--cursor <cursor>] [--limit <n>] [--from <address>] [--mail-from <address>] [--subject <text>] [--text <text>] [--has-code true|false] [--has-link true|false] [--has-attachment true|false] [--read true|false] [--label <label>]
44
+ kivel email wait <id> [--checkpoint] [--after <id>] [--timeout-seconds <n>] [--token <token>]
41
45
  kivel memory set <namespace> <key> [--ttl-seconds <n>] < value.json
42
46
  kivel memory get|delete <namespace> <key>
43
47
  kivel memory list <namespace> [--prefix <prefix>]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kivel.io/cli",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "kivel": "./bin/kivel.mjs"
@@ -18,7 +18,7 @@
18
18
  "CHANGELOG.md"
19
19
  ],
20
20
  "dependencies": {
21
- "@kivel.io/sdk": "0.10.1"
21
+ "@kivel.io/sdk": "0.11.0"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/node": "^26.6.5",
@@ -49,6 +49,6 @@
49
49
  "scripts": {
50
50
  "build": "node -e \"require('node:fs').rmSync('dist', {recursive:true,force:true})\" && tsc -p tsconfig.json",
51
51
  "typecheck": "tsc -p tsconfig.json --noEmit",
52
- "test": "node --import tsx --test src/listen.test.ts"
52
+ "test": "node --import tsx --test src/listen.test.ts src/email.test.ts"
53
53
  }
54
54
  }