@agentisend/sdk-node 0.1.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 (50) hide show
  1. package/README.md +97 -0
  2. package/dist/cli/args.d.ts +24 -0
  3. package/dist/cli/args.js +71 -0
  4. package/dist/cli/args.js.map +1 -0
  5. package/dist/cli/commands.d.ts +29 -0
  6. package/dist/cli/commands.js +147 -0
  7. package/dist/cli/commands.js.map +1 -0
  8. package/dist/cli/config.d.ts +31 -0
  9. package/dist/cli/config.js +73 -0
  10. package/dist/cli/config.js.map +1 -0
  11. package/dist/cli/doctor.d.ts +36 -0
  12. package/dist/cli/doctor.js +161 -0
  13. package/dist/cli/doctor.js.map +1 -0
  14. package/dist/cli/listen.d.ts +28 -0
  15. package/dist/cli/listen.js +140 -0
  16. package/dist/cli/listen.js.map +1 -0
  17. package/dist/cli/main.d.ts +14 -0
  18. package/dist/cli/main.js +369 -0
  19. package/dist/cli/main.js.map +1 -0
  20. package/dist/cli/output.d.ts +40 -0
  21. package/dist/cli/output.js +35 -0
  22. package/dist/cli/output.js.map +1 -0
  23. package/dist/cli/scheduled-at.d.ts +19 -0
  24. package/dist/cli/scheduled-at.js +108 -0
  25. package/dist/cli/scheduled-at.js.map +1 -0
  26. package/dist/cli.d.ts +2 -0
  27. package/dist/cli.js +17 -0
  28. package/dist/cli.js.map +1 -0
  29. package/dist/client.d.ts +426 -0
  30. package/dist/client.js +542 -0
  31. package/dist/client.js.map +1 -0
  32. package/dist/compat-resend.d.ts +194 -0
  33. package/dist/compat-resend.js +233 -0
  34. package/dist/compat-resend.js.map +1 -0
  35. package/dist/errors.d.ts +82 -0
  36. package/dist/errors.js +92 -0
  37. package/dist/errors.js.map +1 -0
  38. package/dist/index.d.ts +10 -0
  39. package/dist/index.js +9 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/types.d.ts +499 -0
  42. package/dist/types.js +9 -0
  43. package/dist/types.js.map +1 -0
  44. package/dist/version.d.ts +8 -0
  45. package/dist/version.js +9 -0
  46. package/dist/version.js.map +1 -0
  47. package/dist/webhook-signing.d.ts +64 -0
  48. package/dist/webhook-signing.js +125 -0
  49. package/dist/webhook-signing.js.map +1 -0
  50. package/package.json +65 -0
