hikoutei 0.5.17 → 0.5.18
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/README.md +12 -9
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +14 -7
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/confirm.d.ts +31 -0
- package/dist/cli/confirm.d.ts.map +1 -1
- package/dist/cli/confirm.js +58 -5
- package/dist/cli/confirm.js.map +1 -1
- package/dist/cli/errors.d.ts +2 -0
- package/dist/cli/errors.d.ts.map +1 -1
- package/dist/cli/errors.js +2 -0
- package/dist/cli/errors.js.map +1 -1
- package/dist/cli/gcloudRunner.d.ts +62 -0
- package/dist/cli/gcloudRunner.d.ts.map +1 -1
- package/dist/cli/gcloudRunner.js +56 -1
- package/dist/cli/gcloudRunner.js.map +1 -1
- package/dist/cli/setup.d.ts +106 -8
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +255 -73
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/setupFlow.d.ts.map +1 -1
- package/dist/cli/setupFlow.js +18 -3
- package/dist/cli/setupFlow.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -125,15 +125,18 @@ an operation for each write. The sync runtime uses one Google Sheets API
|
|
|
125
125
|
provider (the internal `googleSheetsApi` bootstrap option) with a service
|
|
126
126
|
account — no Apps Script deployment.
|
|
127
127
|
|
|
128
|
-
**Fastest path:** install the gcloud CLI
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
128
|
+
**Fastest path:** install the gcloud CLI, then run `npx hikoutei setup` from your
|
|
129
|
+
project directory. On an interactive terminal it offers (press Enter) to
|
|
130
|
+
start `gcloud auth login --enable-gdrive-access --force` for you when the
|
|
131
|
+
active account is missing or lacks Drive access — you only complete the
|
|
132
|
+
browser approval yourself. (In `--yes`, CI, or non-TTY sessions, run that
|
|
133
|
+
login command yourself first.) Setup then creates the project, service
|
|
134
|
+
account, and key, creates a spreadsheet owned by your account, shares it
|
|
135
|
+
with the service account as an Editor, verifies service-account access, and
|
|
136
|
+
writes `GOOGLE_APPLICATION_CREDENTIALS` plus `HIKOUTEI_SYNC_SPREADSHEET_URL`
|
|
137
|
+
into your `.env`. The human access token is used in memory only and never
|
|
138
|
+
stored. Automatic setup runs on macOS and Linux; on Windows a non-dry-run
|
|
139
|
+
is refused before any mutation and manual setup is available. Interrupted runs resume from a local checkpoint
|
|
137
140
|
(`.hikoutei-setup-state.json`); a spreadsheet create whose outcome is
|
|
138
141
|
unknown is reconciled by its creation marker on the next run and setup
|
|
139
142
|
never creates a second spreadsheet (inspect Drive and rerun if setup
|
package/dist/cli/args.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAmC,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEjF,kEAAkE;AAClE,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,iFAAiF;AACjF,eAAO,MAAM,wBAAwB,SAAS,CAAC;AAE/C,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,gDAAgD;AAChD,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC;AAanE,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAmC,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEjF,kEAAkE;AAClE,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,iFAAiF;AACjF,eAAO,MAAM,wBAAwB,SAAS,CAAC;AAE/C,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,gDAAgD;AAChD,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC;AAanE,eAAO,MAAM,eAAe,QAyEhB,CAAC;AAUb;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,oBAAoB,CAyG5E"}
|
package/dist/cli/args.js
CHANGED
|
@@ -25,10 +25,14 @@ export const SETUP_HELP_TEXT = [
|
|
|
25
25
|
"hikoutei setup - bootstrap a Google Cloud project, service account, key, and",
|
|
26
26
|
"a human-owned spreadsheet for Hikoutei sync, then write a ready-to-use .env file.",
|
|
27
27
|
"",
|
|
28
|
-
"Prerequisites: the gcloud CLI is installed
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
28
|
+
"Prerequisites: the gcloud CLI is installed. On an interactive terminal,",
|
|
29
|
+
"`npx hikoutei setup` offers to start `gcloud auth login",
|
|
30
|
+
"--enable-gdrive-access --force` for you (press Enter) when the active",
|
|
31
|
+
"account is missing or lacks Drive access; you complete the browser",
|
|
32
|
+
"approval. In --yes / CI / non-TTY sessions, run that login command",
|
|
33
|
+
"yourself first. Setup creates the spreadsheet as the logged-in user",
|
|
34
|
+
"and shares it with the service account as a writer, so the active",
|
|
35
|
+
"account must grant Drive access.",
|
|
32
36
|
"",
|
|
33
37
|
"Usage:",
|
|
34
38
|
" hikoutei setup [options]",
|
|
@@ -43,13 +47,16 @@ export const SETUP_HELP_TEXT = [
|
|
|
43
47
|
" --output <path> .env file to write or update (default: .env in",
|
|
44
48
|
" the current directory).",
|
|
45
49
|
" --yes Skip interactive confirmation (non-interactive",
|
|
46
|
-
" mode).",
|
|
50
|
+
" mode). Also disables the Enter-to-login",
|
|
51
|
+
" handoff: log in with `gcloud auth login",
|
|
52
|
+
" --enable-gdrive-access --force` first.",
|
|
47
53
|
" --dry-run Print the exact command sequence and",
|
|
48
54
|
" simulated outcomes without executing anything",
|
|
49
55
|
" (read-only local path-safety checks only;",
|
|
50
56
|
" no subprocess, network, cloud, or file",
|
|
51
|
-
" mutations;
|
|
52
|
-
"
|
|
57
|
+
" mutations; never runs the interactive",
|
|
58
|
+
" gcloud login handoff; the gcloud key create",
|
|
59
|
+
" shows the private staging placeholder",
|
|
53
60
|
" <private-key-staging-dir>/key.json — never the",
|
|
54
61
|
" final key path).",
|
|
55
62
|
" -h, --help Show this help and exit.",
|
package/dist/cli/args.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAqB,MAAM,aAAa,CAAC;AAEjF,kEAAkE;AAClE,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAC;AAE7C,iFAAiF;AACjF,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAwB/C,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,WAAW;IACpB,OAAO,EAAE,WAAW;IACpB,iBAAiB,EAAE,qBAAqB;IACxC,MAAM,EAAE,UAAU;IAClB,GAAG,EAAE,OAAO;IACZ,OAAO,EAAE,WAAW;CACZ,CAAC;AAEX,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,8EAA8E;IAC9E,mFAAmF;IACnF,EAAE;IACF,
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/confirm.d.ts
CHANGED
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
* y/N confirmation before running unless `--yes` (non-interactive mode) or
|
|
6
6
|
* `--dry-run` is given. The input and output sinks are injected so tests can
|
|
7
7
|
* exercise the prompt without a TTY.
|
|
8
|
+
*
|
|
9
|
+
* The separate {@link promptLoginHandoff} prompt offers an Enter-to-start
|
|
10
|
+
* handoff into `gcloud auth login`: when the preflight detects a missing or
|
|
11
|
+
* Drive-less account on a real terminal, Enter launches the browser login in
|
|
12
|
+
* the inherited terminal, while any other input or end-of-input cancels and
|
|
13
|
+
* leaves setup for a later run.
|
|
8
14
|
*/
|
|
9
15
|
export interface ConfirmSetupOptions {
|
|
10
16
|
readonly yes: boolean;
|
|
@@ -20,6 +26,31 @@ export type ConfirmSetupResult = {
|
|
|
20
26
|
} | {
|
|
21
27
|
readonly status: "declined";
|
|
22
28
|
};
|
|
29
|
+
/** Input and output sinks for the Enter-to-login handoff prompt. */
|
|
30
|
+
export interface PromptLoginHandoffOptions {
|
|
31
|
+
/** Line/chunk source; `process.stdin` in the real CLI. */
|
|
32
|
+
readonly input: AsyncIterable<string>;
|
|
33
|
+
readonly output: {
|
|
34
|
+
readonly write: (text: string) => void;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** Result of the Enter-to-login handoff prompt. */
|
|
38
|
+
export type PromptLoginHandoffResult = {
|
|
39
|
+
readonly status: "proceed";
|
|
40
|
+
} | {
|
|
41
|
+
readonly status: "cancel";
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Prompts once for the Enter-to-login handoff.
|
|
45
|
+
*
|
|
46
|
+
* Reads a single input chunk: an empty line (Enter) or whitespace-only input
|
|
47
|
+
* proceeds with the gcloud login; any other input or end-of-input cancels.
|
|
48
|
+
* Buffers are decoded as UTF-8 so the function works with both string and
|
|
49
|
+
* Buffer stdin streams. This prompt is intentionally separate from the
|
|
50
|
+
* resource-creation {@link confirmSetup} prompt and never runs for `--yes`,
|
|
51
|
+
* `--dry-run`, or non-TTY sessions.
|
|
52
|
+
*/
|
|
53
|
+
export declare function promptLoginHandoff(options: PromptLoginHandoffOptions): Promise<PromptLoginHandoffResult>;
|
|
23
54
|
/**
|
|
24
55
|
* Asks for confirmation unless `--yes` or `--dry-run` was given.
|
|
25
56
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirm.d.ts","sourceRoot":"","sources":["../../src/cli/confirm.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"confirm.d.ts","sourceRoot":"","sources":["../../src/cli/confirm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CAC7D;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC;AAEpG,oEAAoE;AACpE,MAAM,WAAW,yBAAyB;IACxC,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CAC7D;AAED,mDAAmD;AACnD,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC;AAkClC;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,wBAAwB,CAAC,CAOnC;AAKD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAW5F"}
|
package/dist/cli/confirm.js
CHANGED
|
@@ -5,7 +5,60 @@
|
|
|
5
5
|
* y/N confirmation before running unless `--yes` (non-interactive mode) or
|
|
6
6
|
* `--dry-run` is given. The input and output sinks are injected so tests can
|
|
7
7
|
* exercise the prompt without a TTY.
|
|
8
|
+
*
|
|
9
|
+
* The separate {@link promptLoginHandoff} prompt offers an Enter-to-start
|
|
10
|
+
* handoff into `gcloud auth login`: when the preflight detects a missing or
|
|
11
|
+
* Drive-less account on a real terminal, Enter launches the browser login in
|
|
12
|
+
* the inherited terminal, while any other input or end-of-input cancels and
|
|
13
|
+
* leaves setup for a later run.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Reads exactly one input chunk from a shared async iterable WITHOUT closing
|
|
17
|
+
* or aborting it.
|
|
18
|
+
*
|
|
19
|
+
* A `for await (... of input) { ... return; }` loop calls the iterator's
|
|
20
|
+
* `return()` on early completion. For a Node Readable such as `process.stdin`,
|
|
21
|
+
* `return()` destroys the stream, so the very next read raises `ABORT_ERR`.
|
|
22
|
+
* Setup asks two sequential prompts (the y/N confirmation, then the
|
|
23
|
+
* Enter-to-login handoff) over the SAME shared stdin, so each prompt must
|
|
24
|
+
* consume exactly one chunk and leave the stream open for the next one.
|
|
25
|
+
*
|
|
26
|
+
* This helper acquires the shared iterator — `process.stdin` is its own
|
|
27
|
+
* self-iterator, so re-acquiring it on the next prompt continues right after
|
|
28
|
+
* the last read — and calls `next()` once. It deliberately never calls
|
|
29
|
+
* `return()`, which is the one difference that keeps a later prompt working.
|
|
30
|
+
*/
|
|
31
|
+
async function readOneInputChunk(input) {
|
|
32
|
+
const iterator = input[Symbol.asyncIterator]();
|
|
33
|
+
const result = await iterator.next();
|
|
34
|
+
if (result.done === true || result.value === undefined) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const value = result.value;
|
|
38
|
+
return typeof value === "string" ? value : String(value);
|
|
39
|
+
}
|
|
40
|
+
const LOGIN_HANDOFF_PROMPT = "The active gcloud account is missing or lacks Drive access. Press Enter to " +
|
|
41
|
+
"start `gcloud auth login --enable-gdrive-access --force` in this terminal (a " +
|
|
42
|
+
"browser window opens for you to approve); press any other key or Ctrl-D to " +
|
|
43
|
+
"cancel and finish setup later. ";
|
|
44
|
+
/**
|
|
45
|
+
* Prompts once for the Enter-to-login handoff.
|
|
46
|
+
*
|
|
47
|
+
* Reads a single input chunk: an empty line (Enter) or whitespace-only input
|
|
48
|
+
* proceeds with the gcloud login; any other input or end-of-input cancels.
|
|
49
|
+
* Buffers are decoded as UTF-8 so the function works with both string and
|
|
50
|
+
* Buffer stdin streams. This prompt is intentionally separate from the
|
|
51
|
+
* resource-creation {@link confirmSetup} prompt and never runs for `--yes`,
|
|
52
|
+
* `--dry-run`, or non-TTY sessions.
|
|
8
53
|
*/
|
|
54
|
+
export async function promptLoginHandoff(options) {
|
|
55
|
+
options.output.write(LOGIN_HANDOFF_PROMPT);
|
|
56
|
+
const chunk = await readOneInputChunk(options.input);
|
|
57
|
+
if (chunk === null) {
|
|
58
|
+
return { status: "cancel" };
|
|
59
|
+
}
|
|
60
|
+
return chunk.trim() === "" ? { status: "proceed" } : { status: "cancel" };
|
|
61
|
+
}
|
|
9
62
|
const CONFIRMATION_PROMPT = "This will create Google Cloud resources (project, service account, key, spreadsheet). Continue? [y/N] ";
|
|
10
63
|
/**
|
|
11
64
|
* Asks for confirmation unless `--yes` or `--dry-run` was given.
|
|
@@ -19,11 +72,11 @@ export async function confirmSetup(options) {
|
|
|
19
72
|
return { status: "confirmed" };
|
|
20
73
|
}
|
|
21
74
|
options.output.write(CONFIRMATION_PROMPT);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return answer === "y" || answer === "yes" ? { status: "confirmed" } : { status: "declined" };
|
|
75
|
+
const chunk = await readOneInputChunk(options.input);
|
|
76
|
+
if (chunk === null) {
|
|
77
|
+
return { status: "declined" };
|
|
26
78
|
}
|
|
27
|
-
|
|
79
|
+
const answer = chunk.trim().toLowerCase();
|
|
80
|
+
return answer === "y" || answer === "yes" ? { status: "confirmed" } : { status: "declined" };
|
|
28
81
|
}
|
|
29
82
|
//# sourceMappingURL=confirm.js.map
|
package/dist/cli/confirm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirm.js","sourceRoot":"","sources":["../../src/cli/confirm.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"confirm.js","sourceRoot":"","sources":["../../src/cli/confirm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAwBH;;;;;;;;;;;;;;;GAeG;AACH,KAAK,UAAU,iBAAiB,CAAC,KAA4B;IAC3D,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;IAC/C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACrC,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,oBAAoB,GACxB,6EAA6E;IAC7E,+EAA+E;IAC/E,6EAA6E;IAC7E,iCAAiC,CAAC;AAEpC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAkC;IAElC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC5E,CAAC;AAED,MAAM,mBAAmB,GACvB,wGAAwG,CAAC;AAE3G;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACjC,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAChC,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,OAAO,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAC/F,CAAC"}
|
package/dist/cli/errors.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export declare const SETUP_ERROR_CODES: {
|
|
|
14
14
|
readonly GCLOUD_NOT_LOGGED_IN: "gcloud_not_logged_in";
|
|
15
15
|
/** The active gcloud account lacks the Drive scope needed to create and own the spreadsheet. */
|
|
16
16
|
readonly GCLOUD_DRIVE_ACCESS_REQUIRED: "gcloud_drive_access_required";
|
|
17
|
+
/** The interactive `gcloud auth login --enable-gdrive-access --force` handoff did not complete successfully. */
|
|
18
|
+
readonly GCLOUD_LOGIN_FAILED: "gcloud_login_failed";
|
|
17
19
|
/** The user access token could not be retrieved or validated through tokeninfo. */
|
|
18
20
|
readonly USER_TOKEN_FAILED: "user_token_failed";
|
|
19
21
|
/** `gcloud projects create` failed for a reason other than "already exists". */
|
package/dist/cli/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,iBAAiB;IAC5B,+DAA+D;;IAE/D,6DAA6D;;IAE7D,gGAAgG;;IAEhG,mFAAmF;;IAEnF,gFAAgF;;IAEhF,iGAAiG;;IAEjG,0CAA0C;;IAE1C,6DAA6D;;IAE7D,kDAAkD;;IAElD,mEAAmE;;IAEnE,yXAAyX;;IAEzX,mGAAmG;;IAEnG,iGAAiG;;IAEjG,0HAA0H;;IAE1H,oHAAoH;;IAEpH,sGAAsG;;IAEtG,wFAAwF;;IAExF,qFAAqF;;IAErF,0FAA0F;;IAE1F,yFAAyF;;IAEzF,kEAAkE;;IAElE,oDAAoD;;IAEpD,+EAA+E;;CAEvE,CAAC;AAEX,wDAAwD;AACxD,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAExF,2CAA2C;AAC3C,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C,sCAAsC;AACtC,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAE/C,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,yCAAyC;AACzC,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAEhF"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,iBAAiB;IAC5B,+DAA+D;;IAE/D,6DAA6D;;IAE7D,gGAAgG;;IAEhG,gHAAgH;;IAEhH,mFAAmF;;IAEnF,gFAAgF;;IAEhF,iGAAiG;;IAEjG,0CAA0C;;IAE1C,6DAA6D;;IAE7D,kDAAkD;;IAElD,mEAAmE;;IAEnE,yXAAyX;;IAEzX,mGAAmG;;IAEnG,iGAAiG;;IAEjG,0HAA0H;;IAE1H,oHAAoH;;IAEpH,sGAAsG;;IAEtG,wFAAwF;;IAExF,qFAAqF;;IAErF,0FAA0F;;IAE1F,yFAAyF;;IAEzF,kEAAkE;;IAElE,oDAAoD;;IAEpD,+EAA+E;;CAEvE,CAAC;AAEX,wDAAwD;AACxD,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAExF,2CAA2C;AAC3C,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C,sCAAsC;AACtC,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAE/C,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,yCAAyC;AACzC,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAEhF"}
|
package/dist/cli/errors.js
CHANGED
|
@@ -14,6 +14,8 @@ export const SETUP_ERROR_CODES = {
|
|
|
14
14
|
GCLOUD_NOT_LOGGED_IN: "gcloud_not_logged_in",
|
|
15
15
|
/** The active gcloud account lacks the Drive scope needed to create and own the spreadsheet. */
|
|
16
16
|
GCLOUD_DRIVE_ACCESS_REQUIRED: "gcloud_drive_access_required",
|
|
17
|
+
/** The interactive `gcloud auth login --enable-gdrive-access --force` handoff did not complete successfully. */
|
|
18
|
+
GCLOUD_LOGIN_FAILED: "gcloud_login_failed",
|
|
17
19
|
/** The user access token could not be retrieved or validated through tokeninfo. */
|
|
18
20
|
USER_TOKEN_FAILED: "user_token_failed",
|
|
19
21
|
/** `gcloud projects create` failed for a reason other than "already exists". */
|
package/dist/cli/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,+DAA+D;IAC/D,cAAc,EAAE,gBAAgB;IAChC,6DAA6D;IAC7D,oBAAoB,EAAE,sBAAsB;IAC5C,gGAAgG;IAChG,4BAA4B,EAAE,8BAA8B;IAC5D,mFAAmF;IACnF,iBAAiB,EAAE,mBAAmB;IACtC,gFAAgF;IAChF,qBAAqB,EAAE,uBAAuB;IAC9C,iGAAiG;IACjG,iBAAiB,EAAE,mBAAmB;IACtC,0CAA0C;IAC1C,qBAAqB,EAAE,uBAAuB;IAC9C,6DAA6D;IAC7D,iBAAiB,EAAE,mBAAmB;IACtC,kDAAkD;IAClD,gBAAgB,EAAE,kBAAkB;IACpC,mEAAmE;IACnE,iBAAiB,EAAE,mBAAmB;IACtC,yXAAyX;IACzX,oBAAoB,EAAE,sBAAsB;IAC5C,mGAAmG;IACnG,oBAAoB,EAAE,sBAAsB;IAC5C,iGAAiG;IACjG,mBAAmB,EAAE,qBAAqB;IAC1C,0HAA0H;IAC1H,sBAAsB,EAAE,wBAAwB;IAChD,oHAAoH;IACpH,iBAAiB,EAAE,mBAAmB;IACtC,sGAAsG;IACtG,iBAAiB,EAAE,mBAAmB;IACtC,wFAAwF;IACxF,kBAAkB,EAAE,oBAAoB;IACxC,qFAAqF;IACrF,uBAAuB,EAAE,yBAAyB;IAClD,0FAA0F;IAC1F,mBAAmB,EAAE,qBAAqB;IAC1C,yFAAyF;IACzF,oBAAoB,EAAE,sBAAsB;IAC5C,kEAAkE;IAClE,wBAAwB,EAAE,0BAA0B;IACpD,oDAAoD;IACpD,mBAAmB,EAAE,qBAAqB;IAC1C,+EAA+E;IAC/E,YAAY,EAAE,cAAc;CACpB,CAAC;AAKX,2CAA2C;AAC3C,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC;AAE3C,sCAAsC;AACtC,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAQ/C,yCAAyC;AACzC,MAAM,UAAU,YAAY,CAAC,IAAoB,EAAE,OAAe;IAChE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC"}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,+DAA+D;IAC/D,cAAc,EAAE,gBAAgB;IAChC,6DAA6D;IAC7D,oBAAoB,EAAE,sBAAsB;IAC5C,gGAAgG;IAChG,4BAA4B,EAAE,8BAA8B;IAC5D,gHAAgH;IAChH,mBAAmB,EAAE,qBAAqB;IAC1C,mFAAmF;IACnF,iBAAiB,EAAE,mBAAmB;IACtC,gFAAgF;IAChF,qBAAqB,EAAE,uBAAuB;IAC9C,iGAAiG;IACjG,iBAAiB,EAAE,mBAAmB;IACtC,0CAA0C;IAC1C,qBAAqB,EAAE,uBAAuB;IAC9C,6DAA6D;IAC7D,iBAAiB,EAAE,mBAAmB;IACtC,kDAAkD;IAClD,gBAAgB,EAAE,kBAAkB;IACpC,mEAAmE;IACnE,iBAAiB,EAAE,mBAAmB;IACtC,yXAAyX;IACzX,oBAAoB,EAAE,sBAAsB;IAC5C,mGAAmG;IACnG,oBAAoB,EAAE,sBAAsB;IAC5C,iGAAiG;IACjG,mBAAmB,EAAE,qBAAqB;IAC1C,0HAA0H;IAC1H,sBAAsB,EAAE,wBAAwB;IAChD,oHAAoH;IACpH,iBAAiB,EAAE,mBAAmB;IACtC,sGAAsG;IACtG,iBAAiB,EAAE,mBAAmB;IACtC,wFAAwF;IACxF,kBAAkB,EAAE,oBAAoB;IACxC,qFAAqF;IACrF,uBAAuB,EAAE,yBAAyB;IAClD,0FAA0F;IAC1F,mBAAmB,EAAE,qBAAqB;IAC1C,yFAAyF;IACzF,oBAAoB,EAAE,sBAAsB;IAC5C,kEAAkE;IAClE,wBAAwB,EAAE,0BAA0B;IACpD,oDAAoD;IACpD,mBAAmB,EAAE,qBAAqB;IAC1C,+EAA+E;IAC/E,YAAY,EAAE,cAAc;CACpB,CAAC;AAKX,2CAA2C;AAC3C,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC;AAE3C,sCAAsC;AACtC,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAQ/C,yCAAyC;AACzC,MAAM,UAAU,YAAY,CAAC,IAAoB,EAAE,OAAe;IAChE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -49,6 +49,68 @@ export interface GcloudRunner {
|
|
|
49
49
|
* non-thrown results pass through unchanged.
|
|
50
50
|
*/
|
|
51
51
|
export declare function createSafeRunner(runner: GcloudRunner): GcloudRunner;
|
|
52
|
+
/**
|
|
53
|
+
* Exact `gcloud auth login` arguments used for the interactive handoff.
|
|
54
|
+
*
|
|
55
|
+
* These mirror {@link DRIVE_ACCESS_COMMAND} in `humanAuth.ts`; the constant
|
|
56
|
+
* is duplicated here so `gcloudRunner` (which `humanAuth` imports) stays free
|
|
57
|
+
* of a runtime import cycle. `--enable-gdrive-access` grants the Drive scope
|
|
58
|
+
* needed to create and own the spreadsheet; `--force` refreshes the cached
|
|
59
|
+
* credentials of an already-logged-in account that lacks the scope.
|
|
60
|
+
*/
|
|
61
|
+
export declare const LOGIN_ARGS: readonly ["auth", "login", "--enable-gdrive-access", "--force"];
|
|
62
|
+
/**
|
|
63
|
+
* Sanitized outcome of the interactive `gcloud auth login` handoff.
|
|
64
|
+
*
|
|
65
|
+
* Only the process exit result is exposed: stdout, stderr, and any access
|
|
66
|
+
* token stay in the user's own gcloud credential store and are never
|
|
67
|
+
* captured, stored, checkpointed, or forwarded by Hikoutei.
|
|
68
|
+
*/
|
|
69
|
+
export type GcloudLoginResult = {
|
|
70
|
+
readonly status: "ok";
|
|
71
|
+
} | {
|
|
72
|
+
readonly status: "not_found";
|
|
73
|
+
} | {
|
|
74
|
+
readonly status: "spawn_error";
|
|
75
|
+
} | {
|
|
76
|
+
readonly status: "failed";
|
|
77
|
+
readonly code: number | null;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Minimal child-process surface the login runner observes.
|
|
81
|
+
*
|
|
82
|
+
* The real `spawn` returns a `ChildProcess`; tests inject a fake that emits
|
|
83
|
+
* `error`/`exit`. Only the two lifecycle events the runner maps to a sanitized
|
|
84
|
+
* result are required.
|
|
85
|
+
*/
|
|
86
|
+
export interface LoginChildProcess {
|
|
87
|
+
on(event: "error", listener: (error: NodeJS.ErrnoException) => void): unknown;
|
|
88
|
+
on(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): unknown;
|
|
89
|
+
}
|
|
90
|
+
/** Spawns the login subprocess; injectable so tests assert the exact command and stdio. */
|
|
91
|
+
export type LoginSpawner = (command: string, args: readonly string[], options: {
|
|
92
|
+
readonly stdio: "inherit";
|
|
93
|
+
}) => LoginChildProcess;
|
|
94
|
+
/** Runs the interactive `gcloud auth login` handoff attached to the terminal. */
|
|
95
|
+
export interface GcloudLoginRunner {
|
|
96
|
+
runInteractiveLogin(): Promise<GcloudLoginResult>;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Production interactive login runner.
|
|
100
|
+
*
|
|
101
|
+
* Spawns `gcloud auth login --enable-gdrive-access --force` with the terminal
|
|
102
|
+
* streams inherited (`stdio: "inherit"`) so the user completes the browser
|
|
103
|
+
* OAuth flow in their own gcloud session and Hikoutei never touches the
|
|
104
|
+
* resulting token. Only the exit outcome is reduced to a sanitized result:
|
|
105
|
+
* `ENOENT` (gcloud not installed) is `not_found`, any other spawn failure is
|
|
106
|
+
* `spawn_error`, a non-zero exit is `failed` with the exit code, and a clean
|
|
107
|
+
* exit is `ok`. The runner resolves exactly once even if both `error` and
|
|
108
|
+
* `exit` arrive.
|
|
109
|
+
*
|
|
110
|
+
* @param spawner Process spawner; defaults to Node's `spawn`. Injectable so
|
|
111
|
+
* tests assert the exact command and the inherited stdio without spawning.
|
|
112
|
+
*/
|
|
113
|
+
export declare function createInteractiveLoginRunner(spawner?: LoginSpawner): GcloudLoginRunner;
|
|
52
114
|
/**
|
|
53
115
|
* Production runner: executes `gcloud <args>` with `execFile`.
|
|
54
116
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcloudRunner.d.ts","sourceRoot":"","sources":["../../src/cli/gcloudRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,wCAAwC;AACxC,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3E;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAChC;IACA,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEJ,+CAA+C;AAC/C,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACpF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAYnE;AAKD;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CA6BjD"}
|
|
1
|
+
{"version":3,"file":"gcloudRunner.d.ts","sourceRoot":"","sources":["../../src/cli/gcloudRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,wCAAwC;AACxC,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3E;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAChC;IACA,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEJ,+CAA+C;AAC/C,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACpF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAYnE;AAKD;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,iEAAkE,CAAC;AAE1F;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAChC;IAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GAClC;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAEhE;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC;IAC9E,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC;CACpG;AAED,2FAA2F;AAC3F,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;CAAE,KACnC,iBAAiB,CAAC;AAEvB,iFAAiF;AACjF,MAAM,WAAW,iBAAiB;IAChC,mBAAmB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACnD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,GAAE,YAAkC,GAAG,iBAAiB,CAyB3G;AAWD;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CA6BjD"}
|
package/dist/cli/gcloudRunner.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* implementation shells out with `node:child_process` `execFile`; a missing
|
|
8
8
|
* binary is reported distinctly (`not_found`) from a failed invocation.
|
|
9
9
|
*/
|
|
10
|
-
import { execFile } from "node:child_process";
|
|
10
|
+
import { execFile, spawn } from "node:child_process";
|
|
11
11
|
/**
|
|
12
12
|
* Wraps a runner so a throwing invocation becomes a sanitized failed result.
|
|
13
13
|
*
|
|
@@ -36,6 +36,61 @@ export function createSafeRunner(runner) {
|
|
|
36
36
|
}
|
|
37
37
|
const GCLOUD_BINARY = "gcloud";
|
|
38
38
|
const MAX_BUFFER_BYTES = 1024 * 1024;
|
|
39
|
+
/**
|
|
40
|
+
* Exact `gcloud auth login` arguments used for the interactive handoff.
|
|
41
|
+
*
|
|
42
|
+
* These mirror {@link DRIVE_ACCESS_COMMAND} in `humanAuth.ts`; the constant
|
|
43
|
+
* is duplicated here so `gcloudRunner` (which `humanAuth` imports) stays free
|
|
44
|
+
* of a runtime import cycle. `--enable-gdrive-access` grants the Drive scope
|
|
45
|
+
* needed to create and own the spreadsheet; `--force` refreshes the cached
|
|
46
|
+
* credentials of an already-logged-in account that lacks the scope.
|
|
47
|
+
*/
|
|
48
|
+
export const LOGIN_ARGS = ["auth", "login", "--enable-gdrive-access", "--force"];
|
|
49
|
+
/**
|
|
50
|
+
* Production interactive login runner.
|
|
51
|
+
*
|
|
52
|
+
* Spawns `gcloud auth login --enable-gdrive-access --force` with the terminal
|
|
53
|
+
* streams inherited (`stdio: "inherit"`) so the user completes the browser
|
|
54
|
+
* OAuth flow in their own gcloud session and Hikoutei never touches the
|
|
55
|
+
* resulting token. Only the exit outcome is reduced to a sanitized result:
|
|
56
|
+
* `ENOENT` (gcloud not installed) is `not_found`, any other spawn failure is
|
|
57
|
+
* `spawn_error`, a non-zero exit is `failed` with the exit code, and a clean
|
|
58
|
+
* exit is `ok`. The runner resolves exactly once even if both `error` and
|
|
59
|
+
* `exit` arrive.
|
|
60
|
+
*
|
|
61
|
+
* @param spawner Process spawner; defaults to Node's `spawn`. Injectable so
|
|
62
|
+
* tests assert the exact command and the inherited stdio without spawning.
|
|
63
|
+
*/
|
|
64
|
+
export function createInteractiveLoginRunner(spawner = spawnAsLoginSpawner) {
|
|
65
|
+
return {
|
|
66
|
+
runInteractiveLogin() {
|
|
67
|
+
return new Promise((resolve) => {
|
|
68
|
+
let settled = false;
|
|
69
|
+
const finish = (result) => {
|
|
70
|
+
if (settled) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
settled = true;
|
|
74
|
+
resolve(result);
|
|
75
|
+
};
|
|
76
|
+
const child = spawner(GCLOUD_BINARY, LOGIN_ARGS, { stdio: "inherit" });
|
|
77
|
+
child.on("error", (error) => {
|
|
78
|
+
// The subprocess could not be started. `ENOENT` means gcloud is
|
|
79
|
+
// absent from PATH; anything else is an opaque spawn failure.
|
|
80
|
+
// The error text may carry transport detail and is never forwarded.
|
|
81
|
+
finish(error.code === "ENOENT" ? { status: "not_found" } : { status: "spawn_error" });
|
|
82
|
+
});
|
|
83
|
+
child.on("exit", (code) => {
|
|
84
|
+
finish(code === 0 ? { status: "ok" } : { status: "failed", code });
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** Default spawner backed by Node's `child_process.spawn`. */
|
|
91
|
+
function spawnAsLoginSpawner(command, args, options) {
|
|
92
|
+
return spawn(command, [...args], options);
|
|
93
|
+
}
|
|
39
94
|
/**
|
|
40
95
|
* Production runner: executes `gcloud <args>` with `execFile`.
|
|
41
96
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcloudRunner.js","sourceRoot":"","sources":["../../src/cli/gcloudRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AA+
|
|
1
|
+
{"version":3,"file":"gcloudRunner.js","sourceRoot":"","sources":["../../src/cli/gcloudRunner.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/setup.d.ts
CHANGED
|
@@ -2,12 +2,110 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* `hikoutei setup` CLI entry.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
* The orchestration is split into a thin `main()` that wires production
|
|
6
|
+
* dependencies (gcloud runner, token validator, sheet factory, SA verifier,
|
|
7
|
+
* interactive login runner) and a testable {@link runSetupCli} that owns the
|
|
8
|
+
* sequence: resolve paths, reject canonical path collisions, ask for the
|
|
9
|
+
* one-time y/N confirmation (skipped by `--yes`/`--dry-run`), run setup, and
|
|
10
|
+
* on an auth preflight failure offer a single interactive Enter-to-login
|
|
11
|
+
* handoff into `gcloud auth login` before retrying exactly once. Exit codes:
|
|
12
|
+
* 0 success, 2 argument errors, 1 runtime failures. Errors are printed as
|
|
13
|
+
* `hikoutei-setup:<code>: <message>` for machine consumption, and key
|
|
14
|
+
* material and the user access token are never printed.
|
|
15
|
+
*/
|
|
16
|
+
import { type SetupOptions } from "./args.js";
|
|
17
|
+
import { type GcloudLoginRunner } from "./gcloudRunner.js";
|
|
18
|
+
import { type SetupResult } from "./setupFlow.js";
|
|
19
|
+
/** Pure parameters for one setup attempt (no injected infrastructure). */
|
|
20
|
+
export interface RunSetupParams {
|
|
21
|
+
readonly projectId: string | undefined;
|
|
22
|
+
readonly saName: string;
|
|
23
|
+
readonly spreadsheetTitle: string | undefined;
|
|
24
|
+
readonly keyPath: string;
|
|
25
|
+
readonly outputPath: string;
|
|
26
|
+
readonly statePath: string;
|
|
27
|
+
readonly dryRun: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Runs one setup attempt.
|
|
31
|
+
*
|
|
32
|
+
* Infrastructure (gcloud runner, token validator, sheet factory, SA verifier)
|
|
33
|
+
* is closed over by the caller, so {@link runSetupCli} can be tested with a
|
|
34
|
+
* scripted callable that returns auth preflight failures and successes
|
|
35
|
+
* without wiring up the full harness.
|
|
36
|
+
*/
|
|
37
|
+
export type RunSetupCallable = (params: RunSetupParams) => Promise<SetupResult>;
|
|
38
|
+
/** Terminal line source for the CLI; `process.stdin` in production. */
|
|
39
|
+
export interface CliStdin extends AsyncIterable<string> {
|
|
40
|
+
/** True when stdin is attached to a terminal (gates the login handoff). */
|
|
41
|
+
readonly isTTY?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** Terminal output sink; `process.stdout` in production. */
|
|
44
|
+
export interface CliStdout {
|
|
45
|
+
/** True when stdout is attached to a terminal (gates the login handoff). */
|
|
46
|
+
readonly isTTY?: boolean;
|
|
47
|
+
readonly write: (text: string) => void;
|
|
48
|
+
}
|
|
49
|
+
/** Diagnostic output sink; `process.stderr` in production. */
|
|
50
|
+
export interface CliStderr {
|
|
51
|
+
readonly write: (text: string) => void;
|
|
52
|
+
}
|
|
53
|
+
/** Context injected into {@link runSetupCli}; production values come from `main()`. */
|
|
54
|
+
export interface RunSetupCliContext {
|
|
55
|
+
readonly options: SetupOptions;
|
|
56
|
+
readonly cwd: string;
|
|
57
|
+
/** Runs one setup attempt with all real/fake infrastructure closed over. */
|
|
58
|
+
readonly runSetup: RunSetupCallable;
|
|
59
|
+
/** Runs the interactive `gcloud auth login` handoff attached to the terminal. */
|
|
60
|
+
readonly loginRunner: GcloudLoginRunner;
|
|
61
|
+
readonly stdin: CliStdin;
|
|
62
|
+
readonly stdout: CliStdout;
|
|
63
|
+
readonly stderr: CliStderr;
|
|
64
|
+
/**
|
|
65
|
+
* Releases the shared stdin after every prompt and the inherited gcloud
|
|
66
|
+
* login have finished; called exactly once on every setup outcome
|
|
67
|
+
* (collision, declined confirmation, success, dry run, errors, login
|
|
68
|
+
* cancel/failure, and retries). Optional so tests that do not exercise
|
|
69
|
+
* the lifecycle run unchanged.
|
|
70
|
+
*
|
|
71
|
+
* The confirmation and login-handoff prompts read `process.stdin` through
|
|
72
|
+
* its async iterator WITHOUT calling the iterator's `return()` so the two
|
|
73
|
+
* sequential prompts share one stream; that open iterator keeps an internal
|
|
74
|
+
* listener on the Readable and would hold the process alive after setup
|
|
75
|
+
* finishes. The production finalizer destroys `process.stdin` to release
|
|
76
|
+
* it. It is invoked from a `finally` AFTER the inherited login subprocess
|
|
77
|
+
* (which needs the live terminal) resolves, never before it.
|
|
78
|
+
*/
|
|
79
|
+
readonly finalizeStdin?: () => void;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Orchestrates the setup CLI: path resolution, collision guard, one-time
|
|
83
|
+
* confirmation, the setup run, and the optional interactive login handoff.
|
|
84
|
+
*
|
|
85
|
+
* The handoff runs ONLY when the first attempt fails with an auth preflight
|
|
86
|
+
* error (`gcloud_not_logged_in` or `gcloud_drive_access_required`) AND the
|
|
87
|
+
* session is a real interactive terminal (`stdin.isTTY && stdout.isTTY`) AND
|
|
88
|
+
* neither `--yes` nor `--dry-run` was given. The preflight runs before any
|
|
89
|
+
* lock, checkpoint, cloud, or file mutation, so retrying after a successful
|
|
90
|
+
* login cannot create duplicate resources. The login is attempted at most
|
|
91
|
+
* once and the setup retried at most once; if the retry still lacks the
|
|
92
|
+
* scope, the original sanitized error is reported with no further login.
|
|
93
|
+
*
|
|
94
|
+
* @returns the process exit code (0 success, 2 argument collision, 1 failure).
|
|
95
|
+
*/
|
|
96
|
+
export declare function runSetupCli(context: RunSetupCliContext): Promise<number>;
|
|
97
|
+
/**
|
|
98
|
+
* Pure ESM entrypoint guard: true only when `entryArg` resolves (following
|
|
99
|
+
* symlinks) to the same file as `moduleUrl`.
|
|
100
|
+
*
|
|
101
|
+
* In CommonJS the bin would use `require.main === module`; in this package's
|
|
102
|
+
* pure-ESM layout (`"type": "module"`) this realpath comparison is the robust
|
|
103
|
+
* equivalent. `npx hikoutei` runs the published bin through a symlink, so the
|
|
104
|
+
* realpath step resolves `.bin/hikoutei` to `dist/cli/setup.js` and matches
|
|
105
|
+
* `import.meta.url`. When this module is imported — for example by the unit
|
|
106
|
+
* tests importing `runSetupCli` — the entry argument is the test runner binary
|
|
107
|
+
* and never matches, so `main()` is not executed and nothing parses argv,
|
|
108
|
+
* writes CLI errors, or mutates `process.exitCode` on import.
|
|
109
|
+
*/
|
|
110
|
+
export declare function isModuleMainEntry(entryArg: string | undefined, moduleUrl: string): boolean;
|
|
13
111
|
//# sourceMappingURL=setup.d.ts.map
|
package/dist/cli/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG;AAKH,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAS9D,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAC;AAS3B,OAAO,EAOL,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;AAExB,0EAA0E;AAC1E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAEhF,uEAAuE;AACvE,MAAM,WAAW,QAAS,SAAQ,aAAa,CAAC,MAAM,CAAC;IACrD,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,4DAA4D;AAC5D,MAAM,WAAW,SAAS;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,8DAA8D;AAC9D,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,uFAAuF;AACvF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,iFAAiF;IACjF,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CACrC;AAQD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiG9E;AAsCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAW1F"}
|