gws-axi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +91 -0
- package/dist/bin/gws-axi.d.ts +2 -0
- package/dist/bin/gws-axi.js +4 -0
- package/dist/bin/gws-axi.js.map +1 -0
- package/dist/src/auth/gcloud.d.ts +21 -0
- package/dist/src/auth/gcloud.js +134 -0
- package/dist/src/auth/gcloud.js.map +1 -0
- package/dist/src/auth/loopback.d.ts +50 -0
- package/dist/src/auth/loopback.js +420 -0
- package/dist/src/auth/loopback.js.map +1 -0
- package/dist/src/auth/pending.d.ts +15 -0
- package/dist/src/auth/pending.js +35 -0
- package/dist/src/auth/pending.js.map +1 -0
- package/dist/src/auth/scopes.d.ts +13 -0
- package/dist/src/auth/scopes.js +29 -0
- package/dist/src/auth/scopes.js.map +1 -0
- package/dist/src/auth/setup-html.d.ts +13 -0
- package/dist/src/auth/setup-html.js +245 -0
- package/dist/src/auth/setup-html.js.map +1 -0
- package/dist/src/auth/state.d.ts +4 -0
- package/dist/src/auth/state.js +41 -0
- package/dist/src/auth/state.js.map +1 -0
- package/dist/src/auth/steps.d.ts +30 -0
- package/dist/src/auth/steps.js +306 -0
- package/dist/src/auth/steps.js.map +1 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +72 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/commands/auth.d.ts +2 -0
- package/dist/src/commands/auth.js +453 -0
- package/dist/src/commands/auth.js.map +1 -0
- package/dist/src/commands/calendar/calendars.d.ts +2 -0
- package/dist/src/commands/calendar/calendars.js +98 -0
- package/dist/src/commands/calendar/calendars.js.map +1 -0
- package/dist/src/commands/calendar/events.d.ts +2 -0
- package/dist/src/commands/calendar/events.js +261 -0
- package/dist/src/commands/calendar/events.js.map +1 -0
- package/dist/src/commands/calendar/get.d.ts +2 -0
- package/dist/src/commands/calendar/get.js +176 -0
- package/dist/src/commands/calendar/get.js.map +1 -0
- package/dist/src/commands/calendar.d.ts +2 -0
- package/dist/src/commands/calendar.js +76 -0
- package/dist/src/commands/calendar.js.map +1 -0
- package/dist/src/commands/docs.d.ts +2 -0
- package/dist/src/commands/docs.js +19 -0
- package/dist/src/commands/docs.js.map +1 -0
- package/dist/src/commands/doctor.d.ts +2 -0
- package/dist/src/commands/doctor.js +213 -0
- package/dist/src/commands/doctor.js.map +1 -0
- package/dist/src/commands/drive.d.ts +2 -0
- package/dist/src/commands/drive.js +17 -0
- package/dist/src/commands/drive.js.map +1 -0
- package/dist/src/commands/gmail.d.ts +2 -0
- package/dist/src/commands/gmail.js +20 -0
- package/dist/src/commands/gmail.js.map +1 -0
- package/dist/src/commands/home.d.ts +1 -0
- package/dist/src/commands/home.js +42 -0
- package/dist/src/commands/home.js.map +1 -0
- package/dist/src/commands/service-stub.d.ts +8 -0
- package/dist/src/commands/service-stub.js +67 -0
- package/dist/src/commands/service-stub.js.map +1 -0
- package/dist/src/commands/slides.d.ts +2 -0
- package/dist/src/commands/slides.js +11 -0
- package/dist/src/commands/slides.js.map +1 -0
- package/dist/src/config.d.ts +46 -0
- package/dist/src/config.js +155 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/google/account.d.ts +12 -0
- package/dist/src/google/account.js +65 -0
- package/dist/src/google/account.js.map +1 -0
- package/dist/src/google/client.d.ts +29 -0
- package/dist/src/google/client.js +106 -0
- package/dist/src/google/client.js.map +1 -0
- package/dist/src/google/probe.d.ts +15 -0
- package/dist/src/google/probe.js +200 -0
- package/dist/src/google/probe.js.map +1 -0
- package/dist/src/google/tokens.d.ts +22 -0
- package/dist/src/google/tokens.js +91 -0
- package/dist/src/google/tokens.js.map +1 -0
- package/dist/src/output/index.d.ts +2 -0
- package/dist/src/output/index.js +3 -0
- package/dist/src/output/index.js.map +1 -0
- package/dist/src/output/render.d.ts +40 -0
- package/dist/src/output/render.js +65 -0
- package/dist/src/output/render.js.map +1 -0
- package/dist/src/output/schema.d.ts +32 -0
- package/dist/src/output/schema.js +69 -0
- package/dist/src/output/schema.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const TOP_HELP = "usage: gws-axi [command] [args] [flags]\ncommands[8]:\n (none)=home, auth, doctor, calendar, gmail, docs, drive, slides\nflags[2]:\n --help, -v/-V/--version\nexamples:\n gws-axi\n gws-axi auth setup\n gws-axi doctor\n gws-axi calendar events\n";
|
|
2
|
+
export declare function main(): Promise<void>;
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { runAxiCli } from "axi-sdk-js";
|
|
5
|
+
import { homeCommand } from "./commands/home.js";
|
|
6
|
+
import { authCommand, AUTH_HELP } from "./commands/auth.js";
|
|
7
|
+
import { doctorCommand, DOCTOR_HELP } from "./commands/doctor.js";
|
|
8
|
+
import { calendarCommand } from "./commands/calendar.js";
|
|
9
|
+
import { gmailCommand, GMAIL_HELP } from "./commands/gmail.js";
|
|
10
|
+
import { docsCommand, DOCS_HELP } from "./commands/docs.js";
|
|
11
|
+
import { driveCommand, DRIVE_HELP } from "./commands/drive.js";
|
|
12
|
+
import { slidesCommand, SLIDES_HELP } from "./commands/slides.js";
|
|
13
|
+
const DESCRIPTION = "Agent ergonomic CLI for Google Workspace. Unified interface for Gmail, Calendar, Docs, Drive, and Slides with agent-guided OAuth setup.";
|
|
14
|
+
const VERSION = readPackageVersion();
|
|
15
|
+
export const TOP_HELP = `usage: gws-axi [command] [args] [flags]
|
|
16
|
+
commands[8]:
|
|
17
|
+
(none)=home, auth, doctor, calendar, gmail, docs, drive, slides
|
|
18
|
+
flags[2]:
|
|
19
|
+
--help, -v/-V/--version
|
|
20
|
+
examples:
|
|
21
|
+
gws-axi
|
|
22
|
+
gws-axi auth setup
|
|
23
|
+
gws-axi doctor
|
|
24
|
+
gws-axi calendar events
|
|
25
|
+
`;
|
|
26
|
+
// Services that have real subcommand dispatchers handle --help themselves
|
|
27
|
+
// (so `<service> <sub> --help` shows subcommand-specific help). For stubs
|
|
28
|
+
// that just print help, we keep them in the SDK's auto-help map.
|
|
29
|
+
const COMMAND_HELP = {
|
|
30
|
+
auth: AUTH_HELP,
|
|
31
|
+
doctor: DOCTOR_HELP,
|
|
32
|
+
gmail: GMAIL_HELP,
|
|
33
|
+
docs: DOCS_HELP,
|
|
34
|
+
drive: DRIVE_HELP,
|
|
35
|
+
slides: SLIDES_HELP,
|
|
36
|
+
};
|
|
37
|
+
export async function main() {
|
|
38
|
+
await runAxiCli({
|
|
39
|
+
description: DESCRIPTION,
|
|
40
|
+
version: VERSION,
|
|
41
|
+
topLevelHelp: TOP_HELP,
|
|
42
|
+
...(process.env.GWS_AXI_DISABLE_HOOKS === "1" ? { hooks: false } : {}),
|
|
43
|
+
home: async () => homeCommand(),
|
|
44
|
+
commands: {
|
|
45
|
+
auth: authCommand,
|
|
46
|
+
doctor: doctorCommand,
|
|
47
|
+
calendar: calendarCommand,
|
|
48
|
+
gmail: gmailCommand,
|
|
49
|
+
docs: docsCommand,
|
|
50
|
+
drive: driveCommand,
|
|
51
|
+
slides: slidesCommand,
|
|
52
|
+
},
|
|
53
|
+
getCommandHelp: (command) => COMMAND_HELP[command],
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function readPackageVersion() {
|
|
57
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
58
|
+
for (const candidate of [
|
|
59
|
+
join(here, "..", "package.json"),
|
|
60
|
+
join(here, "..", "..", "package.json"),
|
|
61
|
+
]) {
|
|
62
|
+
if (!existsSync(candidate)) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const parsed = JSON.parse(readFileSync(candidate, "utf-8"));
|
|
66
|
+
if (typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
67
|
+
return parsed.version;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
throw new Error("Could not determine gws-axi package version");
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const AUTH_HELP = "usage: gws-axi auth <subcommand> [flags]\nsubcommands[7]:\n setup Progressive agent-guided OAuth setup (run repeatedly until complete)\n login Prepare OAuth flow (non-blocking by default); add --wait to block\n accounts List authenticated accounts\n use Set the default account: gws-axi auth use <email>\n revoke Delete an account's tokens: gws-axi auth revoke <email>\n status Terse one-line status\n reset Clear setup state, optionally from a specific step\nsetup flags[6]:\n --project <id> Use existing GCP project (step 1)\n --create-project <id> Create new GCP project (step 1, needs gcloud)\n --project-name <name> Display name when creating (step 1)\n --credentials-json <path> Path to downloaded OAuth client JSON (step 4)\n --test-user <email> Record test user email (step 6 metadata)\n --confirm-step <step> Mark a manual step done (consent_screen, test_user_added)\nlogin flags[2]:\n --account <email> Authenticate or re-auth a specific account\n --wait Block on the callback (up to 5 min). Run this\n AFTER instructing the user to click the\n Authenticate button on the setup page.\nreset flags[1]:\n --from <step> Clear from this step forward\nexamples:\n gws-axi auth setup\n gws-axi auth setup --create-project gws-axi-chris-9f3a\n gws-axi auth setup --credentials-json ~/Downloads/client_secret_xxx.json\n gws-axi auth login --account chris@personal.com # prepare only, returns fast\n gws-axi auth login --wait # blocks until user clicks\n gws-axi auth accounts\n gws-axi auth use chris@jarv.us\n gws-axi auth revoke chris@personal.com\nflow:\n For agent-driven auth: run `gws-axi auth login --account <email>`,\n relay the returned instructions to the user, THEN run\n `gws-axi auth login --wait`. Splitting lets the agent tell the user\n what to do before committing to the blocking callback wait.\n";
|
|
2
|
+
export declare function authCommand(args: string[]): Promise<string | Record<string, unknown>>;
|
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { AxiError } from "axi-sdk-js";
|
|
4
|
+
import { credentialsPath, getDefaultAccount, hasAccount, listAccounts, normalizeEmail, profilePathForAccount, readSetupState, removeAccount, setDefaultAccount, setupProgress, tokensPathForAccount, SETUP_STEP_ORDER, } from "../config.js";
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
import { markStepDone, resetFrom } from "../auth/state.js";
|
|
7
|
+
import { advanceApisEnabled, advanceConsentScreen, advanceCredentialsSaved, advanceGcpProject, advanceOauthClient, advanceTestUserAdded, } from "../auth/steps.js";
|
|
8
|
+
import { advanceTokensObtained, awaitPendingAuth, preparePendingAuth, } from "../auth/loopback.js";
|
|
9
|
+
import { setupHtmlPath, writeSetupHtml } from "../auth/setup-html.js";
|
|
10
|
+
export const AUTH_HELP = `usage: gws-axi auth <subcommand> [flags]
|
|
11
|
+
subcommands[7]:
|
|
12
|
+
setup Progressive agent-guided OAuth setup (run repeatedly until complete)
|
|
13
|
+
login Prepare OAuth flow (non-blocking by default); add --wait to block
|
|
14
|
+
accounts List authenticated accounts
|
|
15
|
+
use Set the default account: gws-axi auth use <email>
|
|
16
|
+
revoke Delete an account's tokens: gws-axi auth revoke <email>
|
|
17
|
+
status Terse one-line status
|
|
18
|
+
reset Clear setup state, optionally from a specific step
|
|
19
|
+
setup flags[6]:
|
|
20
|
+
--project <id> Use existing GCP project (step 1)
|
|
21
|
+
--create-project <id> Create new GCP project (step 1, needs gcloud)
|
|
22
|
+
--project-name <name> Display name when creating (step 1)
|
|
23
|
+
--credentials-json <path> Path to downloaded OAuth client JSON (step 4)
|
|
24
|
+
--test-user <email> Record test user email (step 6 metadata)
|
|
25
|
+
--confirm-step <step> Mark a manual step done (consent_screen, test_user_added)
|
|
26
|
+
login flags[2]:
|
|
27
|
+
--account <email> Authenticate or re-auth a specific account
|
|
28
|
+
--wait Block on the callback (up to 5 min). Run this
|
|
29
|
+
AFTER instructing the user to click the
|
|
30
|
+
Authenticate button on the setup page.
|
|
31
|
+
reset flags[1]:
|
|
32
|
+
--from <step> Clear from this step forward
|
|
33
|
+
examples:
|
|
34
|
+
gws-axi auth setup
|
|
35
|
+
gws-axi auth setup --create-project gws-axi-chris-9f3a
|
|
36
|
+
gws-axi auth setup --credentials-json ~/Downloads/client_secret_xxx.json
|
|
37
|
+
gws-axi auth login --account chris@personal.com # prepare only, returns fast
|
|
38
|
+
gws-axi auth login --wait # blocks until user clicks
|
|
39
|
+
gws-axi auth accounts
|
|
40
|
+
gws-axi auth use chris@jarv.us
|
|
41
|
+
gws-axi auth revoke chris@personal.com
|
|
42
|
+
flow:
|
|
43
|
+
For agent-driven auth: run \`gws-axi auth login --account <email>\`,
|
|
44
|
+
relay the returned instructions to the user, THEN run
|
|
45
|
+
\`gws-axi auth login --wait\`. Splitting lets the agent tell the user
|
|
46
|
+
what to do before committing to the blocking callback wait.
|
|
47
|
+
`;
|
|
48
|
+
function parseArgs(args) {
|
|
49
|
+
const flags = {};
|
|
50
|
+
const positional = [];
|
|
51
|
+
let confirmStep;
|
|
52
|
+
let resetFromKey;
|
|
53
|
+
let account;
|
|
54
|
+
let wait = false;
|
|
55
|
+
for (let i = 0; i < args.length; i++) {
|
|
56
|
+
const arg = args[i];
|
|
57
|
+
const next = args[i + 1];
|
|
58
|
+
switch (arg) {
|
|
59
|
+
case "--project":
|
|
60
|
+
flags.projectId = next;
|
|
61
|
+
i++;
|
|
62
|
+
break;
|
|
63
|
+
case "--create-project":
|
|
64
|
+
flags.createProject = next;
|
|
65
|
+
i++;
|
|
66
|
+
break;
|
|
67
|
+
case "--project-name":
|
|
68
|
+
flags.projectName = next;
|
|
69
|
+
i++;
|
|
70
|
+
break;
|
|
71
|
+
case "--credentials-json":
|
|
72
|
+
flags.credentialsJson = expandHome(next);
|
|
73
|
+
i++;
|
|
74
|
+
break;
|
|
75
|
+
case "--test-user":
|
|
76
|
+
flags.testUserEmail = next;
|
|
77
|
+
i++;
|
|
78
|
+
break;
|
|
79
|
+
case "--confirm-step":
|
|
80
|
+
confirmStep = next;
|
|
81
|
+
i++;
|
|
82
|
+
break;
|
|
83
|
+
case "--from":
|
|
84
|
+
resetFromKey = next;
|
|
85
|
+
i++;
|
|
86
|
+
break;
|
|
87
|
+
case "--account":
|
|
88
|
+
account = next;
|
|
89
|
+
i++;
|
|
90
|
+
break;
|
|
91
|
+
case "--wait":
|
|
92
|
+
wait = true;
|
|
93
|
+
break;
|
|
94
|
+
default:
|
|
95
|
+
if (!arg.startsWith("--")) {
|
|
96
|
+
positional.push(arg);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { flags, confirmStep, resetFromKey, account, wait, positional };
|
|
101
|
+
}
|
|
102
|
+
function expandHome(path) {
|
|
103
|
+
if (!path)
|
|
104
|
+
return undefined;
|
|
105
|
+
return path.startsWith("~/") ? `${homedir()}${path.slice(1)}` : path;
|
|
106
|
+
}
|
|
107
|
+
async function runSetup(args) {
|
|
108
|
+
const { flags, confirmStep } = parseArgs(args);
|
|
109
|
+
if (confirmStep) {
|
|
110
|
+
if (!SETUP_STEP_ORDER.includes(confirmStep)) {
|
|
111
|
+
throw new AxiError(`Unknown step: ${confirmStep}`, "VALIDATION_ERROR", [`Valid steps: ${SETUP_STEP_ORDER.join(", ")}`]);
|
|
112
|
+
}
|
|
113
|
+
const extra = {};
|
|
114
|
+
if (confirmStep === "test_user_added" && flags.testUserEmail) {
|
|
115
|
+
extra.email = flags.testUserEmail;
|
|
116
|
+
}
|
|
117
|
+
markStepDone(confirmStep, extra);
|
|
118
|
+
}
|
|
119
|
+
// Auto-confirm step 3 (oauth_client) when the user provides a valid Desktop
|
|
120
|
+
// OAuth JSON — the file couldn't exist unless they completed the manual
|
|
121
|
+
// Console step. Prevents the common footgun of running
|
|
122
|
+
// `gws-axi auth setup --credentials-json <path>`
|
|
123
|
+
// and having it stall on step 3 because the agent forgot to also pass
|
|
124
|
+
// `--confirm-step oauth_client`.
|
|
125
|
+
if (flags.credentialsJson && !readSetupState().steps.oauth_client.done) {
|
|
126
|
+
if (existsSync(flags.credentialsJson)) {
|
|
127
|
+
try {
|
|
128
|
+
const parsed = JSON.parse(readFileSync(flags.credentialsJson, "utf-8"));
|
|
129
|
+
if (parsed.installed?.client_id && parsed.installed?.client_secret) {
|
|
130
|
+
markStepDone("oauth_client", {
|
|
131
|
+
auto_confirmed: true,
|
|
132
|
+
via: "credentials-json",
|
|
133
|
+
client_id: parsed.installed.client_id,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// fall through; advanceCredentialsSaved will surface the JSON error
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const advanced = [];
|
|
143
|
+
let nextOutcome = null;
|
|
144
|
+
for (let i = 0; i < SETUP_STEP_ORDER.length; i++) {
|
|
145
|
+
const state = readSetupState();
|
|
146
|
+
const { nextStep } = setupProgress(state);
|
|
147
|
+
if (!nextStep)
|
|
148
|
+
break;
|
|
149
|
+
const handler = handlerFor(nextStep);
|
|
150
|
+
const outcome = await handler(flags, state);
|
|
151
|
+
if (outcome.advanced) {
|
|
152
|
+
advanced.push({
|
|
153
|
+
step: outcome.step,
|
|
154
|
+
detail: summarizeDetail(outcome.detail),
|
|
155
|
+
});
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
nextOutcome = outcome;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
writeSetupHtml();
|
|
162
|
+
const state = readSetupState();
|
|
163
|
+
const { done, total } = setupProgress(state);
|
|
164
|
+
const output = {
|
|
165
|
+
progress: `${done} of ${total} steps complete`,
|
|
166
|
+
};
|
|
167
|
+
if (advanced.length > 0) {
|
|
168
|
+
output.advanced = advanced;
|
|
169
|
+
}
|
|
170
|
+
if (!nextOutcome) {
|
|
171
|
+
const accounts = listAccounts();
|
|
172
|
+
output.status = "complete";
|
|
173
|
+
output.accounts = accounts;
|
|
174
|
+
output.help = [
|
|
175
|
+
"All setup steps complete",
|
|
176
|
+
"Run `gws-axi doctor` to verify runtime health",
|
|
177
|
+
"Run `gws-axi auth login --account <email>` to add another account",
|
|
178
|
+
];
|
|
179
|
+
return output;
|
|
180
|
+
}
|
|
181
|
+
// Intentionally do NOT include deep_links in CLI output — Console URLs
|
|
182
|
+
// live only on setup.html. This prevents agents from opening them with
|
|
183
|
+
// `open <url>`, which lands in whatever browser the OS picks (often the
|
|
184
|
+
// wrong session / profile / an agent's debug browser). Instructions
|
|
185
|
+
// reference setup-page buttons by label; the user clicks them in the
|
|
186
|
+
// browser they chose when they opened setup.html.
|
|
187
|
+
output.next_step = {
|
|
188
|
+
step: nextOutcome.step,
|
|
189
|
+
title: nextOutcome.title,
|
|
190
|
+
...(nextOutcome.detail ? { detail: nextOutcome.detail } : {}),
|
|
191
|
+
...(nextOutcome.instructions ? { instructions: nextOutcome.instructions } : {}),
|
|
192
|
+
};
|
|
193
|
+
const htmlPath = collapseHome(setupHtmlPath());
|
|
194
|
+
const isFreshSetup = advanced.length === 0 && done === 0;
|
|
195
|
+
output.setup_html = {
|
|
196
|
+
path: htmlPath,
|
|
197
|
+
note: "Open this page ONCE in the user's primary browser (the one they use for Google). Keep the tab open — it auto-refreshes as setup progresses. All Console actions happen via buttons on this page.",
|
|
198
|
+
};
|
|
199
|
+
if (nextOutcome.error) {
|
|
200
|
+
throw new AxiError(nextOutcome.error, nextOutcome.code ?? "SETUP_ERROR", nextOutcome.instructions ?? []);
|
|
201
|
+
}
|
|
202
|
+
const help = [];
|
|
203
|
+
if (isFreshSetup) {
|
|
204
|
+
help.push(`FIRST-TIME: ask the user to open \`${htmlPath}\` in their primary browser (where they're signed into Google) and keep it open. Don't invoke \`open\` yourself — browser session may differ.`);
|
|
205
|
+
}
|
|
206
|
+
else if (stepHasConsoleButtons(nextOutcome.step)) {
|
|
207
|
+
help.push(`Have the user click the button(s) for step '${nextOutcome.step}' on their gws-axi setup page (should already be open in their primary browser)`);
|
|
208
|
+
}
|
|
209
|
+
if (nextOutcome.step === "tokens_obtained") {
|
|
210
|
+
// Step 7 is special: the prepare has already happened (advanceTokensObtained
|
|
211
|
+
// wrote pending state + setup.html). The agent relays the instructions
|
|
212
|
+
// and then must invoke `auth login --wait` to block on the callback in a
|
|
213
|
+
// SEPARATE bash turn — so the user sees the instructions before the wait.
|
|
214
|
+
help.push("Relay the instructions above to the user, then run `gws-axi auth login --wait` in a NEW bash turn to block on the callback (up to 5 minutes).");
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
help.push(`Complete step ${nextOutcome.step} and re-run \`gws-axi auth setup\``);
|
|
218
|
+
}
|
|
219
|
+
output.help = help;
|
|
220
|
+
return output;
|
|
221
|
+
}
|
|
222
|
+
function stepHasConsoleButtons(step) {
|
|
223
|
+
// Steps where the user needs to click something on setup.html. Anything
|
|
224
|
+
// automatable (gcp_project/apis_enabled with gcloud, tokens_obtained via
|
|
225
|
+
// loopback) or pure-CLI (credentials_saved) doesn't need the setup page.
|
|
226
|
+
return (step === "oauth_client" ||
|
|
227
|
+
step === "consent_screen" ||
|
|
228
|
+
step === "test_user_added");
|
|
229
|
+
}
|
|
230
|
+
function handlerFor(key) {
|
|
231
|
+
switch (key) {
|
|
232
|
+
case "gcp_project":
|
|
233
|
+
return (flags) => advanceGcpProject(flags);
|
|
234
|
+
case "apis_enabled":
|
|
235
|
+
return (flags, state) => advanceApisEnabled(flags, state);
|
|
236
|
+
case "oauth_client":
|
|
237
|
+
return (flags, state) => advanceOauthClient(flags, state);
|
|
238
|
+
case "credentials_saved":
|
|
239
|
+
return (flags) => advanceCredentialsSaved(flags);
|
|
240
|
+
case "consent_screen":
|
|
241
|
+
return (flags, state) => advanceConsentScreen(flags, state);
|
|
242
|
+
case "test_user_added":
|
|
243
|
+
return (flags, state) => advanceTestUserAdded(flags, state);
|
|
244
|
+
case "tokens_obtained":
|
|
245
|
+
return () => advanceTokensObtained();
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function summarizeDetail(detail) {
|
|
249
|
+
if (!detail)
|
|
250
|
+
return "";
|
|
251
|
+
if (typeof detail.project_id === "string")
|
|
252
|
+
return detail.project_id;
|
|
253
|
+
if (typeof detail.path === "string")
|
|
254
|
+
return collapseHome(detail.path);
|
|
255
|
+
if (Array.isArray(detail.apis))
|
|
256
|
+
return `${detail.apis.length} APIs enabled`;
|
|
257
|
+
if (typeof detail.account === "string")
|
|
258
|
+
return detail.account;
|
|
259
|
+
if (typeof detail.scopes_granted === "number") {
|
|
260
|
+
return `${detail.scopes_granted} scopes granted`;
|
|
261
|
+
}
|
|
262
|
+
return "";
|
|
263
|
+
}
|
|
264
|
+
function collapseHome(path) {
|
|
265
|
+
const home = homedir();
|
|
266
|
+
return path.startsWith(home) ? `~${path.slice(home.length)}` : path;
|
|
267
|
+
}
|
|
268
|
+
async function runLogin(args) {
|
|
269
|
+
const { account, wait } = parseArgs(args);
|
|
270
|
+
if (wait) {
|
|
271
|
+
// Phase 2: block on callback.
|
|
272
|
+
const outcome = await awaitPendingAuth();
|
|
273
|
+
if (outcome.advanced) {
|
|
274
|
+
return {
|
|
275
|
+
status: "ok",
|
|
276
|
+
...(outcome.detail ?? {}),
|
|
277
|
+
accounts: listAccounts(),
|
|
278
|
+
default_account: getDefaultAccount(),
|
|
279
|
+
help: ["Run `gws-axi doctor` to verify runtime health"],
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
throw new AxiError(outcome.error ?? "OAuth flow failed", outcome.code ?? "OAUTH_FAILED", outcome.instructions ?? []);
|
|
283
|
+
}
|
|
284
|
+
// Phase 1: prepare, return fast with instructions.
|
|
285
|
+
if (!existsSync(credentialsPath())) {
|
|
286
|
+
throw new AxiError("OAuth credentials not saved — complete setup steps 1-4 first", "PRECONDITION_FAILED", ["Run `gws-axi auth setup` to continue progressive setup"]);
|
|
287
|
+
}
|
|
288
|
+
const prepared = await preparePendingAuth({
|
|
289
|
+
expectedAccount: account ? normalizeEmail(account) : undefined,
|
|
290
|
+
});
|
|
291
|
+
if ("error" in prepared) {
|
|
292
|
+
throw new AxiError(prepared.error, prepared.code, [
|
|
293
|
+
"Run `gws-axi auth setup` to ensure credentials are saved",
|
|
294
|
+
]);
|
|
295
|
+
}
|
|
296
|
+
const htmlPath = collapseHome(prepared.htmlPath);
|
|
297
|
+
const normalizedAccount = account ? normalizeEmail(account) : undefined;
|
|
298
|
+
return {
|
|
299
|
+
status: "prepared",
|
|
300
|
+
...(normalizedAccount ? { account: normalizedAccount } : {}),
|
|
301
|
+
setup_html: htmlPath,
|
|
302
|
+
expires_at: prepared.pending.expires_at,
|
|
303
|
+
instructions: [
|
|
304
|
+
`The gws-axi setup page (${htmlPath}) must be open in the browser PROFILE/SESSION where the user is signed into ${normalizedAccount ? `\`${normalizedAccount}\`` : "the target Google account"}. This may be a DIFFERENT browser profile than the one used for initial setup (e.g., personal Chrome profile vs work). If the setup page is open in the wrong profile, tell the user to open ${htmlPath} in the correct profile.`,
|
|
305
|
+
`In that setup page tab, the user waits for the yellow "Authenticate with Google" button to appear (up to 10s auto-refresh), clicks it, signs in${normalizedAccount ? ` as \`${normalizedAccount}\`` : ""}, approves the requested scopes, and sees the success page.`,
|
|
306
|
+
"After RELAYING these instructions to the user, IMMEDIATELY run `gws-axi auth login --wait` in a new bash turn — do NOT wait for the user to confirm they're ready. The wait command binds the callback server; it must be listening BEFORE the user clicks. If you delay, the user's click hits an unreachable localhost URL. The wait is harmless: it just listens for up to 5 minutes while the user takes their time.",
|
|
307
|
+
],
|
|
308
|
+
help: [
|
|
309
|
+
"Relay instructions, then IMMEDIATELY run `gws-axi auth login --wait` in the next bash turn — no user-confirmation step between them.",
|
|
310
|
+
"The pending flow expires in 10 minutes — if you don't --wait by then, re-run this prepare step",
|
|
311
|
+
],
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
function runAccounts() {
|
|
315
|
+
const emails = listAccounts();
|
|
316
|
+
if (emails.length === 0) {
|
|
317
|
+
return {
|
|
318
|
+
accounts: [],
|
|
319
|
+
help: ["Run `gws-axi auth setup` (or `gws-axi auth login`) to add an account"],
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
const defaultAccount = getDefaultAccount();
|
|
323
|
+
const summaries = emails.map((email) => {
|
|
324
|
+
const summary = { email, default: email === defaultAccount };
|
|
325
|
+
try {
|
|
326
|
+
const profile = JSON.parse(readFileSync(profilePathForAccount(email), "utf-8"));
|
|
327
|
+
summary.name = profile.name;
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
// no profile yet
|
|
331
|
+
}
|
|
332
|
+
try {
|
|
333
|
+
const tokens = JSON.parse(readFileSync(tokensPathForAccount(email), "utf-8"));
|
|
334
|
+
summary.obtained_at = tokens.obtained_at;
|
|
335
|
+
summary.scopes = tokens.scope ? tokens.scope.split(" ").filter(Boolean).length : 0;
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
// no tokens file (shouldn't happen given listAccounts filters on this)
|
|
339
|
+
}
|
|
340
|
+
return summary;
|
|
341
|
+
});
|
|
342
|
+
return {
|
|
343
|
+
count: emails.length,
|
|
344
|
+
accounts: summaries,
|
|
345
|
+
default: defaultAccount,
|
|
346
|
+
help: [
|
|
347
|
+
"Run `gws-axi auth use <email>` to change default",
|
|
348
|
+
"Run `gws-axi auth login --account <email>` to add another",
|
|
349
|
+
"Run `gws-axi auth revoke <email>` to remove one",
|
|
350
|
+
],
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
function runUse(args) {
|
|
354
|
+
const { positional } = parseArgs(args);
|
|
355
|
+
const email = positional[0];
|
|
356
|
+
if (!email) {
|
|
357
|
+
throw new AxiError("Usage: gws-axi auth use <email>", "VALIDATION_ERROR", ["Run `gws-axi auth accounts` to see authenticated accounts"]);
|
|
358
|
+
}
|
|
359
|
+
if (!hasAccount(email)) {
|
|
360
|
+
throw new AxiError(`Account ${email} is not authenticated`, "ACCOUNT_NOT_FOUND", [
|
|
361
|
+
`Authenticated accounts: ${listAccounts().join(", ") || "(none)"}`,
|
|
362
|
+
`Run \`gws-axi auth login --account ${email}\` to add it`,
|
|
363
|
+
]);
|
|
364
|
+
}
|
|
365
|
+
setDefaultAccount(email);
|
|
366
|
+
return {
|
|
367
|
+
status: "ok",
|
|
368
|
+
default: normalizeEmail(email),
|
|
369
|
+
help: [`Commands without --account will now use ${normalizeEmail(email)}`],
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
function runRevoke(args) {
|
|
373
|
+
const { positional } = parseArgs(args);
|
|
374
|
+
const email = positional[0];
|
|
375
|
+
if (!email) {
|
|
376
|
+
throw new AxiError("Usage: gws-axi auth revoke <email>", "VALIDATION_ERROR", ["Run `gws-axi auth accounts` to see authenticated accounts"]);
|
|
377
|
+
}
|
|
378
|
+
if (!hasAccount(email)) {
|
|
379
|
+
return {
|
|
380
|
+
status: "no-op",
|
|
381
|
+
message: `${normalizeEmail(email)} was not authenticated`,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
removeAccount(email);
|
|
385
|
+
const remaining = listAccounts();
|
|
386
|
+
return {
|
|
387
|
+
status: "revoked",
|
|
388
|
+
removed: normalizeEmail(email),
|
|
389
|
+
remaining_count: remaining.length,
|
|
390
|
+
new_default: getDefaultAccount(),
|
|
391
|
+
help: remaining.length === 0
|
|
392
|
+
? ["Run `gws-axi auth login` to add an account"]
|
|
393
|
+
: [`${remaining.length} account(s) remain authenticated`],
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
function runStatus() {
|
|
397
|
+
const state = readSetupState();
|
|
398
|
+
const { done, total, nextStep } = setupProgress(state);
|
|
399
|
+
const accounts = listAccounts();
|
|
400
|
+
if (done < total) {
|
|
401
|
+
return {
|
|
402
|
+
status: `incomplete (${done}/${total})`,
|
|
403
|
+
next_step: nextStep,
|
|
404
|
+
accounts_count: accounts.length,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
if (accounts.length === 0) {
|
|
408
|
+
return { status: "broken: setup complete but no accounts authenticated" };
|
|
409
|
+
}
|
|
410
|
+
return {
|
|
411
|
+
status: "ok",
|
|
412
|
+
accounts_count: accounts.length,
|
|
413
|
+
default: getDefaultAccount(),
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
function runReset(args) {
|
|
417
|
+
const { resetFromKey } = parseArgs(args);
|
|
418
|
+
if (resetFromKey && !SETUP_STEP_ORDER.includes(resetFromKey)) {
|
|
419
|
+
throw new AxiError(`Unknown step: ${resetFromKey}`, "VALIDATION_ERROR", [`Valid steps: ${SETUP_STEP_ORDER.join(", ")}`]);
|
|
420
|
+
}
|
|
421
|
+
const state = resetFrom(resetFromKey ?? "gcp_project");
|
|
422
|
+
const { done, total } = setupProgress(state);
|
|
423
|
+
return {
|
|
424
|
+
status: "reset",
|
|
425
|
+
progress: `${done} of ${total} steps remain complete`,
|
|
426
|
+
help: ["Run `gws-axi auth setup` to begin again"],
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
export async function authCommand(args) {
|
|
430
|
+
const sub = args[0];
|
|
431
|
+
if (!sub)
|
|
432
|
+
return AUTH_HELP;
|
|
433
|
+
const rest = args.slice(1);
|
|
434
|
+
switch (sub) {
|
|
435
|
+
case "setup":
|
|
436
|
+
return runSetup(rest);
|
|
437
|
+
case "login":
|
|
438
|
+
return runLogin(rest);
|
|
439
|
+
case "accounts":
|
|
440
|
+
return runAccounts();
|
|
441
|
+
case "use":
|
|
442
|
+
return runUse(rest);
|
|
443
|
+
case "revoke":
|
|
444
|
+
return runRevoke(rest);
|
|
445
|
+
case "status":
|
|
446
|
+
return runStatus();
|
|
447
|
+
case "reset":
|
|
448
|
+
return runReset(rest);
|
|
449
|
+
default:
|
|
450
|
+
throw new AxiError(`Unknown auth subcommand: ${sub}`, "VALIDATION_ERROR", ["Run `gws-axi auth --help` to see available subcommands"]);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const CALENDARS_HELP = "usage: gws-axi calendar calendars [flags]\nflags[2]:\n --account <email> Account override when 2+ are configured\n --fields <list> Extra columns: timezone, description, colorId\nexamples:\n gws-axi calendar calendars\n gws-axi calendar calendars --account chris@personal.com\n gws-axi calendar calendars --fields timezone\ndefault columns:\n id Calendar ID (use with `calendar events --calendar <id>`)\n summary Human-readable name\n access reader | writer | owner | free_busy\n primary \u2713 for the account's primary calendar\nnotes:\n Lists ALL calendars this account can access \u2014 your own plus ones\n you're subscribed to. Shared / team calendars appear here too.\n";
|
|
2
|
+
export declare function calendarCalendarsCommand(account: string, args: string[]): Promise<string>;
|