@kodycodes/cli 3.1.6 → 3.3.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.
Files changed (73) hide show
  1. package/README.md +23 -1
  2. package/dist/{auth-YUFNOOTY.js → auth-KD6IT7RH.js} +8 -5
  3. package/dist/auth.d.ts +24 -0
  4. package/dist/bin.js +10 -9
  5. package/dist/bin.js.map +1 -1
  6. package/dist/{chunk-AFGRPGHE.js → chunk-2DCCAVPD.js} +159 -65
  7. package/dist/chunk-2DCCAVPD.js.map +6 -0
  8. package/dist/{chunk-NRLXYJKW.js → chunk-3DASQK6N.js} +3 -3
  9. package/dist/{chunk-OIXNZ63K.js → chunk-3PN6V3EX.js} +13 -13
  10. package/dist/chunk-AED3YBAI.js +355 -0
  11. package/dist/chunk-AED3YBAI.js.map +6 -0
  12. package/dist/{chunk-2GSKFEWW.js → chunk-AWDVFTR2.js} +95 -5
  13. package/dist/chunk-AWDVFTR2.js.map +6 -0
  14. package/dist/{chunk-BQOJGN24.js → chunk-F7MVIDV6.js} +3 -3
  15. package/dist/{chunk-2XSV546S.js → chunk-FB6I4T2J.js} +292 -78
  16. package/dist/{chunk-2XSV546S.js.map → chunk-FB6I4T2J.js.map} +1 -1
  17. package/dist/{chunk-ZK52DY36.js → chunk-MU6NWE3A.js} +6 -6
  18. package/dist/{chunk-SAK2XRKX.js → chunk-RETDMHIH.js} +3 -3
  19. package/dist/chunk-S3KLKZ4C.js +124 -0
  20. package/dist/chunk-S3KLKZ4C.js.map +6 -0
  21. package/dist/{chunk-LISUPAAK.js → chunk-TZKZOMEA.js} +5 -117
  22. package/dist/chunk-TZKZOMEA.js.map +6 -0
  23. package/dist/{chunk-OWIJPBAX.js → chunk-Y6JYX35N.js} +6 -4
  24. package/dist/chunk-Y6JYX35N.js.map +6 -0
  25. package/dist/cli.d.ts +4 -1
  26. package/dist/cli.js +11 -10
  27. package/dist/commands-RPUZAOAB.js +806 -0
  28. package/dist/commands-RPUZAOAB.js.map +6 -0
  29. package/dist/{dev-command-NUN5HHRC.js → dev-command-Y2TN23BI.js} +28 -27
  30. package/dist/dev-command-Y2TN23BI.js.map +6 -0
  31. package/dist/execution-context/client.d.ts +89 -0
  32. package/dist/execution-context/commands.d.ts +26 -0
  33. package/dist/execution-context/daemon.d.ts +47 -0
  34. package/dist/execution-context/keystore.d.ts +58 -0
  35. package/dist/execution-context/run-executor.d.ts +20 -0
  36. package/dist/{git-credential-SL4Y6YKO.js → git-credential-WTF6ZIL4.js} +8 -7
  37. package/dist/git-credential-WTF6ZIL4.js.map +6 -0
  38. package/dist/{local-execute-5J53ZM5Z.js → local-execute-3H2ROHTP.js} +14 -13
  39. package/dist/local-execute-3H2ROHTP.js.map +6 -0
  40. package/dist/{local-package-graph-7TEPDAGV.js → local-package-graph-657CN4KN.js} +4 -3
  41. package/dist/{local-package-run-OPC7VXO3.js → local-package-run-C2XX2U5D.js} +10 -9
  42. package/dist/login-notice.d.ts +28 -1
  43. package/dist/{mock-dep-resolve-QRMNGDHM.js → mock-dep-resolve-BSFBRPO6.js} +8 -7
  44. package/dist/mock-dep-resolve-BSFBRPO6.js.map +6 -0
  45. package/dist/{mock-local-deps-EUL62AHI.js → mock-local-deps-6D73XVTZ.js} +6 -5
  46. package/dist/oauth-browser.d.ts +24 -0
  47. package/dist/{open-api-client-K2BEQBO3.js → open-api-client-L472YVI6.js} +4 -3
  48. package/dist/{remote-execute-BRXK2NIJ.js → remote-execute-J4SASOP2.js} +5 -4
  49. package/dist/remote-execute-J4SASOP2.js.map +6 -0
  50. package/dist/run-executor-VXPFKJ3K.js +27 -0
  51. package/dist/run-executor-VXPFKJ3K.js.map +6 -0
  52. package/dist/{setup-git-DCMWZYIG.js → setup-git-WDMOJAFN.js} +5 -4
  53. package/package.json +1 -1
  54. package/dist/chunk-2GSKFEWW.js.map +0 -6
  55. package/dist/chunk-AFGRPGHE.js.map +0 -6
  56. package/dist/chunk-LISUPAAK.js.map +0 -6
  57. package/dist/chunk-OWIJPBAX.js.map +0 -6
  58. package/dist/dev-command-NUN5HHRC.js.map +0 -6
  59. package/dist/git-credential-SL4Y6YKO.js.map +0 -6
  60. package/dist/local-execute-5J53ZM5Z.js.map +0 -6
  61. package/dist/mock-dep-resolve-QRMNGDHM.js.map +0 -6
  62. package/dist/remote-execute-BRXK2NIJ.js.map +0 -6
  63. /package/dist/{auth-YUFNOOTY.js.map → auth-KD6IT7RH.js.map} +0 -0
  64. /package/dist/{chunk-NRLXYJKW.js.map → chunk-3DASQK6N.js.map} +0 -0
  65. /package/dist/{chunk-OIXNZ63K.js.map → chunk-3PN6V3EX.js.map} +0 -0
  66. /package/dist/{chunk-BQOJGN24.js.map → chunk-F7MVIDV6.js.map} +0 -0
  67. /package/dist/{chunk-ZK52DY36.js.map → chunk-MU6NWE3A.js.map} +0 -0
  68. /package/dist/{chunk-SAK2XRKX.js.map → chunk-RETDMHIH.js.map} +0 -0
  69. /package/dist/{local-package-graph-7TEPDAGV.js.map → local-package-graph-657CN4KN.js.map} +0 -0
  70. /package/dist/{local-package-run-OPC7VXO3.js.map → local-package-run-C2XX2U5D.js.map} +0 -0
  71. /package/dist/{mock-local-deps-EUL62AHI.js.map → mock-local-deps-6D73XVTZ.js.map} +0 -0
  72. /package/dist/{open-api-client-K2BEQBO3.js.map → open-api-client-L472YVI6.js.map} +0 -0
  73. /package/dist/{setup-git-DCMWZYIG.js.map → setup-git-WDMOJAFN.js.map} +0 -0
