@wootsup/yt-builder-mcp 1.3.0 → 1.4.1
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 +1 -1
- package/dist/cli/doctor-command.d.ts +21 -0
- package/dist/cli/doctor-command.d.ts.map +1 -0
- package/dist/cli/doctor-command.js +111 -0
- package/dist/cli/doctor-command.js.map +1 -0
- package/dist/cli/invocation-decision.d.ts.map +1 -1
- package/dist/cli/invocation-decision.js +2 -0
- package/dist/cli/invocation-decision.js.map +1 -1
- package/dist/client.d.ts +14 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +9 -0
- package/dist/client.js.map +1 -1
- package/dist/diagnostics/ca-trust.d.ts +16 -0
- package/dist/diagnostics/ca-trust.d.ts.map +1 -0
- package/dist/diagnostics/ca-trust.js +54 -0
- package/dist/diagnostics/ca-trust.js.map +1 -0
- package/dist/diagnostics/diagnose-network-error.d.ts +37 -0
- package/dist/diagnostics/diagnose-network-error.d.ts.map +1 -0
- package/dist/diagnostics/diagnose-network-error.js +158 -0
- package/dist/diagnostics/diagnose-network-error.js.map +1 -0
- package/dist/diagnostics/doctor.d.ts +62 -0
- package/dist/diagnostics/doctor.d.ts.map +1 -0
- package/dist/diagnostics/doctor.js +165 -0
- package/dist/diagnostics/doctor.js.map +1 -0
- package/dist/gateway/essentials.d.ts +1 -1
- package/dist/gateway/essentials.d.ts.map +1 -1
- package/dist/gateway/essentials.js +5 -0
- package/dist/gateway/essentials.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -1
- package/dist/install-skill.d.ts +1 -1
- package/dist/install-skill.js +1 -1
- package/dist/net/extra-headers.d.ts +66 -0
- package/dist/net/extra-headers.d.ts.map +1 -0
- package/dist/net/extra-headers.js +164 -0
- package/dist/net/extra-headers.js.map +1 -0
- package/dist/net/internal-host.d.ts +45 -0
- package/dist/net/internal-host.d.ts.map +1 -0
- package/dist/net/internal-host.js +164 -0
- package/dist/net/internal-host.js.map +1 -0
- package/dist/net/proxy-dispatcher.d.ts +40 -0
- package/dist/net/proxy-dispatcher.d.ts.map +1 -0
- package/dist/net/proxy-dispatcher.js +65 -0
- package/dist/net/proxy-dispatcher.js.map +1 -0
- package/dist/proxy/bridge.d.ts +45 -13
- package/dist/proxy/bridge.d.ts.map +1 -1
- package/dist/proxy/bridge.js +113 -7
- package/dist/proxy/bridge.js.map +1 -1
- package/dist/setup-ca-env.d.ts +40 -0
- package/dist/setup-ca-env.d.ts.map +1 -0
- package/dist/setup-ca-env.js +58 -0
- package/dist/setup-ca-env.js.map +1 -0
- package/dist/setup-ca-reprobe.d.ts +38 -0
- package/dist/setup-ca-reprobe.d.ts.map +1 -0
- package/dist/setup-ca-reprobe.js +68 -0
- package/dist/setup-ca-reprobe.js.map +1 -0
- package/dist/setup-cli.d.ts +37 -2
- package/dist/setup-cli.d.ts.map +1 -1
- package/dist/setup-cli.js +178 -4
- package/dist/setup-cli.js.map +1 -1
- package/dist/setup-npx-spec.d.ts +44 -0
- package/dist/setup-npx-spec.d.ts.map +1 -0
- package/dist/setup-npx-spec.js +66 -0
- package/dist/setup-npx-spec.js.map +1 -0
- package/dist/setup-prompts.d.ts +14 -1
- package/dist/setup-prompts.d.ts.map +1 -1
- package/dist/setup-prompts.js +53 -1
- package/dist/setup-prompts.js.map +1 -1
- package/dist/setup-wizard-defaults.d.ts.map +1 -1
- package/dist/setup-wizard-defaults.js +29 -5
- package/dist/setup-wizard-defaults.js.map +1 -1
- package/dist/setup-wizard-handshake.d.ts +4 -4
- package/dist/setup-wizard-handshake.d.ts.map +1 -1
- package/dist/setup-wizard-handshake.js +46 -12
- package/dist/setup-wizard-handshake.js.map +1 -1
- package/dist/setup-wizard-types.d.ts +81 -0
- package/dist/setup-wizard-types.d.ts.map +1 -1
- package/dist/setup-wizard.d.ts +2 -2
- package/dist/setup-wizard.d.ts.map +1 -1
- package/dist/setup-wizard.js +133 -18
- package/dist/setup-wizard.js.map +1 -1
- package/dist/sites/client-pool.d.ts +8 -1
- package/dist/sites/client-pool.d.ts.map +1 -1
- package/dist/sites/client-pool.js +13 -1
- package/dist/sites/client-pool.js.map +1 -1
- package/dist/tools/elements/builders.d.ts.map +1 -1
- package/dist/tools/elements/builders.js +4 -2
- package/dist/tools/elements/builders.js.map +1 -1
- package/dist/tools/elements/handlers.d.ts +2 -1
- package/dist/tools/elements/handlers.d.ts.map +1 -1
- package/dist/tools/elements/handlers.js +3 -22
- package/dist/tools/elements/handlers.js.map +1 -1
- package/dist/tools/format/health-format.d.ts +3 -0
- package/dist/tools/format/health-format.d.ts.map +1 -1
- package/dist/tools/format/health-format.js +21 -4
- package/dist/tools/format/health-format.js.map +1 -1
- package/dist/tools/health.d.ts.map +1 -1
- package/dist/tools/health.js +32 -0
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/pages/builders.d.ts.map +1 -1
- package/dist/tools/pages/builders.js +78 -27
- package/dist/tools/pages/builders.js.map +1 -1
- package/dist/tools/pages/handlers-read.d.ts +36 -5
- package/dist/tools/pages/handlers-read.d.ts.map +1 -1
- package/dist/tools/pages/handlers-read.js +217 -34
- package/dist/tools/pages/handlers-read.js.map +1 -1
- package/dist/tools/pages/schemas.d.ts +20 -5
- package/dist/tools/pages/schemas.d.ts.map +1 -1
- package/dist/tools/pages/schemas.js +44 -6
- package/dist/tools/pages/schemas.js.map +1 -1
- package/dist/tools/shared-schemas.d.ts +3 -0
- package/dist/tools/shared-schemas.d.ts.map +1 -1
- package/dist/tools/shared-schemas.js +28 -0
- package/dist/tools/shared-schemas.js.map +1 -1
- package/dist/tools/sources/builders.d.ts.map +1 -1
- package/dist/tools/sources/builders.js +30 -5
- package/dist/tools/sources/builders.js.map +1 -1
- package/dist/tools/sources/handlers.d.ts +9 -1
- package/dist/tools/sources/handlers.d.ts.map +1 -1
- package/dist/tools/sources/handlers.js +62 -12
- package/dist/tools/sources/handlers.js.map +1 -1
- package/dist/tools/sparse-fields.d.ts +50 -0
- package/dist/tools/sparse-fields.d.ts.map +1 -1
- package/dist/tools/sparse-fields.js +107 -0
- package/dist/tools/sparse-fields.js.map +1 -1
- package/dist/update/update-check.d.ts +56 -0
- package/dist/update/update-check.d.ts.map +1 -0
- package/dist/update/update-check.js +155 -0
- package/dist/update/update-check.js.map +1 -0
- package/manifest.json +1 -1
- package/package.json +2 -1
- package/skills/yt-builder-mcp/SKILL.md +13 -12
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `setup-ca-env` — translate a wizard/CLI CA choice into MCP-server env keys.
|
|
3
|
+
*
|
|
4
|
+
* G-D #7: corporate TLS-inspection has two trust strategies, and exactly which
|
|
5
|
+
* env the server entry needs depends on the running Node:
|
|
6
|
+
*
|
|
7
|
+
* - **file mode** (`caCertPath`): write `NODE_EXTRA_CA_CERTS=<path>`. Works on
|
|
8
|
+
* every supported Node; the only option below the system-CA floor.
|
|
9
|
+
* - **system mode** (`caMode: 'system'`): write `NODE_OPTIONS=--use-system-ca`
|
|
10
|
+
* so Node reads the OS trust store (Windows CryptoAPI / macOS Keychain) —
|
|
11
|
+
* the zero-export path, but only on Node ≥ 22.15. Below that floor we emit
|
|
12
|
+
* NOTHING and warn to supply a `.pem` instead, so we never write a flag the
|
|
13
|
+
* target Node would reject at startup.
|
|
14
|
+
*
|
|
15
|
+
* Pure + Node-version-injectable so it is unit-testable offline. Never disables
|
|
16
|
+
* TLS verification.
|
|
17
|
+
*
|
|
18
|
+
* @license MIT
|
|
19
|
+
*/
|
|
20
|
+
/** The CA-trust portion of a {@link WizardAnswers}. */
|
|
21
|
+
export interface CaChoice {
|
|
22
|
+
readonly caCertPath?: string;
|
|
23
|
+
readonly caMode?: 'system';
|
|
24
|
+
}
|
|
25
|
+
export interface CaEnvResult {
|
|
26
|
+
/** Env keys to merge into the MCP server entry's env block. */
|
|
27
|
+
readonly env: Record<string, string>;
|
|
28
|
+
/** Non-fatal warnings (e.g. system-CA requested on too-old a Node). */
|
|
29
|
+
readonly warnings: readonly string[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the CA env-block keys for `choice` under `nodeVersion` (default
|
|
33
|
+
* `process.version`). `currentEnv` (default `process.env`) is only read to
|
|
34
|
+
* preserve a pre-existing `NODE_OPTIONS` when appending the system-CA flag.
|
|
35
|
+
*
|
|
36
|
+
* File mode wins deterministically if both are set (an explicit `.pem` is the
|
|
37
|
+
* stronger signal). Pure — returns a fresh object, mutates nothing.
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildCaEnv(choice: CaChoice, nodeVersion?: string, currentEnv?: NodeJS.ProcessEnv): CaEnvResult;
|
|
40
|
+
//# sourceMappingURL=setup-ca-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-ca-env.d.ts","sourceRoot":"","sources":["../src/setup-ca-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,uDAAuD;AACvD,MAAM,WAAW,QAAQ;IACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAYD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACtB,MAAM,EAAE,QAAQ,EAChB,WAAW,GAAE,MAAwB,EACrC,UAAU,GAAE,MAAM,CAAC,UAAwB,GAC5C,WAAW,CAoBb"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `setup-ca-env` — translate a wizard/CLI CA choice into MCP-server env keys.
|
|
3
|
+
*
|
|
4
|
+
* G-D #7: corporate TLS-inspection has two trust strategies, and exactly which
|
|
5
|
+
* env the server entry needs depends on the running Node:
|
|
6
|
+
*
|
|
7
|
+
* - **file mode** (`caCertPath`): write `NODE_EXTRA_CA_CERTS=<path>`. Works on
|
|
8
|
+
* every supported Node; the only option below the system-CA floor.
|
|
9
|
+
* - **system mode** (`caMode: 'system'`): write `NODE_OPTIONS=--use-system-ca`
|
|
10
|
+
* so Node reads the OS trust store (Windows CryptoAPI / macOS Keychain) —
|
|
11
|
+
* the zero-export path, but only on Node ≥ 22.15. Below that floor we emit
|
|
12
|
+
* NOTHING and warn to supply a `.pem` instead, so we never write a flag the
|
|
13
|
+
* target Node would reject at startup.
|
|
14
|
+
*
|
|
15
|
+
* Pure + Node-version-injectable so it is unit-testable offline. Never disables
|
|
16
|
+
* TLS verification.
|
|
17
|
+
*
|
|
18
|
+
* @license MIT
|
|
19
|
+
*/
|
|
20
|
+
import { supportsSystemCa } from './diagnostics/ca-trust.js';
|
|
21
|
+
const SYSTEM_CA_FLAG = '--use-system-ca';
|
|
22
|
+
/** Append `--use-system-ca` to an existing NODE_OPTIONS without duplicating it. */
|
|
23
|
+
function withSystemCaFlag(existing) {
|
|
24
|
+
const trimmed = (existing ?? '').trim();
|
|
25
|
+
if (trimmed === '')
|
|
26
|
+
return SYSTEM_CA_FLAG;
|
|
27
|
+
if (trimmed.split(/\s+/).includes(SYSTEM_CA_FLAG))
|
|
28
|
+
return trimmed;
|
|
29
|
+
return `${trimmed} ${SYSTEM_CA_FLAG}`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the CA env-block keys for `choice` under `nodeVersion` (default
|
|
33
|
+
* `process.version`). `currentEnv` (default `process.env`) is only read to
|
|
34
|
+
* preserve a pre-existing `NODE_OPTIONS` when appending the system-CA flag.
|
|
35
|
+
*
|
|
36
|
+
* File mode wins deterministically if both are set (an explicit `.pem` is the
|
|
37
|
+
* stronger signal). Pure — returns a fresh object, mutates nothing.
|
|
38
|
+
*/
|
|
39
|
+
export function buildCaEnv(choice, nodeVersion = process.version, currentEnv = process.env) {
|
|
40
|
+
const path = choice.caCertPath?.trim();
|
|
41
|
+
if (path !== undefined && path !== '') {
|
|
42
|
+
return { env: { NODE_EXTRA_CA_CERTS: path }, warnings: [] };
|
|
43
|
+
}
|
|
44
|
+
if (choice.caMode === 'system') {
|
|
45
|
+
if (supportsSystemCa(nodeVersion)) {
|
|
46
|
+
return { env: { NODE_OPTIONS: withSystemCaFlag(currentEnv.NODE_OPTIONS) }, warnings: [] };
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
env: {},
|
|
50
|
+
warnings: [
|
|
51
|
+
`OS trust store (--use-system-ca) needs Node ≥ 22.15 — this Node is ${nodeVersion}. ` +
|
|
52
|
+
'Re-run setup with `--ca <path-to-corp-root-ca.pem>` (export your corporate root CA to a .pem) instead. Never disable TLS verification.',
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return { env: {}, warnings: [] };
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=setup-ca-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-ca-env.js","sourceRoot":"","sources":["../src/setup-ca-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAe7D,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAEzC,mFAAmF;AACnF,SAAS,gBAAgB,CAAC,QAA4B;IAClD,MAAM,OAAO,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACxC,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,cAAc,CAAC;IAC1C,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO,OAAO,CAAC;IAClE,OAAO,GAAG,OAAO,IAAI,cAAc,EAAE,CAAC;AAC1C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CACtB,MAAgB,EAChB,cAAsB,OAAO,CAAC,OAAO,EACrC,aAAgC,OAAO,CAAC,GAAG;IAE3C,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC;IACvC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QACpC,OAAO,EAAE,GAAG,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAChE,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7B,IAAI,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,GAAG,EAAE,EAAE,YAAY,EAAE,gBAAgB,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QAC9F,CAAC;QACD,OAAO;YACH,GAAG,EAAE,EAAE;YACP,QAAQ,EAAE;gBACN,sEAAsE,WAAW,IAAI;oBACjF,wIAAwI;aAC/I;SACJ,CAAC;IACN,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `setup-ca-reprobe` — default `WizardDeps.applyAndReProbe` (G-D #6/#8).
|
|
3
|
+
*
|
|
4
|
+
* After the user picks a corporate-CA strategy, RE-PROBE the connection so the
|
|
5
|
+
* wizard can print ✅/❌ now instead of leaving a silent first-tool-call
|
|
6
|
+
* timeout for after the restart:
|
|
7
|
+
*
|
|
8
|
+
* - **file mode**: read the `.pem` and run the probes through an undici
|
|
9
|
+
* `Agent` whose connector trusts that CA — this validates in-process,
|
|
10
|
+
* immediately, without a restart.
|
|
11
|
+
* - **system mode**: the OS trust store is only consulted when Node is
|
|
12
|
+
* (re)started with `--use-system-ca`, which the written config now does —
|
|
13
|
+
* so we re-run the ordinary probes (best-effort) and report the truthful
|
|
14
|
+
* current state; the config is already correct for the next launch.
|
|
15
|
+
*
|
|
16
|
+
* Never disables TLS verification.
|
|
17
|
+
*
|
|
18
|
+
* @license MIT
|
|
19
|
+
*/
|
|
20
|
+
import type { AuthProbeResult, CaPromptChoice, HealthProbeResult } from './setup-wizard-types.js';
|
|
21
|
+
/**
|
|
22
|
+
* Probe health + auth for `wpUrl`/`bearer` under the chosen CA. The probes are
|
|
23
|
+
* injected (default to the real handshake probes) so this stays testable; the
|
|
24
|
+
* file-mode CA wiring is the only real-I/O part and is exercised by an
|
|
25
|
+
* integration probe, never a unit mock.
|
|
26
|
+
*/
|
|
27
|
+
export declare function defaultApplyAndReProbe(input: {
|
|
28
|
+
readonly wpUrl: string;
|
|
29
|
+
readonly bearer: string;
|
|
30
|
+
readonly choice: CaPromptChoice;
|
|
31
|
+
}, probes?: {
|
|
32
|
+
probeHealth?: (wpUrl: string, fetchImpl?: typeof fetch) => Promise<HealthProbeResult>;
|
|
33
|
+
probeAuth?: (wpUrl: string, bearer: string, fetchImpl?: typeof fetch) => Promise<AuthProbeResult>;
|
|
34
|
+
}): Promise<{
|
|
35
|
+
health: HealthProbeResult;
|
|
36
|
+
auth: AuthProbeResult;
|
|
37
|
+
}>;
|
|
38
|
+
//# sourceMappingURL=setup-ca-reprobe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-ca-reprobe.d.ts","sourceRoot":"","sources":["../src/setup-ca-reprobe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAElG;;;;;GAKG;AACH,wBAAsB,sBAAsB,CACxC,KAAK,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;CAAE,EAC3F,MAAM,GAAE;IACJ,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,KAAK,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACtF,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,KAAK,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;CAChG,GACP,OAAO,CAAC;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,CAAC,CAkB/D"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `setup-ca-reprobe` — default `WizardDeps.applyAndReProbe` (G-D #6/#8).
|
|
3
|
+
*
|
|
4
|
+
* After the user picks a corporate-CA strategy, RE-PROBE the connection so the
|
|
5
|
+
* wizard can print ✅/❌ now instead of leaving a silent first-tool-call
|
|
6
|
+
* timeout for after the restart:
|
|
7
|
+
*
|
|
8
|
+
* - **file mode**: read the `.pem` and run the probes through an undici
|
|
9
|
+
* `Agent` whose connector trusts that CA — this validates in-process,
|
|
10
|
+
* immediately, without a restart.
|
|
11
|
+
* - **system mode**: the OS trust store is only consulted when Node is
|
|
12
|
+
* (re)started with `--use-system-ca`, which the written config now does —
|
|
13
|
+
* so we re-run the ordinary probes (best-effort) and report the truthful
|
|
14
|
+
* current state; the config is already correct for the next launch.
|
|
15
|
+
*
|
|
16
|
+
* Never disables TLS verification.
|
|
17
|
+
*
|
|
18
|
+
* @license MIT
|
|
19
|
+
*/
|
|
20
|
+
import { readFile } from 'node:fs/promises';
|
|
21
|
+
import { Agent, fetch as undiciFetch } from 'undici';
|
|
22
|
+
import { defaultProbeAuth, defaultProbeHealth } from './setup-wizard-handshake.js';
|
|
23
|
+
/**
|
|
24
|
+
* Probe health + auth for `wpUrl`/`bearer` under the chosen CA. The probes are
|
|
25
|
+
* injected (default to the real handshake probes) so this stays testable; the
|
|
26
|
+
* file-mode CA wiring is the only real-I/O part and is exercised by an
|
|
27
|
+
* integration probe, never a unit mock.
|
|
28
|
+
*/
|
|
29
|
+
export async function defaultApplyAndReProbe(input, probes = {}) {
|
|
30
|
+
const probeHealth = probes.probeHealth ?? defaultProbeHealth;
|
|
31
|
+
const probeAuth = probes.probeAuth ?? defaultProbeAuth;
|
|
32
|
+
if (input.choice.choice === 'file') {
|
|
33
|
+
const fetchImpl = await caBoundFetch(input.choice.path);
|
|
34
|
+
if (fetchImpl !== null) {
|
|
35
|
+
const health = await probeHealth(input.wpUrl, fetchImpl);
|
|
36
|
+
const auth = await probeAuth(input.wpUrl, input.bearer, fetchImpl);
|
|
37
|
+
return { health, auth };
|
|
38
|
+
}
|
|
39
|
+
// Could not read the .pem — fall through to a plain re-probe so the
|
|
40
|
+
// operator still gets a (failing) verdict + the file warning above.
|
|
41
|
+
}
|
|
42
|
+
const health = await probeHealth(input.wpUrl);
|
|
43
|
+
const auth = await probeAuth(input.wpUrl, input.bearer);
|
|
44
|
+
return { health, auth };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A `fetch` whose TLS connector additionally trusts the PEM at `caPath`, or
|
|
48
|
+
* `null` when the file cannot be read. The CA is ADDED to the default trust
|
|
49
|
+
* set (undici merges it with the system roots) — verification stays on.
|
|
50
|
+
*/
|
|
51
|
+
async function caBoundFetch(caPath) {
|
|
52
|
+
let ca;
|
|
53
|
+
try {
|
|
54
|
+
ca = await readFile(caPath, 'utf8');
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const agent = new Agent({ connect: { ca } });
|
|
60
|
+
// undici's fetch accepts a per-call `dispatcher`; wrap it to match the
|
|
61
|
+
// global `fetch` signature the RestClient expects.
|
|
62
|
+
const bound = ((input, init) => undiciFetch(input, {
|
|
63
|
+
...init,
|
|
64
|
+
dispatcher: agent,
|
|
65
|
+
}));
|
|
66
|
+
return bound;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=setup-ca-reprobe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-ca-reprobe.js","sourceRoot":"","sources":["../src/setup-ca-reprobe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAGnF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CACxC,KAA2F,EAC3F,SAGI,EAAE;IAEN,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,kBAAkB,CAAC;IAC7D,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,gBAAgB,CAAC;IAEvD,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YACzD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YACnE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC5B,CAAC;QACD,oEAAoE;QACpE,oEAAoE;IACxE,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACxD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,YAAY,CAAC,MAAc;IACtC,IAAI,EAAU,CAAC;IACf,IAAI,CAAC;QACD,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7C,uEAAuE;IACvE,mDAAmD;IACnD,MAAM,KAAK,GAAG,CAAC,CAAC,KAAkC,EAAE,IAAkC,EAAE,EAAE,CACtF,WAAW,CAAC,KAA0C,EAAE;QACpD,GAAI,IAA0C;QAC9C,UAAU,EAAE,KAAK;KACpB,CAAwC,CAAiB,CAAC;IAC/D,OAAO,KAAK,CAAC;AACjB,CAAC"}
|
package/dist/setup-cli.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ import { type ListSitesDeps } from './sites/cli/list-sites.js';
|
|
|
29
29
|
import { type RemoveSiteDeps } from './sites/cli/remove-site.js';
|
|
30
30
|
import { type SetDefaultDeps } from './sites/cli/set-default.js';
|
|
31
31
|
import { type TestSiteDeps } from './sites/cli/test-site.js';
|
|
32
|
-
export { DEFAULT_WIZARD_DEPS, majorMinor, runWizard, type AuthProbeResult, type HandshakeResult, type HealthProbeResult, type WizardAnswers, type WizardDeps, type WriteResult, } from './setup-wizard.js';
|
|
32
|
+
export { DEFAULT_WIZARD_DEPS, majorMinor, runWizard, type AuthProbeResult, type CaPromptChoice, type HandshakeResult, type HealthProbeResult, type WizardAnswers, type WizardDeps, type WriteResult, } from './setup-wizard.js';
|
|
33
33
|
export interface ParsedSetupArgs {
|
|
34
34
|
/** True when `--non-interactive` was passed. Always boolean. */
|
|
35
35
|
readonly nonInteractive: boolean;
|
|
@@ -58,14 +58,41 @@ export interface ParsedSetupArgs {
|
|
|
58
58
|
* pickup mode"). These do NOT block the wizard from running.
|
|
59
59
|
*/
|
|
60
60
|
readonly warnings: readonly string[];
|
|
61
|
+
/**
|
|
62
|
+
* Path to a corporate/proxy root CA `.pem` from `--ca <path>`. When set,
|
|
63
|
+
* the generated server entry's env block gets `NODE_EXTRA_CA_CERTS=<path>`
|
|
64
|
+
* so the MCP server trusts a TLS-inspection chain (never `strict-ssl
|
|
65
|
+
* false`). Mutually exclusive with {@link caMode}.
|
|
66
|
+
*/
|
|
67
|
+
readonly caCertPath?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Corporate-CA trust strategy from `--ca=system` / `--use-system-ca`.
|
|
70
|
+
* `'system'` writes `NODE_OPTIONS=--use-system-ca` into the env block so
|
|
71
|
+
* Node reads the OS trust store (Windows CryptoAPI / macOS Keychain) — the
|
|
72
|
+
* zero-export path on Node ≥ 22.15. Mutually exclusive with
|
|
73
|
+
* {@link caCertPath}. Undefined = no system-CA request.
|
|
74
|
+
*/
|
|
75
|
+
readonly caMode?: 'system';
|
|
76
|
+
/**
|
|
77
|
+
* Glöckle gap #15 — version pin from `--pin <version>`. When set, the
|
|
78
|
+
* generated client config runs `npx -y @wootsup/yt-builder-mcp@<version>`
|
|
79
|
+
* (reproducible / air-gapped) instead of the default floating `@latest`.
|
|
80
|
+
* Falls back to the `YTB_MCP_VERSION` env var when the flag is absent
|
|
81
|
+
* (resolved by the dispatcher, which holds process.env). Undefined = float.
|
|
82
|
+
*/
|
|
83
|
+
readonly versionPin?: string;
|
|
61
84
|
}
|
|
62
85
|
/**
|
|
63
86
|
* Parse the `setup` subcommand argv tail. Pure function; does no I/O.
|
|
64
87
|
*
|
|
65
88
|
* Accepts both `--key value` and `--key=value` styles. Unknown flags
|
|
66
89
|
* are reported as errors so typos don't silently disable validation.
|
|
90
|
+
*
|
|
91
|
+
* `env` (default `{}`, kept empty so the function stays pure) supplies the
|
|
92
|
+
* `YTB_MCP_VERSION` fallback for the `--pin` version-pin (Glöckle gap #15):
|
|
93
|
+
* an explicit `--pin` always wins; otherwise `YTB_MCP_VERSION` is used.
|
|
67
94
|
*/
|
|
68
|
-
export declare function parseSetupArgs(argv: readonly string[]): ParsedSetupArgs;
|
|
95
|
+
export declare function parseSetupArgs(argv: readonly string[], env?: NodeJS.ProcessEnv): ParsedSetupArgs;
|
|
69
96
|
/**
|
|
70
97
|
* Build a `WizardDeps` bag that answers prompts from CLI flags instead
|
|
71
98
|
* of asking a human. Reuses every other dependency (probes, writes,
|
|
@@ -138,6 +165,14 @@ export interface RunCliDeps {
|
|
|
138
165
|
* nothing and the wizard uses `DEFAULT_WIZARD_DEPS`.
|
|
139
166
|
*/
|
|
140
167
|
runWizard: (deps?: WizardDeps) => Promise<number>;
|
|
168
|
+
/**
|
|
169
|
+
* Base `WizardDeps` the INTERACTIVE setup path folds (withCa / withPin /
|
|
170
|
+
* withPersist) over. Defaults to {@link DEFAULT_WIZARD_DEPS}. Tests inject a
|
|
171
|
+
* bag with a synthetic `prompt` + capturing `writeClient` so the folds can
|
|
172
|
+
* be asserted on the default interactive run without driving real clack
|
|
173
|
+
* prompts. Production callers never set this.
|
|
174
|
+
*/
|
|
175
|
+
interactiveWizardDeps?: WizardDeps;
|
|
141
176
|
installSkill: typeof defaultInstallSkill;
|
|
142
177
|
log?: (line: string) => void;
|
|
143
178
|
error?: (line: string) => void;
|
package/dist/setup-cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-cli.d.ts","sourceRoot":"","sources":["../src/setup-cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAKzE,OAAO,KAAK,EAAiB,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAIH,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAIH,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,aAAa,EACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGH,KAAK,aAAa,EACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAIH,KAAK,cAAc,EACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAIH,KAAK,cAAc,EACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAKH,KAAK,YAAY,EACpB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EACH,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,WAAW,GACnB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"setup-cli.d.ts","sourceRoot":"","sources":["../src/setup-cli.ts"],"names":[],"mappings":"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"}
|
package/dist/setup-cli.js
CHANGED
|
@@ -41,6 +41,12 @@ const HELP_TEXT = `Usage: yt-builder-mcp <command> [flags]
|
|
|
41
41
|
|
|
42
42
|
Commands:
|
|
43
43
|
setup Interactive first-run wizard (default if no command)
|
|
44
|
+
doctor Diagnose connectivity: Node version, corporate proxy,
|
|
45
|
+
TLS chain (detects a TLS-inspection CA), site
|
|
46
|
+
reachability, bearer validity, and update status — each
|
|
47
|
+
with an actionable fix. Flags: --url <site> --token
|
|
48
|
+
<key> (else falls back to YTB_MCP_SITE_URL /
|
|
49
|
+
YTB_MCP_BEARER_TOKEN). Run this first when setup "hangs".
|
|
44
50
|
install-skill Copy the bundled YOOtheme Builder skill into
|
|
45
51
|
~/.claude/skills/ and register it in ~/AGENTS.md.
|
|
46
52
|
Note: ~/.claude/skills/ is the universal-marker path
|
|
@@ -75,6 +81,28 @@ Setup flags (for non-interactive / CI usage):
|
|
|
75
81
|
claude-desktop, claude-code, cursor, zed, continue,
|
|
76
82
|
cline, roo-code, codex-cli, gemini-cli.
|
|
77
83
|
|
|
84
|
+
Corporate TLS-inspection (Zscaler / Netskope etc.) — pick ONE:
|
|
85
|
+
--use-system-ca Trust your OS store (Windows cert store / macOS
|
|
86
|
+
(or --ca=system) Keychain). Zero-export — needs Node ≥ 22.15. Writes
|
|
87
|
+
NODE_OPTIONS=--use-system-ca into the server entry.
|
|
88
|
+
--ca <path> Path to an exported corporate root CA .pem. Writes
|
|
89
|
+
NODE_EXTRA_CA_CERTS=<path>. Works on any Node.
|
|
90
|
+
(The interactive wizard auto-offers these when a
|
|
91
|
+
probe fails with a TLS-inspection certificate error.)
|
|
92
|
+
|
|
93
|
+
Air-gapped / locked-down corporate environments (version pinning):
|
|
94
|
+
--pin <version> Pin the generated client config to an exact version
|
|
95
|
+
instead of the floating @latest. Writes
|
|
96
|
+
\`npx -y @wootsup/yt-builder-mcp@<version>\` so a
|
|
97
|
+
locked-down environment that forbids floating installs
|
|
98
|
+
has a reproducible path. Accepts an exact semver
|
|
99
|
+
(1.4.0), an optional leading v (v1.4.0), or a dist-tag
|
|
100
|
+
(next). \`--pin latest\` is the same as omitting it
|
|
101
|
+
(floats; the startup notifier nudges new versions).
|
|
102
|
+
Falls back to the YTB_MCP_VERSION env var when unset.
|
|
103
|
+
Fully npx-free alternative: install the .dxt Desktop
|
|
104
|
+
build (bundles a fixed version; no network at launch).
|
|
105
|
+
|
|
78
106
|
Example (non-interactive):
|
|
79
107
|
npx -y @wootsup/yt-builder-mcp setup \\
|
|
80
108
|
--non-interactive \\
|
|
@@ -82,6 +110,12 @@ Example (non-interactive):
|
|
|
82
110
|
--url https://example.com \\
|
|
83
111
|
--token "$YTB_TOKEN"
|
|
84
112
|
|
|
113
|
+
Example (pinned, air-gapped):
|
|
114
|
+
npx -y @wootsup/yt-builder-mcp setup \\
|
|
115
|
+
--non-interactive --client cursor \\
|
|
116
|
+
--url https://example.com --token "$YTB_TOKEN" \\
|
|
117
|
+
--pin 1.4.0
|
|
118
|
+
|
|
85
119
|
Pickup mode (one-click setup from the admin "Setup wizard" flow):
|
|
86
120
|
--pickup <url> Pickup URL revealed by the host CMS admin (WordPress:
|
|
87
121
|
wp-admin → Tools → "YT Builder MCP"; Joomla:
|
|
@@ -124,6 +158,25 @@ Environment (when launched by an AI client):
|
|
|
124
158
|
Defaults to URL-shape auto-detection.
|
|
125
159
|
YTB_MCP_TEST_MODE=1 Print the registered tool list to stderr and exit 0
|
|
126
160
|
without starting the stdio loop (smoke-test probe).
|
|
161
|
+
YTB_MCP_EXTRA_HEADERS Extra HTTP headers merged into EVERY outbound request
|
|
162
|
+
(corporate edge: HTTP Basic-Auth, a WAF cookie, a
|
|
163
|
+
required gateway header). Two accepted formats:
|
|
164
|
+
JSON object: {"X-WAF-Token":"abc","Cookie":"sid=42"}
|
|
165
|
+
Name: value lines (one per line, first ":" splits):
|
|
166
|
+
X-WAF-Token: abc
|
|
167
|
+
Cookie: sid=42
|
|
168
|
+
The Bearer token is set automatically and ALWAYS wins —
|
|
169
|
+
an "Authorization" entry here is ignored. Applies on
|
|
170
|
+
both fat mode and proxy mode.
|
|
171
|
+
YTB_MCP_VERSION Version pin fallback for --pin (see above). When set to
|
|
172
|
+
an exact version, the server runs that version instead
|
|
173
|
+
of floating @latest. Air-gapped alternative: .dxt build.
|
|
174
|
+
NO_PROXY / HTTPS_PROXY Standard proxy env. When HTTP(S)_PROXY is set and
|
|
175
|
+
YTB_MCP_SITE_URL points at an INTERNAL host (private IP,
|
|
176
|
+
.local/.internal, a bare hostname, or loopback), that
|
|
177
|
+
host is auto-added to NO_PROXY so intranet traffic
|
|
178
|
+
bypasses the corporate proxy. A public host is never
|
|
179
|
+
touched; an operator-set NO_PROXY is preserved verbatim.
|
|
127
180
|
|
|
128
181
|
Documentation: https://github.com/wootsup/yt-builder-mcp
|
|
129
182
|
`;
|
|
@@ -132,13 +185,20 @@ Documentation: https://github.com/wootsup/yt-builder-mcp
|
|
|
132
185
|
*
|
|
133
186
|
* Accepts both `--key value` and `--key=value` styles. Unknown flags
|
|
134
187
|
* are reported as errors so typos don't silently disable validation.
|
|
188
|
+
*
|
|
189
|
+
* `env` (default `{}`, kept empty so the function stays pure) supplies the
|
|
190
|
+
* `YTB_MCP_VERSION` fallback for the `--pin` version-pin (Glöckle gap #15):
|
|
191
|
+
* an explicit `--pin` always wins; otherwise `YTB_MCP_VERSION` is used.
|
|
135
192
|
*/
|
|
136
|
-
export function parseSetupArgs(argv) {
|
|
193
|
+
export function parseSetupArgs(argv, env = {}) {
|
|
137
194
|
let nonInteractive = false;
|
|
138
195
|
let url = '';
|
|
139
196
|
let token = '';
|
|
140
197
|
let pickup = '';
|
|
141
198
|
let nonce = '';
|
|
199
|
+
let caCertPath = '';
|
|
200
|
+
let caSystem = false;
|
|
201
|
+
let versionPin = '';
|
|
142
202
|
const clients = [];
|
|
143
203
|
const errors = [];
|
|
144
204
|
const warnings = [];
|
|
@@ -197,6 +257,37 @@ export function parseSetupArgs(argv) {
|
|
|
197
257
|
i = nextIndex;
|
|
198
258
|
break;
|
|
199
259
|
}
|
|
260
|
+
case '--ca': {
|
|
261
|
+
// Corporate TLS-inspection root CA. Two strategies:
|
|
262
|
+
// --ca=system / --ca system → OS trust store (NODE_OPTIONS=--use-system-ca)
|
|
263
|
+
// --ca <path> → .pem file (NODE_EXTRA_CA_CERTS=<path>)
|
|
264
|
+
const { value, nextIndex } = consumeValue('--ca', inline, i);
|
|
265
|
+
const v = value.trim();
|
|
266
|
+
if (v.toLowerCase() === 'system') {
|
|
267
|
+
caSystem = true;
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
caCertPath = v;
|
|
271
|
+
}
|
|
272
|
+
i = nextIndex;
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
case '--use-system-ca': {
|
|
276
|
+
// Alias for `--ca=system`: trust the OS store natively (no .pem).
|
|
277
|
+
caSystem = true;
|
|
278
|
+
if (inline !== undefined) {
|
|
279
|
+
errors.push('Flag --use-system-ca does not take a value.');
|
|
280
|
+
}
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
case '--pin': {
|
|
284
|
+
// Glöckle gap #15 — pin the npx version (air-gapped / locked-down
|
|
285
|
+
// corp envs that forbid floating @latest installs).
|
|
286
|
+
const { value, nextIndex } = consumeValue('--pin', inline, i);
|
|
287
|
+
versionPin = value.trim();
|
|
288
|
+
i = nextIndex;
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
200
291
|
default: {
|
|
201
292
|
errors.push(`Unknown setup flag: ${flag}`);
|
|
202
293
|
}
|
|
@@ -239,7 +330,27 @@ export function parseSetupArgs(argv) {
|
|
|
239
330
|
}
|
|
240
331
|
}
|
|
241
332
|
}
|
|
242
|
-
|
|
333
|
+
// A .pem path and the OS-trust-store are two mutually-exclusive ways to
|
|
334
|
+
// trust the same CA — refuse the ambiguous combination rather than silently
|
|
335
|
+
// pick one.
|
|
336
|
+
if (caSystem && caCertPath !== '') {
|
|
337
|
+
errors.push('Pass either a CA .pem path (--ca <path>) or the OS trust store (--ca=system / --use-system-ca), not both.');
|
|
338
|
+
}
|
|
339
|
+
// #15 — an explicit `--pin` wins; otherwise fall back to YTB_MCP_VERSION.
|
|
340
|
+
const resolvedPin = versionPin !== '' ? versionPin : (env.YTB_MCP_VERSION ?? '').trim();
|
|
341
|
+
return {
|
|
342
|
+
nonInteractive,
|
|
343
|
+
url,
|
|
344
|
+
token,
|
|
345
|
+
pickup,
|
|
346
|
+
nonce,
|
|
347
|
+
clients,
|
|
348
|
+
errors,
|
|
349
|
+
warnings,
|
|
350
|
+
...(caCertPath !== '' ? { caCertPath } : {}),
|
|
351
|
+
...(caSystem ? { caMode: 'system' } : {}),
|
|
352
|
+
...(resolvedPin !== '' ? { versionPin: resolvedPin } : {}),
|
|
353
|
+
};
|
|
243
354
|
}
|
|
244
355
|
/**
|
|
245
356
|
* Build a `WizardDeps` bag that answers prompts from CLI flags instead
|
|
@@ -255,11 +366,19 @@ export function buildNonInteractiveDeps(parsed, base = DEFAULT_WIZARD_DEPS) {
|
|
|
255
366
|
wpUrl: parsed.url,
|
|
256
367
|
bearer: parsed.token,
|
|
257
368
|
selectedClients: parsed.clients,
|
|
369
|
+
...(parsed.caCertPath !== undefined ? { caCertPath: parsed.caCertPath } : {}),
|
|
370
|
+
...(parsed.caMode !== undefined ? { caMode: parsed.caMode } : {}),
|
|
371
|
+
...(parsed.versionPin !== undefined ? { versionPin: parsed.versionPin } : {}),
|
|
258
372
|
};
|
|
259
373
|
return {
|
|
260
374
|
...base,
|
|
261
375
|
prompt: async () => answers,
|
|
262
376
|
confirmContinue: async () => false,
|
|
377
|
+
// No human to answer the interactive CA prompt — the CA comes from
|
|
378
|
+
// `--ca` / `--ca=system` flags (already in `answers`). Stripping the
|
|
379
|
+
// prompt keeps a CA-trust probe failure on the documented exit-code
|
|
380
|
+
// path instead of hanging on a prompt with no TTY.
|
|
381
|
+
promptCa: undefined,
|
|
263
382
|
};
|
|
264
383
|
}
|
|
265
384
|
/**
|
|
@@ -298,6 +417,7 @@ export function buildPickupDeps(parsed, base = DEFAULT_WIZARD_DEPS) {
|
|
|
298
417
|
wpUrl: result.siteurl,
|
|
299
418
|
bearer: result.token,
|
|
300
419
|
selectedClients: parsed.clients,
|
|
420
|
+
...(parsed.versionPin !== undefined ? { versionPin: parsed.versionPin } : {}),
|
|
301
421
|
};
|
|
302
422
|
}
|
|
303
423
|
catch (e) {
|
|
@@ -310,6 +430,8 @@ export function buildPickupDeps(parsed, base = DEFAULT_WIZARD_DEPS) {
|
|
|
310
430
|
}
|
|
311
431
|
},
|
|
312
432
|
confirmContinue: async () => false,
|
|
433
|
+
// Pickup is non-interactive too — no TTY for the CA prompt.
|
|
434
|
+
promptCa: undefined,
|
|
313
435
|
};
|
|
314
436
|
}
|
|
315
437
|
/**
|
|
@@ -595,6 +717,7 @@ export async function runCli(argv, deps) {
|
|
|
595
717
|
const out = deps?.log ?? ((s) => process.stdout.write(`${s}\n`));
|
|
596
718
|
const err = deps?.error ?? ((s) => process.stderr.write(`${s}\n`));
|
|
597
719
|
const wizard = deps?.runWizard ?? ((wizDeps) => runWizardImpl(wizDeps));
|
|
720
|
+
const interactiveBase = deps?.interactiveWizardDeps ?? DEFAULT_WIZARD_DEPS;
|
|
598
721
|
const install = deps?.installSkill ?? defaultInstallSkill;
|
|
599
722
|
const resolveSitesPath = deps?.resolveSitesPath ?? (() => defaultSitesFilePath());
|
|
600
723
|
const addSiteDeps = deps?.addSiteDeps ?? DEFAULT_ADD_SITE_DEPS;
|
|
@@ -639,7 +762,7 @@ export async function runCli(argv, deps) {
|
|
|
639
762
|
};
|
|
640
763
|
if (subcommand === undefined || subcommand === 'setup') {
|
|
641
764
|
const setupArgs = argv[0] === 'setup' ? argv.slice(1) : argv;
|
|
642
|
-
const parsed = parseSetupArgs(setupArgs);
|
|
765
|
+
const parsed = parseSetupArgs(setupArgs, process.env);
|
|
643
766
|
// Surface non-fatal warnings (e.g. "--url ignored in pickup mode").
|
|
644
767
|
for (const line of parsed.warnings)
|
|
645
768
|
err(`yt-builder-mcp: warning: ${line}`);
|
|
@@ -648,6 +771,53 @@ export async function runCli(argv, deps) {
|
|
|
648
771
|
function withPersist(base) {
|
|
649
772
|
return { ...base, persistSite };
|
|
650
773
|
}
|
|
774
|
+
// #15 — when `--pin` / YTB_MCP_VERSION is set on the INTERACTIVE path,
|
|
775
|
+
// the prompt collects its own answers, so fold the pin into them after
|
|
776
|
+
// the prompt resolves. Non-interactive / pickup paths already inject the
|
|
777
|
+
// pin via their answers builders.
|
|
778
|
+
function withPin(base) {
|
|
779
|
+
if (parsed.versionPin === undefined)
|
|
780
|
+
return base;
|
|
781
|
+
const pin = parsed.versionPin;
|
|
782
|
+
const innerPrompt = base.prompt;
|
|
783
|
+
return {
|
|
784
|
+
...base,
|
|
785
|
+
prompt: async (input) => {
|
|
786
|
+
const answers = await innerPrompt(input);
|
|
787
|
+
if (answers === null)
|
|
788
|
+
return null;
|
|
789
|
+
return { ...answers, versionPin: pin };
|
|
790
|
+
},
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
// G-D #6 — when `--use-system-ca` / `--ca=system` / `--ca <path>` is
|
|
794
|
+
// passed on the INTERACTIVE path, the prompt collects its own answers,
|
|
795
|
+
// so fold the CA choice into them after the prompt resolves (mirrors
|
|
796
|
+
// withPin). Without this fold an explicit CA flag on the default
|
|
797
|
+
// interactive run was a SILENT NO-OP: it was parsed then dropped before
|
|
798
|
+
// reaching the env block (only buildNonInteractiveDeps threaded it). The
|
|
799
|
+
// non-interactive / pickup paths already inject the CA via their answers
|
|
800
|
+
// builders, so this fold is the interactive-path counterpart.
|
|
801
|
+
function withCa(base) {
|
|
802
|
+
if (parsed.caMode === undefined && parsed.caCertPath === undefined)
|
|
803
|
+
return base;
|
|
804
|
+
const caMode = parsed.caMode;
|
|
805
|
+
const caCertPath = parsed.caCertPath;
|
|
806
|
+
const innerPrompt = base.prompt;
|
|
807
|
+
return {
|
|
808
|
+
...base,
|
|
809
|
+
prompt: async (input) => {
|
|
810
|
+
const answers = await innerPrompt(input);
|
|
811
|
+
if (answers === null)
|
|
812
|
+
return null;
|
|
813
|
+
return {
|
|
814
|
+
...answers,
|
|
815
|
+
...(caMode !== undefined ? { caMode } : {}),
|
|
816
|
+
...(caCertPath !== undefined ? { caCertPath } : {}),
|
|
817
|
+
};
|
|
818
|
+
},
|
|
819
|
+
};
|
|
820
|
+
}
|
|
651
821
|
if (pickupMode) {
|
|
652
822
|
if (parsed.errors.length > 0) {
|
|
653
823
|
for (const line of parsed.errors)
|
|
@@ -672,9 +842,13 @@ export async function runCli(argv, deps) {
|
|
|
672
842
|
err(HELP_TEXT);
|
|
673
843
|
return 1;
|
|
674
844
|
}
|
|
675
|
-
return wizard(withPersist(
|
|
845
|
+
return wizard(withCa(withPin(withPersist(interactiveBase))));
|
|
676
846
|
}
|
|
677
847
|
switch (subcommand) {
|
|
848
|
+
case 'doctor': {
|
|
849
|
+
const { doctorCommand } = await import('./cli/doctor-command.js');
|
|
850
|
+
return doctorCommand(argv.slice(1), { log: out });
|
|
851
|
+
}
|
|
678
852
|
case 'install-skill':
|
|
679
853
|
case 'install': {
|
|
680
854
|
try {
|