gws-axi 0.2.0 → 0.4.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 (46) hide show
  1. package/README.md +91 -18
  2. package/dist/src/cli.js +1 -2
  3. package/dist/src/cli.js.map +1 -1
  4. package/dist/src/commands/calendar/create.d.ts +2 -0
  5. package/dist/src/commands/calendar/create.js +247 -0
  6. package/dist/src/commands/calendar/create.js.map +1 -0
  7. package/dist/src/commands/calendar/dateish.d.ts +14 -0
  8. package/dist/src/commands/calendar/dateish.js +19 -0
  9. package/dist/src/commands/calendar/dateish.js.map +1 -1
  10. package/dist/src/commands/calendar/delete.d.ts +2 -0
  11. package/dist/src/commands/calendar/delete.js +97 -0
  12. package/dist/src/commands/calendar/delete.js.map +1 -0
  13. package/dist/src/commands/calendar/get.js +12 -16
  14. package/dist/src/commands/calendar/get.js.map +1 -1
  15. package/dist/src/commands/calendar/respond.d.ts +2 -0
  16. package/dist/src/commands/calendar/respond.js +156 -0
  17. package/dist/src/commands/calendar/respond.js.map +1 -0
  18. package/dist/src/commands/calendar/update.d.ts +2 -0
  19. package/dist/src/commands/calendar/update.js +279 -0
  20. package/dist/src/commands/calendar/update.js.map +1 -0
  21. package/dist/src/commands/calendar.js +8 -4
  22. package/dist/src/commands/calendar.js.map +1 -1
  23. package/dist/src/commands/docs/comments.d.ts +2 -0
  24. package/dist/src/commands/docs/comments.js +172 -0
  25. package/dist/src/commands/docs/comments.js.map +1 -0
  26. package/dist/src/commands/docs/download.d.ts +2 -0
  27. package/dist/src/commands/docs/download.js +213 -0
  28. package/dist/src/commands/docs/download.js.map +1 -0
  29. package/dist/src/commands/docs/find.d.ts +2 -0
  30. package/dist/src/commands/docs/find.js +227 -0
  31. package/dist/src/commands/docs/find.js.map +1 -0
  32. package/dist/src/commands/docs/markdown.d.ts +8 -0
  33. package/dist/src/commands/docs/markdown.js +168 -0
  34. package/dist/src/commands/docs/markdown.js.map +1 -0
  35. package/dist/src/commands/docs/paths.d.ts +13 -0
  36. package/dist/src/commands/docs/paths.js +38 -0
  37. package/dist/src/commands/docs/paths.js.map +1 -0
  38. package/dist/src/commands/docs/read.d.ts +2 -0
  39. package/dist/src/commands/docs/read.js +235 -0
  40. package/dist/src/commands/docs/read.js.map +1 -0
  41. package/dist/src/commands/docs.d.ts +1 -1
  42. package/dist/src/commands/docs.js +125 -18
  43. package/dist/src/commands/docs.js.map +1 -1
  44. package/dist/src/google/client.js +3 -0
  45. package/dist/src/google/client.js.map +1 -1
  46. package/package.json +2 -2
package/README.md CHANGED
@@ -4,7 +4,7 @@ Agent-ergonomic CLI for Google Workspace — Gmail, Calendar, Docs, Drive, and S
4
4
 
5
5
  Designed for use by AI agents. Every response is structured, every error names a specific fix, and write operations lock to the explicit account when multiple are authenticated — so two agents in parallel sessions can't silently touch the wrong mailbox.
6
6
 
7
- > **Status:** early release. **Calendar reads** (`calendar events`) are implemented with real TOON output. Other subcommands (`calendar get|create|update|…`, `gmail`, `docs`, `drive`, `slides`) are scaffolded but return `NOT_IMPLEMENTED`. Auth, doctor, and multi-account management are complete.
7
+ > **Status (v0.3):** **Calendar is complete** — all 9 subcommands (5 reads + 4 writes) are implemented. Gmail, Docs, Drive, and Slides are scaffolded stubs that exercise auth + account resolution but return `NOT_IMPLEMENTED` on their concrete operations. Auth, doctor (with live per-account API probes), and multi-account management are stable.
8
8
 
9
9
  ## Requirements
10
10
 
@@ -12,41 +12,113 @@ Designed for use by AI agents. Every response is structured, every error names a
12
12
  - A Google account (personal or Workspace)
13
13
  - `gcloud` CLI (optional — speeds up initial setup, not required)
14
14
 