package/README.md CHANGED
@@ -70,13 +70,35 @@ org. Git auth stays user-wide (`kody auth setup-git` once covers every repo
70
70
  across orgs). Existing single-org keychain credentials migrate silently into the
71
71
  multi-org store as the active org (no re-login).
72
72
 
73
+ ## Remote or headless machines
74
+
75
+ `kody login` opens a browser and waits for it on `http://127.0.0.1:43742`, so
76
+ the browser has to run on the same machine as the CLI. On a remote VM, a NAS, or
77
+ over SSH, use the device flow instead:
78
+
79
+ ```bash
80
+ kody login --device # prints a URL and a code; approve on any device
81
+ kody login --device --org acme # same, bound to the acme org
82
+ ```
83
+
84
+ The CLI prints `https://kody.codes/device` and an 8-letter code such as
85
+ `BCDF-GHJK`, plus a link that fills the code in for you. Open either one on your
86
+ phone or laptop, sign in, check that the code matches, and choose **Approve**.
87
+ The CLI polls in the background and stores the same device API token
88
+ `kody login` stores. Codes expire after 10 minutes. Only approve a code you
89
+ started yourself on a device you control.
90
+
91
+ `kody login` suggests `--device` when it detects an SSH session or no display,
92
+ when it cannot open a browser, or when the callback port is busy. The browser
93
+ flow stays the default.
94
+
73
95
  ## Commands
74
96
 
75
97
  | Command | Purpose |
76
98
  | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
77
99
  | `kody install` | Detect running local MCP clients and write their remote MCP config. The host client starts OAuth when the user connects. **Recommended long-term path.** |
78
100
  | `kody skill install` | Installs the hosted `kody-cli` skill (or the bundled stub offline) into Claude Code / Cursor / Codex / `.agents`. Later CLI runs refresh stale copies by digest. |