@@ -0,0 +1,369 @@
1
+ /**
2
+ * M4.16 / M5.30 — the CLI, dispatched.
3
+ *
4
+ * `run()` takes argv, an environment and a pair of writers, so every command
5
+ * is testable without spawning a process — and the binary is a five-line
6
+ * wrapper around it. Nothing here reads a module-level global.
7
+ *
8
+ * The rules that make it usable by an agent as well as a person:
9
+ * - not a TTY ⇒ JSON, without asking;
10
+ * - errors carry code/message/fix, on stderr, always as JSON;
11
+ * - an unknown flag is refused before anything runs;
12
+ * - `-` means stdin for every *-file option;
13
+ * - exit codes: 0 ok, 1 the API refused, 2 the caller made a mistake.
14
+ */
15
+ import { readFileSync } from 'node:fs';
16
+ import { AgentiSend } from '../client.js';
17
+ import { SDK_VERSION } from '../version.js';
18
+ import { AgentiSendError } from '../errors.js';
19
+ import { flag, has, list, parseArgs, UsageError } from './args.js';
20
+ import { completionScript, flagsFor, helpText, isShell } from './commands.js';
21
+ import { configPath, keyPreview, readConfig, resolveCredentials, writeConfig, } from './config.js';
22
+ import { renderDoctor, runDoctor } from './doctor.js';
23
+ import { startWebhookListener } from './listen.js';
24
+ import { createOutput, emit, emitError, jsonModeFor, rows } from './output.js';
25
+ import { parseScheduledAt } from './scheduled-at.js';
26
+ const EXIT_OK = 0;
27
+ const EXIT_REFUSED = 1;
28
+ const EXIT_USAGE = 2;
29
+ function readBodyFile(path, ctx) {
30
+ if (path === '-') {
31
+ // M5.30: `-` is stdin. An email body is exactly the kind of thing that
32
+ // arrives from a pipe, and shell-quoting HTML by hand is how bodies get
33
+ // mangled.
34
+ return ctx.readStdin ? ctx.readStdin() : readFileSync(0, 'utf8');
35
+ }
36
+ return readFileSync(path, 'utf8');
37
+ }
38
+ function tagsFrom(values) {
39
+ if (values.length === 0)
40
+ return undefined;
41
+ const tags = {};
42
+ for (const value of values) {
43
+ const eq = value.indexOf('=');
44
+ if (eq === -1) {
45
+ throw new UsageError(`--tag ${value} is not a pair.`, 'Write tags as --tag name=value.');
46
+ }
47
+ tags[value.slice(0, eq)] = value.slice(eq + 1);
48
+ }
49
+ return tags;
50
+ }
51
+ async function sendEmail(client, args, out, ctx) {
52
+ const htmlFile = flag(args, 'html-file');
53
+ const textFile = flag(args, 'text-file');
54
+ const html = flag(args, 'html') ?? (htmlFile ? readBodyFile(htmlFile, ctx) : undefined);
55
+ const text = flag(args, 'text') ?? (textFile ? readBodyFile(textFile, ctx) : undefined);
56
+ const to = list(args, 'to');
57
+ const from = flag(args, 'from');
58
+ const subject = flag(args, 'subject');
59
+ if (!from || to.length === 0 || !subject) {
60
+ throw new UsageError('A send needs --from, --to and --subject.', 'Example: agentisend emails send --from "Acme <hi@acme.com>" --to you@example.com --subject Hi --text-file -');
61
+ }
62
+ if (html === undefined && text === undefined) {
63
+ throw new UsageError('A send needs a body.', 'Pass --text, --html, or --text-file/--html-file (use - to read stdin).');
64
+ }
65
+ let scheduledAt;
66
+ const rawSchedule = flag(args, 'scheduled-at');
67
+ if (rawSchedule !== undefined) {
68
+ const parsed = parseScheduledAt(rawSchedule, ctx.now?.() ?? new Date());
69
+ if (!parsed.ok) {
70
+ throw new UsageError(`--scheduled-at: ${parsed.error ?? 'unreadable'}`, 'Nothing was sent.');
71
+ }
72
+ scheduledAt = parsed.iso;
73
+ }
74
+ const idempotencyKey = flag(args, 'idempotency-key');
75
+ const cc = list(args, 'cc');
76
+ const bcc = list(args, 'bcc');
77
+ const replyTo = list(args, 'reply-to');
78
+ const tags = tagsFrom(list(args, 'tag'));
79
+ const result = await client.emails.send({
80
+ from,
81
+ to,
82
+ subject,
83
+ ...(html !== undefined ? { html } : {}),
84
+ ...(text !== undefined ? { text } : {}),
85
+ ...(cc.length > 0 ? { cc } : {}),
86
+ ...(bcc.length > 0 ? { bcc } : {}),
87
+ ...(replyTo.length > 0 ? { reply_to: replyTo } : {}),
88
+ ...(tags ? { tags } : {}),
89
+ ...(scheduledAt !== undefined ? { scheduled_at: scheduledAt } : {}),
90
+ }, idempotencyKey !== undefined ? { idempotencyKey } : undefined);
91
+ // `status` comes from the API rather than being inferred here: a send that
92
+ // was deferred says so, and a script branches on one field either way.
93
+ const status = result.status ?? (scheduledAt ? 'scheduled' : 'queued');
94
+ emit(out, { id: result.id, status, ...(scheduledAt !== undefined ? { scheduled_at: scheduledAt } : {}) }, scheduledAt !== undefined ? `Scheduled ${result.id} for ${scheduledAt}` : `Queued ${result.id}`);
95
+ return EXIT_OK;
96
+ }
97
+ async function receivingListen(client, args, out) {
98
+ // NDJSON, one object per line: the shape a pipeline can consume as it goes,
99
+ // rather than a JSON array nobody can read until the command ends.
100
+ const seen = new Set();
101
+ const limit = Number(flag(args, 'limit') ?? 20);
102
+ const intervalMs = Number(flag(args, 'interval') ?? 5) * 1000;
103
+ const once = has(args, 'once');
104
+ const to = flag(args, 'to');
105
+ for (;;) {
106
+ const page = await client.receiving.list({ limit, ...(to ? { to } : {}) });
107
+ // Oldest first within a page, so the stream reads in arrival order.
108
+ for (const message of [...page.data].reverse()) {
109
+ if (seen.has(message.id))
110
+ continue;
111
+ seen.add(message.id);
112
+ out.stdout(JSON.stringify({
113
+ id: message.id,
114
+ from: message.from,
115
+ to: message.to,
116
+ subject: message.subject,
117
+ received_at: message.received_at,
118
+ }));
119
+ }
120
+ if (once)
121
+ return EXIT_OK;
122
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
123
+ }
124
+ }
125
+ async function webhooksListen(args, out) {
126
+ const secret = flag(args, 'secret');
127
+ const forwardTo = flag(args, 'forward-to');
128
+ if (!secret) {
129
+ throw new UsageError('webhooks listen needs --secret.', 'It is the endpoint signing secret, shown once when the endpoint is created. Without it nothing can be verified.');
130
+ }
131
+ if (!forwardTo && !has(args, 'verify-only')) {
132
+ throw new UsageError('webhooks listen needs --forward-to, or --verify-only.', 'Example: agentisend webhooks listen --secret whsec_… --forward-to http://localhost:3000/webhooks');
133
+ }
134
+ const listener = await startWebhookListener({
135
+ secret,
136
+ ...(forwardTo !== undefined ? { forwardTo } : {}),
137
+ port: Number(flag(args, 'port') ?? 4000),
138
+ onEvent: (event) => {
139
+ out.stdout(JSON.stringify(event));
140
+ },
141
+ });
142
+ out.stderr(JSON.stringify({
143
+ listening: `http://127.0.0.1:${String(listener.port)}`,
144
+ forwarding_to: forwardTo ?? null,
145
+ note: 'Deliveries that do not verify are dropped, never forwarded.',
146
+ }));
147
+ // Runs until interrupted: that is the whole command.
148
+ await new Promise(() => { });
149
+ return EXIT_OK;
150
+ }
151
+ function profileCommand(args, ctx, out) {
152
+ const env = ctx.env ?? process.env;
153
+ const path = configPath(env);
154
+ const config = readConfig(path);
155
+ const [, sub, name] = args.positional;
156
+ if (sub === 'list') {
157
+ const names = Object.keys(config.profiles);
158
+ emit(out, {
159
+ current: config.current,
160
+ config_path: path,
161
+ profiles: names.map((profileName) => ({
162
+ name: profileName,
163
+ base_url: config.profiles[profileName]?.base_url ?? null,
164
+ api_key: keyPreview(config.profiles[profileName]?.api_key ?? ''),
165
+ })),
166
+ }, names.length === 0
167
+ ? `No profiles yet. Add one: agentisend profile set default --api-key as_… (${path})`
168
+ : rows(names.map((profileName) => [
169
+ profileName === config.current ? `* ${profileName}` : ` ${profileName}`,
170
+ keyPreview(config.profiles[profileName]?.api_key ?? ''),
171
+ ])));
172
+ return EXIT_OK;
173
+ }
174
+ if (sub === 'use' && name) {
175
+ if (!config.profiles[name]) {
176
+ throw new UsageError(`No profile named "${name}".`, `Create it first: agentisend profile set ${name} --api-key as_…`);
177
+ }
178
+ writeConfig({ ...config, current: name }, path);
179
+ emit(out, { current: name }, `Now using profile "${name}".`);
180
+ return EXIT_OK;
181
+ }
182
+ if (sub === 'set' && name) {
183
+ const apiKey = flag(args, 'api-key');
184
+ if (!apiKey) {
185
+ throw new UsageError('profile set needs --api-key.', `Example: agentisend profile set ${name} --api-key as_…`);
186
+ }
187
+ const baseUrl = flag(args, 'base-url');
188
+ config.profiles[name] = { api_key: apiKey, ...(baseUrl ? { base_url: baseUrl } : {}) };
189
+ if (!config.profiles[config.current])
190
+ config.current = name;
191
+ writeConfig(config, path);
192
+ emit(out, { profile: name, api_key: keyPreview(apiKey), config_path: path }, `Saved profile "${name}" (${keyPreview(apiKey)}) to ${path}.`);
193
+ return EXIT_OK;
194
+ }
195
+ throw new UsageError('Unknown profile command.', 'Try: profile list | profile use <name> | profile set <name> --api-key as_…');
196
+ }
197
+ export async function run(ctx) {
198
+ const env = ctx.env ?? process.env;
199
+ const json = jsonModeFor(ctx.argv, ctx.isTty ?? false);
200
+ const out = createOutput({
201
+ json,
202
+ ...(ctx.stdout ? { stdout: ctx.stdout } : {}),
203
+ ...(ctx.stderr ? { stderr: ctx.stderr } : {}),
204
+ });
205
+ try {
206
+ const bare = parseArgs(ctx.argv);
207
+ const command = bare.positional.slice(0, 2).join(' ');
208
+ const oneWord = bare.positional[0] ?? '';
209
+ if (has(bare, 'version')) {
210
+ out.stdout(SDK_VERSION);
211
+ return EXIT_OK;
212
+ }
213
+ if (bare.positional.length === 0 || has(bare, 'help')) {
214
+ out.stdout(helpText());
215
+ return bare.positional.length === 0 ? EXIT_USAGE : EXIT_OK;
216
+ }
217
+ if (oneWord === 'completions') {
218
+ const shell = bare.positional[1] ?? 'bash';
219
+ if (!isShell(shell)) {
220
+ throw new UsageError(`No completions for "${shell}".`, 'Choose bash, zsh or fish.');
221
+ }
222
+ out.stdout(completionScript(shell));
223
+ return EXIT_OK;
224
+ }
225
+ // Re-parse against the command's own flags: unknown flags are refused
226
+ // here, before anything is sent.
227
+ const knownFor = flagsFor(command.length > 0 ? command : oneWord);
228
+ const args = parseArgs(ctx.argv, knownFor);
229
+ if (oneWord === 'profile')
230
+ return profileCommand(args, ctx, out);
231
+ const credentials = resolveCredentials({
232
+ apiKeyFlag: flag(args, 'api-key'),
233
+ baseUrlFlag: flag(args, 'base-url'),
234
+ profileFlag: flag(args, 'profile'),
235
+ env,
236
+ });
237
+ const makeClient = () => {
238
+ if (!credentials.apiKey) {
239
+ throw new UsageError(`No API key for profile "${credentials.profile}".`, 'Set AGENTISEND_API_KEY, pass --api-key, or save one: agentisend profile set default --api-key as_…');
240
+ }
241
+ return ctx.clientFactory
242
+ ? ctx.clientFactory(credentials.apiKey, credentials.baseUrl)
243
+ : new AgentiSend(credentials.apiKey, credentials.baseUrl ? { baseUrl: credentials.baseUrl } : {});
244
+ };
245
+ if (oneWord === 'doctor') {
246
+ const client = credentials.apiKey ? makeClient() : null;
247
+ const report = await runDoctor({
248
+ client,
249
+ baseUrl: credentials.baseUrl ?? client?.baseUrl ?? 'https://api.agentisend.com',
250
+ profile: credentials.profile,
251
+ keySource: credentials.source,
252
+ configPath: configPath(env),
253
+ });
254
+ emit(out, report, renderDoctor(report));
255
+ return report.ok ? EXIT_OK : EXIT_REFUSED;
256
+ }
257
+ if (command === 'webhooks listen')
258
+ return await webhooksListen(args, out);
259
+ const client = makeClient();
260
+ const positional = args.positional[2];
261
+ switch (command) {
262
+ case 'emails send':
263
+ return await sendEmail(client, args, out, ctx);
264
+ case 'emails get': {
265
+ if (!positional)
266
+ throw new UsageError('emails get needs an id.', 'agentisend emails get <id>');
267
+ const email = await client.emails.get(positional);
268
+ emit(out, email, rows([
269
+ ['id', email.id],
270
+ ['status', email.status],
271
+ ['to', email.to.join(', ')],
272
+ ['subject', email.subject],
273
+ ]));
274
+ return EXIT_OK;
275
+ }
276
+ case 'emails list': {
277
+ const page = await client.emails.list({
278
+ ...(flag(args, 'status') ? { status: flag(args, 'status') } : {}),
279
+ ...(flag(args, 'limit') ? { limit: Number(flag(args, 'limit')) } : {}),
280
+ });
281
+ emit(out, page, page.data.length === 0
282
+ ? 'No messages.'
283
+ : rows(page.data.map((email) => [email.id, `${email.status} ${email.subject}`])));
284
+ return EXIT_OK;
285
+ }
286
+ case 'emails cancel': {
287
+ if (!positional)
288
+ throw new UsageError('emails cancel needs an id.', 'agentisend emails cancel <id>');
289
+ const result = await client.emails.cancel(positional);
290
+ emit(out, result, `Cancelled ${result.id}.`);
291
+ return EXIT_OK;
292
+ }
293
+ case 'emails explain': {
294
+ if (!positional)
295
+ throw new UsageError('emails explain needs an id.', 'agentisend emails explain <id>');
296
+ const report = await client.emails.explain(positional);
297
+ emit(out, report, [
298
+ `${report.verdict}: ${report.what_happened}`,
299
+ ...report.actions.map((action) => action.call
300
+ ? ` → ${action.do} (${action.call.method} ${action.call.path})`
301
+ : ` → ${action.do}`),
302
+ ].join('\n'));
303
+ return EXIT_OK;
304
+ }
305
+ case 'domains list': {
306
+ const page = await client.domains.list();
307
+ emit(out, page, page.data.length === 0
308
+ ? 'No domains.'
309
+ : rows(page.data.map((domain) => [domain.name, domain.status])));
310
+ return EXIT_OK;
311
+ }
312
+ case 'domains verify': {
313
+ if (!positional)
314
+ throw new UsageError('domains verify needs a domain id.', 'agentisend domains verify <id>');
315
+ const result = await client.domains.verify(positional);
316
+ emit(out, result, `${result.name}: ${result.status}`);
317
+ return EXIT_OK;
318
+ }
319
+ case 'receiving listen':
320
+ return await receivingListen(client, args, out);
321
+ case 'limits kill': {
322
+ if (!positional)
323
+ throw new UsageError('limits kill needs a key id.', 'agentisend limits kill <key-id>');
324
+ const limit = await client.limits.kill(positional, flag(args, 'reason'));
325
+ emit(out, limit, `Key ${limit.api_key_id} is paused.`);
326
+ return EXIT_OK;
327
+ }
328
+ case 'limits resume': {
329
+ if (!positional)
330
+ throw new UsageError('limits resume needs a key id.', 'agentisend limits resume <key-id>');
331
+ const limit = await client.limits.resume(positional);
332
+ emit(out, limit, `Key ${limit.api_key_id} is sending again.`);
333
+ return EXIT_OK;
334
+ }
335
+ case 'trust standing': {
336
+ const standing = await client.trust.standing();
337
+ emit(out, standing, `${standing.state}${standing.reasons.length > 0 ? `: ${standing.reasons.join('; ')}` : ''}`);
338
+ return EXIT_OK;
339
+ }
340
+ default:
341
+ throw new UsageError(`Unknown command "${command || oneWord}".`, 'Run agentisend --help for the list.');
342
+ }
343
+ }
344
+ catch (err) {
345
+ if (err instanceof UsageError) {
346
+ emitError(out, { code: 'usage', message: err.message, fix: err.fix });
347
+ return EXIT_USAGE;
348
+ }
349
+ if (err instanceof AgentiSendError) {
350
+ emitError(out, {
351
+ code: err.code,
352
+ message: err.message,
353
+ fix: err.fix,
354
+ ...(err.requestId !== undefined ? { request_id: err.requestId } : {}),
355
+ ...(err.retryAfterSeconds !== undefined
356
+ ? { retry_after_seconds: err.retryAfterSeconds }
357
+ : {}),
358
+ });
359
+ return EXIT_REFUSED;
360
+ }
361
+ emitError(out, {
362
+ code: 'cli_error',
363
+ message: err instanceof Error ? err.message : String(err),
364
+ fix: 'This was not a refusal from the API. Check the base URL and your network.',
365
+ });
366
+ return EXIT_REFUSED;
367
+ }
368
+ }
369
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * M5.30 — how the CLI writes.
3
+ *
4
+ * The rule: **if nobody is watching, print JSON.** A CLI whose human output a
5
+ * script has to scrape is a CLI that breaks every time the wording improves,
6
+ * and an agent running commands is never a TTY. `--json` forces it on;
7
+ * `--no-json` is not a thing, because a pipe wanting prose is not a case worth
8
+ * breaking every script for.
9
+ *
10
+ * Errors keep the envelope the API uses — code, message, fix — so a caller
11
+ * branches on `code` whichever surface it came from.
12
+ */
13
+ export interface OutputOptions {
14
+ json: boolean;
15
+ stdout: (line: string) => void;
16
+ stderr: (line: string) => void;
17
+ }
18
+ export declare function jsonModeFor(argv: string[], isTty: boolean): boolean;
19
+ export declare function createOutput(options: {
20
+ json: boolean;
21
+ stdout?: (line: string) => void;
22
+ stderr?: (line: string) => void;
23
+ }): OutputOptions;
24
+ /** One value, two audiences: the JSON document, or the human line. */
25
+ export declare function emit(out: OutputOptions, value: unknown, human: string): void;
26
+ export interface CliErrorBody {
27
+ code: string;
28
+ message: string;
29
+ fix: string;
30
+ request_id?: string;
31
+ retry_after_seconds?: number;
32
+ }
33
+ /**
34
+ * Errors always go out as JSON, TTY or not: an error is the output most likely
35
+ * to be read by a machine deciding what to do next, and `{"error":{...}}` on
36
+ * stderr costs a human nothing.
37
+ */
38
+ export declare function emitError(out: OutputOptions, body: CliErrorBody): void;
39
+ /** Aligned key/value lines for the human case. No table library, no colours. */
40
+ export declare function rows(pairs: [string, string][]): string;
@@ -0,0 +1,35 @@
1
+ export function jsonModeFor(argv, isTty) {
2
+ if (argv.includes('--json'))
3
+ return true;
4
+ // Not a terminal = something is parsing this. Give it JSON.
5
+ return !isTty;
6
+ }
7
+ export function createOutput(options) {
8
+ /* eslint-disable no-console -- a CLI's whole job is writing to the console */
9
+ return {
10
+ json: options.json,
11
+ stdout: options.stdout ?? ((line) => console.log(line)),
12
+ stderr: options.stderr ?? ((line) => console.error(line)),
13
+ };
14
+ /* eslint-enable no-console */
15
+ }
16
+ /** One value, two audiences: the JSON document, or the human line. */
17
+ export function emit(out, value, human) {
18
+ out.stdout(out.json ? JSON.stringify(value, null, 2) : human);
19
+ }
20
+ /**
21
+ * Errors always go out as JSON, TTY or not: an error is the output most likely
22
+ * to be read by a machine deciding what to do next, and `{"error":{...}}` on
23
+ * stderr costs a human nothing.
24
+ */
25
+ export function emitError(out, body) {
26
+ // ONE line, deliberately: an error is read by a log collector or a `| tail
27
+ // -1 | jq`, and a pretty-printed object breaks both.
28
+ out.stderr(JSON.stringify({ error: body }));
29
+ }
30
+ /** Aligned key/value lines for the human case. No table library, no colours. */
31
+ export function rows(pairs) {
32
+ const width = Math.max(...pairs.map(([key]) => key.length));
33
+ return pairs.map(([key, value]) => `${key.padEnd(width)} ${value}`).join('\n');
34
+ }
35
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"AAkBA,MAAM,UAAU,WAAW,CAAC,IAAc,EAAE,KAAc;IACxD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,4DAA4D;IAC5D,OAAO,CAAC,KAAK,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAI5B;IACC,8EAA8E;IAC9E,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;KAC1D,CAAC;IACF,8BAA8B;AAChC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,IAAI,CAAC,GAAkB,EAAE,KAAc,EAAE,KAAa;IACpE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAUD;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,GAAkB,EAAE,IAAkB;IAC9D,2EAA2E;IAC3E,qDAAqD;IACrD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,IAAI,CAAC,KAAyB;IAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5D,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClF,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * M5.30 — `--scheduled-at "tomorrow 9am"`.
3
+ *
4
+ * People do not type ISO 8601 by hand, and the failure mode of getting it
5
+ * wrong is silent: a malformed offset schedules a send eight hours early into
6
+ * someone's night. So a small, explicit grammar — no dependency, no fuzzy
7
+ * guessing — and anything it cannot parse is REFUSED with what it does
8
+ * understand, never guessed at.
9
+ *
10
+ * Everything resolves in the caller's local timezone, because "9am" means 9am
11
+ * where the person typing it is.
12
+ */
13
+ export interface ScheduleParse {
14
+ ok: boolean;
15
+ iso?: string;
16
+ error?: string;
17
+ }
18
+ export declare const SCHEDULE_EXAMPLES: string;
19
+ export declare function parseScheduledAt(input: string, now?: Date): ScheduleParse;
@@ -0,0 +1,108 @@
1
+ const UNITS = {
2
+ second: 1000,
3
+ seconds: 1000,
4
+ sec: 1000,
5
+ secs: 1000,
6
+ minute: 60_000,
7
+ minutes: 60_000,
8
+ min: 60_000,
9
+ mins: 60_000,
10
+ hour: 3_600_000,
11
+ hours: 3_600_000,
12
+ hr: 3_600_000,
13
+ hrs: 3_600_000,
14
+ day: 86_400_000,
15
+ days: 86_400_000,
16
+ week: 604_800_000,
17
+ weeks: 604_800_000,
18
+ };
19
+ const WEEKDAYS = [
20
+ 'sunday',
21
+ 'monday',
22
+ 'tuesday',
23
+ 'wednesday',
24
+ 'thursday',
25
+ 'friday',
26
+ 'saturday',
27
+ ];
28
+ export const SCHEDULE_EXAMPLES = 'Try an ISO time ("2026-09-05T09:00:00Z"), "in 30 minutes", "tomorrow 9am", ' +
29
+ '"today 17:30", or a weekday with a time ("friday 14:00").';
30
+ /** "9am", "09:30", "17:30", "9:05pm" → minutes since midnight, or null. */
31
+ function parseClock(raw) {
32
+ const match = /^(\d{1,2})(?::(\d{2}))?\s*(am|pm)?$/i.exec(raw.trim());
33
+ if (!match)
34
+ return null;
35
+ let hour = Number(match[1]);
36
+ const minute = match[2] ? Number(match[2]) : 0;
37
+ const meridiem = match[3]?.toLowerCase();
38
+ if (minute > 59)
39
+ return null;
40
+ if (meridiem) {
41
+ if (hour < 1 || hour > 12)
42
+ return null;
43
+ if (meridiem === 'pm' && hour !== 12)
44
+ hour += 12;
45
+ if (meridiem === 'am' && hour === 12)
46
+ hour = 0;
47
+ }
48
+ else if (hour > 23)
49
+ return null;
50
+ return hour * 60 + minute;
51
+ }
52
+ function atClock(base, dayOffset, minutes) {
53
+ const result = new Date(base);
54
+ result.setDate(result.getDate() + dayOffset);
55
+ result.setHours(Math.floor(minutes / 60), minutes % 60, 0, 0);
56
+ return result;
57
+ }
58
+ export function parseScheduledAt(input, now = new Date()) {
59
+ const raw = input.trim();
60
+ if (raw.length === 0)
61
+ return { ok: false, error: `An empty time. ${SCHEDULE_EXAMPLES}` };
62
+ // An ISO timestamp passes straight through — it is already unambiguous.
63
+ if (/^\d{4}-\d{2}-\d{2}[T ]/.test(raw)) {
64
+ const parsed = new Date(raw);
65
+ if (Number.isNaN(parsed.getTime())) {
66
+ return { ok: false, error: `"${raw}" looks like a date but is not a valid one.` };
67
+ }
68
+ return { ok: true, iso: parsed.toISOString() };
69
+ }
70
+ const lower = raw.toLowerCase();
71
+ if (lower === 'now')
72
+ return { ok: true, iso: now.toISOString() };
73
+ const relative = /^in\s+(\d+)\s+([a-z]+)$/.exec(lower);
74
+ if (relative) {
75
+ const unit = UNITS[relative[2]];
76
+ if (unit === undefined) {
77
+ return {
78
+ ok: false,
79
+ error: `I do not know the unit "${relative[2]}". Use seconds, minutes, hours, days or weeks.`,
80
+ };
81
+ }
82
+ return { ok: true, iso: new Date(now.getTime() + Number(relative[1]) * unit).toISOString() };
83
+ }
84
+ const dayAndTime = /^(today|tomorrow|[a-z]+day)(?:\s+(?:at\s+)?(.+))?$/.exec(lower);
85
+ if (dayAndTime) {
86
+ const word = dayAndTime[1];
87
+ const clock = dayAndTime[2] ? parseClock(dayAndTime[2]) : 9 * 60;
88
+ if (clock === null) {
89
+ return { ok: false, error: `I could not read the time in "${raw}". ${SCHEDULE_EXAMPLES}` };
90
+ }
91
+ if (word === 'today')
92
+ return { ok: true, iso: atClock(now, 0, clock).toISOString() };
93
+ if (word === 'tomorrow')
94
+ return { ok: true, iso: atClock(now, 1, clock).toISOString() };
95
+ const target = WEEKDAYS.indexOf(word);
96
+ if (target === -1) {
97
+ return { ok: false, error: `I do not know the day "${word}". ${SCHEDULE_EXAMPLES}` };
98
+ }
99
+ // The NEXT one: "friday" on a Friday means next Friday unless the time is
100
+ // still ahead of us today, which is what people mean when they say it.
101
+ let offset = (target - now.getDay() + 7) % 7;
102
+ if (offset === 0 && atClock(now, 0, clock).getTime() <= now.getTime())
103
+ offset = 7;
104
+ return { ok: true, iso: atClock(now, offset, clock).toISOString() };
105
+ }
106
+ return { ok: false, error: `I could not read "${raw}" as a time. ${SCHEDULE_EXAMPLES}` };
107
+ }
108
+ //# sourceMappingURL=scheduled-at.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduled-at.js","sourceRoot":"","sources":["../../src/cli/scheduled-at.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * The AgentiSend CLI binary — a wrapper, deliberately.
4
+ *
5
+ * Everything lives in `cli/main.ts` behind `run()`, which takes argv, an
6
+ * environment and two writers. That is what makes the commands testable
7
+ * without spawning a process, and it is why this file has nothing in it worth
8
+ * reading twice.
9
+ */
10
+ import { run } from './cli/main.js';
11
+ const code = await run({
12
+ argv: process.argv.slice(2),
13
+ env: process.env,
14
+ isTty: process.stdout.isTTY === true,
15
+ });
16
+ process.exit(code);
17
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3B,GAAG,EAAE,OAAO,CAAC,GAAG;IAChB,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI;CACrC,CAAC,CAAC;AACH,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"}