15
- ## Install
15
+ ## Getting started
16
+
17
+ ### 1. Install
16
18
 
17
19
  ```bash
18
20
  npm install -g gws-axi
19
21
  ```
20
22
 
21
- ## First-run setup
23
+ ### 2. Let an agent walk you through setup
24
+
25
+ `gws-axi` is designed to be driven by an AI coding agent (Claude Code, Cursor, anything that can run shell commands). The setup flow is progressive — the CLI emits structured TOON output telling the agent what to do next, and the agent coordinates with you through the handful of Google Cloud Console steps that can't be automated.
26
+
27
+ Start a fresh agent session and paste a prompt like:
28
+
29
+ ```
30
+ Run `gws-axi auth setup` and walk me through the progressive setup
31
+ flow it describes. The CLI's output will tell you exactly what to do
32
+ at each step — relay the instructions to me, and run follow-up
33
+ commands as you go.
34
+
35
+ I want to authenticate the following Google accounts:
36
+ - you@example.com
37
+ - personal@gmail.com
38
+ ```
39
+
40
+ The explicit `gws-axi auth setup` in the prompt matters: this is your very first session, so the agent doesn't yet have any ambient context about `gws-axi`. Naming the first command gets the agent into the structured flow, where the CLI's output takes over. Every subsequent session auto-loads a compact `gws-axi` status line via a session-start hook (installed on first invocation) — so after this one, you can skip the command and just say "use gws-axi to ..." and the agent knows.
41
+
42
+ Expect ~10 minutes end-to-end for a fresh Google Cloud project; ~3 minutes if you already have one you want to reuse.
22
43
 
23
- `gws-axi` uses a **bring-your-own OAuth client** model: you create your own Google Cloud project with OAuth credentials, and tokens live locally at `~/.config/gws-axi/`. This avoids verification/CASA overhead for public apps and keeps the blast radius of any token revocation scoped to you.
44
+ **What happens during setup:** you create your own Google Cloud project with OAuth credentials, enable the Workspace APIs, configure the consent screen, and add your Google accounts as test users. This is the [**bring-your-own OAuth client**](docs/shared-client-future.md) model — avoids public-app verification overhead and keeps the blast radius of any token revocation scoped to you. Tokens live locally at `~/.config/gws-axi/`.
24
45
 
25
- The setup is progressive — run `gws-axi auth setup` repeatedly and each invocation walks you through the next step:
46
+ The CLI generates an auto-refreshing HTML helper page (`~/.config/gws-axi/setup.html`) with clickable Console deep-links — so you never copy long URLs from terminal to browser and you stay in the right browser profile throughout.
47
+
48
+ ### 3. Check it works
26
49
 
27
50
  ```bash
28
- gws-axi auth setup # start or continue — 7 steps, mostly automated
29
- gws-axi doctor # check setup + live API health at any time
51
+ gws-axi doctor # setup + live API health
52
+ gws-axi calendar events # upcoming 7 days on your primary calendar
30
53
  ```
31
54
 
32
- The CLI generates a styled, auto-refreshing HTML helper page at `~/.config/gws-axi/setup.html` with clickable Console deep-links — so you never copy long URLs from terminal to browser and you stay in the right browser profile throughout.
55
+ ### 4. Make gws-axi your agent's default for Google Workspace
56
+
57
+ On first invocation (which already happened during step 2), `gws-axi` auto-installed a **SessionStart hook** into your agent's config (Claude Code's `~/.claude/settings.json`, Codex's `~/.codex/hooks.json`). From now on, every new agent session will see a compact `gws-axi` status line in ambient context — authenticated accounts, write-protection status, setup health — with no extra wiring. Nothing for you to configure.
58
+
59
+ To make sure agents reach for `gws-axi` instead of stale alternatives, also consider:
60
+
61
+ - **Remove existing Google Workspace MCP servers and skills.** If you already have Gmail / Calendar / Drive / Docs / Slides integrations installed (community MCP servers, bespoke skills, etc.), disable them. Keeping both creates ambiguity — agents may pick whichever they noticed first, and the tools have different auth models, flag names, and output shapes. Typical candidates to disable: `google-calendar-mcp`, `gmail-mcp`, `google-docs-mcp`, any `@modelcontextprotocol/server-google-*`, and skills with similar names.
62
+
63
+ - **Add a directive to your `CLAUDE.md`.** A short note in your project-level (`.claude/CLAUDE.md`) or user-level (`~/.claude/CLAUDE.md`) file nudges agents to consistently use `gws-axi`. Example:
64
+
65
+ ```markdown
66
+ ## Google Workspace
67
+
68
+ Use `gws-axi` for ALL Google Calendar, Gmail, Docs, Drive, and Slides
69
+ interactions. Check the SessionStart `gws-axi` line for current auth
70
+ state; run `gws-axi --help` for the command surface. Prefer this over
71
+ any other Google integrations.
72
+ ```
33
73
 
