gws-axi 0.19.0 → 0.20.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.
@@ -1,11 +1,21 @@
1
1
  import { AxiError } from "axi-sdk-js";
2
2
  import { resolveAccount } from "../google/account.js";
3
+ import { notImplemented, renderAlternatives, withInstead } from "./stub-signposts.js";
3
4
  import { docsCommentsCommand, COMMENTS_HELP } from "./docs/comments.js";
4
5
  import { docsDiffCommand, DIFF_HELP } from "./docs/diff.js";
5
6
  import { docsDownloadCommand, DOWNLOAD_HELP } from "./docs/download.js";
6
7
  import { docsFindCommand, FIND_HELP } from "./docs/find.js";
7
8
  import { docsReadCommand, READ_HELP } from "./docs/read.js";
8
9
  import { driveRevisionsCommand, REVISIONS_HELP } from "./drive/revisions.js";
10
+ // Granular Docs edits need documents.batchUpdate, which isn't wired yet. The
11
+ // download → edit → upload round trip is the shipped substitute, and it
12
+ // replaces the whole document — so the lines say that rather than implying a
13
+ // targeted edit.
14
+ const ROUND_TRIP = [
15
+ "gws-axi docs download <documentId> --out ./doc.md — export the current content to edit locally",
16
+ "gws-axi drive upload ./doc.md --update <documentId> --convert --account <email> — write it back as a NEW REVISION, replacing the ENTIRE document",
17
+ "Multi-tab Docs are refused with MULTI_TAB_TARGET unless --replace-all-tabs; `gws-axi docs diff <documentId> <revA>` compares revisions afterward",
18
+ ];
9
19
  // Write subcommands are still stubs but we keep per-command --help text
10
20
  // so agents can plan around the future surface.
11
21
  const APPEND_HELP = `usage: gws-axi docs append <documentId> --text <markdown> [--tab <id>] [flags]
@@ -53,13 +63,15 @@ const SUBCOMMANDS = [
53
63
  // model, but the implementation is Drive-wide (any file type).
54
64
  { name: "revisions", mutation: false, help: REVISIONS_HELP, handler: driveRevisionsCommand },
55
65
  { name: "diff", mutation: false, help: DIFF_HELP, handler: docsDiffCommand },
56
- { name: "append", mutation: true, help: APPEND_HELP },
57
- { name: "insert-text", mutation: true, help: INSERT_TEXT_HELP },
58
- { name: "delete-range", mutation: true, help: DELETE_RANGE_HELP },
59
- { name: "style-text", mutation: true, help: STYLE_TEXT_HELP },
60
- { name: "style-paragraph", mutation: true, help: STYLE_PARAGRAPH_HELP },
61
- { name: "insert-table", mutation: true, help: INSERT_TABLE_HELP },
62
- { name: "edit-cell", mutation: true, help: EDIT_CELL_HELP },
66
+ { name: "append", mutation: true, help: APPEND_HELP, instead: ROUND_TRIP },
67
+ { name: "insert-text", mutation: true, help: INSERT_TEXT_HELP, instead: ROUND_TRIP },
68
+ { name: "delete-range", mutation: true, help: DELETE_RANGE_HELP, instead: ROUND_TRIP },
69
+ { name: "style-text", mutation: true, help: STYLE_TEXT_HELP, instead: ROUND_TRIP },
70
+ { name: "style-paragraph", mutation: true, help: STYLE_PARAGRAPH_HELP, instead: ROUND_TRIP },
71
+ { name: "insert-table", mutation: true, help: INSERT_TABLE_HELP, instead: ROUND_TRIP },
72
+ { name: "edit-cell", mutation: true, help: EDIT_CELL_HELP, instead: ROUND_TRIP },
73
+ // Comment writes need the Drive comments API, which no shipped command
74
+ // touches — the round trip below rewrites body content only.
63
75
  { name: "comment-add", mutation: true, help: COMMENT_ADD_HELP },
64
76
  { name: "comment-reply", mutation: true, help: COMMENT_REPLY_HELP },
65
77
  { name: "comment-resolve", mutation: true, help: COMMENT_RESOLVE_HELP },
@@ -91,7 +103,7 @@ notes:
91
103
  Reads use the default account when --account is not provided.
92
104
  Write subcommands are scaffolded for the next slice — all currently
93
105
  throw NOT_IMPLEMENTED after account resolution runs.
94
- subcommand help:
106
+ ${renderAlternatives(SUBCOMMANDS)}subcommand help:
95
107
  gws-axi docs read --help for documentId + tab handling
96
108
  gws-axi docs find --help for text-match search
97
109
  gws-axi docs comments --help for review comments + replies
@@ -118,7 +130,7 @@ export async function docsCommand(args) {
118
130
  }
119
131
  const rest = args.slice(1);
120
132
  if (rest.includes("--help")) {
121
- return def.help;
133
+ return def.handler ? def.help : withInstead(def.help, def.instead);
122
134
  }
123
135
  const { account: accountFlag, rest: remaining } = parseAccountFlag(rest);
124
136
  const resolution = resolveAccount(accountFlag, {
@@ -126,10 +138,7 @@ export async function docsCommand(args) {
126
138
  commandName: `docs ${sub}`,
127
139
  });
128
140
  if (!def.handler) {
129
- throw new AxiError(`gws-axi docs ${sub} is not yet implemented`, "NOT_IMPLEMENTED", [
130
- `Account resolution succeeded: would run as ${resolution.account}`,
131
- `See \`gws-axi docs ${sub} --help\` for the planned surface`,
132
- ]);
141
+ throw notImplemented("docs", sub, resolution.account, def.instead);
133
142
  }
134
143
  return def.handler(resolution.account, remaining);
135
144
  }