79
- | `kody login` | Browser OAuth (CIMD + PKCE) for the CLI itself. Adds/replaces one org login (browser picker, or `kody login --org acme`) and keeps other org logins. |
101
+ | `kody login` | Browser OAuth (CIMD + PKCE) for the CLI itself. Adds/replaces one org login (browser picker, or `kody login --org acme`) and keeps other org logins. `--device` signs in from another device instead ([Remote or headless machines](#remote-or-headless-machines)). |
80
102
  | `kody org list` | Lists logged-in orgs and marks the active one. `--json` for agents. |
81
103
  | `kody org use [<slug>]` | Switches the active org. With a slug (agents) switches directly; with no slug on a TTY opens a chooser; without a TTY pass a slug. |
82
104
  | `kody logout` | Removes the active org login (or `--org <slug>` for one org) and clears a stored bootstrap/API token when appropriate. |
@@ -5,16 +5,18 @@ import {
5
5
  ensureOpenApiCredentials,
6
6
  isAccessTokenExpired,
7
7
  login,
8
+ loginWithDevice,
8
9
  refreshStoredCredentials,
9
10
  resolvePendingOrgSlug
10
- } from "./chunk-2XSV546S.js";
11
- import "./chunk-CASGRYOF.js";
11
+ } from "./chunk-FB6I4T2J.js";
12
12
  import "./chunk-GVSGNTG6.js";
13
13
  import "./chunk-CWWHR4FH.js";
14
- import "./chunk-2GSKFEWW.js";
14
+ import "./chunk-CASGRYOF.js";
15
+ import "./chunk-AWDVFTR2.js";
15
16
  import "./chunk-46IJPEID.js";
16
- import "./chunk-LISUPAAK.js";
17
17
  import "./chunk-BML3W5CO.js";
18
+ import "./chunk-TZKZOMEA.js";
19
+ import "./chunk-S3KLKZ4C.js";
18
20
  import "./chunk-NHRYNRXG.js";
19
21
  import "./chunk-CMIH7XDH.js";
20
22
  import "./chunk-V7P2QDVU.js";
@@ -25,7 +27,8 @@ export {
25
27
  ensureOpenApiCredentials,
26
28
  isAccessTokenExpired,
27
29
  login,
30
+ loginWithDevice,
28
31
  refreshStoredCredentials,
29
32
  resolvePendingOrgSlug
30
33
  };
31
- //# sourceMappingURL=auth-YUFNOOTY.js.map
34
+ //# sourceMappingURL=auth-KD6IT7RH.js.map
package/dist/auth.d.ts CHANGED
@@ -118,3 +118,27 @@ export declare function login(options?: LoginOptions): Promise<{
118
118
  org?: string;
119
119
  account?: LoginCallbackAccount;
120
120
  }>;
121
+ export type DeviceLoginPrompt = {
122
+ userCode: string;
123
+ verificationUri: string;
124
+ verificationUriComplete?: string;
125
+ expiresIn: number;
126
+ };
127
+ export type DeviceLoginOptions = Omit<LoginOptions, 'openBrowser' | 'onAuthorizationUrl' | 'onBrowserOpenResult' | 'openUrlFn'> & {
128
+ /** Called once with the code and URLs the person must open elsewhere. */
129
+ onDeviceCode?: (prompt: DeviceLoginPrompt) => void;
130
+ /** Test seam for the poll wait. */
131
+ sleep?: (ms: number) => Promise<void>;
132
+ };
133
+ /**
134
+ * `kody login --device`: OAuth 2.0 Device Authorization Grant (RFC 8628,
135
+ * ADR 0082) for machines whose browser cannot reach the localhost callback.
136
+ * The result is stored exactly like the browser flow (device API token).
137
+ */
138
+ export declare function loginWithDevice(options?: DeviceLoginOptions): Promise<{
139
+ credentials: StoredCredentials;
140
+ backendKind: 'keyring' | 'file';
141
+ backendPath?: string;
142
+ org?: string;
143
+ account?: LoginCallbackAccount;
144
+ }>;
package/dist/bin.js CHANGED
@@ -2,22 +2,23 @@
2
2
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
3
3
  import {
4
4
  runCli
5
- } from "./chunk-AFGRPGHE.js";
6
- import "./chunk-2XPH7L2P.js";
7
- import "./chunk-SLNAWWQK.js";
5
+ } from "./chunk-2DCCAVPD.js";
8
6
  import "./chunk-YDWTXEKQ.js";
9
7
  import "./chunk-7PRJ36I5.js";
10
- import "./chunk-BQOJGN24.js";
11
- import "./chunk-OWIJPBAX.js";
8
+ import "./chunk-F7MVIDV6.js";
9
+ import "./chunk-SLNAWWQK.js";
10
+ import "./chunk-2XPH7L2P.js";
11
+ import "./chunk-Y6JYX35N.js";
12
12
  import "./chunk-6ZYUGXVW.js";
13
- import "./chunk-2XSV546S.js";
14
- import "./chunk-CASGRYOF.js";
13
+ import "./chunk-FB6I4T2J.js";
15
14
  import "./chunk-GVSGNTG6.js";
16
15
  import "./chunk-CWWHR4FH.js";
17
- import "./chunk-2GSKFEWW.js";
16
+ import "./chunk-CASGRYOF.js";
17
+ import "./chunk-AWDVFTR2.js";
18
18
  import "./chunk-46IJPEID.js";
19
- import "./chunk-LISUPAAK.js";
20
19
  import "./chunk-BML3W5CO.js";
20
+ import "./chunk-TZKZOMEA.js";
21
+ import "./chunk-S3KLKZ4C.js";
21
22
  import "./chunk-NHRYNRXG.js";
22
23
  import "./chunk-CMIH7XDH.js";
23
24
  import "./chunk-V7P2QDVU.js";
package/dist/bin.js.map CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/bin.ts"],
4
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,IAAM,OAAO,MAAM,OAAO;AAC1B,QAAQ,WAAW;",
4
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,IAAM,OAAO,MAAM,OAAO;AAC1B,QAAQ,WAAW;",
5
5
  "names": []
6
6
  }
@@ -1,11 +1,4 @@
1
1
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
- import {
3
- assertLocalExecuteNodeEngine
4
- } from "./chunk-2XPH7L2P.js";
5
- import {
6
- isPublishedPackageInvokeSpecifier,
7
- resolveExecuteInvokeCode
8
- } from "./chunk-SLNAWWQK.js";
9
2
  import {
10
3
  hostIds
11
4
  } from "./chunk-YDWTXEKQ.js";
@@ -14,7 +7,14 @@ import {
14
7
  } from "./chunk-7PRJ36I5.js";