34
- Typical flow: set project → enable APIs → create OAuth client → download JSON → configure consent screen → add test users → authenticate. See the in-CLI guidance as you go; every step tells you exactly what to do next.
74
+ ### Prefer to drive it manually?
75
+
76
+ The CLI works fine without an agent — each `gws-axi auth setup` invocation prints its own instructions and updates `setup.html`. Run it repeatedly as you complete each step; no state is lost between invocations.
35
77
 
36
78
  ## Usage
37
79
 
38
80
  Every subcommand supports `--help`. The bare `gws-axi` command prints current state, authenticated accounts, and top suggestions.
39
81
 
82
+ ### Home / auth / health
83
+
40
84
  ```bash
41
- gws-axi # home view
42
- gws-axi calendar events # list upcoming events
43
- gws-axi calendar events --query standup # full-text search
44
- gws-axi calendar events --fields attendees,location
85
+ gws-axi # home view — current state + suggestions
45
86
  gws-axi auth accounts # list authenticated Google accounts
46
- gws-axi auth login --account <email> # add another account
47
- gws-axi doctor # full health check
87
+ gws-axi auth login --account <email> # add another account (prepare + --wait)
88
+ gws-axi auth use <email> # set the default account
89
+ gws-axi doctor # prerequisites + setup + live API probes
90
+ ```
91
+
92
+ ### Calendar reads
93
+
94
+ ```bash
95
+ gws-axi calendar events # upcoming 7 days on primary
96
+ gws-axi calendar events --from 2026-04-20T00:00 --to 2026-04-27T00:00
97
+ gws-axi calendar events --fields attendees,location,status
98
+ gws-axi calendar get <event-id> # full detail + attendees
99
+ gws-axi calendar get <event-id> --full # don't truncate description
100
+ gws-axi calendar calendars # list calendars accessible to this account
101
+ gws-axi calendar search --query "standup" # primary calendar by default
102
+ gws-axi calendar search --query "chris" --include-shared # include delegated + subscribed
103
+ gws-axi calendar freebusy --calendars primary,team@jarv.us # cross-calendar availability
104
+ ```
105
+
106
+ ### Calendar writes
107
+
108
+ ```bash
109
+ gws-axi calendar create \
110
+ --summary "Team sync" --start 2026-04-22T14:00 --duration 30m
111
+
112
+ gws-axi calendar update <event-id> \
113
+ --summary "Team sync (rescheduled)" --start 2026-04-22T15:00
114
+
115
+ gws-axi calendar delete <event-id> # idempotent (404/410 → noop)
116
+
117
+ gws-axi calendar respond <event-id> --response accepted
48
118
  ```
49
119
 
120
+ Writes default `--send-updates` to `none` so agent-created events don't spam attendees. Pass `--send-updates all` for production-style invite behavior.
121
+
50
122
  ### Multi-account with write protection
51
123
 
52
124
  gws-axi supports multiple Google accounts under one OAuth client. When two or more are authenticated, write operations require `--account <email>` explicitly — silent wrong-account mutations are impossible:
@@ -77,10 +149,11 @@ help[2]:
77
149
  - [`docs/design.md`](https://github.com/JarvusInnovations/gws-axi/blob/main/docs/design.md) — architecture, auth model, doctor tiers, command surface
78
150
  - [`docs/shared-client-future.md`](https://github.com/JarvusInnovations/gws-axi/blob/main/docs/shared-client-future.md) — why BYO-only for v1, what a shared-client public distribution would involve
79
151
 
80
- ## Known issues
152
+ ## Known issues & roadmap
81
153
 
82
- - **Testing-mode tokens expire every 7 days.** Google's OAuth policy. Re-run `gws-axi auth login --wait` when it happens. A future `gws-axi auth publish` helper will walk single-developer verification to eliminate this.
83
- - **Most service subcommands are not yet implemented.** Only `calendar events` does real work as of v0.1. The rest will follow — see the design doc for the order.
154
+ - **Testing-mode tokens expire every 7 days.** Google's OAuth policy for unpublished apps. Re-run `gws-axi auth login --account <email>` + `auth login --wait` when it happens. A future `gws-axi auth publish` helper will walk single-developer verification to eliminate this.
155
+ - **Gmail, Docs, Drive, Slides**: not yet implemented. Stubs exercise auth + account resolution so write-protection errors still surface correctly; actual operations return `NOT_IMPLEMENTED`. Gmail is next.
156
+ - **Tests**: not yet — coming alongside Gmail.
84
157
 
85
158
  ## Contributing
86
159
 
package/dist/src/cli.js CHANGED
@@ -7,7 +7,7 @@ import { authCommand, AUTH_HELP } from "./commands/auth.js";
7
7
  import { doctorCommand, DOCTOR_HELP } from "./commands/doctor.js";
8
8
  import { calendarCommand } from "./commands/calendar.js";
9
9
  import { gmailCommand, GMAIL_HELP } from "./commands/gmail.js";
10
- import { docsCommand, DOCS_HELP } from "./commands/docs.js";
10
+ import { docsCommand } from "./commands/docs.js";
11
11
  import { driveCommand, DRIVE_HELP } from "./commands/drive.js";
12
12
  import { slidesCommand, SLIDES_HELP } from "./commands/slides.js";
13
13
  const DESCRIPTION = "Agent ergonomic CLI for Google Workspace. Unified interface for Gmail, Calendar, Docs, Drive, and Slides with agent-guided OAuth setup.";
@@ -30,7 +30,6 @@ const COMMAND_HELP = {
30
30
  auth: AUTH_HELP,
31
31
  doctor: DOCTOR_HELP,
32
32
  gmail: GMAIL_HELP,
33
- docs: DOCS_HELP,
34
33
  drive: DRIVE_HELP,
35
34
  slides: SLIDES_HELP,
36
35
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAElE,MAAM,WAAW,GACf,yIAAyI,CAAC;AAE5I,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;AAErC,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;CAUvB,CAAC;AAEF,0EAA0E;AAC1E,0EAA0E;AAC1E,iEAAiE;AACjE,MAAM,YAAY,GAA2B;IAC3C,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,WAAW;IACnB,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,WAAW;CACpB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,SAAS,CAAC;QACd,WAAW,EAAE,WAAW;QACxB,OAAO,EAAE,OAAO;QAChB,YAAY,EAAE,QAAQ;QACtB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,WAAW,EAAE;QAC/B,QAAQ,EAAE;YACR,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,aAAa;YACrB,QAAQ,EAAE,eAAe;YACzB,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,WAAW;YACjB,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,aAAa;SACtB;QACD,cAAc,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC;KACnD,CAAC,CAAC;AACL,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAErD,KAAK,MAAM,SAAS,IAAI;QACtB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;QAChC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;KACvC,EAAE,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAEzD,CAAC;QACF,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const CREATE_HELP = "usage: gws-axi calendar create --summary <text> --start <iso> [flags]\nflags[13]:\n --summary <text> REQUIRED \u2014 event title\n --start <iso> REQUIRED \u2014 event start (ISO datetime or YYYY-MM-DD for all-day)\n --end <iso> End time (default: start + 1h for timed, start + 1d for all-day)\n --duration <h|m> Alternative to --end, e.g. \"1h\", \"30m\", \"90m\", \"1h30m\"\n --all-day Treat --start as a date (not datetime); all-day event\n --description <text> Multi-line ok; pass via shell heredoc or quoted string\n --location <text> Freeform location string\n --attendees <emails> Comma-separated emails (no spaces). Invites sent per --send-updates\n --timezone <tz> IANA TZ (e.g. America/New_York) for timed events (default: calendar's tz)\n --recurrence <rrule> RFC 5545 RRULE (e.g. \"RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR\")\n --send-updates <mode> none | all | externalOnly (default: none \u2014 agent-safe)\n --calendar <id> Calendar to write to (default: primary)\n --account <email> REQUIRED when 2+ accounts are authenticated\nexamples:\n gws-axi calendar create --summary \"Team sync\" --start 2026-04-22T14:00 --duration 30m\n gws-axi calendar create --summary \"Holiday\" --start 2026-05-26 --all-day\n gws-axi calendar create --summary \"1:1\" --start 2026-04-22T10:00 --end 2026-04-22T10:30 --attendees alice@x.com,bob@x.com --send-updates all\nnotes:\n --send-updates defaults to \"none\" so agent-created events don't spam\n invited guests with notifications unless explicitly requested. Pass\n --send-updates all for production-style invite behavior.\noutput:\n Returns the newly-created event's key fields (id, summary, start, end,\n organizer, attendees count, htmlLink) plus an `action: created` line.\n";
2
+ export declare function calendarCreateCommand(account: string, args: string[]): Promise<string>;
@@ -0,0 +1,247 @@
1
+ import { AxiError } from "axi-sdk-js";
2
+ import { calendarClient, translateGoogleError } from "../../google/client.js";
3
+ import { joinBlocks, renderObject } from "../../output/index.js";
4
+ import { formatEventTime, parseDateishFlag } from "./dateish.js";
5
+ export const CREATE_HELP = `usage: gws-axi calendar create --summary <text> --start <iso> [flags]
6
+ flags[13]:
7
+ --summary <text> REQUIRED — event title
8
+ --start <iso> REQUIRED — event start (ISO datetime or YYYY-MM-DD for all-day)
9
+ --end <iso> End time (default: start + 1h for timed, start + 1d for all-day)
10
+ --duration <h|m> Alternative to --end, e.g. "1h", "30m", "90m", "1h30m"
11
+ --all-day Treat --start as a date (not datetime); all-day event
12
+ --description <text> Multi-line ok; pass via shell heredoc or quoted string
13
+ --location <text> Freeform location string
14
+ --attendees <emails> Comma-separated emails (no spaces). Invites sent per --send-updates
15
+ --timezone <tz> IANA TZ (e.g. America/New_York) for timed events (default: calendar's tz)
16
+ --recurrence <rrule> RFC 5545 RRULE (e.g. "RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR")
17
+ --send-updates <mode> none | all | externalOnly (default: none — agent-safe)
18
+ --calendar <id> Calendar to write to (default: primary)
19
+ --account <email> REQUIRED when 2+ accounts are authenticated
20
+ examples:
21
+ gws-axi calendar create --summary "Team sync" --start 2026-04-22T14:00 --duration 30m
22
+ gws-axi calendar create --summary "Holiday" --start 2026-05-26 --all-day
23
+ gws-axi calendar create --summary "1:1" --start 2026-04-22T10:00 --end 2026-04-22T10:30 --attendees alice@x.com,bob@x.com --send-updates all
24
+ notes:
25
+ --send-updates defaults to "none" so agent-created events don't spam
26
+ invited guests with notifications unless explicitly requested. Pass
27
+ --send-updates all for production-style invite behavior.
28
+ output:
29
+ Returns the newly-created event's key fields (id, summary, start, end,
30
+ organizer, attendees count, htmlLink) plus an \`action: created\` line.
31
+ `;
32
+ function parseDurationMs(value) {
33
+ // Accept forms like "90m", "1h", "1h30m", "45min"
34
+ const re = /^(?:(\d+)h)?(?:(\d+)(?:m|min)?)?$/i;
35
+ const m = value.trim().match(re);
36
+ if (!m || (!m[1] && !m[2])) {
37
+ throw new AxiError(`Cannot parse duration: ${value}`, "VALIDATION_ERROR", ["Use forms like 1h, 30m, 90m, or 1h30m"]);
38
+ }
39
+ const hours = parseInt(m[1] ?? "0", 10);
40
+ const minutes = parseInt(m[2] ?? "0", 10);
41
+ return (hours * 60 + minutes) * 60 * 1000;
42
+ }
43
+ function parseFlags(args) {
44
+ const flags = {
45
+ summary: undefined,
46
+ start: undefined,
47
+ end: undefined,
48
+ duration: undefined,
49
+ allDay: false,
50
+ description: undefined,
51
+ location: undefined,
52
+ attendees: [],
53
+ timezone: undefined,
54
+ recurrence: undefined,
55
+ sendUpdates: "none",
56
+ calendar: "primary",
57
+ };
58
+ for (let i = 0; i < args.length; i++) {
59
+ const arg = args[i];
60
+ const next = args[i + 1];
61
+ switch (arg) {
62
+ case "--summary":
63
+ flags.summary = next;
64
+ i++;
65
+ break;
66
+ case "--start":
67
+ flags.start = next;
68
+ i++;
69
+ break;
70
+ case "--end":
71
+ flags.end = next;
72
+ i++;
73
+ break;
74
+ case "--duration":
75
+ flags.duration = next;
76
+ i++;
77
+ break;
78
+ case "--all-day":
79
+ flags.allDay = true;
80
+ break;
81
+ case "--description":
82
+ flags.description = next;
83
+ i++;
84
+ break;
85
+ case "--location":
86
+ flags.location = next;
87
+ i++;
88
+ break;
89
+ case "--attendees":
90
+ flags.attendees = next.split(",").map((s) => s.trim()).filter(Boolean);
91
+ i++;
92
+ break;
93
+ case "--timezone":
94
+ flags.timezone = next;
95
+ i++;
96
+ break;
97
+ case "--recurrence":
98
+ flags.recurrence = next;
99
+ i++;
100
+ break;
101
+ case "--send-updates":
102
+ if (next === "all" || next === "externalOnly" || next === "none") {
103
+ flags.sendUpdates = next;
104
+ }
105
+ else {
106
+ throw new AxiError(`Invalid --send-updates value: ${next}`, "VALIDATION_ERROR", ["Valid values: none, all, externalOnly"]);
107
+ }
108
+ i++;
109
+ break;
110
+ case "--calendar":
111
+ flags.calendar = next;
112
+ i++;
113
+ break;
114
+ }
115
+ }
116
+ return flags;
117
+ }
118
+ /** Format a Date to `YYYY-MM-DD` in local time. */
119
+ function toDateOnly(d) {
120
+ const pad = (n) => String(n).padStart(2, "0");
121
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
122
+ }
123
+ function buildEventBody(flags) {
124
+ if (!flags.summary) {
125
+ throw new AxiError("--summary is required", "VALIDATION_ERROR", [
126
+ "Pass --summary 'Event title'",
127
+ ]);
128
+ }
129
+ if (!flags.start) {
130
+ throw new AxiError("--start is required", "VALIDATION_ERROR", [
131
+ "Pass --start 2026-04-22T14:00 (timed) or --start 2026-04-22 --all-day",
132
+ ]);
133
+ }
134
+ const body = {
135
+ summary: flags.summary,
136
+ };
137
+ if (flags.description !== undefined)
138
+ body.description = flags.description;
139
+ if (flags.location !== undefined)
140
+ body.location = flags.location;
141
+ if (flags.attendees.length > 0) {
142
+ body.attendees = flags.attendees.map((email) => ({ email }));
143
+ }
144
+ if (flags.recurrence) {
145
+ const line = flags.recurrence.startsWith("RRULE:")
146
+ ? flags.recurrence
147
+ : `RRULE:${flags.recurrence}`;
148
+ body.recurrence = [line];
149
+ }
150
+ if (flags.allDay) {
151
+ // All-day events use the date field; Google expects exclusive end date,
152
+ // so default end = start + 1 day if neither --end nor --duration given.
153
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(flags.start)) {
154
+ throw new AxiError("--all-day requires --start in YYYY-MM-DD form", "VALIDATION_ERROR", [`Got: ${flags.start}`]);
155
+ }
156
+ body.start = { date: flags.start };
157
+ let endDate;
158
+ if (flags.end) {
159
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(flags.end)) {
160
+ throw new AxiError("--all-day requires --end in YYYY-MM-DD form", "VALIDATION_ERROR", [`Got: ${flags.end}`]);
161
+ }
162
+ endDate = flags.end;
163
+ }
164
+ else {
165
+ // Google's all-day end date is exclusive — default to start + 1 day
166
+ const d = new Date(`${flags.start}T00:00:00`);
167
+ d.setDate(d.getDate() + 1);
168
+ endDate = toDateOnly(d);
169
+ }
170
+ body.end = { date: endDate };
171
+ }
172
+ else {
173
+ // Timed event: parse via parseDateishFlag (handles ISO, local, date-only)
174
+ const startIso = parseDateishFlag(flags.start);
175
+ let endIso;
176
+ if (flags.end) {
177
+ endIso = parseDateishFlag(flags.end);
178
+ }
179
+ else if (flags.duration) {
180
+ const ms = parseDurationMs(flags.duration);
181
+ endIso = new Date(new Date(startIso).getTime() + ms).toISOString();
182
+ }
183
+ else {
184
+ // Default: 1 hour after start
185
+ endIso = new Date(new Date(startIso).getTime() + 60 * 60 * 1000).toISOString();
186
+ }
187
+ body.start = flags.timezone
188
+ ? { dateTime: startIso, timeZone: flags.timezone }
189
+ : { dateTime: startIso };
190
+ body.end = flags.timezone
191
+ ? { dateTime: endIso, timeZone: flags.timezone }
192
+ : { dateTime: endIso };
193
+ }
194
+ return body;
195
+ }
196
+ export async function calendarCreateCommand(account, args) {
197
+ const flags = parseFlags(args);
198
+ const body = buildEventBody(flags);
199
+ const api = await calendarClient(account);
200
+ let created;
201
+ try {
202
+ const res = await api.events.insert({
203
+ calendarId: flags.calendar,
204
+ requestBody: body,
205
+ sendUpdates: flags.sendUpdates,
206
+ });
207
+ created = res.data;
208
+ }
209
+ catch (err) {
210
+ throw translateGoogleError(err, {
211
+ account,
212
+ operation: "calendar.events.insert",
213
+ });
214
+ }
215
+ const blocks = [];
216
+ blocks.push(renderObject({
217
+ action: "created",
218
+ account,
219
+ calendar: flags.calendar,
220
+ }));
221
+ const attendees = created.attendees ?? [];
222
+ const event = {
223
+ id: created.id ?? "",
224
+ summary: created.summary ?? "",
225
+ start: formatEventTime(created.start),
226
+ end: formatEventTime(created.end),
227
+ status: created.status ?? "",
228
+ organizer: created.organizer?.email ?? "",
229
+ attendee_count: attendees.length,
230
+ send_updates: flags.sendUpdates,
231
+ };
232
+ if (created.location)
233
+ event.location = created.location;
234
+ if (created.htmlLink)
235
+ event.html_link = created.htmlLink;
236
+ if (created.recurrence?.length)
237
+ event.recurrence = created.recurrence;
238
+ blocks.push(renderObject({ event }));
239
+ const suggestions = [];
240
+ suggestions.push(`Run \`gws-axi calendar get ${created.id} --calendar ${flags.calendar}\` to view full details`);
241
+ if (attendees.length > 0 && flags.sendUpdates === "none") {
242
+ suggestions.push(`Attendees were NOT notified (--send-updates none). Run \`calendar update ${created.id} --send-updates all\` to resend`);
243
+ }
244
+ blocks.push(renderObject({ help: suggestions }));
245
+ return joinBlocks(...blocks);
246
+ }
247
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../../src/commands/calendar/create.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,20 @@
16
16
  * `timeMin` / `timeMax` parameters.
17
17
  */
18
18
  export declare function parseDateishFlag(value: string): string;
19
+ /**
20
+ * Format a Google Calendar dateTime/date field for detail-view output.
21
+ * Timed events: datetime + "(IANA tz)" suffix when timeZone is set.
22
+ * All-day events: "YYYY-MM-DD (all-day)".
23
+ * Missing/empty: empty string.
24
+ *
25
+ * Use for single-event detail views (get, create, update, respond).
26
+ * List views should stick to offset-only for compact columns.
27
+ */
28
+ export declare function formatEventTime(value: {
29
+ dateTime?: string | null;
30
+ date?: string | null;
31
+ timeZone?: string | null;
32
+ } | null | undefined): string;
19
33
  /**
20
34
  * Convert a UTC timestamp string (e.g. "2026-04-22T13:00:00Z") to an ISO
21
35
  * string with the system's local timezone offset (e.g.
@@ -40,6 +40,25 @@ export function parseDateishFlag(value) {
40
40
  }
41
41
  return parsed.toISOString();
42
42
  }
43
+ /**
44
+ * Format a Google Calendar dateTime/date field for detail-view output.
45
+ * Timed events: datetime + "(IANA tz)" suffix when timeZone is set.
46
+ * All-day events: "YYYY-MM-DD (all-day)".
47
+ * Missing/empty: empty string.
48
+ *
49
+ * Use for single-event detail views (get, create, update, respond).
50
+ * List views should stick to offset-only for compact columns.
51
+ */
52
+ export function formatEventTime(value) {
53
+ if (!value)
54
+ return "";
55
+ if (value.dateTime) {
56
+ return value.timeZone ? `${value.dateTime} (${value.timeZone})` : value.dateTime;
57
+ }
58
+ if (value.date)
59
+ return `${value.date} (all-day)`;
60
+ return "";
61
+ }
43
62
  /**
44
63
  * Convert a UTC timestamp string (e.g. "2026-04-22T13:00:00Z") to an ISO
45
64
  * string with the system's local timezone offset (e.g.
@@ -1 +1 @@
1
- {"version":3,"file":"dateish.js","sourceRoot":"","sources":["../../../../src/commands/calendar/dateish.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dateish.js","sourceRoot":"","sources":["../../../../src/commands/calendar/dateish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const DELETE_HELP = "usage: gws-axi calendar delete <event-id> [flags]\nargs[1]:\n <event-id> Event ID to delete\nflags[4]:\n --calendar <id> Calendar containing the event (default: primary)\n --send-updates <mode> none | all | externalOnly (default: none)\n --account <email> REQUIRED when 2+ accounts are authenticated\n --yes Don't warn; just delete (no-op currently \u2014 writes\n are already explicit via --account + this command)\nexamples:\n gws-axi calendar delete abc_123\n gws-axi calendar delete abc_123 --send-updates all --calendar team@jarv.us\nnotes:\n Idempotent: deleting an already-deleted or non-existent event returns\n exit 0 with `action: noop` rather than an error. If you need a hard\n guarantee the event existed before deletion, run `calendar get` first.\n";
2
+ export declare function calendarDeleteCommand(account: string, args: string[]): Promise<string>;
@@ -0,0 +1,97 @@
1
+ import { AxiError } from "axi-sdk-js";
2
+ import { calendarClient, translateGoogleError } from "../../google/client.js";
3
+ import { renderObject } from "../../output/index.js";
4
+ export const DELETE_HELP = `usage: gws-axi calendar delete <event-id> [flags]
5
+ args[1]:
6
+ <event-id> Event ID to delete
7
+ flags[4]:
8
+ --calendar <id> Calendar containing the event (default: primary)
9
+ --send-updates <mode> none | all | externalOnly (default: none)
10
+ --account <email> REQUIRED when 2+ accounts are authenticated
11
+ --yes Don't warn; just delete (no-op currently — writes
12
+ are already explicit via --account + this command)
13
+ examples:
14
+ gws-axi calendar delete abc_123
15
+ gws-axi calendar delete abc_123 --send-updates all --calendar team@jarv.us
16
+ notes:
17
+ Idempotent: deleting an already-deleted or non-existent event returns
18
+ exit 0 with \`action: noop\` rather than an error. If you need a hard
19
+ guarantee the event existed before deletion, run \`calendar get\` first.
20
+ `;
21
+ function parseFlags(args) {
22
+ let eventId;
23
+ let calendar = "primary";
24
+ let sendUpdates = "none";
25
+ for (let i = 0; i < args.length; i++) {
26
+ const arg = args[i];
27
+ const next = args[i + 1];
28
+ switch (arg) {
29
+ case "--calendar":
30
+ calendar = next;
31
+ i++;
32
+ break;
33
+ case "--send-updates":
34
+ if (next === "all" || next === "externalOnly" || next === "none") {
35
+ sendUpdates = next;
36
+ }
37
+ else {
38
+ throw new AxiError(`Invalid --send-updates value: ${next}`, "VALIDATION_ERROR", ["Valid values: none, all, externalOnly"]);
39
+ }
40
+ i++;
41
+ break;
42
+ case "--yes":
43
+ // no-op — reserved for future confirmation prompts
44
+ break;
45
+ default:
46
+ if (!arg.startsWith("--") && eventId === undefined) {
47
+ eventId = arg;
48
+ }
49
+ }
50
+ }
51
+ if (!eventId) {
52
+ throw new AxiError("Missing event ID argument", "VALIDATION_ERROR", [
53
+ "Usage: gws-axi calendar delete <event-id> [flags]",
54
+ "Get an ID from `gws-axi calendar events`",
55
+ ]);
56
+ }
57
+ return { eventId, calendar, sendUpdates };
58
+ }
59
+ export async function calendarDeleteCommand(account, args) {
60
+ const flags = parseFlags(args);
61
+ const api = await calendarClient(account);
62
+ try {
63
+ await api.events.delete({
64
+ calendarId: flags.calendar,
65
+ eventId: flags.eventId,
66
+ sendUpdates: flags.sendUpdates,
67
+ });
68
+ return renderObject({
69
+ action: "deleted",
70
+ account,
71
+ calendar: flags.calendar,
72
+ event_id: flags.eventId,
73
+ send_updates: flags.sendUpdates,
74
+ help: [
75
+ `Run \`gws-axi calendar events --calendar ${flags.calendar}\` to verify`,
76
+ ],
77
+ });
78
+ }
79
+ catch (err) {
80
+ const translated = translateGoogleError(err, {
81
+ account,
82
+ operation: "calendar.events.delete",
83
+ });
84
+ if (translated.code === "NOT_FOUND" || translated.code === "GOOGLE_API_ERROR_410") {
85
+ // 404 or 410 (gone) — already deleted. Idempotent success.
86
+ return renderObject({
87
+ action: "noop",
88
+ account,
89
+ calendar: flags.calendar,
90
+ event_id: flags.eventId,
91
+ reason: "event was already deleted or never existed",
92
+ });
93
+ }
94
+ throw translated;
95
+ }
96
+ }
97
+ //# sourceMappingURL=delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../../src/commands/calendar/delete.ts"],"names":[],"mappings":"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"}