gws-axi 0.18.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.
- package/dist/src/commands/docs.js +22 -13
- package/dist/src/commands/docs.js.map +1 -1
- package/dist/src/commands/drive/upload.d.ts +1 -1
- package/dist/src/commands/drive/upload.js +51 -19
- package/dist/src/commands/drive/upload.js.map +1 -1
- package/dist/src/commands/drive.js +16 -7
- package/dist/src/commands/drive.js.map +1 -1
- package/dist/src/commands/gmail/compose.d.ts +24 -7
- package/dist/src/commands/gmail/compose.js +45 -14
- package/dist/src/commands/gmail/compose.js.map +1 -1
- package/dist/src/commands/gmail/compose.test.js +85 -11
- package/dist/src/commands/gmail/compose.test.js.map +1 -1
- package/dist/src/commands/gmail/draft.d.ts +1 -1
- package/dist/src/commands/gmail/draft.js +8 -2
- package/dist/src/commands/gmail/draft.js.map +1 -1
- package/dist/src/commands/sheets/tabs.d.ts +7 -0
- package/dist/src/commands/sheets/tabs.js +34 -0
- package/dist/src/commands/sheets/tabs.js.map +1 -0
- package/dist/src/commands/sheets/tabs.test.d.ts +1 -0
- package/dist/src/commands/sheets/tabs.test.js +34 -0
- package/dist/src/commands/sheets/tabs.test.js.map +1 -0
- package/dist/src/commands/sheets.js +21 -10
- package/dist/src/commands/sheets.js.map +1 -1
- package/dist/src/commands/slides.js +21 -8
- package/dist/src/commands/slides.js.map +1 -1
- package/dist/src/commands/stub-signposts.d.ts +41 -0
- package/dist/src/commands/stub-signposts.js +51 -0
- package/dist/src/commands/stub-signposts.js.map +1 -0
- package/dist/src/commands/stub-signposts.test.d.ts +1 -0
- package/dist/src/commands/stub-signposts.test.js +54 -0
- package/dist/src/commands/stub-signposts.test.js.map +1 -0
- package/package.json +2 -1
|
@@ -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
|
|
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":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../../src/commands/docs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const UPLOAD_HELP = "usage: gws-axi drive upload <source> [flags]\nargs[1]:\n <source> Content source \u2014 exactly one of: a local file path\n (default), `-` to read from stdin, or --content below\nflags[7]:\n --content <string> Inline upload body (alternative to a path or stdin)\n --parent <folder-id> Destination folder ID (default: My Drive root).\n Cannot be combined with --update.\n --name <name> Name to give the file in Drive (default: the local\n file's basename). REQUIRED for stdin / --content (no\n filename to infer). With --update, renames the target.\n --mime <type> Override the source content type (default: detected from\n the file \u2014 or, for stdin/--content, the --name \u2014\n extension; unknown \u2192 application/octet-stream)\n --convert Convert to the matching native Google format on upload\n (.docx\u2192Doc, .xlsx/.csv\u2192Sheet, .pptx\u2192Slides). With\n --update, only when the target is already that native type.\n --update <file-id> Replace an existing file's content (new revision)\n instead of creating a new file.\n --replace-all-tabs Required to --update a Doc
|
|
1
|
+
export declare const UPLOAD_HELP = "usage: gws-axi drive upload <source> [flags]\nargs[1]:\n <source> Content source \u2014 exactly one of: a local file path\n (default), `-` to read from stdin, or --content below\nflags[7]:\n --content <string> Inline upload body (alternative to a path or stdin)\n --parent <folder-id> Destination folder ID (default: My Drive root).\n Cannot be combined with --update.\n --name <name> Name to give the file in Drive (default: the local\n file's basename). REQUIRED for stdin / --content (no\n filename to infer). With --update, renames the target.\n --mime <type> Override the source content type (default: detected from\n the file \u2014 or, for stdin/--content, the --name \u2014\n extension; unknown \u2192 application/octet-stream)\n --convert Convert to the matching native Google format on upload\n (.docx\u2192Doc, .xlsx/.csv\u2192Sheet, .pptx\u2192Slides). With\n --update, only when the target is already that native type.\n --update <file-id> Replace an existing file's content (new revision)\n instead of creating a new file.\n --replace-all-tabs Required to --update a Doc with 2+ tabs or a Sheet with\n 2+ sheets: the import collapses it to a single tab /\n sheet, destroying the others.\n --account <email> REQUIRED when 2+ accounts are authenticated\nexamples:\n gws-axi drive upload ./report.pdf\n gws-axi drive upload ./report.pdf --parent 1AbC... --name \"Q2 Report.pdf\"\n gws-axi drive upload ./notes.docx --convert\n echo '# Notes' | gws-axi drive upload - --name notes.md --convert\n gws-axi drive upload --content '# Notes' --name notes.md --convert\n gws-axi drive upload ./edited.md --convert --update 1XyZ...\nnotes:\n Without --update, every upload creates a NEW Drive file \u2014 re-running makes\n another copy (Drive allows duplicate names). Use --update <id> to replace an\n existing file's content in place.\n --update replaces a Doc or Sheet WHOLESALE: it cannot target one tab of a\n multi-tab doc or one sheet of a multi-sheet spreadsheet, and the import\n leaves a single tab / sheet behind. Such targets are refused unless you\n pass --replace-all-tabs.\noutput:\n An `action: created` (or `updated`) line plus a `file{...}` object with\n id, name, mime_type, size_bytes, parents, and web_view_link.\n";
|
|
2
2
|
export interface ParsedFlags {
|
|
3
3
|
localPath: string | undefined;
|
|
4
4
|
stdin: boolean;
|
|
@@ -6,7 +6,32 @@ import { driveClient, translateGoogleError } from "../../google/client.js";
|
|
|
6
6
|
import { joinBlocks, renderHelp, renderObject } from "../../output/index.js";
|
|
7
7
|
import { detectMimeType, googleConversionTarget } from "../../util/mime-types.js";
|
|
8
8
|
import { listDocumentTabs } from "../docs/tabs.js";
|
|
9
|
+
import { listSpreadsheetSheets } from "../sheets/tabs.js";
|
|
9
10
|
const GOOGLE_DOC_MIME = "application/vnd.google-apps.document";
|
|
11
|
+
const GOOGLE_SHEET_MIME = "application/vnd.google-apps.spreadsheet";
|
|
12
|
+
/**
|
|
13
|
+
* Native types whose content is split across named sub-surfaces that a
|
|
14
|
+
* wholesale upload would flatten. Keyed by mimeType so the guard is one code
|
|
15
|
+
* path: a Doc's tabs and a Spreadsheet's sheets collapse identically, and both
|
|
16
|
+
* are gated by the same `--replace-all-tabs` opt-in (a spreadsheet's sheets
|
|
17
|
+
* *are* its tabs — the framing `sheets read` already uses).
|
|
18
|
+
*/
|
|
19
|
+
const TAB_CONTAINERS = {
|
|
20
|
+
[GOOGLE_DOC_MIME]: {
|
|
21
|
+
noun: "Document",
|
|
22
|
+
singular: "tab",
|
|
23
|
+
plural: "tabs",
|
|
24
|
+
readCommand: "docs read",
|
|
25
|
+
list: listDocumentTabs,
|
|
26
|
+
},
|
|
27
|
+
[GOOGLE_SHEET_MIME]: {
|
|
28
|
+
noun: "Spreadsheet",
|
|
29
|
+
singular: "sheet",
|
|
30
|
+
plural: "sheets",
|
|
31
|
+
readCommand: "sheets read",
|
|
32
|
+
list: listSpreadsheetSheets,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
10
35
|
export const UPLOAD_HELP = `usage: gws-axi drive upload <source> [flags]
|
|
11
36
|
args[1]:
|
|
12
37
|
<source> Content source — exactly one of: a local file path
|
|
@@ -26,8 +51,9 @@ flags[7]:
|
|
|
26
51
|
--update, only when the target is already that native type.
|
|
27
52
|
--update <file-id> Replace an existing file's content (new revision)
|
|
28
53
|
instead of creating a new file.
|
|
29
|
-
--replace-all-tabs Required to --update a Doc
|
|
30
|
-
collapses it to a single tab
|
|
54
|
+
--replace-all-tabs Required to --update a Doc with 2+ tabs or a Sheet with
|
|
55
|
+
2+ sheets: the import collapses it to a single tab /
|
|
56
|
+
sheet, destroying the others.
|
|
31
57
|
--account <email> REQUIRED when 2+ accounts are authenticated
|
|
32
58
|
examples:
|
|
33
59
|
gws-axi drive upload ./report.pdf
|
|
@@ -40,9 +66,10 @@ notes:
|
|
|
40
66
|
Without --update, every upload creates a NEW Drive file — re-running makes
|
|
41
67
|
another copy (Drive allows duplicate names). Use --update <id> to replace an
|
|
42
68
|
existing file's content in place.
|
|
43
|
-
--update replaces a Doc WHOLESALE: it cannot target one tab of a
|
|
44
|
-
doc
|
|
45
|
-
refused unless you
|
|
69
|
+
--update replaces a Doc or Sheet WHOLESALE: it cannot target one tab of a
|
|
70
|
+
multi-tab doc or one sheet of a multi-sheet spreadsheet, and the import
|
|
71
|
+
leaves a single tab / sheet behind. Such targets are refused unless you
|
|
72
|
+
pass --replace-all-tabs.
|
|
46
73
|
output:
|
|
47
74
|
An \`action: created\` (or \`updated\`) line plus a \`file{...}\` object with
|
|
48
75
|
id, name, mime_type, size_bytes, parents, and web_view_link.
|
|
@@ -202,6 +229,7 @@ export async function driveUploadCommand(account, args) {
|
|
|
202
229
|
// below — which applies with or without --convert, since Drive converts the
|
|
203
230
|
// media implicitly when the target is already native.
|
|
204
231
|
let collapsedTabs = 0;
|
|
232
|
+
let collapsedNoun = "tabs";
|
|
205
233
|
if (flags.update) {
|
|
206
234
|
let existingMime;
|
|
207
235
|
try {
|
|
@@ -242,22 +270,26 @@ export async function driveUploadCommand(account, args) {
|
|
|
242
270
|
]);
|
|
243
271
|
}
|
|
244
272
|
}
|
|
245
|
-
// A Doc target is replaced WHOLESALE: Drive's import yields
|
|
246
|
-
// document, so every tab
|
|
273
|
+
// A Doc or Spreadsheet target is replaced WHOLESALE: Drive's import yields
|
|
274
|
+
// a single-tab document / single-sheet spreadsheet, so every tab or sheet
|
|
275
|
+
// but the first is destroyed. Both are verified live. Refuse unless the
|
|
247
276
|
// caller has said that's what they meant.
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
277
|
+
const containerKind = TAB_CONTAINERS[existingMime];
|
|
278
|
+
if (containerKind) {
|
|
279
|
+
const parts = await containerKind.list(account, flags.update);
|
|
280
|
+
if (parts.length > 1 && !flags.replaceAllTabs) {
|
|
281
|
+
const titles = parts.map((p) => p.title || p.id).join(", ");
|
|
282
|
+
throw new AxiError(`${containerKind.noun} '${flags.update}' has ${parts.length} ${containerKind.plural} — an update replaces all of them with a single ${containerKind.singular}`, "MULTI_TAB_TARGET", [
|
|
283
|
+
`${containerKind.plural[0].toUpperCase()}${containerKind.plural.slice(1)} that would be lost: ${titles}`,
|
|
284
|
+
`Run \`gws-axi ${containerKind.readCommand} ${flags.update}\` to inspect them first`,
|
|
285
|
+
`Pass --replace-all-tabs to proceed and collapse it to one ${containerKind.singular}`,
|
|
286
|
+
`Per-${containerKind.singular} writes aren't supported — Drive uploads replace a ${containerKind.noun} wholesale`,
|
|
257
287
|
]);
|
|
258
288
|
}
|
|
259
|
-
if (
|
|
260
|
-
collapsedTabs =
|
|
289
|
+
if (parts.length > 1) {
|
|
290
|
+
collapsedTabs = parts.length;
|
|
291
|
+
collapsedNoun = containerKind.plural;
|
|
292
|
+
}
|
|
261
293
|
}
|
|
262
294
|
}
|
|
263
295
|
const media = {
|
|
@@ -333,7 +365,7 @@ export async function driveUploadCommand(account, args) {
|
|
|
333
365
|
const isNativeDoc = file.mimeType === GOOGLE_DOC_MIME;
|
|
334
366
|
if (collapsedTabs > 0) {
|
|
335
367
|
// Disclose the loss we were authorized to cause (surface-completeness-limits).
|
|
336
|
-
suggestions.push(`Replaced ${collapsedTabs}
|
|
368
|
+
suggestions.push(`Replaced ${collapsedTabs} ${collapsedNoun} with a single imported ${collapsedNoun.slice(0, -1)} — the prior version is in \`gws-axi drive revisions ${id}\``);
|
|
337
369
|
}
|
|
338
370
|
if (isNativeDoc) {
|
|
339
371
|
suggestions.push(`Run \`gws-axi docs read ${id}\` to read it as markdown`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../../src/commands/drive/upload.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../../src/commands/drive/upload.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
|
-
{
|
|
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
|
|
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":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
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
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
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.
|
|
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
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
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.
|
|
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(
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
|
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
|
|
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
|
|
9
|
-
|
|
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
|
|
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,
|
|
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(
|
|
36
|
-
|
|
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
|
|
54
|
-
const { header,
|
|
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(
|
|
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).
|
|
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":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
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.
|
|
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.
|
|
24
|
-
|
|
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":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,CAAC,MAAM,UAAU,GAAG
|
|
1
|
+
{"version":3,"file":"draft.js","sourceRoot":"","sources":["../../../../src/commands/gmail/draft.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TabSummary } from "../docs/tabs.js";
|
|
2
|
+
/**
|
|
3
|
+
* List a Spreadsheet's sheets (identity only). Returns `[]` when the API
|
|
4
|
+
* reports none — callers treat "unknown" as "not multi-sheet" rather than
|
|
5
|
+
* blocking a write on a missing field.
|
|
6
|
+
*/
|
|
7
|
+
export declare function listSpreadsheetSheets(account: string, spreadsheetId: string): Promise<TabSummary[]>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { sheetsClient, translateGoogleError } from "../../google/client.js";
|
|
2
|
+
/**
|
|
3
|
+
* Sheet-listing helper for `drive upload --update`. A spreadsheet's sheets are
|
|
4
|
+
* its tabs (the same framing `sheets read` uses), and replacing a Spreadsheet's
|
|
5
|
+
* content collapses it to a single sheet exactly as a Doc collapses to a single
|
|
6
|
+
* tab — so the guard needs a count before it writes.
|
|
7
|
+
*
|
|
8
|
+
* Shares `TabSummary` with the Docs helper: one shape for "named sub-surface of
|
|
9
|
+
* a container file", so `drive upload` handles both with one code path.
|
|
10
|
+
*/
|
|
11
|
+
/** Field mask for a sheet-count fetch: identity only, no cell data. */
|
|
12
|
+
const SHEET_COUNT_FIELDS = "sheets.properties(sheetId,title)";
|
|
13
|
+
/**
|
|
14
|
+
* List a Spreadsheet's sheets (identity only). Returns `[]` when the API
|
|
15
|
+
* reports none — callers treat "unknown" as "not multi-sheet" rather than
|
|
16
|
+
* blocking a write on a missing field.
|
|
17
|
+
*/
|
|
18
|
+
export async function listSpreadsheetSheets(account, spreadsheetId) {
|
|
19
|
+
const sheets = await sheetsClient(account);
|
|
20
|
+
try {
|
|
21
|
+
const res = await sheets.spreadsheets.get({
|
|
22
|
+
spreadsheetId,
|
|
23
|
+
fields: SHEET_COUNT_FIELDS,
|
|
24
|
+
});
|
|
25
|
+
return (res.data.sheets ?? []).map((sheet) => ({
|
|
26
|
+
id: sheet.properties?.sheetId != null ? String(sheet.properties.sheetId) : "",
|
|
27
|
+
title: sheet.properties?.title ?? "",
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
throw translateGoogleError(err, { account, operation: "sheets.spreadsheets.get" });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../../src/commands/sheets/tabs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAG5E;;;;;;;;GAQG;AAEH,uEAAuE;AACvE,MAAM,kBAAkB,GAAG,kCAAkC,CAAC;AAE9D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAe,EACf,aAAqB;IAErB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC;YACxC,aAAa;YACb,MAAM,EAAE,kBAAkB;SAC3B,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC7C,EAAE,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;YAC7E,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;SACrC,CAAC,CAAC,CAAC;IACN,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,oBAAoB,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,yBAAyB,EAAE,CAAC,CAAC;IACrF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
/**
|
|
3
|
+
* `listSpreadsheetSheets` itself is a thin API call; what's worth pinning is
|
|
4
|
+
* the shape it maps into, since `drive upload`'s guard counts and labels these
|
|
5
|
+
* uniformly with a Doc's tabs.
|
|
6
|
+
*/
|
|
7
|
+
function mapSheets(sheets) {
|
|
8
|
+
return sheets.map((sheet) => ({
|
|
9
|
+
id: sheet.properties?.sheetId != null ? String(sheet.properties.sheetId) : "",
|
|
10
|
+
title: sheet.properties?.title ?? "",
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
describe("spreadsheet sheet summaries", () => {
|
|
14
|
+
it("maps sheetId/title into the shared TabSummary shape", () => {
|
|
15
|
+
expect(mapSheets([
|
|
16
|
+
{ properties: { sheetId: 0, title: "Sheet1" } },
|
|
17
|
+
{ properties: { sheetId: 283081854, title: "Second" } },
|
|
18
|
+
])).toEqual([
|
|
19
|
+
{ id: "0", title: "Sheet1" },
|
|
20
|
+
{ id: "283081854", title: "Second" },
|
|
21
|
+
]);
|
|
22
|
+
});
|
|
23
|
+
it('keeps sheetId 0 as "0" rather than dropping it as falsy', () => {
|
|
24
|
+
// gid 0 is the default first sheet — a `||` fallback would blank it.
|
|
25
|
+
expect(mapSheets([{ properties: { sheetId: 0, title: "Sheet1" } }])[0].id).toBe("0");
|
|
26
|
+
});
|
|
27
|
+
it("tolerates missing properties without dropping the sheet from the count", () => {
|
|
28
|
+
expect(mapSheets([{}, { properties: {} }])).toEqual([
|
|
29
|
+
{ id: "", title: "" },
|
|
30
|
+
{ id: "", title: "" },
|
|
31
|
+
]);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=tabs.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.test.js","sourceRoot":"","sources":["../../../../src/commands/sheets/tabs.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAG9C;;;;GAIG;AACH,SAAS,SAAS,CAChB,MAAkF;IAElF,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5B,EAAE,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;QAC7E,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;KACrC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CACJ,SAAS,CAAC;YACR,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;YAC/C,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;SACxD,CAAC,CACH,CAAC,OAAO,CAAC;YACR,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;YAC5B,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE;SACrC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,qEAAqE;QACrE,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAClD,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;YACrB,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;SACtB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -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
|
|
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":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
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
|
-
{
|
|
54
|
-
|
|
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
|
|
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":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/E,wEAAwE;AACxE,qEAAqE;AACrE,uDAAuD;AACvD,MAAM,aAAa,GAAG;;;;;;;;;;;;;;CAcrB,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,OAAe,EAAE,IAAc,EAAmB,EAAE,CACjF,mBAAmB,CAAC,OAAO,EAAE,IAAI,EAAE;IACjC,QAAQ,EAAE,cAAc;IACxB,YAAY,EAAE,wBAAwB;CACvC,CAAC,CAAC;
|
|
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.
|
|
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": {
|