15
8
  import {
16
9
  resolveLocalExecuteBearer
17
- } from "./chunk-BQOJGN24.js";
10
+ } from "./chunk-F7MVIDV6.js";
11
+ import {
12
+ isPublishedPackageInvokeSpecifier,
13
+ resolveExecuteInvokeCode
14
+ } from "./chunk-SLNAWWQK.js";
15
+ import {
16
+ assertLocalExecuteNodeEngine
17
+ } from "./chunk-2XPH7L2P.js";
18
18
  import {
19
19
  authBootstrap,
20
20
  authBootstrapWithScopes,
@@ -24,27 +24,29 @@ import {
24
24
  parseCliScopesFlag,
25
25
  refreshGitCredentialHelperPinIfNeeded,
26
26
  resolveCliTokenLifetime
27
- } from "./chunk-OWIJPBAX.js";
28
- import {
29
- redactError
30
- } from "./chunk-CASGRYOF.js";
27
+ } from "./chunk-Y6JYX35N.js";
31
28
  import {
32
29
  orgEnvVar,
33
30
  orgSlugFromFlag
34
31
  } from "./chunk-CWWHR4FH.js";
32
+ import {
33
+ redactError
34
+ } from "./chunk-CASGRYOF.js";
35
35
  import {
36
36
  formatToolResult
37
37
  } from "./chunk-46IJPEID.js";