@@ -1 +1 @@
1
- {"version":3,"file":"docs.js","sourceRoot":"","sources":["../../../src/commands/docs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"docs.js","sourceRoot":"","sources":["../../../src/commands/docs.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { AxiError } from "axi-sdk-js";
2
2
  import { resolveAccount } from "../google/account.js";
3
+ import { notImplemented, renderAlternatives, withInstead } from "./stub-signposts.js";
3
4
  import { docsDownloadCommand } from "./docs/download.js";
4
5
  import { driveGetCommand, GET_HELP } from "./drive/get.js";
5
6
  import { driveLsCommand, LS_HELP } from "./drive/ls.js";
@@ -82,7 +83,18 @@ const SUBCOMMANDS = [
82
83
  help: UPLOAD_HELP,
83
84
  handler: driveUploadCommand,
84
85
  },
85
- { name: "create", mutation: true, help: CREATE_HELP },
86
+ {
87
+ name: "create",
88
+ mutation: true,
89
+ help: CREATE_HELP,
90
+ instead: [
91
+ "gws-axi drive upload <path|-|--content <string>> --name <name> --account <email> — creates a file from content (add --convert for a native Doc/Sheet/Slides)",
92
+ 'gws-axi drive mkdir "<name>" --account <email> — creates a folder',
93
+ ],
94
+ },
95
+ // copy / move / delete have no shipped equivalent. `rename` deliberately
96
+ // gets none either: `drive upload --update --name` does rename, but only
97
+ // while replacing the file's content, so advertising it here would mislead.
86
98
  { name: "copy", mutation: true, help: COPY_HELP },
87
99
  { name: "move", mutation: true, help: MOVE_HELP },
88
100
  { name: "rename", mutation: true, help: RENAME_HELP },
@@ -121,7 +133,7 @@ notes:
121
133
  Reads use the default account when --account is not provided.
122
134
  upload and mkdir are live; the remaining write subcommands are scaffolded
123
135
  for the next slice and throw NOT_IMPLEMENTED after account resolution runs.
124
- subcommand help:
136
+ ${renderAlternatives(SUBCOMMANDS)}subcommand help:
125
137
  gws-axi drive ls --help for folder listing (incl. --recursive)
126
138
  gws-axi drive get --help for full file metadata
127
139
  gws-axi drive search --help for full-text search
@@ -151,7 +163,7 @@ export async function driveCommand(args) {
151
163
  }
152
164
  const rest = args.slice(1);
153
165
  if (rest.includes("--help")) {
154
- return def.help;
166
+ return def.handler ? def.help : withInstead(def.help, def.instead);
155
167
  }
156
168
  const { account: accountFlag, rest: remaining } = parseAccountFlag(rest);
157
169
  const resolution = resolveAccount(accountFlag, {
@@ -159,10 +171,7 @@ export async function driveCommand(args) {
159
171
  commandName: `drive ${sub}`,
160
172
  });
161
173
  if (!def.handler) {
162
- throw new AxiError(`gws-axi drive ${sub} is not yet implemented`, "NOT_IMPLEMENTED", [
163
- `Account resolution succeeded: would run as ${resolution.account}`,
164
- `See \`gws-axi drive ${sub} --help\` for the planned surface`,
165
- ]);
174
+ throw notImplemented("drive", sub, resolution.account, def.instead);
166
175
  }
167
176
  return def.handler(resolution.account, remaining);
168
177
  }
@@ -1 +1 @@
1
- {"version":3,"file":"drive.js","sourceRoot":"","sources":["../../../src/commands/drive.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"drive.js","sourceRoot":"","sources":["../../../src/commands/drive.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,16 @@
1
1
  /**
2
- * Minimal RFC 5322 message builder for draft creation. We only need the
3
- * plain-text single-part case: agents draft text bodies for human review,
4
- * and Gmail's web composer handles any rich formatting on send. The raw
5
- * message is base64url-encoded as the Gmail API's `raw` field expects.
2
+ * RFC 5322 message builder for draft creation.
3
+ *
4
+ * Drafts go out as `multipart/alternative`: the `--body` markdown verbatim as
5
+ * `text/plain`, and its rendered form as `text/html`. That structure is what
6
+ * Gmail's own composer produces, and emitting it is load-bearing rather than
7
+ * cosmetic — a single-part `text/plain` draft drops Gmail's composer into
8
+ * plain-text mode, and on send Gmail hard-wraps the body at ~70 columns with
9
+ * real CRLFs and ships no HTML alternative. The compose window still shows the
10
+ * original unwrapped paragraphs, so the recipient's ragged columns are
11
+ * invisible until after the message is gone.
12
+ *
13
+ * See specs/commands/gmail-draft.md ("Message structure", "Body rendering").
6
14
  */
7
15
  export interface ComposeFields {
8
16
  /** Sender — the authenticated account's address. */
@@ -11,14 +19,23 @@ export interface ComposeFields {
11
19
  cc?: string[];
12
20
  bcc?: string[];
13
21
  subject: string;
22
+ /** Markdown source. Rendered into the text/html part, kept verbatim as text/plain. */
14
23
  body: string;
15
24
  }
16
25
  /** Split a comma-separated recipient flag into trimmed, non-empty addresses. */
17
26
  export declare function parseRecipients(value: string): string[];
27
+ /**
28
+ * Render the body markdown to an HTML document.
29
+ *
30
+ * `breaks: true` is deliberate: email bodies carry meaningful single-line
31
+ * breaks (signature blocks, addresses, value lists), and markdown's default of
32
+ * collapsing them into spaces would silently reflow content the author laid
33
+ * out. The flip side — a pre-wrapped body keeps its wrapping — is why
34
+ * DRAFT_HELP tells callers not to hard-wrap.
35
+ */
36
+ export declare function renderMarkdown(body: string): string;
18
37
  /**
19
38
  * Build a base64url-encoded RFC 5322 message suitable for
20
- * `users.drafts.create` / `users.messages.send` `raw` fields. Body is sent
21
- * as a single text/plain part with base64 transfer-encoding so any UTF-8
22
- * content survives intact.
39
+ * `users.drafts.create` / `users.messages.send` `raw` fields.
23
40
  */
24
41
  export declare function buildRawMessage(fields: ComposeFields): string;
@@ -1,9 +1,19 @@
1
1
  /**
2
- * Minimal RFC 5322 message builder for draft creation. We only need the
3
- * plain-text single-part case: agents draft text bodies for human review,
4
- * and Gmail's web composer handles any rich formatting on send. The raw
5
- * message is base64url-encoded as the Gmail API's `raw` field expects.
2
+ * RFC 5322 message builder for draft creation.
3
+ *
4
+ * Drafts go out as `multipart/alternative`: the `--body` markdown verbatim as
5
+ * `text/plain`, and its rendered form as `text/html`. That structure is what
6
+ * Gmail's own composer produces, and emitting it is load-bearing rather than
7
+ * cosmetic — a single-part `text/plain` draft drops Gmail's composer into
8
+ * plain-text mode, and on send Gmail hard-wraps the body at ~70 columns with
9
+ * real CRLFs and ships no HTML alternative. The compose window still shows the
10
+ * original unwrapped paragraphs, so the recipient's ragged columns are
11
+ * invisible until after the message is gone.
12
+ *
13
+ * See specs/commands/gmail-draft.md ("Message structure", "Body rendering").
6
14
  */
15
+ import { randomUUID } from "node:crypto";
16
+ import { marked } from "marked";
7
17
  /** Split a comma-separated recipient flag into trimmed, non-empty addresses. */
8
18
  export function parseRecipients(value) {
9
19
  return value
@@ -21,13 +31,33 @@ function encodeHeaderValue(value) {
21
31
  return value;
22
32
  return `=?UTF-8?B?${Buffer.from(value, "utf8").toString("base64")}?=`;
23
33
  }
34
+ /**
35
+ * Render the body markdown to an HTML document.
36
+ *
37
+ * `breaks: true` is deliberate: email bodies carry meaningful single-line
38
+ * breaks (signature blocks, addresses, value lists), and markdown's default of
39
+ * collapsing them into spaces would silently reflow content the author laid
40
+ * out. The flip side — a pre-wrapped body keeps its wrapping — is why
41
+ * DRAFT_HELP tells callers not to hard-wrap.
42
+ */
43
+ export function renderMarkdown(body) {
44
+ const fragment = marked.parse(body, { gfm: true, breaks: true, async: false });
45
+ return `<html><body>${fragment}</body></html>`;
46
+ }
47
+ /** Base64 with CRLF line endings wrapped at 76 columns (RFC 2045). */
48
+ function encodePart(text) {
49
+ return Buffer.from(text, "utf8")
50
+ .toString("base64")
51
+ .replace(/(.{76})/g, "$1\r\n");
52
+ }
24
53
  /**
25
54
  * Build a base64url-encoded RFC 5322 message suitable for
26
- * `users.drafts.create` / `users.messages.send` `raw` fields. Body is sent
27
- * as a single text/plain part with base64 transfer-encoding so any UTF-8
28
- * content survives intact.
55
+ * `users.drafts.create` / `users.messages.send` `raw` fields.
29
56
  */
30
57
  export function buildRawMessage(fields) {
58
+ // Unique per message, so it can never collide with body content — no
59
+ // scanning the body for the boundary, no retry loop.
60
+ const boundary = `=_gws-axi_${randomUUID()}`;
31
61
  const headers = [`From: ${fields.from}`, `To: ${fields.to.join(", ")}`];
32
62
  if (fields.cc?.length)
33
63
  headers.push(`Cc: ${fields.cc.join(", ")}`);
@@ -35,13 +65,14 @@ export function buildRawMessage(fields) {
35
65
  headers.push(`Bcc: ${fields.bcc.join(", ")}`);
36
66
  headers.push(`Subject: ${encodeHeaderValue(fields.subject)}`);
37
67
  headers.push("MIME-Version: 1.0");
38
- headers.push('Content-Type: text/plain; charset="UTF-8"');
39
- headers.push("Content-Transfer-Encoding: base64");
40
- // Wrap the base64 body at 76 columns (RFC 2045) with CRLF line endings.
41
- const encodedBody = Buffer.from(fields.body, "utf8")
42
- .toString("base64")
43
- .replace(/(.{76})/g, "$1\r\n");
44
- const raw = `${headers.join("\r\n")}\r\n\r\n${encodedBody}`;
68
+ headers.push(`Content-Type: multipart/alternative; boundary="${boundary}"`);
69
+ // RFC 2046 orders alternatives least- to most-faithful; clients render the
70
+ // last part they understand, so text/html goes second.
71
+ const parts = [
72
+ ['Content-Type: text/plain; charset="UTF-8"', fields.body],
73
+ ['Content-Type: text/html; charset="UTF-8"', renderMarkdown(fields.body)],
74
+ ].map(([contentType, content]) => `--${boundary}\r\n${contentType}\r\nContent-Transfer-Encoding: base64\r\n\r\n${encodePart(content)}`);
75
+ const raw = `${headers.join("\r\n")}\r\n\r\n${parts.join("\r\n")}\r\n--${boundary}--`;
45
76
  return Buffer.from(raw, "utf8").toString("base64url");
46
77
  }
47
78
  //# sourceMappingURL=compose.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compose.js","sourceRoot":"","sources":["../../../../src/commands/gmail/compose.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,gFAAgF;AAChF,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,KAAa;IACtC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7E,OAAO,aAAa,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;AACxE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,MAAqB;IACnD,MAAM,OAAO,GAAa,CAAC,SAAS,MAAM,CAAC,IAAI,EAAE,EAAE,OAAO,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClF,IAAI,MAAM,CAAC,EAAE,EAAE,MAAM;QAAE,OAAO,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnE,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM;QAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,YAAY,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAClC,OAAO,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAElD,wEAAwE;IACxE,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;SACjD,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAEjC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,WAAW,EAAE,CAAC;IAC5D,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACxD,CAAC"}
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../../../../src/commands/gmail/compose.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,28 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import { buildRawMessage, parseRecipients } from "./compose.js";
3
- /** Decode a base64url raw message back into its header block and body. */
3
+ /** Decode a base64url raw message into its header block and decoded MIME parts. */
4
4
  function decodeRaw(raw) {
5
5
  const text = Buffer.from(raw, "base64url").toString("utf8");
6
6
  const idx = text.indexOf("\r\n\r\n");
7
7
  const header = text.slice(0, idx);
8
- const bodyB64 = text.slice(idx + 4).replace(/\r\n/g, "");
9
- return { header, body: Buffer.from(bodyB64, "base64").toString("utf8") };
8
+ const boundary = /boundary="([^"]+)"/.exec(header)?.[1] ?? "";
9
+ expect(boundary).not.toBe("");
10
+ // Drop the preamble (before the first boundary) and the closing `--<b>--`.
11
+ const parts = text
12
+ .slice(idx + 4)
13
+ .split(`--${boundary}`)
14
+ .slice(1, -1)
15
+ .map((chunk) => {
16
+ const split = chunk.indexOf("\r\n\r\n");
17
+ const partHeaders = chunk.slice(0, split);
18
+ const b64 = chunk.slice(split + 4).replace(/\r\n/g, "");
19
+ return {
20
+ contentType: /Content-Type: ([^;\r\n]+)/.exec(partHeaders)?.[1] ?? "",
21
+ content: Buffer.from(b64, "base64").toString("utf8"),
22
+ };
23
+ });
24
+ const find = (type) => parts.find((p) => p.contentType === type)?.content ?? "";
25
+ return { header, boundary, parts, plain: find("text/plain"), html: find("text/html") };
10
26
  }
11
27
  describe("parseRecipients", () => {
12
28
  it("splits, trims, and drops empties", () => {
@@ -21,19 +37,76 @@ describe("parseRecipients", () => {
21
37
  });
22
38
  });
23
39
  describe("buildRawMessage", () => {
24
- it("emits the core headers and round-trips the body", () => {
40
+ it("emits the core headers and a multipart/alternative body", () => {
25
41
  const raw = buildRawMessage({
26
42
  from: "me@x.com",
27
43
  to: ["alice@x.com", "bob@x.com"],
28
44
  subject: "Hello",
29
45
  body: "Line one\nLine two",
30
46
  });
31
- const { header, body } = decodeRaw(raw);
47
+ const { header, boundary, parts } = decodeRaw(raw);
32
48
  expect(header).toContain("From: me@x.com");
33
49
  expect(header).toContain("To: alice@x.com, bob@x.com");
34
50
  expect(header).toContain("Subject: Hello");
35
- expect(header).toContain('Content-Type: text/plain; charset="UTF-8"');
36
- expect(body).toBe("Line one\nLine two");
51
+ expect(header).toContain(`Content-Type: multipart/alternative; boundary="${boundary}"`);
52
+ // RFC 2046: least-faithful alternative first, so clients pick the HTML.
53
+ expect(parts.map((p) => p.contentType)).toEqual(["text/plain", "text/html"]);
54
+ });
55
+ it("delimits both parts and terminates the multipart body", () => {
56
+ const raw = buildRawMessage({
57
+ from: "me@x.com",
58
+ to: ["a@x.com"],
59
+ subject: "s",
60
+ body: "hello",
61
+ });
62
+ const { boundary } = decodeRaw(raw);
63
+ const text = Buffer.from(raw, "base64url").toString("utf8");
64
+ expect(text.split(`--${boundary}\r\n`)).toHaveLength(3); // two part delimiters
65
+ expect(text.endsWith(`--${boundary}--`)).toBe(true);
66
+ });
67
+ it("uses a fresh boundary per message", () => {
68
+ const fields = { from: "me@x.com", to: ["a@x.com"], subject: "s", body: "b" };
69
+ expect(decodeRaw(buildRawMessage(fields)).boundary).not.toBe(decodeRaw(buildRawMessage(fields)).boundary);
70
+ });
71
+ it("keeps the markdown source verbatim in the text/plain part", () => {
72
+ const body = "# Heading\n\nSome **bold** text.\n\n- one\n- two";
73
+ const { plain } = decodeRaw(buildRawMessage({ from: "me@x.com", to: ["a@x.com"], subject: "s", body }));
74
+ expect(plain).toBe(body);
75
+ });
76
+ it("renders markdown into the text/html part", () => {
77
+ const { html } = decodeRaw(buildRawMessage({
78
+ from: "me@x.com",
79
+ to: ["a@x.com"],
80
+ subject: "s",
81
+ body: "Some **bold** text.\n\n- one\n- two",
82
+ }));
83
+ expect(html).toContain("<strong>bold</strong>");
84
+ expect(html).toContain("<li>one</li>");
85
+ expect(html).toMatch(/^<html><body>/);
86
+ expect(html).toMatch(/<\/body><\/html>$/);
87
+ });
88
+ it("maps a blank line to a new paragraph and a single newline to <br>", () => {
89
+ const { html } = decodeRaw(buildRawMessage({
90
+ from: "me@x.com",
91
+ to: ["a@x.com"],
92
+ subject: "s",
93
+ body: "First para.\n\nSecond line one\nsecond line two",
94
+ }));
95
+ // Two paragraphs...
96
+ expect(html.match(/<p>/g)).toHaveLength(2);
97
+ // ...and the intra-paragraph newline survives as a break, not a space.
98
+ expect(html).toContain("Second line one<br>second line two");
99
+ });
100
+ it("never breaks a long paragraph inside the decoded content of either part", () => {
101
+ // The 76-column wrapping is base64 transport only — it must not survive
102
+ // decoding, or the recipient sees the ragged columns this format exists
103
+ // to prevent.
104
+ const body = `${"word ".repeat(60).trim()}.`;
105
+ const { plain, html } = decodeRaw(buildRawMessage({ from: "me@x.com", to: ["a@x.com"], subject: "s", body }));
106
+ expect(plain).toBe(body);
107
+ expect(plain).not.toContain("\r\n");
108
+ expect(html).not.toContain("\r\n");
109
+ expect(html).toContain(body);
37
110
  });
38
111
  it("includes Cc/Bcc only when provided", () => {
39
112
  const withCc = decodeRaw(buildRawMessage({
@@ -50,8 +123,8 @@ describe("buildRawMessage", () => {
50
123
  expect(without).not.toContain("Cc:");
51
124
  expect(without).not.toContain("Bcc:");
52
125
  });
53
- it("RFC 2047 encodes non-ASCII subjects but leaves the body decodable", () => {
54
- const { header, body } = decodeRaw(buildRawMessage({
126
+ it("RFC 2047 encodes non-ASCII subjects but leaves both parts decodable", () => {
127
+ const { header, plain, html } = decodeRaw(buildRawMessage({
55
128
  from: "me@x.com",
56
129
  to: ["a@x.com"],
57
130
  subject: "café ☕",
@@ -59,7 +132,8 @@ describe("buildRawMessage", () => {
59
132
  }));
60
133
  expect(header).toContain("Subject: =?UTF-8?B?");
61
134
  expect(header).not.toContain("café");
62
- expect(body).toBe("naïve résumé — ☕");
135
+ expect(plain).toBe("naïve résumé — ☕");
136
+ expect(html).toContain("naïve résumé — ☕");
63
137
  });
64
138
  it("produces valid base64url (no +,/,= padding chars)", () => {
65
139
  const raw = buildRawMessage({
@@ -69,7 +143,7 @@ describe("buildRawMessage", () => {
69
143
  body: "x".repeat(200), // force base64 line wrapping
70
144
  });
71
145
  expect(raw).not.toMatch(/[+/=]/);
72
- expect(decodeRaw(raw).body).toBe("x".repeat(200));
146
+ expect(decodeRaw(raw).plain).toBe("x".repeat(200));
73
147
  });
74
148
  });
75
149
  //# sourceMappingURL=compose.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compose.test.js","sourceRoot":"","sources":["../../../../src/commands/gmail/compose.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compose.test.js","sourceRoot":"","sources":["../../../../src/commands/gmail/compose.test.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- export declare const DRAFT_HELP = "usage: gws-axi gmail draft --to <emails> --subject <text> --body <markdown> [flags]\nflags[8]:\n --to <emails> REQUIRED \u2014 comma-separated recipient addresses\n --subject <text> Subject line (default: empty)\n --body <text> Body text. Pass via quoted string or shell heredoc\n --body-file <path> Read the body from a file instead of --body (mutually\n exclusive with --body; use for long/multi-line bodies)\n --cc <emails> Comma-separated Cc addresses\n --bcc <emails> Comma-separated Bcc addresses\n --thread <thread-id> Attach the draft to an existing thread (reply draft)\n --account <email> REQUIRED when 2+ accounts are authenticated\nexamples:\n gws-axi gmail draft --to alice@x.com --subject \"Re: budget\" --body \"Looks good \u2014 approving.\"\n gws-axi gmail draft --to a@x.com,b@x.com --subject Hi --body-file ./note.txt\n gws-axi gmail draft --to alice@x.com --subject \"Re: thread\" --body \"...\" --thread 1899abcd\nnotes:\n Creates a DRAFT only \u2014 gws-axi never sends mail. Review and send from the\n Gmail UI. Body is sent as plain text (text/plain; UTF-8); any markdown is\n preserved verbatim, not rendered to HTML.\noutput:\n Returns `action: drafted` plus the new draft_id, message_id, recipients,\n and subject. A help line links to where to review/send it.\n";
1
+ export declare const DRAFT_HELP = "usage: gws-axi gmail draft --to <emails> --subject <text> --body <markdown> [flags]\nflags[8]:\n --to <emails> REQUIRED \u2014 comma-separated recipient addresses\n --subject <text> Subject line (default: empty)\n --body <text> Body text. Pass via quoted string or shell heredoc\n --body-file <path> Read the body from a file instead of --body (mutually\n exclusive with --body; use for long/multi-line bodies)\n --cc <emails> Comma-separated Cc addresses\n --bcc <emails> Comma-separated Bcc addresses\n --thread <thread-id> Attach the draft to an existing thread (reply draft)\n --account <email> REQUIRED when 2+ accounts are authenticated\nexamples:\n gws-axi gmail draft --to alice@x.com --subject \"Re: budget\" --body \"Looks good \u2014 approving.\"\n gws-axi gmail draft --to a@x.com,b@x.com --subject Hi --body-file ./note.txt\n gws-axi gmail draft --to alice@x.com --subject \"Re: thread\" --body \"...\" --thread 1899abcd\nnotes:\n Creates a DRAFT only \u2014 gws-axi never sends mail. Review and send from the\n Gmail UI. The body is markdown, rendered to HTML: the draft goes out as\n multipart/alternative (markdown source as text/plain, rendered GFM as\n text/html) so recipients get reflowable text.\n DO NOT hard-wrap the body. Write each paragraph as one long line \u2014 every\n newline you write becomes a line break in the sent message, so a body\n pre-wrapped at 72/80 columns arrives locked to that width on every screen.\n Blank line = new paragraph. GFM applies: **bold**, lists, tables, fenced\n code blocks (use those for text meant literally).\noutput:\n Returns `action: drafted` plus the new draft_id, message_id, recipients,\n and subject. A help line links to where to review/send it.\n";
2
2
  export declare const SEND_HELP = "usage: gws-axi gmail send \u2014 INTENTIONALLY OUT OF SCOPE\nstatus: not supported by design\nnotes:\n gws-axi deliberately does not send mail. It can draft messages for you, but\n sending is left to a human in the Gmail UI so an automated agent can't email\n people on your behalf. Use `gws-axi gmail draft` to compose, then review and\n send the draft yourself in Gmail.\n";
3
3
  export declare function gmailDraftCommand(account: string, args: string[]): Promise<string>;
@@ -20,8 +20,14 @@ examples:
20
20
  gws-axi gmail draft --to alice@x.com --subject "Re: thread" --body "..." --thread 1899abcd
21
21
  notes:
22
22
  Creates a DRAFT only — gws-axi never sends mail. Review and send from the
23
- Gmail UI. Body is sent as plain text (text/plain; UTF-8); any markdown is
24
- preserved verbatim, not rendered to HTML.
23
+ Gmail UI. The body is markdown, rendered to HTML: the draft goes out as
24
+ multipart/alternative (markdown source as text/plain, rendered GFM as
25
+ text/html) so recipients get reflowable text.
26
+ DO NOT hard-wrap the body. Write each paragraph as one long line — every
27
+ newline you write becomes a line break in the sent message, so a body
28
+ pre-wrapped at 72/80 columns arrives locked to that width on every screen.
29
+ Blank line = new paragraph. GFM applies: **bold**, lists, tables, fenced
30
+ code blocks (use those for text meant literally).
25
31
  output:
26
32
  Returns \`action: drafted\` plus the new draft_id, message_id, recipients,
27
33
  and subject. A help line links to where to review/send it.
@@ -1 +1 @@
1
- {"version":3,"file":"draft.js","sourceRoot":"","sources":["../../../../src/commands/gmail/draft.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"draft.js","sourceRoot":"","sources":["../../../../src/commands/gmail/draft.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { AxiError } from "axi-sdk-js";
2
2
  import { resolveAccount } from "../google/account.js";
3
3
  import { docsCommentsCommand } from "./docs/comments.js";
4
4
  import { READ_HELP, sheetsReadCommand } from "./sheets/read.js";
5
+ import { notImplemented, renderAlternatives, withInstead } from "./stub-signposts.js";
5
6
  // Google Sheets comments are Drive comments — the exact same file-agnostic API
6
7
  // `docs comments` uses. Alias the handler (cf. `docs revisions` → `drive
7
8
  // revisions`) and give it a Sheets-worded help block.
@@ -21,6 +22,17 @@ notes:
21
22
  data as \`gws-axi docs comments\`. Cell *notes* are distinct — those come
22
23
  back in the notes[] block of \`gws-axi sheets read\`.
23
24
  `;
25
+ // Until the Sheets write surface lands, `drive upload --convert` is the only
26
+ // way to put content into a spreadsheet. It replaces the file wholesale, so
27
+ // each line says so — an agent that reads "use drive upload" and nothing else
28
+ // would silently destroy the sheets it never looked at.
29
+ const REPLACE_WHOLESALE = [
30
+ "gws-axi drive upload <file.csv> --update <spreadsheetId> --convert --account <email> — replaces the ENTIRE spreadsheet from CSV/TSV (or --content <string>); NOT a per-range write",
31
+ "Multi-sheet targets are refused with MULTI_TAB_TARGET unless --replace-all-tabs; read them first with `gws-axi sheets read <spreadsheetId>`",
32
+ ];
33
+ const CREATE_VIA_UPLOAD = [
34
+ 'gws-axi drive upload <file.csv> --convert --name "<title>" --account <email> — creates a new native Spreadsheet and returns its id',
35
+ ];
24
36
  // Write subcommands are stubs for the next slice — kept with per-command --help
25
37
  // so agents can plan around the future surface. They throw NOT_IMPLEMENTED after
26
38
  // account resolution runs.
@@ -56,10 +68,12 @@ const sheetsCommentsCommand = (account, args) => docsCommentsCommand(account, ar
56
68
  const SUBCOMMANDS = [
57
69
  { name: "read", mutation: false, help: READ_HELP, handler: sheetsReadCommand },
58
70
  { name: "comments", mutation: false, help: COMMENTS_HELP, handler: sheetsCommentsCommand },
59
- { name: "update", mutation: true, help: UPDATE_HELP },
60
- { name: "append", mutation: true, help: APPEND_HELP },
61
- { name: "clear", mutation: true, help: CLEAR_HELP },
62
- { name: "create", mutation: true, help: CREATE_HELP },
71
+ { name: "update", mutation: true, help: UPDATE_HELP, instead: REPLACE_WHOLESALE },
72
+ { name: "append", mutation: true, help: APPEND_HELP, instead: REPLACE_WHOLESALE },
73
+ { name: "clear", mutation: true, help: CLEAR_HELP, instead: REPLACE_WHOLESALE },
74
+ { name: "create", mutation: true, help: CREATE_HELP, instead: CREATE_VIA_UPLOAD },
75
+ // Adding a tab needs spreadsheets.batchUpdate — drive upload can only
76
+ // collapse a spreadsheet to one sheet, never grow it one.
63
77
  { name: "add-tab", mutation: true, help: ADD_TAB_HELP },
64
78
  ];
65
79
  const SUB_BY_NAME = Object.fromEntries(SUBCOMMANDS.map((s) => [s.name, s]));
@@ -89,7 +103,7 @@ notes:
89
103
  Reads use the default account when --account is not provided.
90
104
  Write subcommands are scaffolded for the next slice — all currently
91
105
  throw NOT_IMPLEMENTED after account resolution runs.
92
- subcommand help:
106
+ ${renderAlternatives(SUBCOMMANDS)}subcommand help:
93
107
  gws-axi sheets read --help for spreadsheetId + tab/range handling
94
108
  gws-axi sheets comments --help for review comments (Drive comments)
95
109
  examples:
@@ -111,7 +125,7 @@ export async function sheetsCommand(args) {
111
125
  }
112
126
  const rest = args.slice(1);
113
127
  if (rest.includes("--help")) {
114
- return def.help;
128
+ return def.handler ? def.help : withInstead(def.help, def.instead);
115
129
  }
116
130
  const { account: accountFlag, rest: remaining } = parseAccountFlag(rest);
117
131
  const resolution = resolveAccount(accountFlag, {
@@ -119,10 +133,7 @@ export async function sheetsCommand(args) {
119
133
  commandName: `sheets ${sub}`,
120
134
  });
121
135
  if (!def.handler) {
122
- throw new AxiError(`gws-axi sheets ${sub} is not yet implemented`, "NOT_IMPLEMENTED", [
123
- `Account resolution succeeded: would run as ${resolution.account}`,
124
- `See \`gws-axi sheets ${sub} --help\` for the planned surface`,
125
- ]);
136
+ throw notImplemented("sheets", sub, resolution.account, def.instead);
126
137
  }
127
138
  return def.handler(resolution.account, remaining);
128
139
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sheets.js","sourceRoot":"","sources":["../../../src/commands/sheets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sheets.js","sourceRoot":"","sources":["../../../src/commands/sheets.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { AxiError } from "axi-sdk-js";
2
2
  import { resolveAccount } from "../google/account.js";
3
+ import { notImplemented, renderAlternatives, withInstead } from "./stub-signposts.js";
3
4
  import { docsCommentsCommand } from "./docs/comments.js";
4
5
  import { GET_HELP, slidesGetCommand } from "./slides/get.js";
5
6
  import { PAGE_HELP, slidesPageCommand } from "./slides/page.js";
@@ -50,8 +51,23 @@ const SUBCOMMANDS = [
50
51
  handler: slidesSummarizeCommand,
51
52
  },
52
53
  { name: "comments", mutation: false, help: COMMENTS_HELP, handler: slidesCommentsCommand },
53
- { name: "create", mutation: true, help: CREATE_HELP },
54
- { name: "update", mutation: true, help: UPDATE_HELP },
54
+ {
55
+ name: "create",
56
+ mutation: true,
57
+ help: CREATE_HELP,
58
+ instead: [
59
+ 'gws-axi drive upload <deck.pptx> --convert --name "<title>" --account <email> — creates a new native Presentation and returns its id',
60
+ ],
61
+ },
62
+ {
63
+ name: "update",
64
+ mutation: true,
65
+ help: UPDATE_HELP,
66
+ instead: [
67
+ "gws-axi drive upload <deck.pptx> --update <presentationId> --convert --account <email> — replaces the ENTIRE deck as a new revision; NOT a per-slide or per-element edit",
68
+ "gws-axi slides summarize <presentationId> — read the current deck first; there is no export-to-pptx round trip",
69
+ ],
70
+ },
55
71
  ];
56
72
  const SUB_BY_NAME = Object.fromEntries(SUBCOMMANDS.map((s) => [s.name, s]));
57
73
  function parseAccountFlag(args) {
@@ -80,7 +96,7 @@ notes:
80
96
  Reads use the default account when --account is not provided.
81
97
  Write subcommands are scaffolded for the next slice; they throw
82
98
  NOT_IMPLEMENTED after account resolution runs.
83
- subcommand help:
99
+ ${renderAlternatives(SUBCOMMANDS)}subcommand help:
84
100
  gws-axi slides get --help for metadata + slide list
85
101
  gws-axi slides page --help for a single slide's content
86
102
  gws-axi slides summarize --help for the whole deck as markdown
@@ -104,7 +120,7 @@ export async function slidesCommand(args) {
104
120
  }
105
121
  const rest = args.slice(1);
106
122
  if (rest.includes("--help")) {
107
- return def.help;
123
+ return def.handler ? def.help : withInstead(def.help, def.instead);
108
124
  }
109
125
  const { account: accountFlag, rest: remaining } = parseAccountFlag(rest);
110
126
  const resolution = resolveAccount(accountFlag, {
@@ -112,10 +128,7 @@ export async function slidesCommand(args) {
112
128
  commandName: `slides ${sub}`,
113
129
  });
114
130
  if (!def.handler) {
115
- throw new AxiError(`gws-axi slides ${sub} is not yet implemented`, "NOT_IMPLEMENTED", [
116
- `Account resolution succeeded: would run as ${resolution.account}`,
117
- `See \`gws-axi slides ${sub} --help\` for the planned surface`,
118
- ]);
131
+ throw notImplemented("slides", sub, resolution.account, def.instead);
119
132
  }
120
133
  return def.handler(resolution.account, remaining);
121
134
  }
@@ -1 +1 @@
1
- {"version":3,"file":"slides.js","sourceRoot":"","sources":["../../../src/commands/slides.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"slides.js","sourceRoot":"","sources":["../../../src/commands/slides.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Signposts for scaffolded subcommands.
3
+ *
4
+ * A stub that refuses with nothing but "not implemented; see --help" — where
5
+ * `--help` lists the same unimplemented command — is a closed circuit, and an
6
+ * agent's way out of a closed circuit is to leave gws-axi entirely and drive
7
+ * the Google APIs with the raw token, discarding write-protection and error
8
+ * translation with it. So every stub declares the working commands that do
9
+ * some or all of its job, and the same list feeds all three surfaces a caller
10
+ * can hit: the NOT_IMPLEMENTED error, the stub's own --help, and the service
11
+ * help screen.
12
+ *
13
+ * See specs/principles.md#no-dead-end-surfaces and specs/api/conventions.md
14
+ * ("Unimplemented and unsupported surfaces").
15
+ */
16
+ import { AxiError } from "axi-sdk-js";
17
+ export interface StubbableSubcommand {
18
+ name: string;
19
+ handler?: unknown;
20
+ /**
21
+ * Runnable gws-axi commands that accomplish some or all of this subcommand's
22
+ * job. Each line names the command AND where it falls short — these are
23
+ * mostly wholesale-replace substitutes for a granular edit, and a signpost
24
+ * that oversells is worse than none. Omit when nothing comes close.
25
+ */
26
+ instead?: string[];
27
+ }
28
+ /**
29
+ * The refusal for a scaffolded subcommand. Alternatives lead; the account
30
+ * diagnostic and the pointer to the planned surface follow, because they are
31
+ * context rather than a next step.
32
+ */
33
+ export declare function notImplemented(service: string, sub: string, account: string, instead?: string[]): AxiError;
34
+ /** Append the `instead[N]:` block to a stubbed subcommand's own --help. */
35
+ export declare function withInstead(help: string, instead?: string[]): string;
36
+ /**
37
+ * The service-level `alternatives[N]:` block, deduped across every stub.
38
+ * Returns "" when the service has no stubs, so fully-implemented services
39
+ * (calendar) gain nothing.
40
+ */
41
+ export declare function renderAlternatives(subs: StubbableSubcommand[]): string;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Signposts for scaffolded subcommands.
3
+ *
4
+ * A stub that refuses with nothing but "not implemented; see --help" — where
5
+ * `--help` lists the same unimplemented command — is a closed circuit, and an
6
+ * agent's way out of a closed circuit is to leave gws-axi entirely and drive
7
+ * the Google APIs with the raw token, discarding write-protection and error
8
+ * translation with it. So every stub declares the working commands that do
9
+ * some or all of its job, and the same list feeds all three surfaces a caller
10
+ * can hit: the NOT_IMPLEMENTED error, the stub's own --help, and the service
11
+ * help screen.
12
+ *
13
+ * See specs/principles.md#no-dead-end-surfaces and specs/api/conventions.md
14
+ * ("Unimplemented and unsupported surfaces").
15
+ */
16
+ import { AxiError } from "axi-sdk-js";
17
+ // Stated explicitly rather than omitted: "no alternative" is itself the answer
18
+ // an agent needs, and silence reads as an oversight worth working around.
19
+ const NO_ALTERNATIVE = "No gws-axi command does this yet — it needs the planned write surface, so there is nothing to fall back to";
20
+ /** Stubs are the entries with no handler. */
21
+ const stubsOf = (subs) => subs.filter((s) => !s.handler);
22
+ /**
23
+ * The refusal for a scaffolded subcommand. Alternatives lead; the account
24
+ * diagnostic and the pointer to the planned surface follow, because they are
25
+ * context rather than a next step.
26
+ */
27
+ export function notImplemented(service, sub, account, instead) {
28
+ const alternatives = instead?.length ? instead : [NO_ALTERNATIVE];
29
+ return new AxiError(`gws-axi ${service} ${sub} is not yet implemented`, "NOT_IMPLEMENTED", [
30
+ ...alternatives,
31
+ `See \`gws-axi ${service} ${sub} --help\` for the planned surface`,
32
+ `Account resolution succeeded: would run as ${account}`,
33
+ ]);
34
+ }
35
+ /** Append the `instead[N]:` block to a stubbed subcommand's own --help. */
36
+ export function withInstead(help, instead) {
37
+ const lines = instead?.length ? instead : [NO_ALTERNATIVE];
38
+ return `${help.trimEnd()}\ninstead[${lines.length}]:\n${lines.map((l) => ` ${l}`).join("\n")}\n`;
39
+ }
40
+ /**
41
+ * The service-level `alternatives[N]:` block, deduped across every stub.
42
+ * Returns "" when the service has no stubs, so fully-implemented services
43
+ * (calendar) gain nothing.
44
+ */
45
+ export function renderAlternatives(subs) {
46
+ const lines = [...new Set(stubsOf(subs).flatMap((s) => s.instead ?? []))];
47
+ if (lines.length === 0)
48
+ return "";
49
+ return `alternatives[${lines.length}]:\n${lines.map((l) => ` ${l}`).join("\n")}\n`;
50
+ }
51
+ //# sourceMappingURL=stub-signposts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stub-signposts.js","sourceRoot":"","sources":["../../../src/commands/stub-signposts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AActC,+EAA+E;AAC/E,0EAA0E;AAC1E,MAAM,cAAc,GAClB,4GAA4G,CAAC;AAE/G,6CAA6C;AAC7C,MAAM,OAAO,GAAG,CAAC,IAA2B,EAAyB,EAAE,CACrE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAEjC;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAe,EACf,GAAW,EACX,OAAe,EACf,OAAkB;IAElB,MAAM,YAAY,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IAClE,OAAO,IAAI,QAAQ,CAAC,WAAW,OAAO,IAAI,GAAG,yBAAyB,EAAE,iBAAiB,EAAE;QACzF,GAAG,YAAY;QACf,iBAAiB,OAAO,IAAI,GAAG,mCAAmC;QAClE,8CAA8C,OAAO,EAAE;KACxD,CAAC,CAAC;AACL,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,OAAkB;IAC1D,MAAM,KAAK,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IAC3D,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACpG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAA2B;IAC5D,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,OAAO,gBAAgB,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACtF,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,54 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { notImplemented, renderAlternatives, withInstead } from "./stub-signposts.js";
3
+ const noop = async () => "";
4
+ describe("notImplemented", () => {
5
+ it("leads with the alternatives, not the account diagnostic", () => {
6
+ const err = notImplemented("sheets", "update", "me@x.com", [
7
+ "gws-axi drive upload … --convert — replaces the ENTIRE spreadsheet",
8
+ ]);
9
+ expect(err.code).toBe("NOT_IMPLEMENTED");
10
+ expect(err.suggestions[0]).toContain("drive upload");
11
+ // Diagnostics are context, so they come after the next step.
12
+ expect(err.suggestions[err.suggestions.length - 1]).toContain("me@x.com");
13
+ });
14
+ it("still points at the subcommand's planned surface", () => {
15
+ const err = notImplemented("docs", "append", "me@x.com", ["do the other thing"]);
16
+ expect(err.suggestions.some((s) => s.includes("gws-axi docs append --help"))).toBe(true);
17
+ });
18
+ it("says so explicitly when nothing comes close", () => {
19
+ const err = notImplemented("drive", "move", "me@x.com");
20
+ expect(err.suggestions[0]).toContain("No gws-axi command does this yet");
21
+ });
22
+ });
23
+ describe("withInstead", () => {
24
+ it("appends an instead[N] block sized to the lines", () => {
25
+ const out = withInstead("usage: gws-axi sheets update …\nstatus: planned\n", ["a", "b"]);
26
+ expect(out).toContain("instead[2]:\n a\n b");
27
+ });
28
+ it("falls back to the no-alternative line", () => {
29
+ expect(withInstead("usage: …\n")).toContain("instead[1]:");
30
+ expect(withInstead("usage: …\n")).toContain("No gws-axi command does this yet");
31
+ });
32
+ });
33
+ describe("renderAlternatives", () => {
34
+ it("dedupes lines shared across stubs", () => {
35
+ const block = renderAlternatives([
36
+ { name: "read", handler: noop },
37
+ { name: "update", instead: ["shared line", "update only"] },
38
+ { name: "append", instead: ["shared line"] },
39
+ ]);
40
+ expect(block).toContain("alternatives[2]:");
41
+ expect(block.match(/shared line/g)).toHaveLength(1);
42
+ });
43
+ it("ignores alternatives on implemented subcommands", () => {
44
+ const block = renderAlternatives([{ name: "read", handler: noop, instead: ["ignored"] }]);
45
+ expect(block).toBe("");
46
+ });
47
+ it("returns empty for a service with nothing stubbed", () => {
48
+ expect(renderAlternatives([{ name: "events", handler: noop }])).toBe("");
49
+ });
50
+ it("skips stubs that declare no alternative", () => {
51
+ expect(renderAlternatives([{ name: "move" }])).toBe("");
52
+ });
53
+ });
54
+ //# sourceMappingURL=stub-signposts.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stub-signposts.test.js","sourceRoot":"","sources":["../../../src/commands/stub-signposts.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gws-axi",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "description": "AXI-compliant Google Workspace CLI — token-efficient TOON output, agent-guided auth setup, unified interface for Gmail, Calendar, Docs, Drive, Slides",
5
5
  "type": "module",
6
6
  "repository": {
@@ -53,6 +53,7 @@
53
53
  "diff": "^9.0.0",
54
54
  "google-auth-library": "^10.7.0",
55
55
  "googleapis": "^173.0.0",
56
+ "marked": "^18.0.9",
56
57
  "turndown": "^7.2.4"
57
58
  },
58
59
  "overrides": {