@dharta/cli 0.6.77

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 (259) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +167 -0
  3. package/dist/agent.d.ts +17 -0
  4. package/dist/agent.js +134 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/api-error.d.ts +3 -0
  7. package/dist/api-error.js +80 -0
  8. package/dist/api-error.js.map +1 -0
  9. package/dist/browser.d.ts +1 -0
  10. package/dist/browser.js +19 -0
  11. package/dist/browser.js.map +1 -0
  12. package/dist/cli.d.ts +5 -0
  13. package/dist/cli.js +1978 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/commands/agents.d.ts +131 -0
  16. package/dist/commands/agents.js +439 -0
  17. package/dist/commands/agents.js.map +1 -0
  18. package/dist/commands/analytics.d.ts +25 -0
  19. package/dist/commands/analytics.js +166 -0
  20. package/dist/commands/analytics.js.map +1 -0
  21. package/dist/commands/api.d.ts +19 -0
  22. package/dist/commands/api.js +278 -0
  23. package/dist/commands/api.js.map +1 -0
  24. package/dist/commands/appearance.d.ts +19 -0
  25. package/dist/commands/appearance.js +63 -0
  26. package/dist/commands/appearance.js.map +1 -0
  27. package/dist/commands/artifact.d.ts +33 -0
  28. package/dist/commands/artifact.js +235 -0
  29. package/dist/commands/artifact.js.map +1 -0
  30. package/dist/commands/audit-log.d.ts +32 -0
  31. package/dist/commands/audit-log.js +102 -0
  32. package/dist/commands/audit-log.js.map +1 -0
  33. package/dist/commands/auth.d.ts +47 -0
  34. package/dist/commands/auth.js +117 -0
  35. package/dist/commands/auth.js.map +1 -0
  36. package/dist/commands/caps.d.ts +82 -0
  37. package/dist/commands/caps.js +213 -0
  38. package/dist/commands/caps.js.map +1 -0
  39. package/dist/commands/create.d.ts +22 -0
  40. package/dist/commands/create.js +76 -0
  41. package/dist/commands/create.js.map +1 -0
  42. package/dist/commands/deploy.d.ts +45 -0
  43. package/dist/commands/deploy.js +892 -0
  44. package/dist/commands/deploy.js.map +1 -0
  45. package/dist/commands/dev.d.ts +33 -0
  46. package/dist/commands/dev.js +655 -0
  47. package/dist/commands/dev.js.map +1 -0
  48. package/dist/commands/directories.d.ts +60 -0
  49. package/dist/commands/directories.js +83 -0
  50. package/dist/commands/directories.js.map +1 -0
  51. package/dist/commands/doctor.d.ts +13 -0
  52. package/dist/commands/doctor.js +123 -0
  53. package/dist/commands/doctor.js.map +1 -0
  54. package/dist/commands/embed-keys.d.ts +61 -0
  55. package/dist/commands/embed-keys.js +165 -0
  56. package/dist/commands/embed-keys.js.map +1 -0
  57. package/dist/commands/env.d.ts +59 -0
  58. package/dist/commands/env.js +300 -0
  59. package/dist/commands/env.js.map +1 -0
  60. package/dist/commands/files.d.ts +14 -0
  61. package/dist/commands/files.js +84 -0
  62. package/dist/commands/files.js.map +1 -0
  63. package/dist/commands/git-credential.d.ts +1 -0
  64. package/dist/commands/git-credential.js +70 -0
  65. package/dist/commands/git-credential.js.map +1 -0
  66. package/dist/commands/kartas.d.ts +101 -0
  67. package/dist/commands/kartas.js +289 -0
  68. package/dist/commands/kartas.js.map +1 -0
  69. package/dist/commands/keys.d.ts +33 -0
  70. package/dist/commands/keys.js +141 -0
  71. package/dist/commands/keys.js.map +1 -0
  72. package/dist/commands/login.d.ts +22 -0
  73. package/dist/commands/login.js +78 -0
  74. package/dist/commands/login.js.map +1 -0
  75. package/dist/commands/logs.d.ts +14 -0
  76. package/dist/commands/logs.js +89 -0
  77. package/dist/commands/logs.js.map +1 -0
  78. package/dist/commands/members.d.ts +32 -0
  79. package/dist/commands/members.js +77 -0
  80. package/dist/commands/members.js.map +1 -0
  81. package/dist/commands/model-keys.d.ts +22 -0
  82. package/dist/commands/model-keys.js +222 -0
  83. package/dist/commands/model-keys.js.map +1 -0
  84. package/dist/commands/open.d.ts +29 -0
  85. package/dist/commands/open.js +119 -0
  86. package/dist/commands/open.js.map +1 -0
  87. package/dist/commands/parity.d.ts +15 -0
  88. package/dist/commands/parity.js +73 -0
  89. package/dist/commands/parity.js.map +1 -0
  90. package/dist/commands/rollback.d.ts +21 -0
  91. package/dist/commands/rollback.js +26 -0
  92. package/dist/commands/rollback.js.map +1 -0
  93. package/dist/commands/schedules.d.ts +52 -0
  94. package/dist/commands/schedules.js +231 -0
  95. package/dist/commands/schedules.js.map +1 -0
  96. package/dist/commands/scopes.d.ts +3 -0
  97. package/dist/commands/scopes.js +21 -0
  98. package/dist/commands/scopes.js.map +1 -0
  99. package/dist/commands/sessions.d.ts +53 -0
  100. package/dist/commands/sessions.js +142 -0
  101. package/dist/commands/sessions.js.map +1 -0
  102. package/dist/commands/setup.d.ts +28 -0
  103. package/dist/commands/setup.js +949 -0
  104. package/dist/commands/setup.js.map +1 -0
  105. package/dist/commands/status.d.ts +19 -0
  106. package/dist/commands/status.js +63 -0
  107. package/dist/commands/status.js.map +1 -0
  108. package/dist/commands/update.d.ts +14 -0
  109. package/dist/commands/update.js +120 -0
  110. package/dist/commands/update.js.map +1 -0
  111. package/dist/commands/usage.d.ts +3 -0
  112. package/dist/commands/usage.js +37 -0
  113. package/dist/commands/usage.js.map +1 -0
  114. package/dist/commands/webhooks.d.ts +47 -0
  115. package/dist/commands/webhooks.js +156 -0
  116. package/dist/commands/webhooks.js.map +1 -0
  117. package/dist/commands/whoami.d.ts +7 -0
  118. package/dist/commands/whoami.js +17 -0
  119. package/dist/commands/whoami.js.map +1 -0
  120. package/dist/completions.d.ts +13 -0
  121. package/dist/completions.js +120 -0
  122. package/dist/completions.js.map +1 -0
  123. package/dist/config.d.ts +20 -0
  124. package/dist/config.js +98 -0
  125. package/dist/config.js.map +1 -0
  126. package/dist/context.d.ts +14 -0
  127. package/dist/context.js +38 -0
  128. package/dist/context.js.map +1 -0
  129. package/dist/device-flow.d.ts +9 -0
  130. package/dist/device-flow.js +127 -0
  131. package/dist/device-flow.js.map +1 -0
  132. package/dist/harness-preflight.d.ts +24 -0
  133. package/dist/harness-preflight.js +252 -0
  134. package/dist/harness-preflight.js.map +1 -0
  135. package/dist/harnesses.d.ts +11 -0
  136. package/dist/harnesses.js +112 -0
  137. package/dist/harnesses.js.map +1 -0
  138. package/dist/index.d.ts +3 -0
  139. package/dist/index.js +3 -0
  140. package/dist/index.js.map +1 -0
  141. package/dist/login-offer.d.ts +9 -0
  142. package/dist/login-offer.js +36 -0
  143. package/dist/login-offer.js.map +1 -0
  144. package/dist/manifest.d.ts +15 -0
  145. package/dist/manifest.js +142 -0
  146. package/dist/manifest.js.map +1 -0
  147. package/dist/money.d.ts +1 -0
  148. package/dist/money.js +16 -0
  149. package/dist/money.js.map +1 -0
  150. package/dist/output.d.ts +2 -0
  151. package/dist/output.js +20 -0
  152. package/dist/output.js.map +1 -0
  153. package/dist/runtime.d.ts +19 -0
  154. package/dist/runtime.js +95 -0
  155. package/dist/runtime.js.map +1 -0
  156. package/dist/scaffold.d.ts +16 -0
  157. package/dist/scaffold.js +74 -0
  158. package/dist/scaffold.js.map +1 -0
  159. package/dist/setup-scan.d.ts +21 -0
  160. package/dist/setup-scan.js +127 -0
  161. package/dist/setup-scan.js.map +1 -0
  162. package/dist/templates.d.ts +14 -0
  163. package/dist/templates.js +65 -0
  164. package/dist/templates.js.map +1 -0
  165. package/dist/validators.d.ts +10 -0
  166. package/dist/validators.js +116 -0
  167. package/dist/validators.js.map +1 -0
  168. package/dist/version-check.d.ts +25 -0
  169. package/dist/version-check.js +68 -0
  170. package/dist/version-check.js.map +1 -0
  171. package/node_modules/@dharta/sdk/LICENSE +21 -0
  172. package/node_modules/@dharta/sdk/README.md +87 -0
  173. package/node_modules/@dharta/sdk/dist/errors.d.ts +20 -0
  174. package/node_modules/@dharta/sdk/dist/errors.d.ts.map +1 -0
  175. package/node_modules/@dharta/sdk/dist/errors.js +51 -0
  176. package/node_modules/@dharta/sdk/dist/errors.js.map +1 -0
  177. package/node_modules/@dharta/sdk/dist/http.d.ts +26 -0
  178. package/node_modules/@dharta/sdk/dist/http.d.ts.map +1 -0
  179. package/node_modules/@dharta/sdk/dist/http.js +136 -0
  180. package/node_modules/@dharta/sdk/dist/http.js.map +1 -0
  181. package/node_modules/@dharta/sdk/dist/index.d.ts +15 -0
  182. package/node_modules/@dharta/sdk/dist/index.d.ts.map +1 -0
  183. package/node_modules/@dharta/sdk/dist/index.js +21 -0
  184. package/node_modules/@dharta/sdk/dist/index.js.map +1 -0
  185. package/node_modules/@dharta/sdk/dist/resources.d.ts +48 -0
  186. package/node_modules/@dharta/sdk/dist/resources.d.ts.map +1 -0
  187. package/node_modules/@dharta/sdk/dist/resources.js +150 -0
  188. package/node_modules/@dharta/sdk/dist/resources.js.map +1 -0
  189. package/node_modules/@dharta/sdk/dist/types.d.ts +94 -0
  190. package/node_modules/@dharta/sdk/dist/types.d.ts.map +1 -0
  191. package/node_modules/@dharta/sdk/dist/types.js +59 -0
  192. package/node_modules/@dharta/sdk/dist/types.js.map +1 -0
  193. package/node_modules/@dharta/sdk/package.json +32 -0
  194. package/node_modules/@dharta/sdk/src/errors.ts +58 -0
  195. package/node_modules/@dharta/sdk/src/http.ts +166 -0
  196. package/node_modules/@dharta/sdk/src/index.ts +36 -0
  197. package/node_modules/@dharta/sdk/src/resources.ts +197 -0
  198. package/node_modules/@dharta/sdk/src/types.ts +179 -0
  199. package/package.json +38 -0
  200. package/src/agent.ts +147 -0
  201. package/src/api-error.ts +88 -0
  202. package/src/browser.ts +20 -0
  203. package/src/cli.ts +2339 -0
  204. package/src/commands/agents.ts +635 -0
  205. package/src/commands/analytics.ts +181 -0
  206. package/src/commands/api.ts +297 -0
  207. package/src/commands/appearance.ts +79 -0
  208. package/src/commands/artifact.ts +331 -0
  209. package/src/commands/audit-log.ts +125 -0
  210. package/src/commands/auth.ts +186 -0
  211. package/src/commands/caps.ts +302 -0
  212. package/src/commands/create.ts +114 -0
  213. package/src/commands/deploy.ts +1122 -0
  214. package/src/commands/dev.ts +792 -0
  215. package/src/commands/directories.ts +136 -0
  216. package/src/commands/doctor.ts +138 -0
  217. package/src/commands/embed-keys.ts +237 -0
  218. package/src/commands/env.ts +369 -0
  219. package/src/commands/files.ts +124 -0
  220. package/src/commands/git-credential.ts +78 -0
  221. package/src/commands/kartas.ts +439 -0
  222. package/src/commands/keys.ts +206 -0
  223. package/src/commands/login.ts +115 -0
  224. package/src/commands/logs.ts +111 -0
  225. package/src/commands/members.ts +109 -0
  226. package/src/commands/model-keys.ts +278 -0
  227. package/src/commands/open.ts +173 -0
  228. package/src/commands/parity.ts +96 -0
  229. package/src/commands/rollback.ts +45 -0
  230. package/src/commands/schedules.ts +290 -0
  231. package/src/commands/scopes.ts +22 -0
  232. package/src/commands/sessions.ts +225 -0
  233. package/src/commands/setup.ts +1176 -0
  234. package/src/commands/status.ts +94 -0
  235. package/src/commands/update.ts +157 -0
  236. package/src/commands/usage.ts +41 -0
  237. package/src/commands/webhooks.ts +200 -0
  238. package/src/commands/whoami.ts +24 -0
  239. package/src/completions.ts +168 -0
  240. package/src/config.ts +143 -0
  241. package/src/context.ts +59 -0
  242. package/src/device-flow.ts +174 -0
  243. package/src/harness-preflight.ts +293 -0
  244. package/src/harnesses.ts +117 -0
  245. package/src/index.ts +3 -0
  246. package/src/login-offer.ts +49 -0
  247. package/src/manifest.ts +153 -0
  248. package/src/money.ts +15 -0
  249. package/src/output.ts +22 -0
  250. package/src/runtime.ts +127 -0
  251. package/src/scaffold.ts +102 -0
  252. package/src/setup-scan.ts +154 -0
  253. package/src/templates.ts +85 -0
  254. package/src/validators.ts +124 -0
  255. package/src/version-check.ts +75 -0
  256. package/templates/blank/CLAUDE.md +21 -0
  257. package/templates/blank/dharta.toml +11 -0
  258. package/templates/faq-agent/CLAUDE.md +51 -0
  259. package/templates/faq-agent/dharta.toml +11 -0