38
38
  import {
39
39
  cliBootstrapMintCall,
40
- deleteStoredApiToken,
41
40
  hasExplicitTokenFlag,
42
- loadStoredApiToken,
43
41
  parseCredentialFlags,
44
42
  readPackageVersion,
45
43
  requireApiToken,
46
44
  resolveScopedApiToken
47
- } from "./chunk-LISUPAAK.js";
45
+ } from "./chunk-TZKZOMEA.js";
46
+ import {
47
+ deleteStoredApiToken,
48
+ loadStoredApiToken
49
+ } from "./chunk-S3KLKZ4C.js";
48
50
  import {
49
51
  deleteCredentials,
50
52
  listStoredOrgs,
@@ -95,7 +97,7 @@ function buildUsage(input = {}) {
95
97
  Install Kody as a remote MCP server in local agents, or use this CLI as a local client.
96
98
 
97
99
  Usage:
98
- kody login [--mcp-url <url>] [--org <slug>] [--no-browser]
100
+ kody login [--mcp-url <url>] [--org <slug>] [--no-browser | --device]
99
101
  kody logout [--org <slug>] [--mcp-url <url>] [--api-url <url>]
100
102
  kody org list [--json] [--mcp-url <url>]
101
103
  kody org use [<slug>] [--mcp-url <url>]
@@ -113,6 +115,9 @@ Usage:
113
115
  kody package grant <package> (--team <slug> | --user <username>) [--preset use|contribute|manage] [--org <slug>] [--json]
114
116
  kody package revoke <package> (--team <slug> | --user <username> | --grant <grant_id>) [--org <slug>] [--json]
115
117
  kody execute [--org <slug>] [--invoke <ref> | --code <esm> | --file <path>] [--params <json>] [--conversation-id <id>] [--json]
118
+ kody context register --name <name> [--org <slug>] | kody context list [--json]
119
+ kody chain show | add <name> | remove <name> [--org <slug>] [--json]
120
+ kody daemon [--context <ec id>]
116
121
  [--credential <key=name>]\u2026 [--target prod|mock] [--token <token>] [--api-url <url>] [--local] [--allow-private-network]
117
122
  kody dev [serve] [--org <slug>] [--target prod|mock] [--reset-storage] [--port <n>] [--app-base-path <path>] [--allow-private-network] [--no-live-reload] [--json] [--ready-file <path>]
118
123
  kody dev fetch <path> [--method <verb>] [--body <file>] [--target prod|mock] [--json] [--no-attach]
@@ -711,10 +716,62 @@ function formatLoginUrlNotice(input) {
711
716
  Waiting for you to finish signing in\u2026
712
717
  `;
713
718
  }
714
- var loginBrowserOpenFailedNotice = "Kody could not open your browser automatically. Copy the link above into your browser to continue.\n";
719
+ var loginBrowserOpenFailedNotice = "Kody could not open your browser automatically. Copy the link above into your browser to continue.\nIf that browser is on another machine, press Ctrl+C and run `kody login --device` instead.\n";
720
+ function detectHeadlessLoginReason(env = process.env, platform = process.platform) {
721
+ if (env.SSH_CONNECTION || env.SSH_CLIENT || env.SSH_TTY) return "ssh";
722
+ if (platform !== "darwin" && platform !== "win32" && !env.DISPLAY && !env.WAYLAND_DISPLAY) {
723
+ return "no_display";
724
+ }
725
+ return null;
726
+ }
727
+ function formatDeviceLoginSuggestion(reason) {
728
+ const why = reason === "ssh" ? "This looks like an SSH session" : "No display was found on this machine";
729
+ return `${why}, so a browser here may not be able to finish the sign-in.
730
+ If it can't, press Ctrl+C and run \`kody login --device\` to sign in from any other device.
731
+
732
+ `;
733
+ }
734
+ function formatDeviceLoginNotice(input) {
735
+ const minutes = Math.max(1, Math.round(input.expiresIn / 60));
736
+ const direct = input.verificationUriComplete ? `
737
+ Or open this link, which fills in the code for you:
738
+
739
+ ${input.verificationUriComplete}
740
+ ` : "";
741
+ return `To sign in, open this page on any device:
742
+
743
+ ${input.verificationUri}
744
+
745
+ and enter the code:
746
+
747
+ ${input.userCode}
748
+ ${direct}
749
+ Only approve it if the page shows this same code. The code expires in ${minutes} minutes.
750
+ Waiting for approval\u2026
751
+ `;
752
+ }
753
+ function formatLoginSuccess(result) {
754
+ const orgLabel = result.org ? ` as org ${result.org}` : result.credentials.org ? ` as org ${result.credentials.org}` : "";
755
+ const accountLabel = result.account?.email ? ` (${result.account.email})` : result.account?.displayName ? ` (${result.account.displayName})` : "";
756
+ const lines = [
757
+ `Logged in to ${result.credentials.mcpUrl}${orgLabel}${accountLabel}.
758
+ `
759
+ ];
760
+ if (result.backendKind === "file" && result.backendPath) {
761
+ lines.push(
762
+ `OS keychain was unavailable; credentials saved at ${result.backendPath} (mode 0600).
763
+ `
764
+ );
765
+ } else {
766
+ lines.push("Credentials stored in the OS keychain.\n");
767
+ }
768
+ return lines.join("");
769
+ }
715
770
 
716
771
  // src/cli.ts
717
772
  var orgScopedCommands = /* @__PURE__ */ new Set([
773
+ "context",
774
+ "chain",
718
775
  "login",
719
776
  "logout",
720
777
  "whoami",
@@ -755,7 +812,10 @@ var cliFlagOptions = {
755
812
  scopes: { type: "string" },
756
813
  project: { type: "boolean" },
757
814
  "no-browser": { type: "boolean" },
815
+ device: { type: "boolean" },
758
816
  org: { type: "string" },
817
+ name: { type: "string" },
818
+ context: { type: "string" },
759
819
  target: { type: "string" },
760
820
  "reset-storage": { type: "boolean" },
761
821
  "dry-run": { type: "boolean" },
@@ -815,6 +875,9 @@ function resolveCommand(argv) {
815
875
  case "skill":
816
876
  case "help":
817
877
  case "version":
878
+ case "context":
879
+ case "chain":
880
+ case "daemon":
818
881
  return { command: raw, positionals: positionals.slice(1), values };
819
882
  default:
820
883
  throw new Error(
@@ -947,15 +1010,59 @@ async function dispatch(parsed, write, writeErr) {
947
1010
  write(`${readPackageVersion()}
948
1011
  `);
949
1012
  return 0;
1013
+ case "context":
1014
+ case "chain":
1015
+ case "daemon": {
1016
+ const apiUrl = apiUrlFrom({
1017
+ apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
1018
+ });
1019
+ const { runExecutionContextCommand } = await import("./commands-RPUZAOAB.js");
1020
+ return await runExecutionContextCommand({
1021
+ command: parsed.command,
1022
+ positionals: parsed.positionals,
1023
+ values: {
1024
+ ...typeof parsed.values.name === "string" ? { name: parsed.values.name } : {},
1025
+ ...typeof parsed.values.context === "string" ? { context: parsed.values.context } : {},
1026
+ json
1027
+ },
1028
+ apiUrl,
1029
+ ...org ? { org } : {},
1030
+ token: () => accessTokenForOpenApi({
1031
+ tokenValues: tokenFlagValues(parsed.values),
1032
+ apiUrl,
1033
+ mcpUrl,
1034
+ ...org ? { org } : {}
1035
+ }),
1036
+ clientVersion: readPackageVersion(),
1037
+ write
1038
+ });
1039
+ }
950
1040
  case "login": {
951
- const { login } = await import("./auth-YUFNOOTY.js");
1041
+ const { login, loginWithDevice } = await import("./auth-KD6IT7RH.js");
952
1042
  const openBrowser = parsed.values["no-browser"] !== true;
1043
+ const lifetimeOption = typeof parsed.values.lifetime === "string" ? {
1044
+ lifetime: parsed.values.lifetime === "short" ? "short" : "long"
1045
+ } : {};
1046
+ const loginApiUrl = apiUrlFrom({
1047
+ apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
1048
+ });
1049
+ if (parsed.values.device === true) {
1050
+ const result2 = await loginWithDevice({
1051
+ mcpUrl,
1052
+ apiUrl: loginApiUrl,
1053
+ ...lifetimeOption,
1054
+ ...orgFlagOnly ? { org: orgFlagOnly } : {},
1055
+ onDeviceCode: (prompt) => write(formatDeviceLoginNotice(prompt))
1056
+ });
1057
+ write(formatLoginSuccess(result2));
1058
+ return 0;
1059
+ }
1060
+ const headlessReason = openBrowser ? detectHeadlessLoginReason() : null;
1061
+ if (headlessReason) write(formatDeviceLoginSuggestion(headlessReason));
953
1062
  const result = await login({
954
1063
  mcpUrl,
955
- apiUrl: apiUrlFrom({
956
- apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
957
- }),
958
- ...typeof parsed.values.lifetime === "string" ? { lifetime: parsed.values.lifetime === "short" ? "short" : "long" } : {},
1064
+ apiUrl: loginApiUrl,
1065
+ ...lifetimeOption,
959
1066
  ...orgFlagOnly ? { org: orgFlagOnly } : {},
960
1067
  openBrowser,
961
1068
  onAuthorizationUrl: (url) => {
@@ -965,20 +1072,7 @@ async function dispatch(parsed, write, writeErr) {
965
1072
  if (!opened) write(loginBrowserOpenFailedNotice);
966
1073
  }
967
1074
  });
968
- const orgLabel = result.org ? ` as org ${result.org}` : result.credentials.org ? ` as org ${result.credentials.org}` : "";
969
- const accountLabel = result.account?.email ? ` (${result.account.email})` : result.account?.displayName ? ` (${result.account.displayName})` : "";
970
- write(
971
- `Logged in to ${result.credentials.mcpUrl}${orgLabel}${accountLabel}.
972
- `
973
- );
974
- if (result.backendKind === "file" && result.backendPath) {
975
- write(
976
- `OS keychain was unavailable; credentials saved at ${result.backendPath} (mode 0600).
977
- `
978
- );
979
- } else {
980
- write("Credentials stored in the OS keychain.\n");
981
- }
1075
+ write(formatLoginSuccess(result));
982
1076
  return 0;
983
1077
  }
984
1078
  case "logout": {
@@ -1174,7 +1268,7 @@ async function dispatch(parsed, write, writeErr) {
1174
1268
  parseGitCredentialAction,
1175
1269
  parseGitCredentialInput,
1176
1270
  readGitCredentialStdin
1177
- } = await import("./git-credential-SL4Y6YKO.js");
1271
+ } = await import("./git-credential-WTF6ZIL4.js");
1178
1272
  const action = parseGitCredentialAction(parsed.positionals);
1179
1273
  const raw = await readGitCredentialStdin(process.stdin);
1180
1274
  const output = await handleGitCredential({
@@ -1241,7 +1335,7 @@ async function dispatch(parsed, write, writeErr) {
1241
1335
  allowEnvWithoutLogin: true,
1242
1336
  ...org ? { org } : {}
1243
1337
  })) {
1244
- const { whoamiWithApiToken: whoamiWithApiToken2 } = await import("./open-api-client-K2BEQBO3.js");
1338
+ const { whoamiWithApiToken: whoamiWithApiToken2 } = await import("./open-api-client-L472YVI6.js");
1245
1339
  const identity2 = await whoamiWithApiToken2({
1246
1340
  token: requireApiToken(tokenValues, process.env, "whoami", {
1247
1341
  apiUrl
@@ -1268,13 +1362,13 @@ async function dispatch(parsed, write, writeErr) {
1268
1362
  );
1269
1363
  return 0;
1270
1364
  }
1271
- const { ensureOpenApiCredentials } = await import("./auth-YUFNOOTY.js");
1365
+ const { ensureOpenApiCredentials } = await import("./auth-KD6IT7RH.js");
1272
1366
  const credentials = await ensureOpenApiCredentials({
1273
1367
  mcpUrl,
1274
1368
  org,
1275
1369
  apiUrl
1276
1370
  });
1277
- const { whoamiWithApiToken } = await import("./open-api-client-K2BEQBO3.js");
1371
+ const { whoamiWithApiToken } = await import("./open-api-client-L472YVI6.js");
1278
1372
  const identity = await whoamiWithApiToken({
1279
1373
  token: credentials.accessToken,
1280
1374
  apiUrl,
@@ -1328,7 +1422,7 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1328
1422
  });
1329
1423
  apiUrl = mock.apiUrl;
1330
1424
  closeMock = mock.started ? () => mock.server.close() : void 0;
1331
- const { searchWithApiToken: searchWithApiToken2 } = await import("./open-api-client-K2BEQBO3.js");
1425
+ const { searchWithApiToken: searchWithApiToken2 } = await import("./open-api-client-L472YVI6.js");
1332
1426
  const result2 = await searchWithApiToken2({
1333
1427
  token: mock.token,
1334
1428
  apiUrl,
@@ -1347,7 +1441,7 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1347
1441
  allowEnvWithoutLogin: true,
1348
1442
  ...org ? { org } : {}
1349
1443
  })) {
1350
- const { searchWithApiToken: searchWithApiToken2 } = await import("./open-api-client-K2BEQBO3.js");
1444
+ const { searchWithApiToken: searchWithApiToken2 } = await import("./open-api-client-L472YVI6.js");
1351
1445
  const result2 = await searchWithApiToken2({
1352
1446
  token: requireApiToken(tokenValues, process.env, "search", {
1353
1447
  apiUrl
@@ -1362,13 +1456,13 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1362
1456
  write(formatToolResult(result2, json));
1363
1457
  return result2.isError ? 1 : 0;
1364
1458
  }
1365
- const { ensureOpenApiCredentials } = await import("./auth-YUFNOOTY.js");
1459
+ const { ensureOpenApiCredentials } = await import("./auth-KD6IT7RH.js");
1366
1460
  const credentials = await ensureOpenApiCredentials({
1367
1461
  mcpUrl,
1368
1462
  org,
1369
1463
  apiUrl
1370
1464
  });
1371
- const { searchWithApiToken } = await import("./open-api-client-K2BEQBO3.js");
1465
+ const { searchWithApiToken } = await import("./open-api-client-L472YVI6.js");
1372
1466
  const result = await searchWithApiToken({
1373
1467
  token: credentials.accessToken,
1374
1468
  apiUrl,
@@ -1475,7 +1569,7 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1475
1569
  apiUrl = mock.apiUrl;
1476
1570
  mockToken = mock.token;
1477
1571
  closeMock = mock.started ? () => mock.server.close() : void 0;
1478
- const { tryResolveMockDepResolve } = await import("./mock-dep-resolve-QRMNGDHM.js");
1572
+ const { tryResolveMockDepResolve } = await import("./mock-dep-resolve-BSFBRPO6.js");
1479
1573
  mockDepResolve = await tryResolveMockDepResolve({
1480
1574
  tokenValues,
1481
1575
  apiUrl: prodApiUrl,
@@ -1484,7 +1578,7 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1484
1578
  });
1485
1579
  }
1486
1580
  if (localPackageRun) {
1487
- const { buildLocalPackageContext, runLocalPackageModule } = await import("./local-package-run-OPC7VXO3.js");
1581
+ const { buildLocalPackageContext, runLocalPackageModule } = await import("./local-package-run-C2XX2U5D.js");
1488
1582
  const result2 = await runLocalPackageModule({
1489
1583
  modulePath: localPackageRun.modulePath,
1490
1584
  params: args.params,
@@ -1528,7 +1622,7 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1528
1622
  packageRootForMocks = void 0;
1529
1623
  }
1530
1624
  }
1531
- const result = local ? await (await import("./local-execute-5J53ZM5Z.js")).runLocalExecute({
1625
+ const result = local ? await (await import("./local-execute-3H2ROHTP.js")).runLocalExecute({
1532
1626
  code: args.code,
1533
1627
  ...modulePath !== void 0 ? { modulePath } : {},
1534
1628
  params: args.params,
@@ -1550,7 +1644,7 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1550
1644
  allowPrivateNetwork: parsed.values["allow-private-network"] === true,
1551
1645
  onStatus: (message) => writeErr(`${message}
1552
1646
  `)
1553
- }) : useToken ? await (await import("./remote-execute-BRXK2NIJ.js")).runRemoteExecuteWithToken({
1647
+ }) : useToken ? await (await import("./remote-execute-J4SASOP2.js")).runRemoteExecuteWithToken({
1554
1648
  code: typeof args.code === "string" ? args.code : void 0,
1555
1649
  invoke,
1556
1650
  params: args.params,
@@ -1565,13 +1659,13 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1565
1659
  apiUrl,
1566
1660
  ...org ? { org } : {}
1567
1661
  }) : await (async () => {
1568
- const { ensureOpenApiCredentials } = await import("./auth-YUFNOOTY.js");
1662
+ const { ensureOpenApiCredentials } = await import("./auth-KD6IT7RH.js");
1569
1663
  const session = await ensureOpenApiCredentials({
1570
1664
  mcpUrl,
1571
1665
  org,
1572
1666
  apiUrl
1573
1667
  });
1574
- return (await import("./remote-execute-BRXK2NIJ.js")).runRemoteExecuteWithToken({
1668
+ return (await import("./remote-execute-J4SASOP2.js")).runRemoteExecuteWithToken({
1575
1669
  code: typeof args.code === "string" ? args.code : void 0,
1576
1670
  invoke,
1577
1671
  params: args.params,
@@ -1586,7 +1680,7 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1586
1680
  return result.isError ? 1 : 0;
1587
1681
  } catch (error) {
1588
1682
  if (json && local) {
1589
- const { LocalPackageGraphError, packageGraphErrorToolResult } = await import("./local-package-graph-7TEPDAGV.js");
1683
+ const { LocalPackageGraphError, packageGraphErrorToolResult } = await import("./local-package-graph-657CN4KN.js");
1590
1684
  if (error instanceof LocalPackageGraphError) {
1591
1685
  const redacted = redactError(error).message;
1592
1686
  const result = packageGraphErrorToolResult(error);
@@ -1616,7 +1710,7 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1616
1710
  runDevServe,
1617
1711
  runDevWebhook,
1618
1712
  tryAttachedDevFetch
1619
- } = await import("./dev-command-NUN5HHRC.js");
1713
+ } = await import("./dev-command-Y2TN23BI.js");
1620
1714
  const target = resolveTarget({
1621
1715
  command: "dev",
1622
1716
  flag: typeof parsed.values.target === "string" ? parsed.values.target : void 0
@@ -1642,8 +1736,8 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1642
1736
  { callOpenApiOperation, formatOpenApiHttpDebugLine },
1643
1737
  { parsePackageCheckResult, PublishChecksAuthError }
1644
1738
  ] = await Promise.all([
1645
- import("./open-api-client-K2BEQBO3.js"),
1646
- import("./dev-command-NUN5HHRC.js")
1739
+ import("./open-api-client-L472YVI6.js"),
1740
+ import("./dev-command-Y2TN23BI.js")
1647
1741
  ]);
1648
1742
  let token2;
1649
1743
  try {
@@ -1754,7 +1848,7 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1754
1848
  purpose: "kody dev",
1755
1849
  ...org ? { org } : {}
1756
1850
  }) : "mock";
1757
- const mockDepResolve = target === "mock" ? await (await import("./mock-dep-resolve-QRMNGDHM.js")).tryResolveMockDepResolve({
1851
+ const mockDepResolve = target === "mock" ? await (await import("./mock-dep-resolve-BSFBRPO6.js")).tryResolveMockDepResolve({
1758
1852
  tokenValues,
1759
1853
  apiUrl: prodApiUrl,
1760
1854
  mcpUrl,
@@ -1895,7 +1989,7 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1895
1989
  const params = parseApiParamsJson(
1896
1990
  typeof parsed.values.params === "string" ? parsed.values.params : void 0
1897
1991
  );
1898
- const { callOpenApiOperation } = await import("./open-api-client-K2BEQBO3.js");
1992
+ const { callOpenApiOperation } = await import("./open-api-client-L472YVI6.js");
1899
1993
  const result = await callOpenApiOperation({
1900
1994
  operationId,
1901
1995
  params,
@@ -1930,7 +2024,7 @@ scopes: ${identity.token.scopes.join(", ") || "(none)"}
1930
2024
  mcpUrl,
1931
2025
  org
1932
2026
  });
1933
- const { callOpenApiOperation: callOpenApiOperation2 } = await import("./open-api-client-K2BEQBO3.js");
2027
+ const { callOpenApiOperation: callOpenApiOperation2 } = await import("./open-api-client-L472YVI6.js");
1934
2028
  write(
1935
2029
  await runPackageCollaboratorPlan({
1936
2030
  plan,
@@ -1956,7 +2050,7 @@ ${packageCollaboratorUsage}`
1956
2050
  positional: parsed.positionals[1],
1957
2051
  paramsJson: typeof parsed.values.params === "string" ? parsed.values.params : void 0
1958
2052
  });
1959
- const { callOpenApiOperation } = await import("./open-api-client-K2BEQBO3.js");
2053
+ const { callOpenApiOperation } = await import("./open-api-client-L472YVI6.js");
1960
2054
  const publishToken = await accessTokenForOpenApi({
1961
2055
  tokenValues,
1962
2056
  apiUrl,
@@ -2094,7 +2188,7 @@ function attachExecuteCommonArgs(args, input) {
2094
2188
  return args;
2095
2189
  }
2096
2190
  async function runAuthSetupGit(input) {
2097
- const { authSetupGit, setupGitDefaultScopes } = await import("./setup-git-DCMWZYIG.js");
2191
+ const { authSetupGit, setupGitDefaultScopes } = await import("./setup-git-WDMOJAFN.js");
2098
2192
  const apiUrl = apiUrlFrom({
2099
2193
  apiUrl: typeof input.values["api-url"] === "string" ? input.values["api-url"] : void 0
2100
2194
  });
@@ -2151,7 +2245,7 @@ async function runAuthSetupGit(input) {
2151
2245
  return 0;
2152
2246
  }
2153
2247
  async function runAuthRemoveGit(input) {
2154
- const { authRemoveGit, formatAuthRemoveGitReport } = await import("./setup-git-DCMWZYIG.js");
2248
+ const { authRemoveGit, formatAuthRemoveGitReport } = await import("./setup-git-WDMOJAFN.js");
2155
2249
  const apiUrl = apiUrlFrom({
2156
2250
  apiUrl: typeof input.values["api-url"] === "string" ? input.values["api-url"] : void 0
2157
2251
  });
@@ -2179,7 +2273,7 @@ function bootstrapMinter(input) {
2179
2273
  apiUrl: input.apiUrl
2180
2274
  }
2181
2275
  );
2182
- const { callOpenApiOperation } = await import("./open-api-client-K2BEQBO3.js");
2276
+ const { callOpenApiOperation } = await import("./open-api-client-L472YVI6.js");
2183
2277
  try {
2184
2278
  return await callOpenApiOperation({
2185
2279
  token,
@@ -2200,13 +2294,13 @@ function bootstrapMinter(input) {
2200
2294
  if (loadCredentials(input.mcpUrl, void 0, void 0, {
2201
2295
  org: input.org
2202
2296
  })) {
2203
- const { ensureOpenApiCredentials } = await import("./auth-YUFNOOTY.js");
2297
+ const { ensureOpenApiCredentials } = await import("./auth-KD6IT7RH.js");
2204
2298
  const session = await ensureOpenApiCredentials({
2205
2299
  mcpUrl: input.mcpUrl,
2206
2300
  apiUrl: input.apiUrl,
2207
2301
  ...input.org ? { org: input.org } : {}
2208
2302
  });
2209
- const { callOpenApiOperation } = await import("./open-api-client-K2BEQBO3.js");
2303
+ const { callOpenApiOperation } = await import("./open-api-client-L472YVI6.js");
2210
2304
  return callOpenApiOperation({
2211
2305
  operationId: cliCredentialBootstrapOperationId,
2212
2306
  params,
@@ -2232,7 +2326,7 @@ async function accessTokenForOpenApi(input) {
2232
2326
  apiUrl: input.apiUrl
2233
2327
  });
2234
2328
  if (explicit) return explicit;
2235
- const { ensureOpenApiCredentials } = await import("./auth-YUFNOOTY.js");
2329
+ const { ensureOpenApiCredentials } = await import("./auth-KD6IT7RH.js");
2236
2330
  const session = await ensureOpenApiCredentials({
2237
2331
  mcpUrl: input.mcpUrl,
2238
2332
  apiUrl: input.apiUrl,
@@ -2317,4 +2411,4 @@ export {
2317
2411
  resolvePackagePublishTarget,
2318
2412
  shouldUseApiToken
2319
2413
  };
2320
- //# sourceMappingURL=chunk-AFGRPGHE.js.map
2414
+ //# sourceMappingURL=chunk-2DCCAVPD.js.map