@aaronsb/kg-cli 0.6.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.
Files changed (266) hide show
  1. package/README.md +112 -0
  2. package/dist/api/client.d.ts +867 -0
  3. package/dist/api/client.d.ts.map +1 -0
  4. package/dist/api/client.js +1362 -0
  5. package/dist/api/client.js.map +1 -0
  6. package/dist/cli/admin/backup.d.ts +9 -0
  7. package/dist/cli/admin/backup.d.ts.map +1 -0
  8. package/dist/cli/admin/backup.js +363 -0
  9. package/dist/cli/admin/backup.js.map +1 -0
  10. package/dist/cli/admin/index.d.ts +7 -0
  11. package/dist/cli/admin/index.d.ts.map +1 -0
  12. package/dist/cli/admin/index.js +52 -0
  13. package/dist/cli/admin/index.js.map +1 -0
  14. package/dist/cli/admin/scheduler.d.ts +7 -0
  15. package/dist/cli/admin/scheduler.d.ts.map +1 -0
  16. package/dist/cli/admin/scheduler.js +125 -0
  17. package/dist/cli/admin/scheduler.js.map +1 -0
  18. package/dist/cli/admin/status.d.ts +7 -0
  19. package/dist/cli/admin/status.d.ts.map +1 -0
  20. package/dist/cli/admin/status.js +134 -0
  21. package/dist/cli/admin/status.js.map +1 -0
  22. package/dist/cli/admin/utils.d.ts +34 -0
  23. package/dist/cli/admin/utils.d.ts.map +1 -0
  24. package/dist/cli/admin/utils.js +441 -0
  25. package/dist/cli/admin/utils.js.map +1 -0
  26. package/dist/cli/ai-config/embedding.d.ts +11 -0
  27. package/dist/cli/ai-config/embedding.d.ts.map +1 -0
  28. package/dist/cli/ai-config/embedding.js +598 -0
  29. package/dist/cli/ai-config/embedding.js.map +1 -0
  30. package/dist/cli/ai-config/extraction.d.ts +11 -0
  31. package/dist/cli/ai-config/extraction.d.ts.map +1 -0
  32. package/dist/cli/ai-config/extraction.js +206 -0
  33. package/dist/cli/ai-config/extraction.js.map +1 -0
  34. package/dist/cli/ai-config/index.d.ts +21 -0
  35. package/dist/cli/ai-config/index.d.ts.map +1 -0
  36. package/dist/cli/ai-config/index.js +27 -0
  37. package/dist/cli/ai-config/index.js.map +1 -0
  38. package/dist/cli/ai-config/keys.d.ts +11 -0
  39. package/dist/cli/ai-config/keys.d.ts.map +1 -0
  40. package/dist/cli/ai-config/keys.js +182 -0
  41. package/dist/cli/ai-config/keys.js.map +1 -0
  42. package/dist/cli/ai-config/utils.d.ts +13 -0
  43. package/dist/cli/ai-config/utils.d.ts.map +1 -0
  44. package/dist/cli/ai-config/utils.js +84 -0
  45. package/dist/cli/ai-config/utils.js.map +1 -0
  46. package/dist/cli/artifact.d.ts +8 -0
  47. package/dist/cli/artifact.d.ts.map +1 -0
  48. package/dist/cli/artifact.js +296 -0
  49. package/dist/cli/artifact.js.map +1 -0
  50. package/dist/cli/auth-admin.d.ts +11 -0
  51. package/dist/cli/auth-admin.d.ts.map +1 -0
  52. package/dist/cli/auth-admin.js +415 -0
  53. package/dist/cli/auth-admin.js.map +1 -0
  54. package/dist/cli/colors.d.ts +105 -0
  55. package/dist/cli/colors.d.ts.map +1 -0
  56. package/dist/cli/colors.js +164 -0
  57. package/dist/cli/colors.js.map +1 -0
  58. package/dist/cli/commands.d.ts +6 -0
  59. package/dist/cli/commands.d.ts.map +1 -0
  60. package/dist/cli/commands.js +164 -0
  61. package/dist/cli/commands.js.map +1 -0
  62. package/dist/cli/config.d.ts +6 -0
  63. package/dist/cli/config.d.ts.map +1 -0
  64. package/dist/cli/config.js +694 -0
  65. package/dist/cli/config.js.map +1 -0
  66. package/dist/cli/curve-viz.d.ts +89 -0
  67. package/dist/cli/curve-viz.d.ts.map +1 -0
  68. package/dist/cli/curve-viz.js +228 -0
  69. package/dist/cli/curve-viz.js.map +1 -0
  70. package/dist/cli/database.d.ts +6 -0
  71. package/dist/cli/database.d.ts.map +1 -0
  72. package/dist/cli/database.js +324 -0
  73. package/dist/cli/database.js.map +1 -0
  74. package/dist/cli/document.d.ts +6 -0
  75. package/dist/cli/document.d.ts.map +1 -0
  76. package/dist/cli/document.js +458 -0
  77. package/dist/cli/document.js.map +1 -0
  78. package/dist/cli/group.d.ts +8 -0
  79. package/dist/cli/group.d.ts.map +1 -0
  80. package/dist/cli/group.js +174 -0
  81. package/dist/cli/group.js.map +1 -0
  82. package/dist/cli/health.d.ts +6 -0
  83. package/dist/cli/health.d.ts.map +1 -0
  84. package/dist/cli/health.js +34 -0
  85. package/dist/cli/health.js.map +1 -0
  86. package/dist/cli/help-formatter.d.ts +16 -0
  87. package/dist/cli/help-formatter.d.ts.map +1 -0
  88. package/dist/cli/help-formatter.js +248 -0
  89. package/dist/cli/help-formatter.js.map +1 -0
  90. package/dist/cli/help.d.ts +9 -0
  91. package/dist/cli/help.d.ts.map +1 -0
  92. package/dist/cli/help.js +227 -0
  93. package/dist/cli/help.js.map +1 -0
  94. package/dist/cli/ingest.d.ts +6 -0
  95. package/dist/cli/ingest.d.ts.map +1 -0
  96. package/dist/cli/ingest.js +722 -0
  97. package/dist/cli/ingest.js.map +1 -0
  98. package/dist/cli/jobs.d.ts +6 -0
  99. package/dist/cli/jobs.d.ts.map +1 -0
  100. package/dist/cli/jobs.js +663 -0
  101. package/dist/cli/jobs.js.map +1 -0
  102. package/dist/cli/login.d.ts +21 -0
  103. package/dist/cli/login.d.ts.map +1 -0
  104. package/dist/cli/login.js +221 -0
  105. package/dist/cli/login.js.map +1 -0
  106. package/dist/cli/logout.d.ts +16 -0
  107. package/dist/cli/logout.d.ts.map +1 -0
  108. package/dist/cli/logout.js +141 -0
  109. package/dist/cli/logout.js.map +1 -0
  110. package/dist/cli/mcp-config.d.ts +10 -0
  111. package/dist/cli/mcp-config.d.ts.map +1 -0
  112. package/dist/cli/mcp-config.js +358 -0
  113. package/dist/cli/mcp-config.js.map +1 -0
  114. package/dist/cli/oauth.d.ts +15 -0
  115. package/dist/cli/oauth.d.ts.map +1 -0
  116. package/dist/cli/oauth.js +296 -0
  117. package/dist/cli/oauth.js.map +1 -0
  118. package/dist/cli/ontology.d.ts +6 -0
  119. package/dist/cli/ontology.d.ts.map +1 -0
  120. package/dist/cli/ontology.js +231 -0
  121. package/dist/cli/ontology.js.map +1 -0
  122. package/dist/cli/polarity.d.ts +6 -0
  123. package/dist/cli/polarity.d.ts.map +1 -0
  124. package/dist/cli/polarity.js +295 -0
  125. package/dist/cli/polarity.js.map +1 -0
  126. package/dist/cli/projection.d.ts +8 -0
  127. package/dist/cli/projection.d.ts.map +1 -0
  128. package/dist/cli/projection.js +297 -0
  129. package/dist/cli/projection.js.map +1 -0
  130. package/dist/cli/query-def.d.ts +8 -0
  131. package/dist/cli/query-def.d.ts.map +1 -0
  132. package/dist/cli/query-def.js +163 -0
  133. package/dist/cli/query-def.js.map +1 -0
  134. package/dist/cli/rbac.d.ts +12 -0
  135. package/dist/cli/rbac.d.ts.map +1 -0
  136. package/dist/cli/rbac.js +615 -0
  137. package/dist/cli/rbac.js.map +1 -0
  138. package/dist/cli/search.d.ts +6 -0
  139. package/dist/cli/search.d.ts.map +1 -0
  140. package/dist/cli/search.js +829 -0
  141. package/dist/cli/search.js.map +1 -0
  142. package/dist/cli/source.d.ts +6 -0
  143. package/dist/cli/source.d.ts.map +1 -0
  144. package/dist/cli/source.js +202 -0
  145. package/dist/cli/source.js.map +1 -0
  146. package/dist/cli/verb-router.d.ts +25 -0
  147. package/dist/cli/verb-router.d.ts.map +1 -0
  148. package/dist/cli/verb-router.js +415 -0
  149. package/dist/cli/verb-router.js.map +1 -0
  150. package/dist/cli/vocabulary/config.d.ts +7 -0
  151. package/dist/cli/vocabulary/config.d.ts.map +1 -0
  152. package/dist/cli/vocabulary/config.js +201 -0
  153. package/dist/cli/vocabulary/config.js.map +1 -0
  154. package/dist/cli/vocabulary/consolidate.d.ts +8 -0
  155. package/dist/cli/vocabulary/consolidate.d.ts.map +1 -0
  156. package/dist/cli/vocabulary/consolidate.js +192 -0
  157. package/dist/cli/vocabulary/consolidate.js.map +1 -0
  158. package/dist/cli/vocabulary/embeddings.d.ts +9 -0
  159. package/dist/cli/vocabulary/embeddings.d.ts.map +1 -0
  160. package/dist/cli/vocabulary/embeddings.js +205 -0
  161. package/dist/cli/vocabulary/embeddings.js.map +1 -0
  162. package/dist/cli/vocabulary/epistemic.d.ts +7 -0
  163. package/dist/cli/vocabulary/epistemic.d.ts.map +1 -0
  164. package/dist/cli/vocabulary/epistemic.js +315 -0
  165. package/dist/cli/vocabulary/epistemic.js.map +1 -0
  166. package/dist/cli/vocabulary/index.d.ts +7 -0
  167. package/dist/cli/vocabulary/index.d.ts.map +1 -0
  168. package/dist/cli/vocabulary/index.js +45 -0
  169. package/dist/cli/vocabulary/index.js.map +1 -0
  170. package/dist/cli/vocabulary/profiles.d.ts +7 -0
  171. package/dist/cli/vocabulary/profiles.d.ts.map +1 -0
  172. package/dist/cli/vocabulary/profiles.js +171 -0
  173. package/dist/cli/vocabulary/profiles.js.map +1 -0
  174. package/dist/cli/vocabulary/similarity.d.ts +9 -0
  175. package/dist/cli/vocabulary/similarity.d.ts.map +1 -0
  176. package/dist/cli/vocabulary/similarity.js +199 -0
  177. package/dist/cli/vocabulary/similarity.js.map +1 -0
  178. package/dist/cli/vocabulary/status.d.ts +8 -0
  179. package/dist/cli/vocabulary/status.d.ts.map +1 -0
  180. package/dist/cli/vocabulary/status.js +280 -0
  181. package/dist/cli/vocabulary/status.js.map +1 -0
  182. package/dist/cli/vocabulary/sync.d.ts +7 -0
  183. package/dist/cli/vocabulary/sync.d.ts.map +1 -0
  184. package/dist/cli/vocabulary/sync.js +111 -0
  185. package/dist/cli/vocabulary/sync.js.map +1 -0
  186. package/dist/index.d.ts +9 -0
  187. package/dist/index.d.ts.map +1 -0
  188. package/dist/index.js +16 -0
  189. package/dist/index.js.map +1 -0
  190. package/dist/lib/auth/auth-client.d.ts +247 -0
  191. package/dist/lib/auth/auth-client.d.ts.map +1 -0
  192. package/dist/lib/auth/auth-client.js +305 -0
  193. package/dist/lib/auth/auth-client.js.map +1 -0
  194. package/dist/lib/auth/challenge.d.ts +39 -0
  195. package/dist/lib/auth/challenge.d.ts.map +1 -0
  196. package/dist/lib/auth/challenge.js +125 -0
  197. package/dist/lib/auth/challenge.js.map +1 -0
  198. package/dist/lib/auth/client-credentials-flow.d.ts +58 -0
  199. package/dist/lib/auth/client-credentials-flow.d.ts.map +1 -0
  200. package/dist/lib/auth/client-credentials-flow.js +118 -0
  201. package/dist/lib/auth/client-credentials-flow.js.map +1 -0
  202. package/dist/lib/auth/device-flow.d.ts +75 -0
  203. package/dist/lib/auth/device-flow.d.ts.map +1 -0
  204. package/dist/lib/auth/device-flow.js +177 -0
  205. package/dist/lib/auth/device-flow.js.map +1 -0
  206. package/dist/lib/auth/index.d.ts +14 -0
  207. package/dist/lib/auth/index.d.ts.map +1 -0
  208. package/dist/lib/auth/index.js +34 -0
  209. package/dist/lib/auth/index.js.map +1 -0
  210. package/dist/lib/auth/oauth-types.d.ts +69 -0
  211. package/dist/lib/auth/oauth-types.d.ts.map +1 -0
  212. package/dist/lib/auth/oauth-types.js +10 -0
  213. package/dist/lib/auth/oauth-types.js.map +1 -0
  214. package/dist/lib/auth/oauth-utils.d.ts +51 -0
  215. package/dist/lib/auth/oauth-utils.d.ts.map +1 -0
  216. package/dist/lib/auth/oauth-utils.js +110 -0
  217. package/dist/lib/auth/oauth-utils.js.map +1 -0
  218. package/dist/lib/auth/token-manager.d.ts +87 -0
  219. package/dist/lib/auth/token-manager.d.ts.map +1 -0
  220. package/dist/lib/auth/token-manager.js +139 -0
  221. package/dist/lib/auth/token-manager.js.map +1 -0
  222. package/dist/lib/auth/token-refresh.d.ts +63 -0
  223. package/dist/lib/auth/token-refresh.d.ts.map +1 -0
  224. package/dist/lib/auth/token-refresh.js +141 -0
  225. package/dist/lib/auth/token-refresh.js.map +1 -0
  226. package/dist/lib/config.d.ts +286 -0
  227. package/dist/lib/config.d.ts.map +1 -0
  228. package/dist/lib/config.js +537 -0
  229. package/dist/lib/config.js.map +1 -0
  230. package/dist/lib/job-stream.d.ts +53 -0
  231. package/dist/lib/job-stream.d.ts.map +1 -0
  232. package/dist/lib/job-stream.js +153 -0
  233. package/dist/lib/job-stream.js.map +1 -0
  234. package/dist/lib/mcp-allowlist.d.ts +101 -0
  235. package/dist/lib/mcp-allowlist.d.ts.map +1 -0
  236. package/dist/lib/mcp-allowlist.js +340 -0
  237. package/dist/lib/mcp-allowlist.js.map +1 -0
  238. package/dist/lib/table-example.d.ts +7 -0
  239. package/dist/lib/table-example.d.ts.map +1 -0
  240. package/dist/lib/table-example.js +105 -0
  241. package/dist/lib/table-example.js.map +1 -0
  242. package/dist/lib/table.d.ts +95 -0
  243. package/dist/lib/table.d.ts.map +1 -0
  244. package/dist/lib/table.js +263 -0
  245. package/dist/lib/table.js.map +1 -0
  246. package/dist/lib/terminal-images.d.ts +66 -0
  247. package/dist/lib/terminal-images.d.ts.map +1 -0
  248. package/dist/lib/terminal-images.js +268 -0
  249. package/dist/lib/terminal-images.js.map +1 -0
  250. package/dist/mcp/formatters.d.ts +100 -0
  251. package/dist/mcp/formatters.d.ts.map +1 -0
  252. package/dist/mcp/formatters.js +1411 -0
  253. package/dist/mcp/formatters.js.map +1 -0
  254. package/dist/mcp-server.d.ts +9 -0
  255. package/dist/mcp-server.d.ts.map +1 -0
  256. package/dist/mcp-server.js +1810 -0
  257. package/dist/mcp-server.js.map +1 -0
  258. package/dist/types/index.d.ts +742 -0
  259. package/dist/types/index.d.ts.map +1 -0
  260. package/dist/types/index.js +6 -0
  261. package/dist/types/index.js.map +1 -0
  262. package/dist/version.d.ts +10 -0
  263. package/dist/version.d.ts.map +1 -0
  264. package/dist/version.js +13 -0
  265. package/dist/version.js.map +1 -0
  266. package/package.json +84 -0
