@arizeai/phoenix-cli 1.9.0 → 1.9.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 +54 -7
- package/build/authFetch.d.ts +24 -0
- package/build/authFetch.d.ts.map +1 -0
- package/build/authFetch.js +44 -0
- package/build/authFetch.js.map +1 -0
- package/build/client.d.ts.map +1 -1
- package/build/client.js +5 -1
- package/build/client.js.map +1 -1
- package/build/commands/api.d.ts.map +1 -1
- package/build/commands/api.js +12 -1
- package/build/commands/api.js.map +1 -1
- package/build/commands/auth.d.ts +4 -1
- package/build/commands/auth.d.ts.map +1 -1
- package/build/commands/auth.js +326 -13
- package/build/commands/auth.js.map +1 -1
- package/build/commands/formatSetup.d.ts +6 -0
- package/build/commands/formatSetup.d.ts.map +1 -1
- package/build/commands/formatSetup.js +10 -1
- package/build/commands/formatSetup.js.map +1 -1
- package/build/commands/setup.d.ts.map +1 -1
- package/build/commands/setup.js +4 -0
- package/build/commands/setup.js.map +1 -1
- package/build/config.d.ts +15 -0
- package/build/config.d.ts.map +1 -1
- package/build/config.js +54 -7
- package/build/config.js.map +1 -1
- package/build/exitCodes.d.ts +6 -0
- package/build/exitCodes.d.ts.map +1 -1
- package/build/exitCodes.js +18 -0
- package/build/exitCodes.js.map +1 -1
- package/build/index.js +2 -1
- package/build/index.js.map +1 -1
- package/build/oauth.d.ts +138 -0
- package/build/oauth.d.ts.map +1 -0
- package/build/oauth.js +465 -0
- package/build/oauth.js.map +1 -0
- package/build/oauthCallbackPage.d.ts +9 -0
- package/build/oauthCallbackPage.d.ts.map +1 -0
- package/build/oauthCallbackPage.js +111 -0
- package/build/oauthCallbackPage.js.map +1 -0
- package/build/pxi/client.d.ts.map +1 -1
- package/build/pxi/client.js +11 -2
- package/build/pxi/client.js.map +1 -1
- package/build/settings.d.ts +19 -0
- package/build/settings.d.ts.map +1 -1
- package/build/settings.js +21 -0
- package/build/settings.js.map +1 -1
- package/build/setup/agents/registry.d.ts +57 -0
- package/build/setup/agents/registry.d.ts.map +1 -1
- package/build/setup/agents/registry.js +45 -0
- package/build/setup/agents/registry.js.map +1 -1
- package/build/setup/copy.d.ts +32 -0
- package/build/setup/copy.d.ts.map +1 -1
- package/build/setup/copy.js +44 -0
- package/build/setup/copy.js.map +1 -1
- package/build/setup/deps/buildDefaultDeps.d.ts.map +1 -1
- package/build/setup/deps/buildDefaultDeps.js +2 -0
- package/build/setup/deps/buildDefaultDeps.js.map +1 -1
- package/build/setup/deps/index.d.ts +4 -0
- package/build/setup/deps/index.d.ts.map +1 -1
- package/build/setup/deps/index.js.map +1 -1
- package/build/setup/deps/oauthLogin.d.ts +64 -0
- package/build/setup/deps/oauthLogin.d.ts.map +1 -0
- package/build/setup/deps/oauthLogin.js +82 -0
- package/build/setup/deps/oauthLogin.js.map +1 -0
- package/build/setup/deps/prompter.d.ts +7 -0
- package/build/setup/deps/prompter.d.ts.map +1 -1
- package/build/setup/options.d.ts +11 -0
- package/build/setup/options.d.ts.map +1 -1
- package/build/setup/options.js +1 -0
- package/build/setup/options.js.map +1 -1
- package/build/setup/prompts/instrumentationPrompt.d.ts +7 -1
- package/build/setup/prompts/instrumentationPrompt.d.ts.map +1 -1
- package/build/setup/prompts/instrumentationPrompt.js +6 -2
- package/build/setup/prompts/instrumentationPrompt.js.map +1 -1
- package/build/setup/runSetup.d.ts +3 -0
- package/build/setup/runSetup.d.ts.map +1 -1
- package/build/setup/runSetup.js +13 -12
- package/build/setup/runSetup.js.map +1 -1
- package/build/setup/steps/establishConnection.d.ts +6 -3
- package/build/setup/steps/establishConnection.d.ts.map +1 -1
- package/build/setup/steps/establishConnection.js +120 -11
- package/build/setup/steps/establishConnection.js.map +1 -1
- package/build/setup/steps/instrumentApp.d.ts +23 -4
- package/build/setup/steps/instrumentApp.d.ts.map +1 -1
- package/build/setup/steps/instrumentApp.js +89 -41
- package/build/setup/steps/instrumentApp.js.map +1 -1
- package/build/setup/steps/offerDocsMcp.d.ts +48 -0
- package/build/setup/steps/offerDocsMcp.d.ts.map +1 -0
- package/build/setup/steps/offerDocsMcp.js +133 -0
- package/build/setup/steps/offerDocsMcp.js.map +1 -0
- package/build/setup/ui/clackPrompter.d.ts.map +1 -1
- package/build/setup/ui/clackPrompter.js +15 -0
- package/build/setup/ui/clackPrompter.js.map +1 -1
- package/build/setup/util/mcpConfig.d.ts +31 -0
- package/build/setup/util/mcpConfig.d.ts.map +1 -0
- package/build/setup/util/mcpConfig.js +62 -0
- package/build/setup/util/mcpConfig.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The browser-login capability: an ephemeral OAuth2 Authorization Code +
|
|
3
|
+
* PKCE flow, used by setup to obtain a short-lived access token so it can
|
|
4
|
+
* mint an API key on the user's behalf instead of asking them to paste one.
|
|
5
|
+
*
|
|
6
|
+
* Contract plus the real, system-backed implementation (the flow is system
|
|
7
|
+
* glue: an HTTP callback server, a browser launch, and token exchange —
|
|
8
|
+
* exactly the effects the seam exists to keep out of steps). Tests script
|
|
9
|
+
* outcomes through a fake.
|
|
10
|
+
*/
|
|
11
|
+
export interface OAuthLoginArgs {
|
|
12
|
+
/** Normalized origin, no trailing slash. */
|
|
13
|
+
endpoint: string;
|
|
14
|
+
/**
|
|
15
|
+
* Called with the authorization URL before the browser opens, so the user
|
|
16
|
+
* can complete the login by hand when the launch fails or goes unnoticed.
|
|
17
|
+
*/
|
|
18
|
+
onAuthorizationUrl: (url: string) => void;
|
|
19
|
+
/**
|
|
20
|
+
* The browser could not be launched (no `xdg-open`, a headless container).
|
|
21
|
+
* The URL was already narrated, so this is a nudge, not a failure.
|
|
22
|
+
*/
|
|
23
|
+
onBrowserOpenFailed: (detail: string) => void;
|
|
24
|
+
/** Abandons an unanswered login, yielding a `cancelled` outcome. */
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
}
|
|
27
|
+
export type OAuthLoginOutcome = {
|
|
28
|
+
status: "success";
|
|
29
|
+
accessToken: string;
|
|
30
|
+
/**
|
|
31
|
+
* End the grant this login just created, once its token has served its
|
|
32
|
+
* purpose. Scoped to that grant alone — an existing `px auth login`
|
|
33
|
+
* session is a separate grant and survives. Best-effort: the tokens
|
|
34
|
+
* expire on their own regardless.
|
|
35
|
+
*/
|
|
36
|
+
revoke: () => Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
/** The user declined the consent screen — a choice, not a failure. */
|
|
39
|
+
| {
|
|
40
|
+
status: "cancelled";
|
|
41
|
+
} | {
|
|
42
|
+
status: "error";
|
|
43
|
+
detail: string;
|
|
44
|
+
};
|
|
45
|
+
export interface OAuthLogin {
|
|
46
|
+
/**
|
|
47
|
+
* Whether the instance runs the OAuth2 authorization server. False on any
|
|
48
|
+
* failure — an unreachable or older server simply keeps the paste lane.
|
|
49
|
+
*/
|
|
50
|
+
isSupported(endpoint: string): Promise<boolean>;
|
|
51
|
+
login(args: OAuthLoginArgs): Promise<OAuthLoginOutcome>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* `apiUrl` is the hidden `--api-url` dev override. It must reach every hop of
|
|
55
|
+
* the flow: the token this mints is spent against the same override by the
|
|
56
|
+
* client factory, so an authorization server at a different host would issue a
|
|
57
|
+
* token the key-minting server rejects. `fetchImpl` is the same transport seam
|
|
58
|
+
* the Phoenix client takes, so the probe is injectable rather than global.
|
|
59
|
+
*/
|
|
60
|
+
export declare function createSystemOAuthLogin({ apiUrl, fetchImpl, }?: {
|
|
61
|
+
apiUrl?: string;
|
|
62
|
+
fetchImpl?: typeof fetch;
|
|
63
|
+
}): OAuthLogin;
|
|
64
|
+
//# sourceMappingURL=oauthLogin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauthLogin.d.ts","sourceRoot":"","sources":["../../../src/setup/deps/oauthLogin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C;;;OAGG;IACH,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,MAAM,iBAAiB,GACzB;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AACH,sEAAsE;GACpE;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACzD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,MAAM,EACN,SAAiB,GAClB,GAAE;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACrB,GAAG,UAAU,CAsElB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The browser-login capability: an ephemeral OAuth2 Authorization Code +
|
|
3
|
+
* PKCE flow, used by setup to obtain a short-lived access token so it can
|
|
4
|
+
* mint an API key on the user's behalf instead of asking them to paste one.
|
|
5
|
+
*
|
|
6
|
+
* Contract plus the real, system-backed implementation (the flow is system
|
|
7
|
+
* glue: an HTTP callback server, a browser launch, and token exchange —
|
|
8
|
+
* exactly the effects the seam exists to keep out of steps). Tests script
|
|
9
|
+
* outcomes through a fake.
|
|
10
|
+
*/
|
|
11
|
+
import { OAuthAuthorizationServerMetadataSchema, normalizeEndpoint, revokeOAuthToken, runBrowserLoginFlow, } from "../../oauth.js";
|
|
12
|
+
const SUPPORT_PROBE_TIMEOUT_MS = 5_000;
|
|
13
|
+
/**
|
|
14
|
+
* `apiUrl` is the hidden `--api-url` dev override. It must reach every hop of
|
|
15
|
+
* the flow: the token this mints is spent against the same override by the
|
|
16
|
+
* client factory, so an authorization server at a different host would issue a
|
|
17
|
+
* token the key-minting server rejects. `fetchImpl` is the same transport seam
|
|
18
|
+
* the Phoenix client takes, so the probe is injectable rather than global.
|
|
19
|
+
*/
|
|
20
|
+
export function createSystemOAuthLogin({ apiUrl, fetchImpl = fetch, } = {}) {
|
|
21
|
+
// Resolved once: the probe and the flow must agree on which host they talk
|
|
22
|
+
// to, and two `??` expressions are two chances to disagree.
|
|
23
|
+
const apiOrigin = (endpoint) => apiUrl ?? endpoint;
|
|
24
|
+
return {
|
|
25
|
+
async isSupported(endpoint) {
|
|
26
|
+
try {
|
|
27
|
+
const response = await fetchImpl(new URL(".well-known/oauth-authorization-server", normalizeEndpoint(apiOrigin(endpoint))), { signal: AbortSignal.timeout(SUPPORT_PROBE_TIMEOUT_MS) });
|
|
28
|
+
if (!response.ok) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
const document = await response.json();
|
|
32
|
+
return OAuthAuthorizationServerMetadataSchema.safeParse(document)
|
|
33
|
+
.success;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
async login({ endpoint, onAuthorizationUrl, onBrowserOpenFailed, signal }) {
|
|
40
|
+
const origin = apiOrigin(endpoint);
|
|
41
|
+
try {
|
|
42
|
+
const result = await runBrowserLoginFlow({
|
|
43
|
+
endpoint: origin,
|
|
44
|
+
onAuthorizationUrl,
|
|
45
|
+
onBrowserOpenFailed: (error) => onBrowserOpenFailed(error instanceof Error ? error.message : String(error)),
|
|
46
|
+
// No pasted-redirect lane here, unlike `px auth login`. It reads a
|
|
47
|
+
// raw readline off stdin, which would both land unannounced in the
|
|
48
|
+
// middle of the clack wizard and — because readline in terminal mode
|
|
49
|
+
// intercepts Ctrl-C itself — kill the interrupt this login promises
|
|
50
|
+
// as its way out. Setup's fallback is pasting an API key, which the
|
|
51
|
+
// prompter asks for properly.
|
|
52
|
+
allowPastedRedirect: false,
|
|
53
|
+
signal,
|
|
54
|
+
});
|
|
55
|
+
if (result.status === "cancelled") {
|
|
56
|
+
return { status: "cancelled" };
|
|
57
|
+
}
|
|
58
|
+
if (result.status === "invalid") {
|
|
59
|
+
return { status: "error", detail: result.message };
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
status: "success",
|
|
63
|
+
accessToken: result.tokens.access_token,
|
|
64
|
+
revoke: () => revokeOAuthToken({
|
|
65
|
+
endpoint: origin,
|
|
66
|
+
refreshToken: result.tokens.refresh_token,
|
|
67
|
+
}),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
// Every failure — a loopback port that will not bind, a token endpoint
|
|
72
|
+
// that never answers — is an outcome the wizard falls back from, never
|
|
73
|
+
// an exception that ends setup.
|
|
74
|
+
return {
|
|
75
|
+
status: "error",
|
|
76
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=oauthLogin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauthLogin.js","sourceRoot":"","sources":["../../../src/setup/deps/oauthLogin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,sCAAsC,EACtC,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,MAAM,wBAAwB,GAAG,KAAK,CAAC;AA4CvC;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,EACrC,MAAM,EACN,SAAS,GAAG,KAAK,GAClB,GAGG,EAAE;IACJ,2EAA2E;IAC3E,4DAA4D;IAC5D,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,MAAM,IAAI,QAAQ,CAAC;IAC3D,OAAO;QACL,KAAK,CAAC,WAAW,CAAC,QAAQ;YACxB,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,IAAI,GAAG,CACL,wCAAwC,EACxC,iBAAiB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CACvC,EACD,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,wBAAwB,CAAC,EAAE,CAC1D,CAAC;gBACF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,OAAO,KAAK,CAAC;gBACf,CAAC;gBACD,MAAM,QAAQ,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAChD,OAAO,sCAAsC,CAAC,SAAS,CAAC,QAAQ,CAAC;qBAC9D,OAAO,CAAC;YACb,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,KAAK,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,EAAE;YACvE,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;YACnC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;oBACvC,QAAQ,EAAE,MAAM;oBAChB,kBAAkB;oBAClB,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE,CAC7B,mBAAmB,CACjB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD;oBACH,mEAAmE;oBACnE,mEAAmE;oBACnE,qEAAqE;oBACrE,oEAAoE;oBACpE,oEAAoE;oBACpE,8BAA8B;oBAC9B,mBAAmB,EAAE,KAAK;oBAC1B,MAAM;iBACP,CAAC,CAAC;gBACH,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;oBAClC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;gBACjC,CAAC;gBACD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBAChC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrD,CAAC;gBACD,OAAO;oBACL,MAAM,EAAE,SAAS;oBACjB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY;oBACvC,MAAM,EAAE,GAAG,EAAE,CACX,gBAAgB,CAAC;wBACf,QAAQ,EAAE,MAAM;wBAChB,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa;qBAC1C,CAAC;iBACL,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,uEAAuE;gBACvE,uEAAuE;gBACvE,gCAAgC;gBAChC,OAAO;oBACL,MAAM,EAAE,OAAO;oBACf,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC/D,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -30,6 +30,13 @@ export interface Prompter {
|
|
|
30
30
|
message: string;
|
|
31
31
|
validate?: (value: string) => string | undefined;
|
|
32
32
|
}): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Run `work` with a signal that aborts on Ctrl-C rather than raising
|
|
35
|
+
* SetupCancelledError. For the waits that have no prompt on screen to
|
|
36
|
+
* cancel — a browser login, say: this seam owns the terminal, so it owns the
|
|
37
|
+
* signal, and `work` decides what an interruption means.
|
|
38
|
+
*/
|
|
39
|
+
runInterruptible<T>(work: (signal: AbortSignal) => Promise<T>): Promise<T>;
|
|
33
40
|
/** Non-interactive display of a block of text between prompts. */
|
|
34
41
|
note(message: string, title?: string): void;
|
|
35
42
|
/** One-line status/warning between prompts (stderr). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompter.d.ts","sourceRoot":"","sources":["../../../src/setup/deps/prompter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,qDAAqD;IACrD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;KACjC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACf,qDAAqD;IACrD,SAAS,CAAC,IAAI,EAAE;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;KAClD,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpB,+EAA+E;IAC/E,aAAa,CAAC,IAAI,EAAE;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;KAClD,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpB,kEAAkE;IAClE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,wDAAwD;IACxD,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oCAAoC;IACpC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qCAAqC;IACrC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B"}
|
|
1
|
+
{"version":3,"file":"prompter.d.ts","sourceRoot":"","sources":["../../../src/setup/deps/prompter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,qDAAqD;IACrD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;KACjC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACf,qDAAqD;IACrD,SAAS,CAAC,IAAI,EAAE;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;KAClD,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpB,+EAA+E;IAC/E,aAAa,CAAC,IAAI,EAAE;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;KAClD,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpB;;;;;OAKG;IACH,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3E,kEAAkE;IAClE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,wDAAwD;IACxD,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oCAAoC;IACpC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qCAAqC;IACrC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B"}
|
package/build/setup/options.d.ts
CHANGED
|
@@ -64,6 +64,12 @@ export interface SetupOptions {
|
|
|
64
64
|
background?: boolean;
|
|
65
65
|
/** Docs prefetch, so the agent instruments against local docs. */
|
|
66
66
|
docs?: DocsPrefetchOptions;
|
|
67
|
+
/**
|
|
68
|
+
* --docs-mcp / --no-docs-mcp: connect the Phoenix docs MCP server to the
|
|
69
|
+
* coding agent's project config (replaces the docs prefetch when taken).
|
|
70
|
+
* Undefined means ask interactively; headless skips unless the flag opts in.
|
|
71
|
+
*/
|
|
72
|
+
docsMcp?: boolean;
|
|
67
73
|
}
|
|
68
74
|
export interface SetupInputs {
|
|
69
75
|
/** Pre-answered endpoint (flag, else env), if any. */
|
|
@@ -92,6 +98,11 @@ export interface SetupInputs {
|
|
|
92
98
|
bypassPermissions: boolean;
|
|
93
99
|
/** Docs prefetch; only consulted when `instrument` is true. */
|
|
94
100
|
docs: DocsPrefetchOptions;
|
|
101
|
+
/**
|
|
102
|
+
* Docs MCP offer; only consulted when `instrument` is true. Undefined means
|
|
103
|
+
* ask interactively — an unattended run skips it unless `--docs-mcp` opts in.
|
|
104
|
+
*/
|
|
105
|
+
docsMcp?: boolean;
|
|
95
106
|
}
|
|
96
107
|
/**
|
|
97
108
|
* A headless run that instruments must name its agent: there is no prompt to
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/setup/options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAG9D;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kEAAkE;IAClE,IAAI,CAAC,EAAE,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/setup/options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAG9D;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kEAAkE;IAClE,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,QAAQ,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yEAAyE;IACzE,UAAU,EAAE,OAAO,CAAC;IACpB,mEAAmE;IACnE,iBAAiB,EAAE,OAAO,CAAC;IAC3B,+DAA+D;IAC/D,IAAI,EAAE,mBAAmB,CAAC;IAC1B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAAC,EAC/C,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,GAAG,IAAI,CAIP;AAED,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,OAAO,GACR,EAAE;IACD,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,YAAY,CAAC,CAAC;CACjD,GAAG,WAAW,CAsCd"}
|
package/build/setup/options.js
CHANGED
|
@@ -58,6 +58,7 @@ export function resolveSetupInputs({ options, context, }) {
|
|
|
58
58
|
background: options.background ?? headless,
|
|
59
59
|
bypassPermissions: Boolean(options.bypassPermissions),
|
|
60
60
|
docs: options.docs ?? { enabled: true },
|
|
61
|
+
docsMcp: options.docsMcp,
|
|
61
62
|
};
|
|
62
63
|
}
|
|
63
64
|
//# sourceMappingURL=options.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/setup/options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,gBAAgB,EAAsB,MAAM,mBAAmB,CAAC;AACzE,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAE/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/setup/options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,gBAAgB,EAAsB,MAAM,mBAAmB,CAAC;AACzE,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAE/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAgG9C;;;;;;;;GAQG;AACH,MAAM,UAAU,gCAAgC,CAAC,EAC/C,QAAQ,EACR,KAAK,GAIN;IACC,IAAI,QAAQ,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EACjC,OAAO,EACP,OAAO,GAIR;IACC,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IACxB,MAAM,QAAQ,GACZ,OAAO,CAAC,QAAQ;QAChB,GAAG,CAAC,YAAY;QAChB,GAAG,CAAC,0BAA0B;QAC9B,SAAS,CAAC;IACZ,MAAM,OAAO,GACX,OAAO,CAAC,OAAO;QACf,GAAG,CAAC,eAAe;QACnB,GAAG,CAAC,oBAAoB;QACxB,SAAS,CAAC;IACZ,MAAM,MAAM,GAAG,GAAG,CAAC,eAAe,IAAI,SAAS,CAAC;IAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;IAEjE,qEAAqE;IACrE,uDAAuD;IACvD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,QAAQ,CAAC;IAEnD,IAAI,UAAU,EAAE,CAAC;QACf,gCAAgC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,SAAS;QACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,SAAS;QACrC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,SAAS;QACnC,QAAQ;QACR,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;QAClC,UAAU;QACV,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,6DAA6D;QAC7D,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,QAAQ;QAC1C,iBAAiB,EAAE,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;QACrD,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE;QACvC,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;AACJ,CAAC"}
|
|
@@ -37,6 +37,12 @@ export interface InstrumentationPromptArgs {
|
|
|
37
37
|
* pages from disk instead of fetching the URLs mid-run.
|
|
38
38
|
*/
|
|
39
39
|
localDocsDir?: string;
|
|
40
|
+
/**
|
|
41
|
+
* True when the phoenix-docs MCP server was connected to the agent's
|
|
42
|
+
* project config. The agent then searches the docs on demand — cheaper
|
|
43
|
+
* than fetching whole pages — instead of reading a local prefetch.
|
|
44
|
+
*/
|
|
45
|
+
docsMcpConfigured?: boolean;
|
|
40
46
|
}
|
|
41
|
-
export declare function buildInstrumentationPrompt({ projectName, endpoint, isDefaultEndpoint, docs, tracesUrl, authEnabled, languages, localDocsDir, }: InstrumentationPromptArgs): string;
|
|
47
|
+
export declare function buildInstrumentationPrompt({ projectName, endpoint, isDefaultEndpoint, docs, tracesUrl, authEnabled, languages, localDocsDir, docsMcpConfigured, }: InstrumentationPromptArgs): string;
|
|
42
48
|
//# sourceMappingURL=instrumentationPrompt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentationPrompt.d.ts","sourceRoot":"","sources":["../../../src/setup/prompts/instrumentationPrompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"instrumentationPrompt.d.ts","sourceRoot":"","sources":["../../../src/setup/prompts/instrumentationPrompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,WAAW,yBAAyB;IACxC,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,oBAAoB,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,0DAA0D;IAC1D,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,IAAI,EAAE,yBAAyB,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,0BAA0B,CAAC,EACzC,WAAW,EACX,QAAQ,EACR,iBAAiB,EACjB,IAAI,EACJ,SAAS,EACT,WAAW,EACX,SAAc,EACd,YAAY,EACZ,iBAAiB,GAClB,EAAE,yBAAyB,GAAG,MAAM,CAuDpC"}
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* agent finishes, so the agent's job ends with an emitted trace, not a
|
|
11
11
|
* self-report.
|
|
12
12
|
*/
|
|
13
|
-
|
|
13
|
+
import { DOCS_MCP_SERVER_NAME } from "../agents/registry.js";
|
|
14
|
+
export function buildInstrumentationPrompt({ projectName, endpoint, isDefaultEndpoint, docs, tracesUrl, authEnabled, languages = [], localDocsDir, docsMcpConfigured, }) {
|
|
14
15
|
const credentialVars = authEnabled
|
|
15
16
|
? "PHOENIX_COLLECTOR_ENDPOINT and PHOENIX_API_KEY"
|
|
16
17
|
: "PHOENIX_COLLECTOR_ENDPOINT";
|
|
@@ -23,6 +24,9 @@ export function buildInstrumentationPrompt({ projectName, endpoint, isDefaultEnd
|
|
|
23
24
|
const localDocsRule = localDocsDir
|
|
24
25
|
? `\nThese pages are already downloaded to ${localDocsDir} — read them from disk first, and only\nfetch a URL if the page you need is missing there.`
|
|
25
26
|
: "";
|
|
27
|
+
const docsMcpRule = docsMcpConfigured
|
|
28
|
+
? `\nThe "${DOCS_MCP_SERVER_NAME}" MCP server is connected in this project — search it for Phoenix docs\nfirst; it returns just the relevant sections. Fetch the URLs above only if its tools are\nunavailable.`
|
|
29
|
+
: "";
|
|
26
30
|
return `You are running as part of the Phoenix setup script. Your ONLY task is to add Phoenix
|
|
27
31
|
tracing to the application in the current working directory and emit one verification
|
|
28
32
|
trace. Do not run setup tools, onboarding scripts, or "px setup" again.
|
|
@@ -31,7 +35,7 @@ Work from the official docs — do not guess package names or APIs from memory:
|
|
|
31
35
|
- Python quickstart (arize-phoenix-otel): ${docs.quickstartPython}
|
|
32
36
|
- TypeScript quickstart (@arizeai/phoenix-otel): ${docs.quickstartTypeScript}
|
|
33
37
|
- register() reference: ${docs.phoenixOtelSetup}
|
|
34
|
-
- Auto-instrumentation guides by framework/provider: ${docs.integrationsIndex}${localDocsRule}
|
|
38
|
+
- Auto-instrumentation guides by framework/provider: ${docs.integrationsIndex}${localDocsRule}${docsMcpRule}
|
|
35
39
|
${languageRule}
|
|
36
40
|
|
|
37
41
|
Rules:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentationPrompt.js","sourceRoot":"","sources":["../../../src/setup/prompts/instrumentationPrompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"instrumentationPrompt.js","sourceRoot":"","sources":["../../../src/setup/prompts/instrumentationPrompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAsC1D,MAAM,UAAU,0BAA0B,CAAC,EACzC,WAAW,EACX,QAAQ,EACR,iBAAiB,EACjB,IAAI,EACJ,SAAS,EACT,WAAW,EACX,SAAS,GAAG,EAAE,EACd,YAAY,EACZ,iBAAiB,GACS;IAC1B,MAAM,cAAc,GAAG,WAAW;QAChC,CAAC,CAAC,gDAAgD;QAClD,CAAC,CAAC,4BAA4B,CAAC;IACjC,MAAM,YAAY,GAAG,iBAAiB;QACpC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,sFAAsF,QAAQ,GAAG,CAAC;IACtG,MAAM,YAAY,GAChB,SAAS,CAAC,MAAM,GAAG,CAAC;QAClB,CAAC,CAAC,yBAAyB,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,oCAAoC;QACtF,CAAC,CAAC,oIAAoI,CAAC;IAC3I,MAAM,aAAa,GAAG,YAAY;QAChC,CAAC,CAAC,2CAA2C,YAAY,4FAA4F;QACrJ,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,WAAW,GAAG,iBAAiB;QACnC,CAAC,CAAC,UAAU,oBAAoB,gLAAgL;QAChN,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;;;;;4CAKmC,IAAI,CAAC,gBAAgB;mDACd,IAAI,CAAC,oBAAoB;0BAClD,IAAI,CAAC,gBAAgB;uDACQ,IAAI,CAAC,iBAAiB,GAAG,aAAa,GAAG,WAAW;EACzG,YAAY;;;;yDAI2C,cAAc;;;;;;mBAMpD,WAAW,KAAK,YAAY;;;;;;;;;;;;;;qCAcV,SAAS;;;CAG7C,CAAC;AACF,CAAC"}
|
|
@@ -16,6 +16,7 @@ import type { SetupInputs } from "./options.js";
|
|
|
16
16
|
import type { Connection } from "./steps/establishConnection.js";
|
|
17
17
|
import { type ToolingResult } from "./steps/installTooling.js";
|
|
18
18
|
import { type InstrumentationLane } from "./steps/instrumentApp.js";
|
|
19
|
+
import type { DocsMcpResult } from "./steps/offerDocsMcp.js";
|
|
19
20
|
/** Everything a run did, in the shape the summary and `--format json` print. */
|
|
20
21
|
export interface SetupReport {
|
|
21
22
|
connection: Connection;
|
|
@@ -26,6 +27,8 @@ export interface SetupReport {
|
|
|
26
27
|
/** Paths appended to a .gitignore. */
|
|
27
28
|
gitignored: string[];
|
|
28
29
|
docs?: DocsPrefetchResult;
|
|
30
|
+
/** The docs MCP offer, when it was made (configured replaces `docs`). */
|
|
31
|
+
docsMcp?: DocsMcpResult;
|
|
29
32
|
instrumentation?: InstrumentationLane;
|
|
30
33
|
/** True once the API confirmed a trace arrived after this run started. */
|
|
31
34
|
tracesVerified?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runSetup.d.ts","sourceRoot":"","sources":["../../src/setup/runSetup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAI7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAiB,KAAK,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"runSetup.d.ts","sourceRoot":"","sources":["../../src/setup/runSetup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAI7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAiB,KAAK,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAS1D,gFAAgF;AAChF,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,uCAAuC;IACvC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,sCAAsC;IACtC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,yEAAyE;IACzE,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,0EAA0E;IAC1E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAeD,mCAAmC;AACnC,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,WAAW,CAAC,CA8CtB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,WAAW,GACpB,OAAO,CAAC,WAAW,CAAC,CAetB;AAED,4EAA4E;AAC5E,wBAAsB,SAAS,CAC7B,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,aAAa,CAAC,CAexB"}
|
package/build/setup/runSetup.js
CHANGED
|
@@ -21,7 +21,6 @@ import { establishConnection } from "./steps/establishConnection.js";
|
|
|
21
21
|
import { offerToolingInstalls, } from "./steps/installTooling.js";
|
|
22
22
|
import { instrumentApp } from "./steps/instrumentApp.js";
|
|
23
23
|
import { offerPxProfile } from "./steps/offerPxProfile.js";
|
|
24
|
-
import { prefetchDocs } from "./steps/prefetchDocs.js";
|
|
25
24
|
import { hasSpansInSkewWindow, waitForFirstTrace, tracesUrl, } from "./steps/verifyTraces.js";
|
|
26
25
|
import { ENV_FILE_NAME, writeEnvFile } from "./steps/writeEnvFile.js";
|
|
27
26
|
/**
|
|
@@ -126,13 +125,6 @@ async function registerAndInstrument(deps, inputs, { agentDetection }) {
|
|
|
126
125
|
if (!inputs.instrument) {
|
|
127
126
|
return base;
|
|
128
127
|
}
|
|
129
|
-
// Only after registration's git-safety gate: the docs fetch writes into
|
|
130
|
-
// `.px/`, which an earlier download can make look like a pre-existing dirty
|
|
131
|
-
// tree in a fast or cached headless run.
|
|
132
|
-
const docs = await prefetchDocs(deps, {
|
|
133
|
-
docs: inputs.docs,
|
|
134
|
-
isGitRepository: registration.isGitRepository,
|
|
135
|
-
});
|
|
136
128
|
const startedAt = deps.clock.now();
|
|
137
129
|
// Any span already visible inside the clock-skew window predates this run —
|
|
138
130
|
// verification must then require spans strictly after the start time, or a
|
|
@@ -140,7 +132,11 @@ async function registerAndInstrument(deps, inputs, { agentDetection }) {
|
|
|
140
132
|
const hadRecentSpans = await hasSpansInSkewWindow(deps, connection, {
|
|
141
133
|
sinceMs: startedAt,
|
|
142
134
|
});
|
|
143
|
-
|
|
135
|
+
// The docs steps live inside instrumentApp, after its lane choice: the docs
|
|
136
|
+
// MCP offer targets exactly the agent doing the hand-off, and taking it
|
|
137
|
+
// replaces the `.px/docs` download outright. Both still run behind
|
|
138
|
+
// registration's git-safety gate, which this call comes after.
|
|
139
|
+
const { lane: instrumentation, docs, docsMcp, } = await instrumentApp(deps, connection, {
|
|
144
140
|
authEnabled,
|
|
145
141
|
agentDetection,
|
|
146
142
|
agent: inputs.agent,
|
|
@@ -149,7 +145,10 @@ async function registerAndInstrument(deps, inputs, { agentDetection }) {
|
|
|
149
145
|
background: inputs.background,
|
|
150
146
|
bypassPermissions: inputs.bypassPermissions,
|
|
151
147
|
},
|
|
152
|
-
|
|
148
|
+
docs: inputs.docs,
|
|
149
|
+
docsMcp: inputs.docsMcp,
|
|
150
|
+
headless: inputs.headless,
|
|
151
|
+
isGitRepository: registration.isGitRepository,
|
|
153
152
|
});
|
|
154
153
|
// The return value is setup's definition of done — a trace the API confirmed
|
|
155
154
|
// arriving, not the agent's own claim that it finished. It is reported, not
|
|
@@ -163,8 +162,10 @@ async function registerAndInstrument(deps, inputs, { agentDetection }) {
|
|
|
163
162
|
return {
|
|
164
163
|
...base,
|
|
165
164
|
...(docs ? { docs } : {}),
|
|
166
|
-
|
|
167
|
-
//
|
|
165
|
+
...(docsMcp && docsMcp.outcome !== "skipped" ? { docsMcp } : {}),
|
|
166
|
+
// The MCP config files and the docs step's own gitignore appends have to
|
|
167
|
+
// fold into the report, or it under-states what setup touched.
|
|
168
|
+
files: [...base.files, ...(docsMcp?.files ?? [])],
|
|
168
169
|
gitignored: [...base.gitignored, ...(docs?.gitignoreAppended ?? [])],
|
|
169
170
|
instrumentation,
|
|
170
171
|
tracesVerified,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runSetup.js","sourceRoot":"","sources":["../../src/setup/runSetup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAEL,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAE/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C,OAAO,EAAE,gCAAgC,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EACL,oBAAoB,GAErB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAA4B,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"runSetup.js","sourceRoot":"","sources":["../../src/setup/runSetup.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
* first ingestion, so setup only needs to settle on a *name* and hand it
|
|
6
6
|
* to the app via `PHOENIX_PROJECT_NAME`. What remains is credential
|
|
7
7
|
* acquisition: the auth-on lanes verify the key with a read-only probe so a
|
|
8
|
-
* bad paste is caught here rather than at first trace.
|
|
9
|
-
*
|
|
8
|
+
* bad paste is caught here rather than at first trace. When the instance runs
|
|
9
|
+
* the OAuth2 authorization server, the interactive lane offers a streamlined
|
|
10
|
+
* path first — log in with the browser, mint an API key over REST, revoke the
|
|
11
|
+
* grant that login created — and every failure along it falls back to the
|
|
12
|
+
* paste prompt rather than aborting setup.
|
|
10
13
|
*/
|
|
11
14
|
import type { SetupDeps } from "../deps/index.js";
|
|
12
15
|
import type { SetupInputs } from "../options.js";
|
|
@@ -25,5 +28,5 @@ export interface EstablishConnectionArgs {
|
|
|
25
28
|
authEnabled: boolean;
|
|
26
29
|
inputs: SetupInputs;
|
|
27
30
|
}
|
|
28
|
-
export declare function establishConnection(deps: Pick<SetupDeps, "context" | "createClient" | "prompter">, { endpoint, authEnabled, inputs }: EstablishConnectionArgs): Promise<Connection>;
|
|
31
|
+
export declare function establishConnection(deps: Pick<SetupDeps, "context" | "createClient" | "prompter" | "oauthLogin">, { endpoint, authEnabled, inputs }: EstablishConnectionArgs): Promise<Connection>;
|
|
29
32
|
//# sourceMappingURL=establishConnection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"establishConnection.d.ts","sourceRoot":"","sources":["../../../src/setup/steps/establishConnection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"establishConnection.d.ts","sourceRoot":"","sources":["../../../src/setup/steps/establishConnection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,MAAM,WAAW,UAAU;IACzB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAQD,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMrE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGtD;AA6QD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC,EAC7E,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,uBAAuB,GACzD,OAAO,CAAC,UAAU,CAAC,CAgBrB"}
|
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
* first ingestion, so setup only needs to settle on a *name* and hand it
|
|
6
6
|
* to the app via `PHOENIX_PROJECT_NAME`. What remains is credential
|
|
7
7
|
* acquisition: the auth-on lanes verify the key with a read-only probe so a
|
|
8
|
-
* bad paste is caught here rather than at first trace.
|
|
9
|
-
*
|
|
8
|
+
* bad paste is caught here rather than at first trace. When the instance runs
|
|
9
|
+
* the OAuth2 authorization server, the interactive lane offers a streamlined
|
|
10
|
+
* path first — log in with the browser, mint an API key over REST, revoke the
|
|
11
|
+
* grant that login created — and every failure along it falls back to the
|
|
12
|
+
* paste prompt rather than aborting setup.
|
|
10
13
|
*/
|
|
11
14
|
import * as path from "node:path";
|
|
12
15
|
import { HttpError } from "@arizeai/phoenix-client";
|
|
@@ -38,6 +41,18 @@ async function promptForProjectName(deps, inputs) {
|
|
|
38
41
|
}));
|
|
39
42
|
return name.trim();
|
|
40
43
|
}
|
|
44
|
+
/** A REST failure, as a short phrase to show the user. */
|
|
45
|
+
function describeRestError(error) {
|
|
46
|
+
if (error instanceof HttpError) {
|
|
47
|
+
return `HTTP ${error.status}`;
|
|
48
|
+
}
|
|
49
|
+
// A 2xx whose body will not parse: something answered, but not the Phoenix
|
|
50
|
+
// API. The raw parser message would only confuse.
|
|
51
|
+
if (error instanceof SyntaxError) {
|
|
52
|
+
return COPY.ENDPOINT.unexpectedBody;
|
|
53
|
+
}
|
|
54
|
+
return redactForDisplay(String(error));
|
|
55
|
+
}
|
|
41
56
|
/**
|
|
42
57
|
* Read-only probe: list one project. Only the credential matters here — an
|
|
43
58
|
* instance with no projects yet still answers 200.
|
|
@@ -52,13 +67,11 @@ async function checkApiKey(deps, endpoint, apiKey) {
|
|
|
52
67
|
return { kind: "ok" };
|
|
53
68
|
}
|
|
54
69
|
catch (error) {
|
|
55
|
-
if (error instanceof HttpError
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
return { kind: "error", detail: `HTTP ${error.status}` };
|
|
70
|
+
if (error instanceof HttpError &&
|
|
71
|
+
(error.status === 401 || error.status === 403)) {
|
|
72
|
+
return { kind: "rejected", status: error.status };
|
|
60
73
|
}
|
|
61
|
-
return { kind: "error", detail:
|
|
74
|
+
return { kind: "error", detail: describeRestError(error) };
|
|
62
75
|
}
|
|
63
76
|
}
|
|
64
77
|
// ---------------------------------------------------------------------------
|
|
@@ -78,13 +91,109 @@ async function promptForApiKey(deps) {
|
|
|
78
91
|
return apiKey.trim();
|
|
79
92
|
}
|
|
80
93
|
/**
|
|
81
|
-
*
|
|
82
|
-
* the
|
|
94
|
+
* Log in via the browser, then mint a personal API key over REST. Every
|
|
95
|
+
* failure returns `undefined` after narrating why, sending the lane to the
|
|
96
|
+
* paste prompt — the login is a shortcut, never a wall.
|
|
97
|
+
*/
|
|
98
|
+
async function acquireApiKeyViaLogin(deps, endpoint, projectName) {
|
|
99
|
+
// Ctrl-C here means "give up on the browser", not "abandon setup" — the
|
|
100
|
+
// paste prompt below is still a way forward, and the project name the user
|
|
101
|
+
// already gave is still good.
|
|
102
|
+
const outcome = await deps.prompter.runInterruptible((signal) => deps.oauthLogin.login({
|
|
103
|
+
endpoint,
|
|
104
|
+
onAuthorizationUrl: (url) => deps.prompter.note(COPY.CREDENTIALS.authorizationUrl(url)),
|
|
105
|
+
onBrowserOpenFailed: (detail) => deps.prompter.line(COPY.CREDENTIALS.browserOpenFailed(redactForDisplay(detail))),
|
|
106
|
+
signal,
|
|
107
|
+
}));
|
|
108
|
+
if (outcome.status === "cancelled") {
|
|
109
|
+
deps.prompter.line(COPY.CREDENTIALS.loginCancelled);
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
if (outcome.status === "error") {
|
|
113
|
+
deps.prompter.line(COPY.CREDENTIALS.loginFailed(redactForDisplay(outcome.detail)));
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const client = deps.createClient({
|
|
118
|
+
endpoint,
|
|
119
|
+
apiKey: outcome.accessToken,
|
|
120
|
+
});
|
|
121
|
+
const name = `px-setup ${projectName}`;
|
|
122
|
+
const response = await client.POST("/v1/user/api_keys", {
|
|
123
|
+
body: {
|
|
124
|
+
data: {
|
|
125
|
+
name,
|
|
126
|
+
description: `Created by px setup for project "${projectName}".`,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
signal: AbortSignal.timeout(REST_TIMEOUT_MS),
|
|
130
|
+
});
|
|
131
|
+
const key = response.data?.data.key;
|
|
132
|
+
if (!key) {
|
|
133
|
+
deps.prompter.line(COPY.CREDENTIALS.keyCreateFailed("empty key in response"));
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
deps.prompter.line(COPY.CREDENTIALS.keyCreated(name));
|
|
137
|
+
return key;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
deps.prompter.line(COPY.CREDENTIALS.keyCreateFailed(describeRestError(error)));
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
// The access token has served its one purpose. Ending the grant leaves the
|
|
145
|
+
// key in local files as the only credential this run created — without it,
|
|
146
|
+
// a refresh token setup no longer holds stays live for its full lifetime
|
|
147
|
+
// (a week by default). This does not touch an existing `px auth login`.
|
|
148
|
+
await outcome.revoke().catch(() => { });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The project name comes first so the browser-login path can stamp it into
|
|
153
|
+
* the minted key's name. A rejected key returns to the masked credential
|
|
154
|
+
* prompt without asking for the project name again.
|
|
83
155
|
*/
|
|
84
156
|
async function connectAuthOnInteractive(deps, endpoint, inputs) {
|
|
157
|
+
// Start the probe before the prompt so it can run while the user types (when
|
|
158
|
+
// --project is given there is no prompt, and this is simply awaited below).
|
|
159
|
+
// The `catch` is not redundant: the contract returns Promise<boolean>, and an
|
|
160
|
+
// implementation that rejected would otherwise go unhandled on the path where
|
|
161
|
+
// the prompt throws SetupCancelledError before the await below is reached.
|
|
162
|
+
const supportsLogin = deps.oauthLogin
|
|
163
|
+
.isSupported(endpoint)
|
|
164
|
+
.catch(() => false);
|
|
165
|
+
const projectName = await promptForProjectName(deps, inputs);
|
|
166
|
+
if (await supportsLogin) {
|
|
167
|
+
const method = await deps.prompter.select({
|
|
168
|
+
message: COPY.CREDENTIALS.methodMessage,
|
|
169
|
+
options: [
|
|
170
|
+
{
|
|
171
|
+
value: "login",
|
|
172
|
+
label: COPY.CREDENTIALS.loginLabel,
|
|
173
|
+
hint: COPY.CREDENTIALS.loginHint,
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
value: "paste",
|
|
177
|
+
label: COPY.CREDENTIALS.pasteLabel,
|
|
178
|
+
hint: COPY.CREDENTIALS.pasteHint,
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
});
|
|
182
|
+
if (method === "login") {
|
|
183
|
+
const apiKey = await acquireApiKeyViaLogin(deps, endpoint, projectName);
|
|
184
|
+
if (apiKey !== undefined) {
|
|
185
|
+
// The key was just minted by an authenticated call to this same
|
|
186
|
+
// endpoint, so a probe could only re-prove what the mint proved. It
|
|
187
|
+
// could, however, fail transiently — and the ephemeral session is
|
|
188
|
+
// already revoked, so a throw here would strand a live key the user
|
|
189
|
+
// never received and cannot name.
|
|
190
|
+
deps.prompter.line(COPY.CONNECT.usingProject(projectName));
|
|
191
|
+
return { endpoint, projectName, apiKey };
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
85
195
|
deps.prompter.note(COPY.API_KEY.instructions, COPY.API_KEY.instructionsTitle);
|
|
86
196
|
let apiKey = await promptForApiKey(deps);
|
|
87
|
-
const projectName = await promptForProjectName(deps, inputs);
|
|
88
197
|
for (;;) {
|
|
89
198
|
const result = await checkApiKey(deps, endpoint, apiKey);
|
|
90
199
|
if (result.kind === "ok") {
|