@aligndottech/cli 0.50.0 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +33 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/connect-agents.d.ts.map +1 -1
- package/dist/commands/connect-agents.js +3 -1
- package/dist/commands/connect-agents.js.map +1 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +11 -0
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/invite.d.ts +8 -18
- package/dist/commands/invite.d.ts.map +1 -1
- package/dist/commands/invite.js +23 -46
- package/dist/commands/invite.js.map +1 -1
- package/dist/commands/join.d.ts +5 -0
- package/dist/commands/join.d.ts.map +1 -0
- package/dist/commands/join.js +49 -0
- package/dist/commands/join.js.map +1 -0
- package/dist/commands/local-relink.d.ts +35 -0
- package/dist/commands/local-relink.d.ts.map +1 -0
- package/dist/commands/local-relink.js +72 -0
- package/dist/commands/local-relink.js.map +1 -0
- package/dist/commands/local.d.ts.map +1 -1
- package/dist/commands/local.js +37 -0
- package/dist/commands/local.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +21 -2
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/mcp.d.ts +8 -0
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +12 -5
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +4 -0
- package/dist/commands/registry.js.map +1 -1
- package/dist/commands/share.d.ts.map +1 -1
- package/dist/commands/share.js +81 -12
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +10 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/detector/detector-version.d.ts +16 -0
- package/dist/detector/detector-version.d.ts.map +1 -0
- package/dist/detector/detector-version.js +36 -0
- package/dist/detector/detector-version.js.map +1 -0
- package/dist/detector/relationship-contract.d.ts +30 -0
- package/dist/detector/relationship-contract.d.ts.map +1 -0
- package/dist/detector/relationship-contract.js +120 -0
- package/dist/detector/relationship-contract.js.map +1 -0
- package/dist/detector/relationship-contract.v1.json +53 -0
- package/dist/detector/relationship-prompt.d.ts +20 -0
- package/dist/detector/relationship-prompt.d.ts.map +1 -0
- package/dist/detector/relationship-prompt.js +55 -0
- package/dist/detector/relationship-prompt.js.map +1 -0
- package/dist/detector/relationship-prompt.v1.json +13 -0
- package/dist/detector/resolve-pair.d.ts +39 -0
- package/dist/detector/resolve-pair.d.ts.map +1 -0
- package/dist/detector/resolve-pair.js +345 -0
- package/dist/detector/resolve-pair.js.map +1 -0
- package/dist/detector/similar-item.d.ts +20 -0
- package/dist/detector/similar-item.d.ts.map +1 -0
- package/dist/detector/similar-item.js +16 -0
- package/dist/detector/similar-item.js.map +1 -0
- package/dist/index.js +37 -13
- package/dist/index.js.map +1 -1
- package/dist/lib/advisory-dedup.d.ts.map +1 -1
- package/dist/lib/advisory-dedup.js +16 -8
- package/dist/lib/advisory-dedup.js.map +1 -1
- package/dist/lib/advisory-verdict.d.ts +19 -0
- package/dist/lib/advisory-verdict.d.ts.map +1 -1
- package/dist/lib/advisory-verdict.js +6 -3
- package/dist/lib/advisory-verdict.js.map +1 -1
- package/dist/lib/backup-exclusion.d.ts +10 -0
- package/dist/lib/backup-exclusion.d.ts.map +1 -0
- package/dist/lib/backup-exclusion.js +58 -0
- package/dist/lib/backup-exclusion.js.map +1 -0
- package/dist/lib/cli-oauth.d.ts +2 -0
- package/dist/lib/cli-oauth.d.ts.map +1 -1
- package/dist/lib/cli-oauth.js +61 -10
- package/dist/lib/cli-oauth.js.map +1 -1
- package/dist/lib/config.d.ts +41 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +109 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/curation/guardrail.d.ts.map +1 -1
- package/dist/lib/curation/guardrail.js +2 -0
- package/dist/lib/curation/guardrail.js.map +1 -1
- package/dist/lib/curation/judgements-db.d.ts +1 -0
- package/dist/lib/curation/judgements-db.d.ts.map +1 -1
- package/dist/lib/curation/judgements-db.js +9 -3
- package/dist/lib/curation/judgements-db.js.map +1 -1
- package/dist/lib/curation/mark.js +4 -2
- package/dist/lib/curation/mark.js.map +1 -1
- package/dist/lib/destination-name.d.ts +24 -0
- package/dist/lib/destination-name.d.ts.map +1 -0
- package/dist/lib/destination-name.js +39 -0
- package/dist/lib/destination-name.js.map +1 -0
- package/dist/lib/destination-summary.d.ts +6 -0
- package/dist/lib/destination-summary.d.ts.map +1 -0
- package/dist/lib/destination-summary.js +27 -0
- package/dist/lib/destination-summary.js.map +1 -0
- package/dist/lib/destination-trust.d.ts +54 -0
- package/dist/lib/destination-trust.d.ts.map +1 -0
- package/dist/lib/destination-trust.js +107 -0
- package/dist/lib/destination-trust.js.map +1 -0
- package/dist/lib/env-resolver.d.ts.map +1 -1
- package/dist/lib/env-resolver.js +3 -0
- package/dist/lib/env-resolver.js.map +1 -1
- package/dist/lib/fatal.d.ts +11 -0
- package/dist/lib/fatal.d.ts.map +1 -0
- package/dist/lib/fatal.js +22 -0
- package/dist/lib/fatal.js.map +1 -0
- package/dist/lib/gateway-client.d.ts +8 -16
- package/dist/lib/gateway-client.d.ts.map +1 -1
- package/dist/lib/gateway-client.js +30 -20
- package/dist/lib/gateway-client.js.map +1 -1
- package/dist/lib/invite-prompt.d.ts +4 -4
- package/dist/lib/invite-prompt.d.ts.map +1 -1
- package/dist/lib/invite-prompt.js +4 -4
- package/dist/lib/invite-prompt.js.map +1 -1
- package/dist/lib/invite-settings.d.ts +18 -0
- package/dist/lib/invite-settings.d.ts.map +1 -0
- package/dist/lib/invite-settings.js +29 -0
- package/dist/lib/invite-settings.js.map +1 -0
- package/dist/lib/join-flow.d.ts +60 -0
- package/dist/lib/join-flow.d.ts.map +1 -0
- package/dist/lib/join-flow.js +282 -0
- package/dist/lib/join-flow.js.map +1 -0
- package/dist/lib/launch/mcp-child-env.d.ts.map +1 -1
- package/dist/lib/launch/mcp-child-env.js +5 -2
- package/dist/lib/launch/mcp-child-env.js.map +1 -1
- package/dist/lib/lead-prompt.d.ts +106 -0
- package/dist/lib/lead-prompt.d.ts.map +1 -0
- package/dist/lib/lead-prompt.js +175 -0
- package/dist/lib/lead-prompt.js.map +1 -0
- package/dist/lib/local-candidate-classify.d.ts +26 -0
- package/dist/lib/local-candidate-classify.d.ts.map +1 -0
- package/dist/lib/local-candidate-classify.js +53 -0
- package/dist/lib/local-candidate-classify.js.map +1 -0
- package/dist/lib/local-db-migrate.d.ts +1 -1
- package/dist/lib/local-db-migrate.d.ts.map +1 -1
- package/dist/lib/local-db-migrate.js +45 -1
- package/dist/lib/local-db-migrate.js.map +1 -1
- package/dist/lib/local-db-v12.d.ts +17 -0
- package/dist/lib/local-db-v12.d.ts.map +1 -0
- package/dist/lib/local-db-v12.js +8 -0
- package/dist/lib/local-db-v12.js.map +1 -0
- package/dist/lib/local-db.d.ts +13 -13
- package/dist/lib/local-db.d.ts.map +1 -1
- package/dist/lib/local-db.js +41 -6
- package/dist/lib/local-db.js.map +1 -1
- package/dist/lib/local-gateway-client.d.ts +1 -0
- package/dist/lib/local-gateway-client.d.ts.map +1 -1
- package/dist/lib/local-gateway-client.js +31 -20
- package/dist/lib/local-gateway-client.js.map +1 -1
- package/dist/lib/local-ingest.d.ts +2 -0
- package/dist/lib/local-ingest.d.ts.map +1 -1
- package/dist/lib/local-ingest.js.map +1 -1
- package/dist/lib/local-link-pass.d.ts.map +1 -1
- package/dist/lib/local-link-pass.js +25 -29
- package/dist/lib/local-link-pass.js.map +1 -1
- package/dist/lib/local-llm.d.ts +1 -1
- package/dist/lib/local-llm.d.ts.map +1 -1
- package/dist/lib/local-llm.js +3 -2
- package/dist/lib/local-llm.js.map +1 -1
- package/dist/lib/local-mode.d.ts +5 -1
- package/dist/lib/local-mode.d.ts.map +1 -1
- package/dist/lib/local-mode.js +11 -6
- package/dist/lib/local-mode.js.map +1 -1
- package/dist/lib/local-relationship-classifier.d.ts +4 -0
- package/dist/lib/local-relationship-classifier.d.ts.map +1 -1
- package/dist/lib/local-relationship-classifier.js +9 -4
- package/dist/lib/local-relationship-classifier.js.map +1 -1
- package/dist/lib/local-relink.d.ts +59 -0
- package/dist/lib/local-relink.d.ts.map +1 -0
- package/dist/lib/local-relink.js +171 -0
- package/dist/lib/local-relink.js.map +1 -0
- package/dist/lib/local-set-classifier.d.ts +36 -0
- package/dist/lib/local-set-classifier.d.ts.map +1 -0
- package/dist/lib/local-set-classifier.js +81 -0
- package/dist/lib/local-set-classifier.js.map +1 -0
- package/dist/lib/local-snapshot-loader.d.ts +29 -0
- package/dist/lib/local-snapshot-loader.d.ts.map +1 -0
- package/dist/lib/local-snapshot-loader.js +108 -0
- package/dist/lib/local-snapshot-loader.js.map +1 -0
- package/dist/lib/login-flow.d.ts +15 -0
- package/dist/lib/login-flow.d.ts.map +1 -1
- package/dist/lib/login-flow.js +80 -4
- package/dist/lib/login-flow.js.map +1 -1
- package/dist/lib/mcp/share-status-tool.d.ts +13 -0
- package/dist/lib/mcp/share-status-tool.d.ts.map +1 -0
- package/dist/lib/mcp/share-status-tool.js +116 -0
- package/dist/lib/mcp/share-status-tool.js.map +1 -0
- package/dist/lib/mcp/share-tool.d.ts +18 -14
- package/dist/lib/mcp/share-tool.d.ts.map +1 -1
- package/dist/lib/mcp/share-tool.js +127 -21
- package/dist/lib/mcp/share-tool.js.map +1 -1
- package/dist/lib/model-cache.d.ts +10 -0
- package/dist/lib/model-cache.d.ts.map +1 -0
- package/dist/lib/model-cache.js +35 -0
- package/dist/lib/model-cache.js.map +1 -0
- package/dist/lib/next-step.d.ts.map +1 -1
- package/dist/lib/next-step.js +2 -1
- package/dist/lib/next-step.js.map +1 -1
- package/dist/lib/private-files.d.ts +38 -0
- package/dist/lib/private-files.d.ts.map +1 -0
- package/dist/lib/private-files.js +102 -0
- package/dist/lib/private-files.js.map +1 -0
- package/dist/lib/redaction-notice.d.ts +7 -0
- package/dist/lib/redaction-notice.d.ts.map +1 -0
- package/dist/lib/redaction-notice.js +32 -0
- package/dist/lib/redaction-notice.js.map +1 -0
- package/dist/lib/relink-estimate.d.ts +16 -0
- package/dist/lib/relink-estimate.d.ts.map +1 -0
- package/dist/lib/relink-estimate.js +30 -0
- package/dist/lib/relink-estimate.js.map +1 -0
- package/dist/lib/resolve-env.d.ts +15 -1
- package/dist/lib/resolve-env.d.ts.map +1 -1
- package/dist/lib/resolve-env.js +27 -7
- package/dist/lib/resolve-env.js.map +1 -1
- package/dist/lib/scope-defaults.d.ts.map +1 -1
- package/dist/lib/scope-defaults.js +2 -0
- package/dist/lib/scope-defaults.js.map +1 -1
- package/dist/lib/scope-real.d.ts +57 -0
- package/dist/lib/scope-real.d.ts.map +1 -1
- package/dist/lib/setup-route.d.ts +4 -2
- package/dist/lib/setup-route.d.ts.map +1 -1
- package/dist/lib/setup-route.js +12 -6
- package/dist/lib/setup-route.js.map +1 -1
- package/dist/lib/share/approval.d.ts +71 -0
- package/dist/lib/share/approval.d.ts.map +1 -0
- package/dist/lib/share/approval.js +139 -0
- package/dist/lib/share/approval.js.map +1 -0
- package/dist/lib/share/approve-link.d.ts +31 -0
- package/dist/lib/share/approve-link.d.ts.map +1 -0
- package/dist/lib/share/approve-link.js +46 -0
- package/dist/lib/share/approve-link.js.map +1 -0
- package/dist/lib/share/browser-flow.d.ts +85 -0
- package/dist/lib/share/browser-flow.d.ts.map +1 -0
- package/dist/lib/share/browser-flow.js +168 -0
- package/dist/lib/share/browser-flow.js.map +1 -0
- package/dist/lib/share/command.d.ts +34 -1
- package/dist/lib/share/command.d.ts.map +1 -1
- package/dist/lib/share/command.js +153 -11
- package/dist/lib/share/command.js.map +1 -1
- package/dist/lib/share/delivery-options.d.ts +15 -0
- package/dist/lib/share/delivery-options.d.ts.map +1 -0
- package/dist/lib/share/delivery-options.js +16 -0
- package/dist/lib/share/delivery-options.js.map +1 -0
- package/dist/lib/share/delivery.d.ts +83 -0
- package/dist/lib/share/delivery.d.ts.map +1 -0
- package/dist/lib/share/delivery.js +134 -0
- package/dist/lib/share/delivery.js.map +1 -0
- package/dist/lib/share/envelope.d.ts +61 -0
- package/dist/lib/share/envelope.d.ts.map +1 -0
- package/dist/lib/share/envelope.js +99 -0
- package/dist/lib/share/envelope.js.map +1 -0
- package/dist/lib/share/ledger.d.ts.map +1 -1
- package/dist/lib/share/ledger.js +3 -1
- package/dist/lib/share/ledger.js.map +1 -1
- package/dist/lib/share/payload.d.ts +9 -0
- package/dist/lib/share/payload.d.ts.map +1 -1
- package/dist/lib/share/payload.js +9 -0
- package/dist/lib/share/payload.js.map +1 -1
- package/dist/lib/share/pending.d.ts +47 -1
- package/dist/lib/share/pending.d.ts.map +1 -1
- package/dist/lib/share/pending.js +139 -13
- package/dist/lib/share/pending.js.map +1 -1
- package/dist/lib/share/preview.d.ts +5 -1
- package/dist/lib/share/preview.d.ts.map +1 -1
- package/dist/lib/share/preview.js +3 -1
- package/dist/lib/share/preview.js.map +1 -1
- package/dist/lib/share/qr.d.ts +13 -0
- package/dist/lib/share/qr.d.ts.map +1 -0
- package/dist/lib/share/qr.js +77 -0
- package/dist/lib/share/qr.js.map +1 -0
- package/dist/lib/share/requests-client.d.ts +63 -0
- package/dist/lib/share/requests-client.d.ts.map +1 -0
- package/dist/lib/share/requests-client.js +69 -0
- package/dist/lib/share/requests-client.js.map +1 -0
- package/dist/lib/share/run.d.ts +20 -1
- package/dist/lib/share/run.d.ts.map +1 -1
- package/dist/lib/share/run.js +27 -10
- package/dist/lib/share/run.js.map +1 -1
- package/dist/lib/share/secret-scan.d.ts +5 -0
- package/dist/lib/share/secret-scan.d.ts.map +1 -1
- package/dist/lib/share/secret-scan.js +43 -2
- package/dist/lib/share/secret-scan.js.map +1 -1
- package/dist/lib/share/target.d.ts +38 -0
- package/dist/lib/share/target.d.ts.map +1 -0
- package/dist/lib/share/target.js +80 -0
- package/dist/lib/share/target.js.map +1 -0
- package/dist/lib/share/tty.d.ts +8 -0
- package/dist/lib/share/tty.d.ts.map +1 -1
- package/dist/lib/share/tty.js +45 -0
- package/dist/lib/share/tty.js.map +1 -1
- package/dist/lib/source-sync-state.d.ts.map +1 -1
- package/dist/lib/source-sync-state.js +2 -0
- package/dist/lib/source-sync-state.js.map +1 -1
- package/dist/lib/sync/blocked.d.ts.map +1 -1
- package/dist/lib/sync/blocked.js +2 -1
- package/dist/lib/sync/blocked.js.map +1 -1
- package/dist/lib/sync/classify.d.ts.map +1 -1
- package/dist/lib/sync/classify.js +2 -0
- package/dist/lib/sync/classify.js.map +1 -1
- package/dist/lib/sync/real-env.d.ts +57 -0
- package/dist/lib/sync/real-env.d.ts.map +1 -1
- package/dist/lib/sync/sync-state.d.ts.map +1 -1
- package/dist/lib/sync/sync-state.js +3 -1
- package/dist/lib/sync/sync-state.js.map +1 -1
- package/dist/lib/usage-telemetry.d.ts +2 -2
- package/dist/lib/usage-telemetry.d.ts.map +1 -1
- package/dist/lib/usage-telemetry.js +21 -3
- package/dist/lib/usage-telemetry.js.map +1 -1
- package/package.json +4 -2
- package/dist/lib/personal-email-domains.d.ts +0 -8
- package/dist/lib/personal-email-domains.d.ts.map +0 -1
- package/dist/lib/personal-email-domains.js +0 -39
- package/dist/lib/personal-email-domains.js.map +0 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `align join <link>`: save a team's server as a named destination, additively.
|
|
3
|
+
*
|
|
4
|
+
* The link is a claim, not an instruction. Everything that decides where a credential goes is
|
|
5
|
+
* checked against the gateway's own answer BEFORE a browser opens, and the person confirms the
|
|
6
|
+
* host when it is not Align's. Nothing already saved is moved, archived or expired: the new token
|
|
7
|
+
* is minted by the server for this machine only, verified with one request, and only then stored.
|
|
8
|
+
* Join plan: thoughts/shared/plans/2026-10-10-org-invite-join-destination.md (attacks S1-S10).
|
|
9
|
+
*/
|
|
10
|
+
import type { CallbackResult } from './cli-oauth.js';
|
|
11
|
+
import type { createConfigStore } from './config.js';
|
|
12
|
+
type ConfigStore = ReturnType<typeof createConfigStore>;
|
|
13
|
+
export interface JoinDeps {
|
|
14
|
+
config: Pick<ConfigStore, 'hasTeamDestination' | 'saveTeamDestination' | 'getShareDestination' | 'setShareDestination' | 'getEnvironment'>;
|
|
15
|
+
/** stdin AND stdout are terminals. Joining is a person's act: it never runs without one. */
|
|
16
|
+
isTTY: boolean;
|
|
17
|
+
/** Inside an agent align launched (ALIGN_WRAPPED). Such a process is not the person, so it cannot join. */
|
|
18
|
+
wrapped: boolean;
|
|
19
|
+
out(line: string): void;
|
|
20
|
+
openUrl(url: string): Promise<boolean>;
|
|
21
|
+
/** One line typed by the person, or null if they cancelled. Only called on a terminal. */
|
|
22
|
+
promptLine(question: string): Promise<string | null>;
|
|
23
|
+
confirm(question: string): Promise<boolean>;
|
|
24
|
+
waitForCallback(opts: {
|
|
25
|
+
ports: number[];
|
|
26
|
+
timeoutMs: number;
|
|
27
|
+
onBound?: (port: number, nonce: string) => void | Promise<void>;
|
|
28
|
+
}): Promise<CallbackResult>;
|
|
29
|
+
now(): Date;
|
|
30
|
+
callbackPorts: number[];
|
|
31
|
+
timeoutMs: number;
|
|
32
|
+
}
|
|
33
|
+
export interface JoinInput {
|
|
34
|
+
link: string;
|
|
35
|
+
gateway?: string;
|
|
36
|
+
name?: string;
|
|
37
|
+
replace?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export type JoinResult = {
|
|
40
|
+
ok: true;
|
|
41
|
+
name: string;
|
|
42
|
+
expiresAt?: string;
|
|
43
|
+
} | {
|
|
44
|
+
ok: false;
|
|
45
|
+
reason: string;
|
|
46
|
+
};
|
|
47
|
+
export declare function runJoin(deps: JoinDeps, input: JoinInput): Promise<JoinResult>;
|
|
48
|
+
export interface VerifiedIdentity {
|
|
49
|
+
email: string;
|
|
50
|
+
tenantId: string;
|
|
51
|
+
tenantName: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* "Verified" means the gateway answered /auth/me like an Align gateway would, with this token and no other, not that it said 2xx.
|
|
55
|
+
* Every field that is saved or printed is checked for type and shape first, so a hostile server cannot save an object as a tenant
|
|
56
|
+
* id or put escape sequences on the person's screen. Anything else is a string saying why, and nothing is saved.
|
|
57
|
+
*/
|
|
58
|
+
export declare function verifyToken(gatewayUrl: string, token: string): Promise<VerifiedIdentity | string>;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=join-flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"join-flow.d.ts","sourceRoot":"","sources":["../../src/lib/join-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKrD,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAExD,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,oBAAoB,GAAG,qBAAqB,GAAG,qBAAqB,GAAG,qBAAqB,GAAG,gBAAgB,CAAC,CAAC;IAC3I,4FAA4F;IAC5F,KAAK,EAAE,OAAO,CAAC;IACf,2GAA2G;IAC3G,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,0FAA0F;IAC1F,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACrD,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,eAAe,CAAC,IAAI,EAAE;QACpB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACjE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC5B,GAAG,IAAI,IAAI,CAAC;IACZ,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,UAAU,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAUxG,wBAAsB,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CA6GnF;AAwGD,MAAM,WAAW,gBAAgB;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE;AAKzF;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,MAAM,CAAC,CAevG"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { createGatewayClient } from './gateway-client.js';
|
|
2
|
+
import { validateDestinationName } from './destination-name.js';
|
|
3
|
+
import { assertTransport, describeHost, needsTypeBack, parseJoinLink, slugOrgName, TransportError } from './destination-trust.js';
|
|
4
|
+
import { visible } from './share/visible.js';
|
|
5
|
+
const PEEK_MAX_BYTES = 16 * 1024;
|
|
6
|
+
const ORG_NOTE = 'chosen by that organisation, not verified by Align';
|
|
7
|
+
const PEEK_TIMEOUT_MS = 10_000;
|
|
8
|
+
const ORG_NAME_MAX = 100;
|
|
9
|
+
const TOKEN_SHAPE = /^[\x21-\x7e]{8,512}$/;
|
|
10
|
+
export async function runJoin(deps, input) {
|
|
11
|
+
const refuse = (reason) => {
|
|
12
|
+
deps.out(`\nNothing was saved and no browser was opened.\n ${reason}\n`);
|
|
13
|
+
return { ok: false, reason };
|
|
14
|
+
};
|
|
15
|
+
// After the browser step: a browser WAS opened, and if the server already issued a token it is still live there. Say both.
|
|
16
|
+
const refuseLate = (reason, issued) => {
|
|
17
|
+
const live = issued
|
|
18
|
+
? `\n ${issued.host} issued a token to this computer and it was not saved. It stays valid until ${issued.expiresAt ? issued.expiresAt.slice(0, 10) : 'it expires'} (or until the organisation's admin revokes the invite); nothing here can revoke it.`
|
|
19
|
+
: '';
|
|
20
|
+
deps.out(`\nNothing was saved. A browser was opened.\n ${reason}${live}\n`);
|
|
21
|
+
return { ok: false, reason };
|
|
22
|
+
};
|
|
23
|
+
// First, before any request: a join gives a server a credential and a place to send shares, so it is a person's act, at a
|
|
24
|
+
// terminal of their own. An agent (or a script) that has been handed a link must not be able to finish it, whichever host
|
|
25
|
+
// the link names, and the refusal says nothing about a way around it.
|
|
26
|
+
if (deps.wrapped)
|
|
27
|
+
return refuse('align join has to be run by you, in your own terminal, not from inside an agent.');
|
|
28
|
+
if (!deps.isTTY)
|
|
29
|
+
return refuse('align join needs a terminal: both input and output must be a terminal, so a person answers the questions.');
|
|
30
|
+
let link;
|
|
31
|
+
try {
|
|
32
|
+
link = parseJoinLink(input.link, input.gateway === undefined ? {} : { gateway: input.gateway });
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
return refuse(e instanceof TransportError ? e.message : 'That link could not be read.');
|
|
36
|
+
}
|
|
37
|
+
const gwHost = new URL(link.gatewayUrl).host;
|
|
38
|
+
if (input.name !== undefined) {
|
|
39
|
+
const bad = validateDestinationName(input.name);
|
|
40
|
+
if (bad)
|
|
41
|
+
return refuse(`The name "${visible(input.name.slice(0, 40))}" cannot be used: ${bad}.`);
|
|
42
|
+
}
|
|
43
|
+
const peeked = await peek(link.gatewayUrl, link.token);
|
|
44
|
+
if (typeof peeked === 'string')
|
|
45
|
+
return refuse(peeked);
|
|
46
|
+
// The gateway's own account of itself has to match the link, or the link is lying about one of them.
|
|
47
|
+
let peekApp;
|
|
48
|
+
try {
|
|
49
|
+
peekApp = assertTransport(peeked.appUrl);
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
return refuse(`The server's web app address is not acceptable: ${e.message}`);
|
|
53
|
+
}
|
|
54
|
+
const peekAppHost = new URL(peekApp).host;
|
|
55
|
+
if (peekAppHost !== link.appHost) {
|
|
56
|
+
return refuse(`The link points at the web app ${link.appHost}, but ${gwHost} says its web app is ${peekAppHost}. Both are shown so you can see which to trust; neither was used.`);
|
|
57
|
+
}
|
|
58
|
+
if (peeked.gatewayClaim !== undefined && peeked.gatewayClaim !== link.gatewayUrl) {
|
|
59
|
+
return refuse(`The link names the server ${gwHost}, but that server says it is ${new URL(peeked.gatewayClaim).host}. Neither was used.`);
|
|
60
|
+
}
|
|
61
|
+
// A gateway that wrote gw= into the link also reports its own address when asked. An answer with none, to a link that carried one, is not that gateway.
|
|
62
|
+
if (peeked.gatewayClaim === undefined && link.gatewayFromLink) {
|
|
63
|
+
return refuse(`The link names the server ${gwHost}, but that server did not say it is the one that made the link. Ask for a new link.`);
|
|
64
|
+
}
|
|
65
|
+
const claimed = visible(peeked.orgName).slice(0, ORG_NAME_MAX);
|
|
66
|
+
const gwShown = describeHost(gwHost);
|
|
67
|
+
const appShown = describeHost(peekAppHost);
|
|
68
|
+
deps.out('\nJoining a team graph');
|
|
69
|
+
deps.out(` Gateway: ${gwShown.text}`);
|
|
70
|
+
deps.out(` Web app: ${appShown.text}`);
|
|
71
|
+
deps.out(` Org: "${claimed || '(no name given)'}" (${ORG_NOTE})`);
|
|
72
|
+
for (const w of new Set([gwShown.warning, appShown.warning]))
|
|
73
|
+
if (w)
|
|
74
|
+
deps.out(` Warning: ${w}`);
|
|
75
|
+
const hostTyped = { done: false };
|
|
76
|
+
if (needsTypeBack(gwHost, peekAppHost)) {
|
|
77
|
+
const typed = await typeBack(deps, gwHost);
|
|
78
|
+
if (typed === null || typed.trim().toLowerCase() !== gwHost)
|
|
79
|
+
return refuse(`That is not ${gwHost}, so nothing was done.`);
|
|
80
|
+
hostTyped.done = true;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// An Align address does not make the org name Align's: any hosted org picks its own name and can issue invites.
|
|
84
|
+
const yes = await deps.promptLine(`Join "${claimed}" at ${gwHost}? The name is ${ORG_NOTE}. Type y to continue: `);
|
|
85
|
+
if (yes === null || !/^y(es)?$/i.test(yes.trim()))
|
|
86
|
+
return refuse('You did not answer y, so nothing was done.');
|
|
87
|
+
}
|
|
88
|
+
const derived = input.name ?? slugOrgName(claimed);
|
|
89
|
+
if (!derived)
|
|
90
|
+
return refuse('Could not make a name from the org name. Choose one with --name <name>.');
|
|
91
|
+
const name = derived;
|
|
92
|
+
if (deps.config.hasTeamDestination(name)) {
|
|
93
|
+
if (!input.replace)
|
|
94
|
+
return refuse(`You already have a destination called "${name}". Use --replace to replace it, or --name <other> to keep both.`);
|
|
95
|
+
const refusal = await confirmReplace(deps, name, gwHost, claimed, hostTyped.done);
|
|
96
|
+
if (refusal)
|
|
97
|
+
return refuse(refusal);
|
|
98
|
+
}
|
|
99
|
+
const received = await receive(deps, link.token, peekApp, link.gatewayUrl);
|
|
100
|
+
if (typeof received === 'string')
|
|
101
|
+
return refuseLate(received);
|
|
102
|
+
const me = await verifyToken(link.gatewayUrl, received.token);
|
|
103
|
+
if (typeof me === 'string')
|
|
104
|
+
return refuseLate(`${gwHost} ${me}`, { host: gwHost, ...(received.expiresAt ? { expiresAt: received.expiresAt } : {}) });
|
|
105
|
+
const tenantName = visible(me.tenantName).slice(0, ORG_NAME_MAX);
|
|
106
|
+
if (tenantName.trim() !== claimed.trim()) {
|
|
107
|
+
deps.out(`\n Heads up: the invite said "${claimed}" but you are signed in to "${tenantName}". Both come from ${gwHost}, so neither proves who runs it.`);
|
|
108
|
+
}
|
|
109
|
+
deps.config.saveTeamDestination(name, {
|
|
110
|
+
gatewayUrl: link.gatewayUrl,
|
|
111
|
+
appUrl: peekApp,
|
|
112
|
+
authToken: received.token,
|
|
113
|
+
tenantId: me.tenantId,
|
|
114
|
+
orgNameClaimed: claimed,
|
|
115
|
+
}, deps.now());
|
|
116
|
+
await chooseShareDestination(deps, name, claimed, gwHost);
|
|
117
|
+
deps.out(`\nJoined as "${name}" (${visible(me.email)}, ${tenantName}).`);
|
|
118
|
+
if (received.expiresAt)
|
|
119
|
+
deps.out(` This access expires on ${received.expiresAt.slice(0, 10)}. Renew it with: align login --env ${name}`);
|
|
120
|
+
deps.out(` Use it with: align <command> --env ${name}`);
|
|
121
|
+
return received.expiresAt ? { ok: true, name, expiresAt: received.expiresAt } : { ok: true, name };
|
|
122
|
+
}
|
|
123
|
+
/** Replacing a destination points a saved name at a server a person has not used under that name. Never silent. */
|
|
124
|
+
async function confirmReplace(deps, name, newHost, claimed, hostAlreadyTyped) {
|
|
125
|
+
let oldHost = '(unknown)';
|
|
126
|
+
try {
|
|
127
|
+
oldHost = new URL(deps.config.getEnvironment(name).gatewayUrl).host;
|
|
128
|
+
}
|
|
129
|
+
catch { /* unreadable entry: shown as unknown */ }
|
|
130
|
+
deps.out(`\n Replacing "${name}": ${describeHost(oldHost).text} -> ${describeHost(newHost).text}`);
|
|
131
|
+
if (!hostAlreadyTyped) {
|
|
132
|
+
const typed = await deps.promptLine('Type the new gateway host to confirm the replacement: ');
|
|
133
|
+
if (typed === null || typed.trim().toLowerCase() !== newHost)
|
|
134
|
+
return `That is not ${newHost}, so "${name}" was not replaced.`;
|
|
135
|
+
}
|
|
136
|
+
if (deps.config.getShareDestination() === name) {
|
|
137
|
+
const ok = await deps.confirm(`"${name}" is where "align share" sends decisions. Send them to "${claimed}" at ${newHost} instead?`);
|
|
138
|
+
if (!ok)
|
|
139
|
+
return `"${name}" was not replaced: it is where your shares go, and you did not agree to move them.`;
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
async function typeBack(deps, gwHost) {
|
|
144
|
+
deps.out(`\n ${gwHost} is not an Align address. If you did not expect this link, stop here.`);
|
|
145
|
+
return deps.promptLine('Type the gateway host to confirm: ');
|
|
146
|
+
}
|
|
147
|
+
/** Reads at most `max` bytes, and stops reading (cancels the stream) the moment it would pass that. Null when the body is too big. */
|
|
148
|
+
async function readCapped(res, max) {
|
|
149
|
+
const reader = res.body?.getReader();
|
|
150
|
+
if (!reader)
|
|
151
|
+
return '';
|
|
152
|
+
const parts = [];
|
|
153
|
+
let total = 0;
|
|
154
|
+
for (;;) {
|
|
155
|
+
const { done, value } = await reader.read();
|
|
156
|
+
if (done)
|
|
157
|
+
break;
|
|
158
|
+
total += value.byteLength;
|
|
159
|
+
if (total > max) {
|
|
160
|
+
await reader.cancel().catch(() => undefined);
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
parts.push(value);
|
|
164
|
+
}
|
|
165
|
+
return Buffer.concat(parts).toString('utf8');
|
|
166
|
+
}
|
|
167
|
+
async function peek(gatewayUrl, token) {
|
|
168
|
+
const host = new URL(gatewayUrl).host;
|
|
169
|
+
let res;
|
|
170
|
+
try {
|
|
171
|
+
res = await fetch(`${gatewayUrl}/auth/invite-peek?token=${encodeURIComponent(token)}`, {
|
|
172
|
+
headers: { accept: 'application/json' },
|
|
173
|
+
redirect: 'error',
|
|
174
|
+
signal: AbortSignal.timeout(PEEK_TIMEOUT_MS),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return `Could not reach ${host}.`;
|
|
179
|
+
}
|
|
180
|
+
if (res.status === 404)
|
|
181
|
+
return 'That invite was not found. It may have expired, been used, or been revoked. Ask for a new link.';
|
|
182
|
+
if (!res.ok)
|
|
183
|
+
return `${host} answered ${res.status} when asked about the invite.`;
|
|
184
|
+
let body;
|
|
185
|
+
try {
|
|
186
|
+
const text = await readCapped(res, PEEK_MAX_BYTES);
|
|
187
|
+
if (text === null)
|
|
188
|
+
return `${host} sent an unexpectedly large answer.`;
|
|
189
|
+
body = JSON.parse(text);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
return `${host} did not answer with an invite description.`;
|
|
193
|
+
}
|
|
194
|
+
const b = body;
|
|
195
|
+
if (typeof b !== 'object' || b === null)
|
|
196
|
+
return `${host} did not answer with an invite description.`;
|
|
197
|
+
if (typeof b.app_url !== 'string' || b.app_url === '') {
|
|
198
|
+
return `${host} did not say where its web app is. It may be too old to join from the CLI; ask its admin to update it.`;
|
|
199
|
+
}
|
|
200
|
+
let gatewayClaim;
|
|
201
|
+
if (b.gateway_url !== undefined) {
|
|
202
|
+
if (typeof b.gateway_url !== 'string')
|
|
203
|
+
return `${host} sent a malformed server address.`;
|
|
204
|
+
try {
|
|
205
|
+
gatewayClaim = assertTransport(b.gateway_url);
|
|
206
|
+
}
|
|
207
|
+
catch (e) {
|
|
208
|
+
return `The server address ${host} reports is not acceptable: ${e.message}`;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return { orgName: typeof b.org_name === 'string' ? b.org_name : '', appUrl: b.app_url, gatewayClaim };
|
|
212
|
+
}
|
|
213
|
+
async function receive(deps, token, appUrl, gatewayUrl) {
|
|
214
|
+
let result;
|
|
215
|
+
try {
|
|
216
|
+
result = await deps.waitForCallback({
|
|
217
|
+
ports: deps.callbackPorts,
|
|
218
|
+
timeoutMs: deps.timeoutMs,
|
|
219
|
+
onBound: async (port, nonce) => {
|
|
220
|
+
// cli_gw: the gateway THIS CLI validated. The web app is the one party that knows its own gateway, so it can refuse a
|
|
221
|
+
// link whose gw= was swapped for another server's, which no check on this side can tell from the real one.
|
|
222
|
+
const url = `${appUrl}/join?token=${token}&cli_port=${port}&cli_nonce=${nonce}&cli_gw=${encodeURIComponent(gatewayUrl)}`;
|
|
223
|
+
deps.out(`\nOpening your browser at:\n ${url}`);
|
|
224
|
+
if (!(await deps.openUrl(url)))
|
|
225
|
+
deps.out(' Could not open a browser here. Open that link yourself.');
|
|
226
|
+
deps.out('Waiting for you to approve in the browser (5 min)...');
|
|
227
|
+
},
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
catch (e) {
|
|
231
|
+
return `No approval arrived: ${e.message}.`;
|
|
232
|
+
}
|
|
233
|
+
const t = result.data['token'];
|
|
234
|
+
if (typeof t !== 'string' || !TOKEN_SHAPE.test(t))
|
|
235
|
+
return 'The browser sent back no usable token. Run the command again.';
|
|
236
|
+
const raw = result.data['expires_at'];
|
|
237
|
+
let expiresAt;
|
|
238
|
+
if (typeof raw === 'string' && !Number.isNaN(Date.parse(raw)))
|
|
239
|
+
expiresAt = new Date(raw).toISOString();
|
|
240
|
+
return expiresAt ? { token: t, expiresAt } : { token: t };
|
|
241
|
+
}
|
|
242
|
+
const ID_SHAPE = /^[\x21-\x7e]{1,128}$/;
|
|
243
|
+
const EMAIL_SHAPE = /^[^\s\p{C}]{3,254}$/u;
|
|
244
|
+
/**
|
|
245
|
+
* "Verified" means the gateway answered /auth/me like an Align gateway would, with this token and no other, not that it said 2xx.
|
|
246
|
+
* Every field that is saved or printed is checked for type and shape first, so a hostile server cannot save an object as a tenant
|
|
247
|
+
* id or put escape sequences on the person's screen. Anything else is a string saying why, and nothing is saved.
|
|
248
|
+
*/
|
|
249
|
+
export async function verifyToken(gatewayUrl, token) {
|
|
250
|
+
let raw;
|
|
251
|
+
try {
|
|
252
|
+
raw = await createGatewayClient({ gatewayUrl, authToken: token, tenantId: null, mode: 'auth' }).whoami();
|
|
253
|
+
}
|
|
254
|
+
catch (e) {
|
|
255
|
+
return `did not accept the new token (${visible(String(e.message).slice(0, 120))}).`;
|
|
256
|
+
}
|
|
257
|
+
const r = raw;
|
|
258
|
+
const email = r?.user?.email;
|
|
259
|
+
const id = r?.tenant?.id;
|
|
260
|
+
const name = r?.tenant?.name;
|
|
261
|
+
if (typeof email !== 'string' || !EMAIL_SHAPE.test(email) || typeof id !== 'string' || !ID_SHAPE.test(id) || typeof name !== 'string') {
|
|
262
|
+
return 'answered, but not the way an Align gateway answers who you are. The token was not saved.';
|
|
263
|
+
}
|
|
264
|
+
return { email, tenantId: id, tenantName: name };
|
|
265
|
+
}
|
|
266
|
+
async function chooseShareDestination(deps, name, claimed, gwHost) {
|
|
267
|
+
const current = deps.config.getShareDestination();
|
|
268
|
+
// Where shares go is a decision about where decisions are sent, so it is made by a yes at this terminal and never by default.
|
|
269
|
+
// (A replace of the share destination was already agreed to, and keeps pointing at the name it had.)
|
|
270
|
+
if (current !== name) {
|
|
271
|
+
const q = current === null
|
|
272
|
+
? `Send "align share" to "${claimed}" at ${gwHost} from now on?`
|
|
273
|
+
: `Send "align share" to "${claimed}" at ${gwHost} from now on? It currently goes to "${current}".`;
|
|
274
|
+
if (!(await deps.confirm(q))) {
|
|
275
|
+
deps.out(` "align share" ${current === null ? 'has no destination yet' : `still goes to "${current}"`}. Send one share to "${name}" with --to ${name}.`);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
deps.config.setShareDestination(name);
|
|
279
|
+
}
|
|
280
|
+
deps.out(` Shares from this machine now go to "${claimed}" at ${gwHost}.`);
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=join-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"join-flow.js","sourceRoot":"","sources":["../../src/lib/join-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-child-env.d.ts","sourceRoot":"","sources":["../../../src/lib/launch/mcp-child-env.ts"],"names":[],"mappings":"AA8CA,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAEvC,CAAC;AAET,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAEpC,CAAC;AAET;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"mcp-child-env.d.ts","sourceRoot":"","sources":["../../../src/lib/launch/mcp-child-env.ts"],"names":[],"mappings":"AA8CA,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAEvC,CAAC;AAET,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAEpC,CAAC;AAET;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAyBvD,CAAC;AAiBF,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CASxF;AAED,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI3F;AAaD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAQhK;AAED,2DAA2D;AAC3D,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAEvD"}
|
|
@@ -15,9 +15,9 @@ import { absoluteXdg, XDG_VARS } from '../xdg.js';
|
|
|
15
15
|
*/
|
|
16
16
|
/** Every ALIGN_* variable align reads from its environment (src/, outside tests). A parity test keeps this complete. */
|
|
17
17
|
const ALIGN_READS = [
|
|
18
|
-
'ALIGN_DEBUG', 'ALIGN_ENV', 'ALIGN_GATEWAY_URL', 'ALIGN_HEAD_SHA', 'ALIGN_INGEST_CONCURRENCY', 'ALIGN_INTERNAL',
|
|
18
|
+
'ALIGN_DEBUG', 'ALIGN_DETECTOR', 'ALIGN_ENV', 'ALIGN_GATEWAY_URL', 'ALIGN_HEAD_SHA', 'ALIGN_INGEST_CONCURRENCY', 'ALIGN_INTERNAL',
|
|
19
19
|
'ALIGN_LAUNCH_DRY_RUN', 'ALIGN_LAUNCH_TRACE', 'ALIGN_LLM_API_KEY', 'ALIGN_LLM_BASE_URL', 'ALIGN_LLM_PROVIDER',
|
|
20
|
-
'ALIGN_LLM_TIMEOUT_MS', 'ALIGN_MODEL_CACHE', 'ALIGN_NO_LAUNCH', 'ALIGN_NO_SYNC', 'ALIGN_OLLAMA_MODEL', 'ALIGN_PLATFORM',
|
|
20
|
+
'ALIGN_LLM_TIMEOUT_MS', 'ALIGN_MODEL_CACHE', 'ALIGN_NO_LAUNCH', 'ALIGN_NO_LEAD_PROMPT', 'ALIGN_NO_SYNC', 'ALIGN_OLLAMA_MODEL', 'ALIGN_PLATFORM',
|
|
21
21
|
'ALIGN_SUBJECT_KEY', 'ALIGN_TELEMETRY', 'ALIGN_TENANT_ID', 'ALIGN_TOKEN', 'ALIGN_WRAPPED',
|
|
22
22
|
];
|
|
23
23
|
/**
|
|
@@ -62,6 +62,9 @@ export const CHILD_ENV_NOT_PINNED = {
|
|
|
62
62
|
COLORTERM: 'output colour only',
|
|
63
63
|
COLORFGBG: 'output colour only',
|
|
64
64
|
DO_NOT_TRACK: 'can only turn telemetry off; not pinned because the first align run that sees it stores the opt-out (storeEnvOptOut), so a trimmed MCP env needs no copy',
|
|
65
|
+
...Object.fromEntries([
|
|
66
|
+
'GITHUB_ACTIONS', 'SSH_CONNECTION', 'SSH_TTY', 'SSH_CLIENT', 'CODESPACES', 'REMOTE_CONTAINERS', 'DISPLAY', 'WAYLAND_DISPLAY', 'TERM', 'LC_ALL', 'LC_CTYPE', 'LANG', 'SystemRoot',
|
|
67
|
+
].map((v) => [v, 'read by `align share` to decide whether to open a browser or draw a QR code at the person\'s terminal; the MCP server never does either'])),
|
|
65
68
|
COPILOT_ALLOW_ALL: 'read by the launcher about Copilot, not by align mcp',
|
|
66
69
|
GEMINI_RESTRICTED_MODE: 'read by the launcher about Gemini folder trust, not by align mcp',
|
|
67
70
|
...Object.fromEntries([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-child-env.js","sourceRoot":"","sources":["../../../src/lib/launch/mcp-child-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAElD;;;;;;;;;;;;GAYG;AAEH,wHAAwH;AACxH,MAAM,WAAW,GAAG;IAClB,aAAa,EAAE,WAAW,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,gBAAgB;
|
|
1
|
+
{"version":3,"file":"mcp-child-env.js","sourceRoot":"","sources":["../../../src/lib/launch/mcp-child-env.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The optional work-email prompt at the share moment. NOT telemetry: it is a separate consent, it is
|
|
3
|
+
* described as its own thing in docs/commands.md, and nothing here touches the telemetry state or events.
|
|
4
|
+
*
|
|
5
|
+
* It appears in one place only: `align share` run by a person at a terminal with no team login, right where
|
|
6
|
+
* the one upgrade line already prints. The decision lives in `leadPromptDecision` so every refusal is one
|
|
7
|
+
* named reason. The address is validated here, sent once to the gateway's public lead route, and never
|
|
8
|
+
* stored anywhere on this machine: the config keeps a timestamp and an outcome word, not the address.
|
|
9
|
+
*
|
|
10
|
+
* `align_share` and `align_share_status` (the MCP tools) never import this module: an agent must not
|
|
11
|
+
* collect an email on a person's behalf. Honest limit: an agent that opens its OWN pseudo-terminal passes every
|
|
12
|
+
* terminal check here and can see the prompt; the server's double opt-in (nothing is stored as confirmed until the
|
|
13
|
+
* address's owner clicks) is the backstop, the same stated limit as the typed share confirmation in SECURITY.md (share-lead-wiring.test.ts holds that: "the MCP tool modules do not import the prompt at all").
|
|
14
|
+
*/
|
|
15
|
+
import { type LeadPromptOutcome, type LeadState } from './config.js';
|
|
16
|
+
/** The consent text version. The privacy page uses the same string: change both together. */
|
|
17
|
+
export declare const LEAD_CONSENT_VERSION = "2026-10-cli-share-1";
|
|
18
|
+
export declare const PRIVACY_URL = "https://align.tech/privacy";
|
|
19
|
+
export declare const LEAD_CONSENT_LINE = "We will store it to email you about team plans. One confirmation email, unsubscribe any time. Details: https://align.tech/privacy.";
|
|
20
|
+
export declare const LEAD_QUESTION_LINE = "Want an email when your team can join Align, or to set up a call?";
|
|
21
|
+
export declare const LEAD_INPUT_PROMPT = "Work email (press Enter to skip):";
|
|
22
|
+
export type LeadSkipReason = 'not-hosted' | 'has-team-destination' | 'wrapped' | 'ci' | 'suppressed' | 'not-a-terminal' | 'has-login' | 'already-asked';
|
|
23
|
+
export interface LeadGateInput {
|
|
24
|
+
env: Record<string, string | undefined>;
|
|
25
|
+
/** stdin, stdout and stderr are all real terminals. */
|
|
26
|
+
tty: boolean;
|
|
27
|
+
hasLogin: boolean;
|
|
28
|
+
inCi: boolean;
|
|
29
|
+
state: LeadState;
|
|
30
|
+
/** The gateway this run talks to (resolved from config, the same one the share path uses). */
|
|
31
|
+
gatewayUrl: string;
|
|
32
|
+
/** Align's own hosted gateway. Only that target may be asked for, or sent, an email. */
|
|
33
|
+
hostedGatewayUrl: string;
|
|
34
|
+
/** The person has joined a team (`align join`): they are not the audience for Align's list. */
|
|
35
|
+
hasTeamDestination: boolean;
|
|
36
|
+
}
|
|
37
|
+
/** Null means ask. Anything else is the one reason it must not. Pure, so the decision table is testable as one. */
|
|
38
|
+
export declare function leadPromptDecision(i: LeadGateInput): LeadSkipReason | null;
|
|
39
|
+
/** The address to send, or null. Trims, lowercases the domain, and refuses anything the server would also refuse. */
|
|
40
|
+
export declare function normaliseEmail(raw: string): string | null;
|
|
41
|
+
export type LeadSendOutcome = {
|
|
42
|
+
kind: 'accepted';
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'invalid';
|
|
45
|
+
} | {
|
|
46
|
+
kind: 'rate-limited';
|
|
47
|
+
} | {
|
|
48
|
+
kind: 'unavailable';
|
|
49
|
+
} | {
|
|
50
|
+
kind: 'failed';
|
|
51
|
+
};
|
|
52
|
+
export interface LeadBody {
|
|
53
|
+
email: string;
|
|
54
|
+
source: 'cli-share';
|
|
55
|
+
consent_version: string;
|
|
56
|
+
cli_version?: string;
|
|
57
|
+
os?: 'darwin' | 'linux' | 'win32';
|
|
58
|
+
}
|
|
59
|
+
export declare function leadBody(email: string): LeadBody;
|
|
60
|
+
/** One attempt. No retry, no redirect, a hard time cap and a size cap on what is read back. Never throws. */
|
|
61
|
+
export declare function postLead(email: string, baseUrl: string, capMs?: number): Promise<LeadSendOutcome>;
|
|
62
|
+
export interface LeadStore {
|
|
63
|
+
getLeadState(): LeadState;
|
|
64
|
+
markLeadPromptShown(version: string): void;
|
|
65
|
+
setLeadOutcome(outcome: LeadPromptOutcome): void;
|
|
66
|
+
clearLeadPromptShown(): void;
|
|
67
|
+
}
|
|
68
|
+
export interface LeadDeps {
|
|
69
|
+
store: LeadStore;
|
|
70
|
+
env: Record<string, string | undefined>;
|
|
71
|
+
hasLogin: boolean;
|
|
72
|
+
inCi: boolean;
|
|
73
|
+
gatewayUrl: string;
|
|
74
|
+
hostedGatewayUrl: string;
|
|
75
|
+
hasTeamDestination: boolean;
|
|
76
|
+
/** stdin, stdout and stderr are terminals. The controlling terminal itself is proven by `ask`. */
|
|
77
|
+
tty: boolean;
|
|
78
|
+
/** Show `shown` on the controlling terminal, call onShown once visible, return the typed line, or null with no terminal. */
|
|
79
|
+
ask: (shown: string, question: string, onShown: () => void) => Promise<string | null>;
|
|
80
|
+
/** Posts to the resolved gateway URL, the same one the gate compared. */
|
|
81
|
+
post: (email: string) => Promise<LeadSendOutcome>;
|
|
82
|
+
out: (line: string) => void;
|
|
83
|
+
}
|
|
84
|
+
/** Runs the whole prompt. Returns what happened, for tests. Never throws: a broken store costs the prompt, never the command. */
|
|
85
|
+
export declare function maybeAskLead(d: LeadDeps): Promise<'skipped-by-gate' | 'no-terminal' | LeadPromptOutcome | 'not-sent'>;
|
|
86
|
+
export interface LeadPromptWiring {
|
|
87
|
+
store: LeadStore & {
|
|
88
|
+
listTeamDestinationNames(): string[];
|
|
89
|
+
};
|
|
90
|
+
/** The gateway this share resolved to: compared with the hosted one, never posted to. */
|
|
91
|
+
cloudGatewayUrl: string;
|
|
92
|
+
hostedGatewayUrl: string;
|
|
93
|
+
env: Record<string, string | undefined>;
|
|
94
|
+
inCi: boolean;
|
|
95
|
+
tty: boolean;
|
|
96
|
+
ask: LeadDeps['ask'];
|
|
97
|
+
out: (line: string) => void;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* What `align share` hands the run as its lead prompt. Two rules live here so a test can hold them:
|
|
101
|
+
* a saved team destination switches the prompt off, and the address is posted to Align's hosted gateway
|
|
102
|
+
* as Align spells it, never to whatever the run resolved (a self-host, or an environment override that merely
|
|
103
|
+
* matches after normalising).
|
|
104
|
+
*/
|
|
105
|
+
export declare function leadPromptFor(w: LeadPromptWiring): () => ReturnType<typeof maybeAskLead>;
|
|
106
|
+
//# sourceMappingURL=lead-prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lead-prompt.d.ts","sourceRoot":"","sources":["../../src/lib/lead-prompt.ts"],"names":[],"mappings":"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"}
|