@@ -0,0 +1,75 @@
1
+ /**
2
+ * OAuth Device Authorization Grant Flow (ADR-054)
3
+ *
4
+ * Implements RFC 8628 Device Authorization Grant for CLI authentication.
5
+ *
6
+ * Flow:
7
+ * 1. Request device and user codes from server
8
+ * 2. Display user_code to user with verification URL
9
+ * 3. Poll token endpoint until user authorizes (or timeout/denial)
10
+ * 4. Store access and refresh tokens
11
+ *
12
+ * Usage:
13
+ * const flow = new DeviceAuthFlow(apiUrl, clientId);
14
+ * const codes = await flow.requestDeviceCode();
15
+ * console.log(`Go to ${codes.verification_uri} and enter: ${codes.user_code}`);
16
+ * const tokens = await flow.pollForToken(codes.device_code, codes.interval);
17
+ */
18
+ import type { DeviceAuthorizationResponse, OAuthTokenInfo } from './oauth-types';
19
+ export interface DeviceFlowCallbacks {
20
+ onDeviceCodeReceived?: (codes: DeviceAuthorizationResponse) => void;
21
+ onPollStart?: () => void;
22
+ onPollTick?: (attempt: number) => void;
23
+ onAuthorizationPending?: () => void;
24
+ onSlowDown?: () => void;
25
+ onSuccess?: (tokenInfo: OAuthTokenInfo) => void;
26
+ onError?: (error: Error) => void;
27
+ }
28
+ export declare class DeviceAuthFlow {
29
+ private client;
30
+ private clientId;
31
+ constructor(apiUrl: string, clientId?: string);
32
+ /**
33
+ * Step 1: Request device and user codes from the authorization server
34
+ *
35
+ * POST /auth/oauth/device
36
+ * Body: client_id=kg-cli&scope=read:* write:*
37
+ *
38
+ * Returns codes and verification URL for the user
39
+ */
40
+ requestDeviceCode(scope?: string): Promise<DeviceAuthorizationResponse>;
41
+ /**
42
+ * Step 2: Poll token endpoint until user authorizes
43
+ *
44
+ * POST /auth/oauth/token
45
+ * Body: grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=<code>&client_id=kg-cli
46
+ *
47
+ * Polls every `interval` seconds until:
48
+ * - User authorizes (returns tokens)
49
+ * - User denies (throws error)
50
+ * - Device code expires (throws error)
51
+ * - Timeout reached (throws error)
52
+ *
53
+ * @param deviceCode - Device code from requestDeviceCode()
54
+ * @param interval - Polling interval in seconds (from requestDeviceCode())
55
+ * @param maxAttempts - Maximum number of poll attempts (default: 120 = 10 minutes at 5s interval)
56
+ * @param callbacks - Optional callbacks for progress tracking
57
+ * @returns OAuth token information
58
+ */
59
+ pollForToken(deviceCode: string, interval?: number, maxAttempts?: number, callbacks?: DeviceFlowCallbacks): Promise<OAuthTokenInfo>;
60
+ /**
61
+ * Complete device flow: request codes and poll for token
62
+ *
63
+ * Convenience method that combines requestDeviceCode() and pollForToken()
64
+ *
65
+ * @param scope - OAuth scopes to request
66
+ * @param callbacks - Optional callbacks for progress tracking
67
+ * @returns OAuth token information
68
+ */
69
+ authenticate(scope?: string, callbacks?: DeviceFlowCallbacks): Promise<OAuthTokenInfo>;
70
+ /**
71
+ * Sleep utility for polling
72
+ */
73
+ private sleep;
74
+ }
75
+ //# sourceMappingURL=device-flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-flow.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/device-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EACV,2BAA2B,EAE3B,cAAc,EAEf,MAAM,eAAe,CAAC;AAGvB,MAAM,WAAW,mBAAmB;IAClC,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,CAAC;IACpE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAS;gBAEb,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAiB;IAWvD;;;;;;;OAOG;IACG,iBAAiB,CAAC,KAAK,GAAE,MAAyB,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAyB/F;;;;;;;;;;;;;;;;;OAiBG;IACG,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,MAAU,EACpB,WAAW,GAAE,MAAY,EACzB,SAAS,CAAC,EAAE,mBAAmB,GAC9B,OAAO,CAAC,cAAc,CAAC;IA+E1B;;;;;;;;OAQG;IACG,YAAY,CAAC,KAAK,GAAE,MAAyB,EAAE,SAAS,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;IAS9G;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd"}
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth Device Authorization Grant Flow (ADR-054)
4
+ *
5
+ * Implements RFC 8628 Device Authorization Grant for CLI authentication.
6
+ *
7
+ * Flow:
8
+ * 1. Request device and user codes from server
9
+ * 2. Display user_code to user with verification URL
10
+ * 3. Poll token endpoint until user authorizes (or timeout/denial)
11
+ * 4. Store access and refresh tokens
12
+ *
13
+ * Usage:
14
+ * const flow = new DeviceAuthFlow(apiUrl, clientId);
15
+ * const codes = await flow.requestDeviceCode();
16
+ * console.log(`Go to ${codes.verification_uri} and enter: ${codes.user_code}`);
17
+ * const tokens = await flow.pollForToken(codes.device_code, codes.interval);
18
+ */
19
+ var __importDefault = (this && this.__importDefault) || function (mod) {
20
+ return (mod && mod.__esModule) ? mod : { "default": mod };
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.DeviceAuthFlow = void 0;
24
+ const axios_1 = __importDefault(require("axios"));
25
+ const oauth_utils_1 = require("./oauth-utils");
26
+ class DeviceAuthFlow {
27
+ constructor(apiUrl, clientId = 'kg-cli') {
28
+ this.clientId = clientId;
29
+ this.client = axios_1.default.create({
30
+ baseURL: apiUrl,
31
+ headers: {
32
+ 'Content-Type': 'application/x-www-form-urlencoded',
33
+ },
34
+ timeout: 10000, // 10 seconds for API calls
35
+ });
36
+ }
37
+ /**
38
+ * Step 1: Request device and user codes from the authorization server
39
+ *
40
+ * POST /auth/oauth/device
41
+ * Body: client_id=kg-cli&scope=read:* write:*
42
+ *
43
+ * Returns codes and verification URL for the user
44
+ */
45
+ async requestDeviceCode(scope = 'read:* write:*') {
46
+ try {
47
+ const params = new URLSearchParams({
48
+ client_id: this.clientId,
49
+ scope: scope,
50
+ });
51
+ const response = await this.client.post('/auth/oauth/device', params.toString());
52
+ return response.data;
53
+ }
54
+ catch (error) {
55
+ if (axios_1.default.isAxiosError(error)) {
56
+ const axiosError = error;
57
+ const errorMessage = axiosError.response?.data?.error_description ||
58
+ axiosError.response?.data?.error ||
59
+ axiosError.message;
60
+ throw new Error(`Failed to request device code: ${errorMessage}`);
61
+ }
62
+ throw error;
63
+ }
64
+ }
65
+ /**
66
+ * Step 2: Poll token endpoint until user authorizes
67
+ *
68
+ * POST /auth/oauth/token
69
+ * Body: grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=<code>&client_id=kg-cli
70
+ *
71
+ * Polls every `interval` seconds until:
72
+ * - User authorizes (returns tokens)
73
+ * - User denies (throws error)
74
+ * - Device code expires (throws error)
75
+ * - Timeout reached (throws error)
76
+ *
77
+ * @param deviceCode - Device code from requestDeviceCode()
78
+ * @param interval - Polling interval in seconds (from requestDeviceCode())
79
+ * @param maxAttempts - Maximum number of poll attempts (default: 120 = 10 minutes at 5s interval)
80
+ * @param callbacks - Optional callbacks for progress tracking
81
+ * @returns OAuth token information
82
+ */
83
+ async pollForToken(deviceCode, interval = 5, maxAttempts = 120, callbacks) {
84
+ callbacks?.onPollStart?.();
85
+ let attempt = 0;
86
+ let currentInterval = interval * 1000; // Convert to milliseconds
87
+ while (attempt < maxAttempts) {
88
+ attempt++;
89
+ callbacks?.onPollTick?.(attempt);
90
+ try {
91
+ // Wait before polling (except first attempt)
92
+ if (attempt > 1) {
93
+ await this.sleep(currentInterval);
94
+ }
95
+ const params = new URLSearchParams({
96
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
97
+ device_code: deviceCode,
98
+ client_id: this.clientId,
99
+ });
100
+ const response = await this.client.post('/auth/oauth/token', params.toString());
101
+ // Success! User authorized
102
+ const tokenInfo = (0, oauth_utils_1.convertTokenResponse)(response.data, this.clientId);
103
+ callbacks?.onSuccess?.(tokenInfo);
104
+ return tokenInfo;
105
+ }
106
+ catch (error) {
107
+ if (axios_1.default.isAxiosError(error)) {
108
+ const axiosError = error;
109
+ const errorCode = axiosError.response?.data?.error;
110
+ const errorDescription = axiosError.response?.data?.error_description;
111
+ // Handle OAuth error responses
112
+ if (errorCode === 'authorization_pending') {
113
+ // User hasn't completed authorization yet - continue polling
114
+ callbacks?.onAuthorizationPending?.();
115
+ continue;
116
+ }
117
+ else if (errorCode === 'slow_down') {
118
+ // Server requested slower polling - increase interval by 5 seconds
119
+ currentInterval += 5000;
120
+ callbacks?.onSlowDown?.();
121
+ continue;
122
+ }
123
+ else if (errorCode === 'access_denied') {
124
+ // User explicitly denied authorization
125
+ const err = new Error('User denied authorization');
126
+ callbacks?.onError?.(err);
127
+ throw err;
128
+ }
129
+ else if (errorCode === 'expired_token' || errorDescription?.includes('expired')) {
130
+ // Device code expired
131
+ const err = new Error('Device code expired. Please try again.');
132
+ callbacks?.onError?.(err);
133
+ throw err;
134
+ }
135
+ else {
136
+ // Other OAuth error
137
+ const err = new Error(`OAuth error: ${errorDescription || errorCode || axiosError.message}`);
138
+ callbacks?.onError?.(err);
139
+ throw err;
140
+ }
141
+ }
142
+ // Non-axios error
143
+ const err = error instanceof Error ? error : new Error('Unknown error during polling');
144
+ callbacks?.onError?.(err);
145
+ throw err;
146
+ }
147
+ }
148
+ // Max attempts reached
149
+ const err = new Error('Polling timeout: User did not authorize within the expected time');
150
+ callbacks?.onError?.(err);
151
+ throw err;
152
+ }
153
+ /**
154
+ * Complete device flow: request codes and poll for token
155
+ *
156
+ * Convenience method that combines requestDeviceCode() and pollForToken()
157
+ *
158
+ * @param scope - OAuth scopes to request
159
+ * @param callbacks - Optional callbacks for progress tracking
160
+ * @returns OAuth token information
161
+ */
162
+ async authenticate(scope = 'read:* write:*', callbacks) {
163
+ // Step 1: Get device and user codes
164
+ const codes = await this.requestDeviceCode(scope);
165
+ callbacks?.onDeviceCodeReceived?.(codes);
166
+ // Step 2: Poll for token
167
+ return await this.pollForToken(codes.device_code, codes.interval, undefined, callbacks);
168
+ }
169
+ /**
170
+ * Sleep utility for polling
171
+ */
172
+ sleep(ms) {
173
+ return new Promise(resolve => setTimeout(resolve, ms));
174
+ }
175
+ }
176
+ exports.DeviceAuthFlow = DeviceAuthFlow;
177
+ //# sourceMappingURL=device-flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-flow.js","sourceRoot":"","sources":["../../../src/lib/auth/device-flow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * OAuth 2.0 Authentication Library (ADR-054)
3
+ *
4
+ * Exports all OAuth utilities for CLI and MCP authentication
5
+ */
6
+ export * from './oauth-types';
7
+ export * from './oauth-utils';
8
+ export * from './device-flow';
9
+ export * from './client-credentials-flow';
10
+ export * from './token-refresh';
11
+ export * from './auth-client';
12
+ export * from './challenge';
13
+ export * from './token-manager';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,eAAe,CAAC;AAG9B,cAAc,eAAe,CAAC;AAG9B,cAAc,eAAe,CAAC;AAC9B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAGhC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth 2.0 Authentication Library (ADR-054)
4
+ *
5
+ * Exports all OAuth utilities for CLI and MCP authentication
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
19
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ // Types
23
+ __exportStar(require("./oauth-types"), exports);
24
+ // Utilities
25
+ __exportStar(require("./oauth-utils"), exports);
26
+ // Flow implementations
27
+ __exportStar(require("./device-flow"), exports);
28
+ __exportStar(require("./client-credentials-flow"), exports);
29
+ __exportStar(require("./token-refresh"), exports);
30
+ // Legacy exports (keeping for backward compatibility during migration)
31
+ __exportStar(require("./auth-client"), exports);
32
+ __exportStar(require("./challenge"), exports);
33
+ __exportStar(require("./token-manager"), exports);
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/auth/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;AAEH,QAAQ;AACR,gDAA8B;AAE9B,YAAY;AACZ,gDAA8B;AAE9B,uBAAuB;AACvB,gDAA8B;AAC9B,4DAA0C;AAC1C,kDAAgC;AAEhC,uEAAuE;AACvE,gDAA8B;AAC9B,8CAA4B;AAC5B,kDAAgC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * OAuth 2.0 Type Definitions (ADR-054)
3
+ *
4
+ * Shared types for OAuth client flows:
5
+ * - Device Authorization Grant (CLI)
6
+ * - Client Credentials (MCP)
7
+ */
8
+ /**
9
+ * OAuth token response from token endpoint
10
+ */
11
+ export interface OAuthTokenResponse {
12
+ access_token: string;
13
+ token_type: string;
14
+ expires_in: number;
15
+ refresh_token?: string;
16
+ scope: string;
17
+ }
18
+ /**
19
+ * Device authorization response (RFC 8628)
20
+ */
21
+ export interface DeviceAuthorizationResponse {
22
+ device_code: string;
23
+ user_code: string;
24
+ verification_uri: string;
25
+ verification_uri_complete?: string;
26
+ expires_in: number;
27
+ interval: number;
28
+ }
29
+ /**
30
+ * Device code status
31
+ */
32
+ export interface DeviceCodeStatus {
33
+ status: 'pending' | 'authorized' | 'denied' | 'expired';
34
+ user_code: string;
35
+ expires_at: string;
36
+ }
37
+ /**
38
+ * OAuth error response (RFC 6749)
39
+ */
40
+ export interface OAuthErrorResponse {
41
+ error: string;
42
+ error_description?: string;
43
+ error_uri?: string;
44
+ }
45
+ /**
46
+ * Stored OAuth token information
47
+ */
48
+ export interface OAuthTokenInfo {
49
+ access_token: string;
50
+ token_type: string;
51
+ expires_at: number;
52
+ refresh_token?: string;
53
+ scope: string;
54
+ client_id: string;
55
+ }
56
+ /**
57
+ * OAuth grant types
58
+ */
59
+ export type OAuthGrantType = 'authorization_code' | 'urn:ietf:params:oauth:grant-type:device_code' | 'client_credentials' | 'refresh_token';
60
+ /**
61
+ * OAuth client configuration
62
+ */
63
+ export interface OAuthClientConfig {
64
+ client_id: string;
65
+ client_secret?: string;
66
+ grant_types: OAuthGrantType[];
67
+ api_url: string;
68
+ }
69
+ //# sourceMappingURL=oauth-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-types.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/oauth-types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,oBAAoB,GACpB,8CAA8C,GAC9C,oBAAoB,GACpB,eAAe,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth 2.0 Type Definitions (ADR-054)
4
+ *
5
+ * Shared types for OAuth client flows:
6
+ * - Device Authorization Grant (CLI)
7
+ * - Client Credentials (MCP)
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ //# sourceMappingURL=oauth-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-types.js","sourceRoot":"","sources":["../../../src/lib/auth/oauth-types.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * OAuth 2.0 Utility Functions (ADR-054)
3
+ *
4
+ * Shared utilities for OAuth token management
5
+ */
6
+ import { OAuthTokenInfo, OAuthTokenResponse } from './oauth-types';
7
+ /**
8
+ * Check if an OAuth token is expired or about to expire
9
+ *
10
+ * @param tokenInfo - Token information with expires_at timestamp
11
+ * @param bufferSeconds - How many seconds before expiry to consider token expired (default: 60)
12
+ * @returns true if token is expired or will expire within buffer period
13
+ */
14
+ export declare function isTokenExpired(tokenInfo: OAuthTokenInfo | null, bufferSeconds?: number): boolean;
15
+ /**
16
+ * Convert OAuth token response to storable token info
17
+ *
18
+ * @param response - Token response from API
19
+ * @param clientId - OAuth client ID
20
+ * @returns Token info object ready for storage
21
+ */
22
+ export declare function convertTokenResponse(response: OAuthTokenResponse, clientId: string): OAuthTokenInfo;
23
+ /**
24
+ * Get time until token expires
25
+ *
26
+ * @param tokenInfo - Token information
27
+ * @returns Seconds until expiration, or 0 if already expired
28
+ */
29
+ export declare function getTimeUntilExpiry(tokenInfo: OAuthTokenInfo | null): number;
30
+ /**
31
+ * Format expiry time as human-readable string
32
+ *
33
+ * @param tokenInfo - Token information
34
+ * @returns Human-readable expiry time (e.g., "in 45 minutes")
35
+ */
36
+ export declare function formatExpiryTime(tokenInfo: OAuthTokenInfo | null): string;
37
+ /**
38
+ * Parse scope string into array
39
+ *
40
+ * @param scope - Space-separated scope string
41
+ * @returns Array of individual scopes
42
+ */
43
+ export declare function parseScopes(scope: string): string[];
44
+ /**
45
+ * Format scope array as space-separated string
46
+ *
47
+ * @param scopes - Array of scopes
48
+ * @returns Space-separated scope string
49
+ */
50
+ export declare function formatScopes(scopes: string[]): string;
51
+ //# sourceMappingURL=oauth-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-utils.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/oauth-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnE;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,EAAE,aAAa,GAAE,MAAW,GAAG,OAAO,CASpG;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAWnG;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,GAAG,MAAM,CAS3E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,GAAG,MAAM,CA2BzE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKnD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAErD"}
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth 2.0 Utility Functions (ADR-054)
4
+ *
5
+ * Shared utilities for OAuth token management
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.isTokenExpired = isTokenExpired;
9
+ exports.convertTokenResponse = convertTokenResponse;
10
+ exports.getTimeUntilExpiry = getTimeUntilExpiry;
11
+ exports.formatExpiryTime = formatExpiryTime;
12
+ exports.parseScopes = parseScopes;
13
+ exports.formatScopes = formatScopes;
14
+ /**
15
+ * Check if an OAuth token is expired or about to expire
16
+ *
17
+ * @param tokenInfo - Token information with expires_at timestamp
18
+ * @param bufferSeconds - How many seconds before expiry to consider token expired (default: 60)
19
+ * @returns true if token is expired or will expire within buffer period
20
+ */
21
+ function isTokenExpired(tokenInfo, bufferSeconds = 60) {
22
+ if (!tokenInfo) {
23
+ return true;
24
+ }
25
+ const now = Math.floor(Date.now() / 1000); // Current time in seconds
26
+ const expiresWithBuffer = tokenInfo.expires_at - bufferSeconds;
27
+ return now >= expiresWithBuffer;
28
+ }
29
+ /**
30
+ * Convert OAuth token response to storable token info
31
+ *
32
+ * @param response - Token response from API
33
+ * @param clientId - OAuth client ID
34
+ * @returns Token info object ready for storage
35
+ */
36
+ function convertTokenResponse(response, clientId) {
37
+ const now = Math.floor(Date.now() / 1000);
38
+ return {
39
+ access_token: response.access_token,
40
+ token_type: response.token_type,
41
+ expires_at: now + response.expires_in,
42
+ refresh_token: response.refresh_token,
43
+ scope: response.scope,
44
+ client_id: clientId,
45
+ };
46
+ }
47
+ /**
48
+ * Get time until token expires
49
+ *
50
+ * @param tokenInfo - Token information
51
+ * @returns Seconds until expiration, or 0 if already expired
52
+ */
53
+ function getTimeUntilExpiry(tokenInfo) {
54
+ if (!tokenInfo) {
55
+ return 0;
56
+ }
57
+ const now = Math.floor(Date.now() / 1000);
58
+ const remaining = tokenInfo.expires_at - now;
59
+ return Math.max(0, remaining);
60
+ }
61
+ /**
62
+ * Format expiry time as human-readable string
63
+ *
64
+ * @param tokenInfo - Token information
65
+ * @returns Human-readable expiry time (e.g., "in 45 minutes")
66
+ */
67
+ function formatExpiryTime(tokenInfo) {
68
+ if (!tokenInfo) {
69
+ return 'expired';
70
+ }
71
+ const seconds = getTimeUntilExpiry(tokenInfo);
72
+ if (seconds === 0) {
73
+ return 'expired';
74
+ }
75
+ if (seconds < 60) {
76
+ return `in ${seconds} second${seconds !== 1 ? 's' : ''}`;
77
+ }
78
+ const minutes = Math.floor(seconds / 60);
79
+ if (minutes < 60) {
80
+ return `in ${minutes} minute${minutes !== 1 ? 's' : ''}`;
81
+ }
82
+ const hours = Math.floor(minutes / 60);
83
+ if (hours < 24) {
84
+ return `in ${hours} hour${hours !== 1 ? 's' : ''}`;
85
+ }
86
+ const days = Math.floor(hours / 24);
87
+ return `in ${days} day${days !== 1 ? 's' : ''}`;
88
+ }
89
+ /**
90
+ * Parse scope string into array
91
+ *
92
+ * @param scope - Space-separated scope string
93
+ * @returns Array of individual scopes
94
+ */
95
+ function parseScopes(scope) {
96
+ if (!scope) {
97
+ return [];
98
+ }
99
+ return scope.trim().split(/\s+/);
100
+ }
101
+ /**
102
+ * Format scope array as space-separated string
103
+ *
104
+ * @param scopes - Array of scopes
105
+ * @returns Space-separated scope string
106
+ */
107
+ function formatScopes(scopes) {
108
+ return scopes.join(' ');
109
+ }
110
+ //# sourceMappingURL=oauth-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-utils.js","sourceRoot":"","sources":["../../../src/lib/auth/oauth-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Token Manager
3
+ *
4
+ * Manages JWT token lifecycle: storage, retrieval, validation, expiration.
5
+ * Tokens are stored in the user's config file (~/.config/kg/config.json).
6
+ */
7
+ import { ConfigManager } from '../config.js';
8
+ export interface TokenInfo {
9
+ access_token: string;
10
+ token_type: string;
11
+ expires_at: number;
12
+ username: string;
13
+ role: string;
14
+ }
15
+ export declare class TokenManager {
16
+ private config;
17
+ constructor(config: ConfigManager);
18
+ /**
19
+ * Store JWT token with metadata
20
+ *
21
+ * @param tokenInfo Token information including access token, expiration, user details
22
+ */
23
+ storeToken(tokenInfo: TokenInfo): void;
24
+ /**
25
+ * Retrieve stored token (returns null if expired or not found)
26
+ *
27
+ * @returns Token information or null if not authenticated
28
+ */
29
+ getToken(): TokenInfo | null;
30
+ /**
31
+ * Check if token is expired (with 5-minute buffer for safety)
32
+ *
33
+ * @param tokenInfo Token information to check
34
+ * @returns true if token is expired or will expire within 5 minutes
35
+ */
36
+ isTokenExpired(tokenInfo: TokenInfo): boolean;
37
+ /**
38
+ * Clear stored token (logout)
39
+ */
40
+ clearToken(): void;
41
+ /**
42
+ * Check if user is logged in (valid token exists)
43
+ *
44
+ * @returns true if user has a valid, non-expired token
45
+ */
46
+ isLoggedIn(): boolean;
47
+ /**
48
+ * Get current username from token
49
+ *
50
+ * @returns Username or null if not logged in
51
+ */
52
+ getUsername(): string | null;
53
+ /**
54
+ * Get current user role from token
55
+ *
56
+ * @returns User role or null if not logged in
57
+ */
58
+ getRole(): string | null;
59
+ /**
60
+ * Get token expiration time as a human-readable string
61
+ *
62
+ * @returns Formatted expiration time or null if not logged in
63
+ */
64
+ getExpirationString(): string | null;
65
+ /**
66
+ * Get minutes until token expiration
67
+ *
68
+ * @returns Minutes until expiration or null if not logged in
69
+ */
70
+ getMinutesUntilExpiration(): number | null;
71
+ /**
72
+ * Create TokenInfo from login response
73
+ *
74
+ * @param loginResponse Response from /auth/login endpoint
75
+ * @returns TokenInfo object ready to be stored
76
+ */
77
+ static fromLoginResponse(loginResponse: {
78
+ access_token: string;
79
+ token_type: string;
80
+ expires_in: number;
81
+ user: {
82
+ username: string;
83
+ role: string;
84
+ };
85
+ }): TokenInfo;
86
+ }
87
+ //# sourceMappingURL=token-manager.d.ts.map