@@ -0,0 +1,120 @@
1
+ // `dharta completion <bash|zsh>` (RFC 0013 CLI-12): shell completion
2
+ // scripts generated statically by walking the commander program - no
3
+ // runtime dependency, no shelling out. The output is a snapshot of this
4
+ // CLI version's command surface; regenerate after updating.
5
+ export function specFromCommand(cmd) {
6
+ return {
7
+ name: cmd.name(),
8
+ aliases: commandAliases(cmd),
9
+ description: sanitize(cmd.description()),
10
+ options: [
11
+ ...cmd.options.filter((o) => !o.hidden && o.long).map((o) => o.long),
12
+ "--help",
13
+ ],
14
+ argChoices: cmd.registeredArguments.flatMap((a) => a.argChoices ?? []),
15
+ subs: cmd.commands
16
+ .filter((c) => !c._hidden)
17
+ .map((c) => specFromCommand(c)),
18
+ };
19
+ }
20
+ // First sentence, single line. Shell-specific escaping happens when rendering
21
+ // so meaningful tokens like audit_log:export keep their punctuation.
22
+ function sanitize(description) {
23
+ const firstSentence = description.replace(/\s+/g, " ").trim().split(". ")[0];
24
+ return firstSentence.replace(/\.$/, "");
25
+ }
26
+ function words(spec) {
27
+ return [...subcommandWords(spec), ...spec.argChoices, ...spec.options].join(" ");
28
+ }
29
+ function subcommandWords(spec) {
30
+ return spec.subs.flatMap((sub) => commandNames(sub));
31
+ }
32
+ function commandNames(spec) {
33
+ return [spec.name, ...spec.aliases];
34
+ }
35
+ function commandAliases(cmd) {
36
+ const maybeAliases = cmd.aliases;
37
+ return typeof maybeAliases === "function" ? maybeAliases.call(cmd) : [];
38
+ }
39
+ function completionEntries(root) {
40
+ const entries = [];
41
+ const visit = (spec, paths) => {
42
+ for (const path of paths) {
43
+ entries.push({
44
+ path,
45
+ words: words(spec),
46
+ describedCommands: describedSubcommands(spec),
47
+ });
48
+ }
49
+ for (const child of spec.subs) {
50
+ const childPaths = expandPaths(paths, commandNames(child));
51
+ visit(child, childPaths);
52
+ }
53
+ };
54
+ visit(root, [""]);
55
+ return entries;
56
+ }
57
+ function expandPaths(prefixes, names) {
58
+ return prefixes.flatMap((prefix) => names.map((name) => (prefix ? `${prefix} ${name}` : name)));
59
+ }
60
+ function describedSubcommands(spec) {
61
+ return spec.subs.flatMap((sub) => [
62
+ `'${escapeZshDescription(sub.name)}:${escapeZshDescription(sub.description)}'`,
63
+ ...sub.aliases.map((alias) => `'${escapeZshDescription(alias)}:Alias of ${escapeZshDescription(sub.name)}'`),
64
+ ]).join(" ");
65
+ }
66
+ function escapeBashCase(value) {
67
+ return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\$/g, "\\$").replace(/`/g, "\\`");
68
+ }
69
+ function escapeZshCase(value) {
70
+ return value.replace(/\\/g, "\\\\").replace(/ /g, "\\ ").replace(/\)/g, "\\)");
71
+ }
72
+ function zshCasePattern(value) {
73
+ return value === "" ? '""' : escapeZshCase(value);
74
+ }
75
+ function escapeZshDescription(value) {
76
+ return value.replace(/\\/g, "\\\\").replace(/'/g, "'\\''").replace(/:/g, "\\:");
77
+ }
78
+ export function bashCompletion(program) {
79
+ const spec = specFromCommand(program);
80
+ const entries = completionEntries(spec);
81
+ const lines = [
82
+ "# bash completion for karta - generated by `dharta completion bash`",
83
+ "# Load with: source <(dharta completion bash) (or append to ~/.bash_completion)",
84
+ "_karta() {",
85
+ ' local cur="${COMP_WORDS[COMP_CWORD]}"',
86
+ ' local path="${COMP_WORDS[@]:1:$((COMP_CWORD - 1))}"',
87
+ ' local words=""',
88
+ ' case "$path" in',
89
+ ];
90
+ for (const entry of entries) {
91
+ lines.push(` "${escapeBashCase(entry.path)}") words="${escapeBashCase(entry.words)}" ;;`);
92
+ }
93
+ lines.push(" esac", ' COMPREPLY=( $(compgen -W "$words" -- "$cur") )', "}", "complete -F _karta karta");
94
+ return lines.join("\n");
95
+ }
96
+ export function zshCompletion(program) {
97
+ const spec = specFromCommand(program);
98
+ const entries = completionEntries(spec);
99
+ const lines = [
100
+ "#compdef karta",
101
+ "# zsh completion for karta - generated by `dharta completion zsh`",
102
+ "# Install: dharta completion zsh > ~/.zfunc/_dharta (with fpath+=(~/.zfunc) before compinit)",
103
+ "",
104
+ "_karta() {",
105
+ " local -a reply",
106
+ ' local path=""',
107
+ " if (( CURRENT > 2 )); then",
108
+ ' path="${(j: :)words[2,$((CURRENT - 1))]}"',
109
+ " fi",
110
+ ' case "$path" in',
111
+ ];
112
+ for (const entry of entries) {
113
+ lines.push(` ${zshCasePattern(entry.path)})`, entry.describedCommands
114
+ ? ` reply=( ${entry.describedCommands} ); _describe -t commands 'dharta command' reply`
115
+ : " true", entry.words ? ` compadd -- ${entry.words}` : " true", " return", " ;;");
116
+ }
117
+ lines.push(" esac", "}", "", '_karta "$@"');
118
+ return lines.join("\n");
119
+ }
120
+ //# sourceMappingURL=completions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completions.js","sourceRoot":"","sources":["../src/completions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface Profile {
2
+ api_key: string;
3
+ base_url: string;
4
+ git_base_url?: string;
5
+ workspace_git_base_url?: string;
6
+ }
7
+ export interface Config {
8
+ default_profile: string;
9
+ profiles: Record<string, Profile>;
10
+ }
11
+ export declare function setHomeForTesting(home: string | undefined): void;
12
+ export declare function configPath(): string;
13
+ declare const DEFAULT_BASE_URL = "https://dharta.ai";
14
+ declare const DEFAULT_GIT_BASE_URL = "https://git.dharta.ai";
15
+ export declare function loadConfig(): Promise<Config | null>;
16
+ export declare function saveProfile(name: string, profile: Profile): Promise<string>;
17
+ export declare function removeProfile(name: string): Promise<boolean>;
18
+ export declare function activeProfile(): Promise<Profile>;
19
+ export declare function resolveBaseUrl(): Promise<string>;
20
+ export { DEFAULT_BASE_URL, DEFAULT_GIT_BASE_URL };
package/dist/config.js ADDED
@@ -0,0 +1,98 @@
1
+ import { promises as fs } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import * as path from "node:path";
4
+ import TOML from "@iarna/toml";
5
+ // Allow tests to redirect HOME without setting process.env.HOME globally.
6
+ let homeOverride;
7
+ export function setHomeForTesting(home) {
8
+ homeOverride = home;
9
+ }
10
+ export function configPath() {
11
+ const home = homeOverride ?? process.env.HOME ?? homedir();
12
+ return path.join(home, ".dharta", "config.toml");
13
+ }
14
+ // NOT api.dharta.ai: that name resolves to the data plane (the RFC 0011
15
+ // as-built base-URL confusion this constant fixes). The control API
16
+ // lives on the Rails app.
17
+ const DEFAULT_BASE_URL = "https://dharta.ai";
18
+ const DEFAULT_GIT_BASE_URL = "https://git.dharta.ai";
19
+ export async function loadConfig() {
20
+ try {
21
+ const raw = await fs.readFile(configPath(), "utf8");
22
+ const parsed = TOML.parse(raw);
23
+ if (!parsed.default_profile || !parsed.profiles)
24
+ return null;
25
+ return {
26
+ default_profile: parsed.default_profile,
27
+ profiles: parsed.profiles,
28
+ };
29
+ }
30
+ catch (err) {
31
+ if (err.code === "ENOENT")
32
+ return null;
33
+ throw err;
34
+ }
35
+ }
36
+ export async function saveProfile(name, profile) {
37
+ const target = configPath();
38
+ await fs.mkdir(path.dirname(target), { recursive: true, mode: 0o700 });
39
+ const existing = (await loadConfig()) ?? {
40
+ default_profile: name,
41
+ profiles: {},
42
+ };
43
+ existing.profiles[name] = profile;
44
+ existing.default_profile = name;
45
+ await fs.writeFile(target, TOML.stringify(existing), {
46
+ mode: 0o600,
47
+ });
48
+ return target;
49
+ }
50
+ // Remove a stored profile (auth logout). Returns false if it didn't
51
+ // exist. If the default profile was removed, the first remaining one
52
+ // becomes the default; the file is deleted when no profiles remain.
53
+ export async function removeProfile(name) {
54
+ const cfg = await loadConfig();
55
+ if (!cfg || !cfg.profiles[name])
56
+ return false;
57
+ delete cfg.profiles[name];
58
+ const remaining = Object.keys(cfg.profiles);
59
+ if (remaining.length === 0) {
60
+ await fs.rm(configPath(), { force: true });
61
+ return true;
62
+ }
63
+ if (cfg.default_profile === name)
64
+ cfg.default_profile = remaining[0];
65
+ await fs.writeFile(configPath(), TOML.stringify(cfg), { mode: 0o600 });
66
+ return true;
67
+ }
68
+ export async function activeProfile() {
69
+ const cfg = await loadConfig();
70
+ if (!cfg) {
71
+ throw new Error("Not logged in. Run `dharta login` to store an API key in ~/.dharta/config.toml.");
72
+ }
73
+ const profile = cfg.profiles[cfg.default_profile];
74
+ if (!profile) {
75
+ throw new Error(`Default profile '${cfg.default_profile}' not found in ${configPath()}. ` +
76
+ "Run `dharta login` to recreate it.");
77
+ }
78
+ return {
79
+ api_key: profile.api_key,
80
+ base_url: profile.base_url || DEFAULT_BASE_URL,
81
+ git_base_url: profile.git_base_url || DEFAULT_GIT_BASE_URL,
82
+ workspace_git_base_url: profile.workspace_git_base_url,
83
+ };
84
+ }
85
+ // Base URL for commands that work without a credential (init's template
86
+ // fetch): env override, then the stored profile, then the default.
87
+ export async function resolveBaseUrl() {
88
+ if (process.env.DHARTA_BASE_URL)
89
+ return process.env.DHARTA_BASE_URL;
90
+ try {
91
+ return (await activeProfile()).base_url;
92
+ }
93
+ catch {
94
+ return DEFAULT_BASE_URL;
95
+ }
96
+ }
97
+ export { DEFAULT_BASE_URL, DEFAULT_GIT_BASE_URL };
98
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Dharta, HttpClient } from "@dharta/sdk";
2
+ export interface CliContext {
3
+ sdk: Dharta;
4
+ http: HttpClient;
5
+ baseUrl: string;
6
+ apiKey: string;
7
+ fetch?: typeof fetch;
8
+ }
9
+ export interface CtxOverrides {
10
+ apiKey?: string;
11
+ baseUrl?: string;
12
+ fetch?: typeof fetch;
13
+ }
14
+ export declare function buildContext(over?: CtxOverrides): Promise<CliContext>;
@@ -0,0 +1,38 @@
1
+ import { Dharta, HttpClient } from "@dharta/sdk";
2
+ import { activeProfile, DEFAULT_BASE_URL } from "./config.js";
3
+ import { cliFormatError, cliFormatNetworkError } from "./api-error.js";
4
+ export async function buildContext(over = {}) {
5
+ let apiKey = over.apiKey;
6
+ let baseUrl = over.baseUrl;
7
+ // Env overrides config everywhere (the GH_TOKEN pattern, RFC 0013
8
+ // §2); explicit per-call overrides beat both. DHARTA_BASE_URL applies
9
+ // regardless of where the key came from, matching resolveBaseUrl.
10
+ baseUrl = baseUrl ?? process.env.DHARTA_BASE_URL;
11
+ if (!apiKey && process.env.DHARTA_API_KEY) {
12
+ apiKey = process.env.DHARTA_API_KEY;
13
+ }
14
+ if (!apiKey) {
15
+ const p = await activeProfile();
16
+ apiKey = p.api_key;
17
+ baseUrl = baseUrl ?? p.base_url;
18
+ }
19
+ if (!baseUrl)
20
+ baseUrl = DEFAULT_BASE_URL;
21
+ const fetchImpl = over.fetch;
22
+ const sdk = new Dharta({
23
+ apiKey,
24
+ baseUrl,
25
+ fetch: fetchImpl,
26
+ formatError: cliFormatError,
27
+ formatNetworkError: cliFormatNetworkError,
28
+ });
29
+ const http = new HttpClient({
30
+ apiKey,
31
+ baseUrl,
32
+ fetch: fetchImpl,
33
+ formatError: cliFormatError,
34
+ formatNetworkError: cliFormatNetworkError,
35
+ });
36
+ return { sdk, http, baseUrl, apiKey, fetch: fetchImpl };
37
+ }
38
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAsBvE,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAqB,EAAE;IAEvB,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC3B,kEAAkE;IAClE,sEAAsE;IACtE,kEAAkE;IAClE,OAAO,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACjD,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QAC1C,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACtC,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,CAAC,GAAG,MAAM,aAAa,EAAE,CAAC;QAChC,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC;QACnB,OAAO,GAAG,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC;IAClC,CAAC;IACD,IAAI,CAAC,OAAO;QAAE,OAAO,GAAG,gBAAgB,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC;QACrB,MAAM;QACN,OAAO;QACP,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,cAAc;QAC3B,kBAAkB,EAAE,qBAAqB;KAC1C,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC;QAC1B,MAAM;QACN,OAAO;QACP,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,cAAc;QAC3B,kBAAkB,EAAE,qBAAqB;KAC1C,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface DeviceFlowOptions {
2
+ baseUrl: string;
3
+ clientName?: string;
4
+ fetchImpl?: typeof fetch;
5
+ log?: (line: string) => void;
6
+ openBrowser?: (url: string) => Promise<boolean>;
7
+ sleep?: (ms: number) => Promise<void>;
8
+ }
9
+ export declare function deviceFlowLogin(opts: DeviceFlowOptions): Promise<string>;
@@ -0,0 +1,127 @@
1
+ // RFC 8628 device-flow client for `dharta login` (RFC 0013 CLI-1).
2
+ // Mints a code pair on the control plane, shows the user code, opens the
3
+ // approve page, and polls the token endpoint until the browser approval
4
+ // mints a named CLI credential.
5
+ import { openBrowser } from "./browser.js";
6
+ const EXPIRED_MESSAGE = "The login code expired before it was approved. Run `dharta login` again.";
7
+ // Consecutive network failures tolerated before giving up — the
8
+ // approval window is minutes long, so one wifi blip must not abort it.
9
+ const MAX_CONSECUTIVE_NETWORK_FAILURES = 5;
10
+ // Resolves to the freshly minted API key (dh_live_…).
11
+ export async function deviceFlowLogin(opts) {
12
+ const fetchImpl = (opts.fetchImpl ?? globalThis.fetch).bind(globalThis);
13
+ const log = opts.log ?? ((line) => console.log(line));
14
+ const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
15
+ const base = opts.baseUrl.replace(/\/+$/, "");
16
+ let mintRes;
17
+ try {
18
+ mintRes = await fetchImpl(`${base}/cli/device_authorizations`, {
19
+ method: "POST",
20
+ headers: { "Content-Type": "application/json", Accept: "application/json" },
21
+ body: JSON.stringify({ client_name: opts.clientName }),
22
+ });
23
+ }
24
+ catch (error) {
25
+ throw new Error(`Could not start the login: could not reach ${base} (${formatCause(error)}). ` +
26
+ "Check your network and try `dharta login` again.");
27
+ }
28
+ if (!mintRes.ok) {
29
+ throw new Error(`Could not start the login (${mintRes.status} from ${base}). ` +
30
+ "Check your network and try `dharta login` again.");
31
+ }
32
+ let mint;
33
+ try {
34
+ mint = (await mintRes.json());
35
+ }
36
+ catch (error) {
37
+ throw new Error(`Could not start the login: ${base} returned invalid JSON (${formatCause(error)}). ` +
38
+ "Check DHARTA_BASE_URL or try `dharta login` again.");
39
+ }
40
+ if (typeof mint.device_code !== "string" ||
41
+ typeof mint.user_code !== "string" ||
42
+ typeof mint.verification_uri !== "string" ||
43
+ typeof mint.expires_in !== "number") {
44
+ throw new Error(`Could not start the login: ${base} returned an incomplete device login response. ` +
45
+ "Check DHARTA_BASE_URL or try `dharta login` again.");
46
+ }
47
+ const approveUrl = mint.verification_uri_complete ?? mint.verification_uri;
48
+ log(`! First, verify this code in your browser: ${mint.user_code}`);
49
+ const opened = await (opts.openBrowser ?? openBrowser)(approveUrl);
50
+ log(opened
51
+ ? `Opening ${approveUrl} in your browser…`
52
+ : `Open this URL to approve: ${approveUrl}`);
53
+ log("Waiting for approval…");
54
+ // RFC 8628: interval is optional, default 5s. Guard against a
55
+ // missing/garbage value — setTimeout(NaN) fires immediately and
56
+ // would hot-loop the poll.
57
+ let intervalMs = Math.max(Number(mint.interval) || 5, 1) * 1000;
58
+ const deadline = Date.now() + mint.expires_in * 1000;
59
+ let networkFailures = 0;
60
+ while (Date.now() < deadline) {
61
+ await sleep(intervalMs);
62
+ let res;
63
+ try {
64
+ res = await fetchImpl(`${base}/cli/device_authorizations/token`, {
65
+ method: "POST",
66
+ headers: { "Content-Type": "application/json", Accept: "application/json" },
67
+ body: JSON.stringify({ device_code: mint.device_code }),
68
+ });
69
+ }
70
+ catch {
71
+ // Transient network failure mid-poll: keep waiting, the
72
+ // deadline bounds the loop.
73
+ networkFailures += 1;
74
+ if (networkFailures >= MAX_CONSECUTIVE_NETWORK_FAILURES) {
75
+ throw new Error(`Lost the connection to ${base} while waiting for approval. ` +
76
+ "Check your network and run `dharta login` again.");
77
+ }
78
+ continue;
79
+ }
80
+ networkFailures = 0;
81
+ if (res.ok) {
82
+ let token;
83
+ try {
84
+ token = (await res.json()).access_token;
85
+ }
86
+ catch {
87
+ // fall through to the throw below
88
+ }
89
+ if (!token) {
90
+ throw new Error("The server approved the login but returned no token. Run `dharta login` again.");
91
+ }
92
+ return token;
93
+ }
94
+ if (res.status === 429) {
95
+ // Rate-limited (Rack::Attack): back off like slow_down rather
96
+ // than keeping the cadence that tripped the limit.
97
+ await res.text().catch(() => { });
98
+ intervalMs += 5000;
99
+ continue;
100
+ }
101
+ let error = "";
102
+ try {
103
+ error = (await res.json()).error ?? "";
104
+ }
105
+ catch {
106
+ // non-JSON error body: fall through to the unknown-error throw
107
+ }
108
+ switch (error) {
109
+ case "authorization_pending":
110
+ continue;
111
+ case "slow_down":
112
+ intervalMs += 5000; // RFC 8628 §3.5: back off by 5s on slow_down
113
+ continue;
114
+ case "expired_token":
115
+ throw new Error(EXPIRED_MESSAGE);
116
+ case "access_denied":
117
+ throw new Error("The login request was denied in the browser.");
118
+ default:
119
+ throw new Error(`Login failed (${error || `HTTP ${res.status}`}). Run \`dharta login\` again.`);
120
+ }
121
+ }
122
+ throw new Error(EXPIRED_MESSAGE);
123
+ }
124
+ function formatCause(error) {
125
+ return error instanceof Error && error.message ? error.message : String(error);
126
+ }
127
+ //# sourceMappingURL=device-flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-flow.js","sourceRoot":"","sources":["../src/device-flow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export interface CatalogVersion {
2
+ version: string;
3
+ status: string;
4
+ }
5
+ export interface CatalogHarness {
6
+ id: string;
7
+ name: string;
8
+ default_version?: string | null;
9
+ versions: CatalogVersion[];
10
+ }
11
+ export interface PreflightDeps {
12
+ dir: string;
13
+ baseUrl: string;
14
+ log: (line: string) => void;
15
+ fetchImpl?: typeof fetch;
16
+ detectLocalVersion?: (type: string) => Promise<string | null>;
17
+ confirm?: (question: string) => Promise<boolean>;
18
+ }
19
+ export declare function sniffType(dir: string): string;
20
+ export declare function compareVersions(a: string, b: string): number;
21
+ export declare function versionHasPrefix(version: string, prefix: string): boolean;
22
+ export declare function resolvePreview(constraint: string | undefined, supported: string[], defaultVersion?: string | null): string | null;
23
+ export declare function closestForParity(local: string | null, supported: string[]): string | null;
24
+ export declare function harnessPreflight(deps: PreflightDeps): Promise<void>;