dexto 1.14.6 → 2.0.0-beta.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 (297) hide show
  1. package/dist/agents/coding-agent/coding-agent.yml +0 -2
  2. package/dist/cli/agent-audit.d.ts +12 -0
  3. package/dist/cli/agent-audit.d.ts.map +1 -0
  4. package/dist/cli/agent-audit.js +52 -0
  5. package/dist/cli/auth/billing.d.ts +0 -6
  6. package/dist/cli/auth/billing.d.ts.map +1 -1
  7. package/dist/cli/auth/billing.js +0 -23
  8. package/dist/cli/auth/constants.d.ts +3 -31
  9. package/dist/cli/auth/constants.d.ts.map +1 -1
  10. package/dist/cli/auth/constants.js +9 -33
  11. package/dist/cli/auth/index.d.ts +2 -9
  12. package/dist/cli/auth/index.d.ts.map +1 -1
  13. package/dist/cli/auth/index.js +2 -7
  14. package/dist/cli/auth/sign-in-runtime.d.ts +12 -0
  15. package/dist/cli/auth/sign-in-runtime.d.ts.map +1 -0
  16. package/dist/cli/auth/sign-in-runtime.js +59 -0
  17. package/dist/cli/cloud/app-scopes.d.ts +4 -0
  18. package/dist/cli/cloud/app-scopes.d.ts.map +1 -0
  19. package/dist/cli/cloud/app-scopes.js +19 -0
  20. package/dist/cli/cloud/command.d.ts +107 -0
  21. package/dist/cli/cloud/command.d.ts.map +1 -0
  22. package/dist/cli/cloud/command.js +154 -0
  23. package/dist/cli/cloud/commands/account.d.ts +11 -0
  24. package/dist/cli/cloud/commands/account.d.ts.map +1 -0
  25. package/dist/cli/cloud/commands/account.js +129 -0
  26. package/dist/cli/cloud/commands/agents.d.ts +3 -0
  27. package/dist/cli/cloud/commands/agents.d.ts.map +1 -0
  28. package/dist/cli/cloud/commands/agents.js +526 -0
  29. package/dist/cli/cloud/commands/api.d.ts +3 -0
  30. package/dist/cli/cloud/commands/api.d.ts.map +1 -0
  31. package/dist/cli/cloud/commands/api.js +26 -0
  32. package/dist/cli/cloud/commands/app-files.d.ts +29 -0
  33. package/dist/cli/cloud/commands/app-files.d.ts.map +1 -0
  34. package/dist/cli/cloud/commands/app-files.js +72 -0
  35. package/dist/cli/cloud/commands/artifacts.d.ts +3 -0
  36. package/dist/cli/cloud/commands/artifacts.d.ts.map +1 -0
  37. package/dist/cli/cloud/commands/artifacts.js +267 -0
  38. package/dist/cli/cloud/commands/automations.d.ts +3 -0
  39. package/dist/cli/cloud/commands/automations.d.ts.map +1 -0
  40. package/dist/cli/cloud/commands/automations.js +233 -0
  41. package/dist/cli/cloud/commands/chats.d.ts +3 -0
  42. package/dist/cli/cloud/commands/chats.d.ts.map +1 -0
  43. package/dist/cli/cloud/commands/chats.js +204 -0
  44. package/dist/cli/cloud/commands/data-deletions.d.ts +3 -0
  45. package/dist/cli/cloud/commands/data-deletions.d.ts.map +1 -0
  46. package/dist/cli/cloud/commands/data-deletions.js +55 -0
  47. package/dist/cli/cloud/commands/deploys.d.ts +10 -0
  48. package/dist/cli/cloud/commands/deploys.d.ts.map +1 -0
  49. package/dist/cli/cloud/commands/deploys.js +225 -0
  50. package/dist/cli/cloud/commands/drive.d.ts +12 -0
  51. package/dist/cli/cloud/commands/drive.d.ts.map +1 -0
  52. package/dist/cli/cloud/commands/drive.js +321 -0
  53. package/dist/cli/cloud/commands/files.d.ts +24 -0
  54. package/dist/cli/cloud/commands/files.d.ts.map +1 -0
  55. package/dist/cli/cloud/commands/files.js +284 -0
  56. package/dist/cli/cloud/commands/find.d.ts +3 -0
  57. package/dist/cli/cloud/commands/find.d.ts.map +1 -0
  58. package/dist/cli/cloud/commands/find.js +63 -0
  59. package/dist/cli/cloud/commands/models.d.ts +3 -0
  60. package/dist/cli/cloud/commands/models.d.ts.map +1 -0
  61. package/dist/cli/cloud/commands/models.js +250 -0
  62. package/dist/cli/cloud/commands/profile.d.ts +3 -0
  63. package/dist/cli/cloud/commands/profile.d.ts.map +1 -0
  64. package/dist/cli/cloud/commands/profile.js +120 -0
  65. package/dist/cli/cloud/commands/projects.d.ts +5 -0
  66. package/dist/cli/cloud/commands/projects.d.ts.map +1 -0
  67. package/dist/cli/cloud/commands/projects.js +66 -0
  68. package/dist/cli/cloud/commands/publish.d.ts +3 -0
  69. package/dist/cli/cloud/commands/publish.d.ts.map +1 -0
  70. package/dist/cli/cloud/commands/publish.js +139 -0
  71. package/dist/cli/cloud/commands/sandboxes.d.ts +3 -0
  72. package/dist/cli/cloud/commands/sandboxes.d.ts.map +1 -0
  73. package/dist/cli/cloud/commands/sandboxes.js +266 -0
  74. package/dist/cli/cloud/commands/secrets.d.ts +3 -0
  75. package/dist/cli/cloud/commands/secrets.d.ts.map +1 -0
  76. package/dist/cli/cloud/commands/secrets.js +111 -0
  77. package/dist/cli/cloud/commands/skills.d.ts +3 -0
  78. package/dist/cli/cloud/commands/skills.d.ts.map +1 -0
  79. package/dist/cli/cloud/commands/skills.js +203 -0
  80. package/dist/cli/cloud/commands/traces.d.ts +3 -0
  81. package/dist/cli/cloud/commands/traces.d.ts.map +1 -0
  82. package/dist/cli/cloud/commands/traces.js +142 -0
  83. package/dist/cli/cloud/commands/web.d.ts +3 -0
  84. package/dist/cli/cloud/commands/web.d.ts.map +1 -0
  85. package/dist/cli/cloud/commands/web.js +53 -0
  86. package/dist/cli/cloud/commands/workspace-apps.d.ts +58 -0
  87. package/dist/cli/cloud/commands/workspace-apps.d.ts.map +1 -0
  88. package/dist/cli/cloud/commands/workspace-apps.js +657 -0
  89. package/dist/cli/cloud/commands/workspace.d.ts +36 -0
  90. package/dist/cli/cloud/commands/workspace.d.ts.map +1 -0
  91. package/dist/cli/cloud/commands/workspace.js +281 -0
  92. package/dist/cli/cloud/connection.d.ts +33 -0
  93. package/dist/cli/cloud/connection.d.ts.map +1 -0
  94. package/dist/cli/cloud/connection.js +38 -0
  95. package/dist/cli/cloud/events.d.ts +63 -0
  96. package/dist/cli/cloud/events.d.ts.map +1 -0
  97. package/dist/cli/cloud/events.js +72 -0
  98. package/dist/cli/cloud/host.d.ts +9 -0
  99. package/dist/cli/cloud/host.d.ts.map +1 -0
  100. package/dist/cli/cloud/host.js +109 -0
  101. package/dist/cli/cloud/output.d.ts +34 -0
  102. package/dist/cli/cloud/output.d.ts.map +1 -0
  103. package/dist/cli/cloud/output.js +77 -0
  104. package/dist/cli/cloud/run.d.ts +26 -0
  105. package/dist/cli/cloud/run.d.ts.map +1 -0
  106. package/dist/cli/cloud/run.js +444 -0
  107. package/dist/cli/cloud/runtime.d.ts +33 -0
  108. package/dist/cli/cloud/runtime.d.ts.map +1 -0
  109. package/dist/cli/cloud/runtime.js +86 -0
  110. package/dist/cli/cloud/tar.d.ts +9 -0
  111. package/dist/cli/cloud/tar.d.ts.map +1 -0
  112. package/dist/cli/cloud/tar.js +69 -0
  113. package/dist/cli/cloud/transfer.d.ts +13 -0
  114. package/dist/cli/cloud/transfer.d.ts.map +1 -0
  115. package/dist/cli/cloud/transfer.js +36 -0
  116. package/dist/cli/cloud/v1.d.ts +20 -0
  117. package/dist/cli/cloud/v1.d.ts.map +1 -0
  118. package/dist/cli/cloud/v1.js +66 -0
  119. package/dist/cli/cloud/zip.d.ts +8 -0
  120. package/dist/cli/cloud/zip.d.ts.map +1 -0
  121. package/dist/cli/cloud/zip.js +66 -0
  122. package/dist/cli/commands/auth/sign-in-commands.d.ts +62 -0
  123. package/dist/cli/commands/auth/sign-in-commands.d.ts.map +1 -0
  124. package/dist/cli/commands/auth/sign-in-commands.js +248 -0
  125. package/dist/cli/commands/auth/sign-in-context.d.ts +16 -0
  126. package/dist/cli/commands/auth/sign-in-context.d.ts.map +1 -0
  127. package/dist/cli/commands/auth/sign-in-context.js +68 -0
  128. package/dist/cli/commands/cloud/register.d.ts +5 -0
  129. package/dist/cli/commands/cloud/register.d.ts.map +1 -1
  130. package/dist/cli/commands/cloud/register.js +44 -24
  131. package/dist/cli/commands/create-app.js +5 -6
  132. package/dist/cli/commands/create-image.d.ts.map +1 -1
  133. package/dist/cli/commands/create-image.js +9 -10
  134. package/dist/cli/commands/index.d.ts +0 -2
  135. package/dist/cli/commands/index.d.ts.map +1 -1
  136. package/dist/cli/commands/index.js +0 -2
  137. package/dist/cli/commands/init.d.ts +0 -2
  138. package/dist/cli/commands/init.d.ts.map +1 -1
  139. package/dist/cli/commands/init.js +5 -26
  140. package/dist/cli/commands/run/headless.d.ts.map +1 -1
  141. package/dist/cli/commands/run/headless.js +57 -2
  142. package/dist/cli/commands/run/output.d.ts +29 -10
  143. package/dist/cli/commands/run/output.d.ts.map +1 -1
  144. package/dist/cli/commands/run/output.js +44 -22
  145. package/dist/cli/commands/run/register.d.ts.map +1 -1
  146. package/dist/cli/commands/run/register.js +21 -9
  147. package/dist/cli/commands/run/step-log.d.ts +11 -0
  148. package/dist/cli/commands/run/step-log.d.ts.map +1 -0
  149. package/dist/cli/commands/run/step-log.js +42 -0
  150. package/dist/cli/commands/session/register.d.ts.map +1 -1
  151. package/dist/cli/commands/session/register.js +51 -21
  152. package/dist/cli/commands/session-commands.js +1 -1
  153. package/dist/cli/commands/setup.js +17 -14
  154. package/dist/cli/failure.d.ts +29 -0
  155. package/dist/cli/failure.d.ts.map +1 -0
  156. package/dist/cli/failure.js +31 -0
  157. package/dist/cli/help-json.d.ts +22 -0
  158. package/dist/cli/help-json.d.ts.map +1 -0
  159. package/dist/cli/help-json.js +20 -0
  160. package/dist/cli/import/claude-code.d.ts +10 -0
  161. package/dist/cli/import/claude-code.d.ts.map +1 -0
  162. package/dist/cli/import/claude-code.js +131 -0
  163. package/dist/cli/import/codex.d.ts +27 -0
  164. package/dist/cli/import/codex.d.ts.map +1 -0
  165. package/dist/cli/import/codex.js +148 -0
  166. package/dist/cli/import/git.d.ts +19 -0
  167. package/dist/cli/import/git.d.ts.map +1 -0
  168. package/dist/cli/import/git.js +95 -0
  169. package/dist/cli/import/local-chats.d.ts +28 -0
  170. package/dist/cli/import/local-chats.d.ts.map +1 -0
  171. package/dist/cli/import/local-chats.js +129 -0
  172. package/dist/cli/import/redaction.d.ts +37 -0
  173. package/dist/cli/import/redaction.d.ts.map +1 -0
  174. package/dist/cli/import/redaction.js +148 -0
  175. package/dist/cli/import/test-utils.d.ts +16 -0
  176. package/dist/cli/import/test-utils.d.ts.map +1 -0
  177. package/dist/cli/import/test-utils.js +223 -0
  178. package/dist/cli/import/transcript.d.ts +75 -0
  179. package/dist/cli/import/transcript.d.ts.map +1 -0
  180. package/dist/cli/import/transcript.js +123 -0
  181. package/dist/cli/interaction.d.ts +18 -0
  182. package/dist/cli/interaction.d.ts.map +1 -0
  183. package/dist/cli/interaction.js +30 -0
  184. package/dist/cli/modes/cli.d.ts.map +1 -1
  185. package/dist/cli/modes/cli.js +42 -9
  186. package/dist/cli/modes/server.js +8 -8
  187. package/dist/cli/modes/web.js +3 -3
  188. package/dist/cli/output.d.ts +9 -0
  189. package/dist/cli/output.d.ts.map +1 -0
  190. package/dist/cli/output.js +6 -0
  191. package/dist/cli/utils/dexto-auth-check.d.ts +1 -1
  192. package/dist/cli/utils/dexto-auth-check.d.ts.map +1 -1
  193. package/dist/cli/utils/dexto-auth-check.js +4 -5
  194. package/dist/cli/utils/dexto-setup.d.ts +4 -5
  195. package/dist/cli/utils/dexto-setup.d.ts.map +1 -1
  196. package/dist/cli/utils/dexto-setup.js +17 -14
  197. package/dist/cli/utils/provider-setup.js +1 -1
  198. package/dist/cli/utils/scaffolding-utils.d.ts +9 -3
  199. package/dist/cli/utils/scaffolding-utils.d.ts.map +1 -1
  200. package/dist/cli/utils/scaffolding-utils.js +48 -40
  201. package/dist/cli/utils/version-check.d.ts.map +1 -1
  202. package/dist/cli/utils/version-check.js +2 -1
  203. package/dist/index-main.js +44 -65
  204. package/dist/webui/assets/index-D9xiOs62.js +1649 -0
  205. package/dist/webui/index.html +1 -1
  206. package/package.json +15 -14
  207. package/dist/cli/auth/api-client.d.ts +0 -125
  208. package/dist/cli/auth/api-client.d.ts.map +0 -1
  209. package/dist/cli/auth/api-client.js +0 -585
  210. package/dist/cli/auth/device.d.ts +0 -14
  211. package/dist/cli/auth/device.d.ts.map +0 -1
  212. package/dist/cli/auth/device.js +0 -84
  213. package/dist/cli/auth/dexto-api-key.d.ts +0 -34
  214. package/dist/cli/auth/dexto-api-key.d.ts.map +0 -1
  215. package/dist/cli/auth/dexto-api-key.js +0 -160
  216. package/dist/cli/auth/login-persistence.d.ts +0 -15
  217. package/dist/cli/auth/login-persistence.d.ts.map +0 -1
  218. package/dist/cli/auth/login-persistence.js +0 -72
  219. package/dist/cli/auth/oauth.d.ts +0 -39
  220. package/dist/cli/auth/oauth.d.ts.map +0 -1
  221. package/dist/cli/auth/oauth.js +0 -434
  222. package/dist/cli/auth/service.d.ts +0 -24
  223. package/dist/cli/auth/service.d.ts.map +0 -1
  224. package/dist/cli/auth/service.js +0 -161
  225. package/dist/cli/auth/types.d.ts +0 -11
  226. package/dist/cli/auth/types.d.ts.map +0 -1
  227. package/dist/cli/auth/types.js +0 -1
  228. package/dist/cli/cloud-chat.d.ts +0 -18
  229. package/dist/cli/cloud-chat.d.ts.map +0 -1
  230. package/dist/cli/cloud-chat.js +0 -734
  231. package/dist/cli/commands/auth/index.d.ts +0 -4
  232. package/dist/cli/commands/auth/index.d.ts.map +0 -1
  233. package/dist/cli/commands/auth/index.js +0 -4
  234. package/dist/cli/commands/auth/login.d.ts +0 -12
  235. package/dist/cli/commands/auth/login.d.ts.map +0 -1
  236. package/dist/cli/commands/auth/login.js +0 -153
  237. package/dist/cli/commands/auth/logout.d.ts +0 -5
  238. package/dist/cli/commands/auth/logout.d.ts.map +0 -1
  239. package/dist/cli/commands/auth/logout.js +0 -81
  240. package/dist/cli/commands/auth/register.d.ts +0 -3
  241. package/dist/cli/commands/auth/register.d.ts.map +0 -1
  242. package/dist/cli/commands/auth/register.js +0 -96
  243. package/dist/cli/commands/auth/status.d.ts +0 -2
  244. package/dist/cli/commands/auth/status.d.ts.map +0 -1
  245. package/dist/cli/commands/auth/status.js +0 -22
  246. package/dist/cli/commands/billing/index.d.ts +0 -2
  247. package/dist/cli/commands/billing/index.d.ts.map +0 -1
  248. package/dist/cli/commands/billing/index.js +0 -2
  249. package/dist/cli/commands/billing/register.d.ts +0 -3
  250. package/dist/cli/commands/billing/register.d.ts.map +0 -1
  251. package/dist/cli/commands/billing/register.js +0 -20
  252. package/dist/cli/commands/billing/status.d.ts +0 -8
  253. package/dist/cli/commands/billing/status.d.ts.map +0 -1
  254. package/dist/cli/commands/billing/status.js +0 -71
  255. package/dist/cli/commands/cloud/discovery.d.ts +0 -17
  256. package/dist/cli/commands/cloud/discovery.d.ts.map +0 -1
  257. package/dist/cli/commands/cloud/discovery.js +0 -88
  258. package/dist/cli/commands/deploy/client.d.ts +0 -113
  259. package/dist/cli/commands/deploy/client.d.ts.map +0 -1
  260. package/dist/cli/commands/deploy/client.js +0 -519
  261. package/dist/cli/commands/deploy/config.d.ts +0 -37
  262. package/dist/cli/commands/deploy/config.d.ts.map +0 -1
  263. package/dist/cli/commands/deploy/config.js +0 -144
  264. package/dist/cli/commands/deploy/entry-agent.d.ts +0 -3
  265. package/dist/cli/commands/deploy/entry-agent.d.ts.map +0 -1
  266. package/dist/cli/commands/deploy/entry-agent.js +0 -70
  267. package/dist/cli/commands/deploy/index.d.ts +0 -12
  268. package/dist/cli/commands/deploy/index.d.ts.map +0 -1
  269. package/dist/cli/commands/deploy/index.js +0 -370
  270. package/dist/cli/commands/deploy/links.d.ts +0 -3
  271. package/dist/cli/commands/deploy/links.d.ts.map +0 -1
  272. package/dist/cli/commands/deploy/links.js +0 -53
  273. package/dist/cli/commands/deploy/register.d.ts +0 -6
  274. package/dist/cli/commands/deploy/register.d.ts.map +0 -1
  275. package/dist/cli/commands/deploy/register.js +0 -128
  276. package/dist/cli/commands/deploy/snapshot.d.ts +0 -12
  277. package/dist/cli/commands/deploy/snapshot.d.ts.map +0 -1
  278. package/dist/cli/commands/deploy/snapshot.js +0 -76
  279. package/dist/cli/commands/deploy/state.d.ts +0 -13
  280. package/dist/cli/commands/deploy/state.d.ts.map +0 -1
  281. package/dist/cli/commands/deploy/state.js +0 -122
  282. package/dist/cli/commands/span/register.d.ts +0 -6
  283. package/dist/cli/commands/span/register.d.ts.map +0 -1
  284. package/dist/cli/commands/span/register.js +0 -25
  285. package/dist/cli/commands/trace/client.d.ts +0 -98
  286. package/dist/cli/commands/trace/client.d.ts.map +0 -1
  287. package/dist/cli/commands/trace/client.js +0 -150
  288. package/dist/cli/commands/trace/format.d.ts +0 -5
  289. package/dist/cli/commands/trace/format.d.ts.map +0 -1
  290. package/dist/cli/commands/trace/format.js +0 -58
  291. package/dist/cli/commands/trace/index.d.ts +0 -21
  292. package/dist/cli/commands/trace/index.d.ts.map +0 -1
  293. package/dist/cli/commands/trace/index.js +0 -49
  294. package/dist/cli/commands/trace/register.d.ts +0 -6
  295. package/dist/cli/commands/trace/register.d.ts.map +0 -1
  296. package/dist/cli/commands/trace/register.js +0 -71
  297. package/dist/webui/assets/index-DEfRFmFT.js +0 -1667
@@ -0,0 +1,204 @@
1
+ // `chat local` and `chat import`: find Claude Code and Codex chats on this machine and import them.
2
+ import { requireConsent } from '../../interaction.js';
3
+ import { z } from 'zod';
4
+ import { flag, MissingScopeFailure, stringOption, UsageError, YES_OPTION, } from '../command.js';
5
+ import { findLocalChats, } from '../../import/local-chats.js';
6
+ import { toImportInput } from '../../import/redaction.js';
7
+ import { LOCAL_CHAT_SOURCES, } from '../../import/transcript.js';
8
+ import { queryWorkspaceTool } from './workspace.js';
9
+ const FIND_OPTIONS = {
10
+ dir: {
11
+ description: 'Read sessions from this folder (default: $CLAUDE_CONFIG_DIR/projects or ~/.claude/projects; $CODEX_HOME/sessions or ~/.codex/sessions).',
12
+ type: 'string',
13
+ valueName: 'PATH',
14
+ },
15
+ from: {
16
+ description: `Where the chats are: ${LOCAL_CHAT_SOURCES.join(' or ')}.`,
17
+ type: 'string',
18
+ valueName: 'SOURCE',
19
+ },
20
+ folder: {
21
+ description: 'Only sessions run in this folder or inside it, such as . for this repository.',
22
+ type: 'string',
23
+ valueName: 'PATH',
24
+ },
25
+ since: {
26
+ description: 'Only sessions with a turn on or after this date, such as 2026-10-01.',
27
+ type: 'string',
28
+ valueName: 'DATE',
29
+ },
30
+ };
31
+ const ImportedSchema = z.object({
32
+ session: z.object({ id: z.string() }),
33
+ status: z.enum(['already_imported', 'imported']),
34
+ url: z.string(),
35
+ });
36
+ function localQuery(input) {
37
+ const from = stringOption(input, 'from');
38
+ if (from === undefined)
39
+ throw new UsageError(`--from is required: ${LOCAL_CHAT_SOURCES.join(' or ')}.`);
40
+ const source = LOCAL_CHAT_SOURCES.find((each) => each === from);
41
+ if (source === undefined)
42
+ throw new UsageError(`--from takes ${LOCAL_CHAT_SOURCES.join(' or ')}, not ${from}.`);
43
+ const since = stringOption(input, 'since') ?? null;
44
+ if (since !== null && Number.isNaN(new Date(since).getTime()))
45
+ throw new UsageError('--since must be a date, such as 2026-10-01.');
46
+ return {
47
+ dir: stringOption(input, 'dir') ?? null,
48
+ folder: stringOption(input, 'folder') ?? null,
49
+ since,
50
+ source,
51
+ };
52
+ }
53
+ function sourceName(source) {
54
+ return source === 'claude-code' ? 'Claude Code' : 'Codex';
55
+ }
56
+ const local = {
57
+ options: FIND_OPTIONS,
58
+ path: ['chat', 'local'],
59
+ summary: 'List Claude Code or Codex chats on this machine, newest first, to pick some for chat import.',
60
+ async run(context, input) {
61
+ const scan = await findLocalChats(context.runtime, localQuery(input));
62
+ noteScan(context, scan);
63
+ context.output.list({
64
+ data: scan.chats.map((chat) => ({
65
+ cwd: chat.cwd,
66
+ id: chat.id,
67
+ messages: chat.messages.length,
68
+ path: chat.path,
69
+ pullRequests: chat.pullRequests,
70
+ repository: chat.repository,
71
+ source: chat.source,
72
+ startedAt: chat.startedAt,
73
+ title: chat.title,
74
+ updatedAt: chat.updatedAt,
75
+ })),
76
+ }, [
77
+ { header: 'id', value: (row) => row.id },
78
+ { header: 'title', value: (row) => row.title },
79
+ { header: 'messages', value: (row) => row.messages },
80
+ { header: 'updated', value: (row) => row.updatedAt },
81
+ { header: 'folder', value: (row) => row.cwd },
82
+ ]);
83
+ },
84
+ };
85
+ const importChats = {
86
+ arguments: '[session_ids...]',
87
+ options: {
88
+ ...FIND_OPTIONS,
89
+ all: { description: 'Import every session chat local lists.', type: 'boolean' },
90
+ 'dry-run': {
91
+ description: 'Send nothing; show what each import would send and what was redacted.',
92
+ type: 'boolean',
93
+ },
94
+ ...YES_OPTION,
95
+ },
96
+ path: ['chat', 'import'],
97
+ summary: 'Import Claude Code or Codex chats from this machine as your private Dexto chats, redacted here first.',
98
+ async run(context, input) {
99
+ const query = localQuery(input);
100
+ const ids = input.positionals;
101
+ const all = flag(input, 'all');
102
+ if (ids.length === 0 && !all)
103
+ throw new UsageError('Name the sessions to import, by the ids chat local lists, or pass --all.');
104
+ const scan = await findLocalChats(context.runtime, query);
105
+ noteScan(context, scan);
106
+ const found = scan.chats;
107
+ const planned = (all ? found : ids.map((id) => found.find((chat) => chat.id === id) ?? id)).map((chat) => plan(chat, query.source));
108
+ const sending = planned.filter((each) => each.input !== null);
109
+ if (flag(input, 'dry-run') || sending.length === 0) {
110
+ report(context, planned.map((each) => each.result));
111
+ return flag(input, 'dry-run') || planned.length === 0 ? 0 : 1;
112
+ }
113
+ const messages = sending.reduce((sum, each) => sum + (each.result.messages ?? 0), 0);
114
+ const redacted = sending.reduce((sum, each) => sum + Object.values(each.result.redactions ?? {}).reduce((one, n) => one + n, 0), 0);
115
+ await requireConsent(context, flag(input, 'yes'), `Upload ${sending.length} ${sourceName(query.source)} chat${sending.length === 1 ? '' : 's'} (${messages} messages, ${redacted} secrets redacted) as your private Dexto chats?`);
116
+ const finished = await Promise.all(planned.map(async ({ input: sent, result }) => {
117
+ if (sent === null)
118
+ return result;
119
+ try {
120
+ const imported = ImportedSchema.parse(await queryWorkspaceTool(context, 'dexto_chat_import', sent));
121
+ return {
122
+ ...result,
123
+ chatId: imported.session.id,
124
+ status: imported.status,
125
+ url: imported.url,
126
+ };
127
+ }
128
+ catch (error) {
129
+ // A missing permission fails every import alike: exit 3 with the sign-in that fixes it.
130
+ if (error instanceof MissingScopeFailure)
131
+ throw error;
132
+ return {
133
+ ...result,
134
+ reason: error instanceof Error ? error.message : 'The import failed.',
135
+ status: 'failed',
136
+ };
137
+ }
138
+ }));
139
+ report(context, finished);
140
+ return finished.some((result) => result.status === 'failed' || result.status === 'skipped')
141
+ ? 1
142
+ : 0;
143
+ },
144
+ };
145
+ /** What importing one chosen session would send, or why it can't go. */
146
+ function plan(chat, source) {
147
+ if (typeof chat === 'string')
148
+ return {
149
+ input: null,
150
+ result: {
151
+ id: chat,
152
+ reason: `No ${sourceName(source)} session with this id matches here.`,
153
+ status: 'skipped',
154
+ },
155
+ };
156
+ const prepared = toImportInput(chat);
157
+ if (prepared.kind === 'skipped')
158
+ return {
159
+ input: null,
160
+ result: { id: chat.id, reason: prepared.reason, status: 'skipped', title: chat.title },
161
+ };
162
+ return {
163
+ input: prepared.input,
164
+ result: {
165
+ id: chat.id,
166
+ leftOut: prepared.leftOut,
167
+ messages: prepared.input.messages.length,
168
+ redactions: prepared.redactions,
169
+ status: 'ready',
170
+ title: prepared.input.title,
171
+ truncated: prepared.truncated,
172
+ },
173
+ };
174
+ }
175
+ /** What the scan found that its chats don't show, such as Codex history it can't read yet. */
176
+ function noteScan(context, scan) {
177
+ for (const notice of scan.notices)
178
+ context.output.note(notice.message);
179
+ }
180
+ function report(context, sessions) {
181
+ context.output.result({ sessions }, sessions
182
+ .map((session) => [
183
+ `${session.status.padEnd(16)} ${session.id}`,
184
+ session.title === undefined ? '' : ` ${session.title}`,
185
+ session.url === undefined ? '' : ` ${session.url}`,
186
+ session.reason === undefined ? '' : ` ${session.reason}`,
187
+ session.status === 'ready' ? ` ${readyLine(session)}` : '',
188
+ ].join(''))
189
+ .join('\n'));
190
+ }
191
+ function readyLine(session) {
192
+ const redactions = Object.entries(session.redactions ?? {})
193
+ .map(([kind, count]) => `${count} ${kind}`)
194
+ .join(', ');
195
+ return [
196
+ `${session.messages ?? 0} messages`,
197
+ redactions === '' ? 'nothing redacted' : `redacted ${redactions}`,
198
+ session.truncated ? `${session.truncated} cut to size` : '',
199
+ session.leftOut ? `first ${session.leftOut} left out` : '',
200
+ ]
201
+ .filter((part) => part !== '')
202
+ .join('; ');
203
+ }
204
+ export const chatCommands = [local, importChats];
@@ -0,0 +1,3 @@
1
+ import { type Command } from '../command.js';
2
+ export declare const dataDeletionCommands: readonly Command[];
3
+ //# sourceMappingURL=data-deletions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-deletions.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/data-deletions.ts"],"names":[],"mappings":"AAKA,OAAO,EAQH,KAAK,OAAO,EACf,MAAM,eAAe,CAAC;AAiFvB,eAAO,MAAM,oBAAoB,EAAE,SAAS,OAAO,EAAwB,CAAC"}
@@ -0,0 +1,55 @@
1
+ // `cloud data-deletions`: delete an end user's or an agent's data in the background.
2
+ import { requireConsent } from '../../interaction.js';
3
+ import { unwrap } from '@dexto/cloud-client';
4
+ import { argument, flag, PAGE_OPTIONS, pageQuery, stringOption, UsageError, YES_OPTION, } from '../command.js';
5
+ const COLUMNS = [
6
+ { header: 'id', value: (deletion) => deletion.id },
7
+ { header: 'status', value: (deletion) => deletion.status },
8
+ { header: 'scope', value: (deletion) => JSON.stringify(deletion.scope) },
9
+ { header: 'created', value: (deletion) => deletion.created_at },
10
+ ];
11
+ const create = {
12
+ options: {
13
+ agent: { description: 'The agent whose data to delete.', type: 'string', valueName: 'ID' },
14
+ user: { description: 'The end-user label whose sessions to delete.', type: 'string' },
15
+ ...YES_OPTION,
16
+ },
17
+ path: ['cloud', 'data-deletions', 'create'],
18
+ summary: "Delete an end user's sessions (--user, optionally of one --agent), or all of an agent's data (--agent).",
19
+ async run(context, input) {
20
+ const agentId = stringOption(input, 'agent');
21
+ const user = stringOption(input, 'user');
22
+ if (agentId === undefined && user === undefined)
23
+ throw new UsageError('Pass --user, --agent, or both.');
24
+ await requireConsent(context, flag(input, 'yes'), user === undefined
25
+ ? `This deletes all of agent ${agentId}'s data for good.`
26
+ : `This deletes ${user}'s sessions${agentId === undefined ? '' : ` with agent ${agentId}`} for good.`);
27
+ const deletion = await unwrap(await (await context.client()).POST('/v1/data_deletions', {
28
+ body: { agent_id: agentId ?? null, ...(user === undefined ? {} : { user }) },
29
+ }));
30
+ context.output.result(deletion, `Data deletion ${deletion.id} is ${deletion.status}.`);
31
+ },
32
+ };
33
+ const list = {
34
+ options: PAGE_OPTIONS,
35
+ path: ['cloud', 'data-deletions', 'list'],
36
+ summary: 'List data deletions.',
37
+ async run(context, input) {
38
+ context.output.list(await unwrap(await (await context.client()).GET('/v1/data_deletions', {
39
+ params: { query: pageQuery(input) },
40
+ })), COLUMNS);
41
+ },
42
+ };
43
+ const get = {
44
+ arguments: '<data_deletion_id>',
45
+ path: ['cloud', 'data-deletions', 'get'],
46
+ summary: 'Show a data deletion and what it deleted.',
47
+ async run(context, input) {
48
+ context.output.record(await unwrap(await (await context.client()).GET('/v1/data_deletions/{data_deletion_id}', {
49
+ params: {
50
+ path: { data_deletion_id: argument(input, 0, 'data_deletion_id') },
51
+ },
52
+ })));
53
+ },
54
+ };
55
+ export const dataDeletionCommands = [create, list, get];
@@ -0,0 +1,10 @@
1
+ import { type Command, type CommandContext } from '../command.js';
2
+ /**
3
+ * A person's sign-in needs the kind's permission, and to deploy also `cloud:write`, which the API
4
+ * checks first; asking for every missing one at once lets a single sign-in cover the command. A
5
+ * deploy spends credits, so running one is asking for `cloud:write`. At a terminal the CLI then
6
+ * offers to sign in again for them. A key's permissions are checked by the API.
7
+ */
8
+ export declare function requireLoginScopes(context: CommandContext, scopes: readonly string[]): Promise<void>;
9
+ export declare const deployCommands: readonly Command[];
10
+ //# sourceMappingURL=deploys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploys.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/deploys.ts"],"names":[],"mappings":"AAWA,OAAO,EAMH,KAAK,OAAO,EACZ,KAAK,cAAc,EAGtB,MAAM,eAAe,CAAC;AAkLvB;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACpC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,SAAS,MAAM,EAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CAYf;AAwED,eAAO,MAAM,cAAc,EAAE,SAAS,OAAO,EAM5C,CAAC"}
@@ -0,0 +1,225 @@
1
+ // `cloud sites` and `cloud functions`: pack a project with its own packer, deploy, list and delete.
2
+ import { CommandFailure } from '../../failure.js';
3
+ import { requireConsent } from '../../interaction.js';
4
+ import { access, mkdtemp, readFile, rm } from 'node:fs/promises';
5
+ import { tmpdir } from 'node:os';
6
+ import path from 'node:path';
7
+ import { z } from 'zod';
8
+ import { argument, flag, MissingScopeFailure, stringOption, UsageError, YES_OPTION, } from '../command.js';
9
+ import { callV1 } from '../v1.js';
10
+ const PACKER = path.join('.dexto', 'pack.mjs');
11
+ const PROVIDERS = ['cloudflare-workers', 'aws-lambda'];
12
+ const SiteSchema = z.object({
13
+ id: z.string(),
14
+ slug: z.string(),
15
+ url: z.string(),
16
+ visibility: z.string(),
17
+ });
18
+ const FunctionSchema = z.object({
19
+ access: z.string(),
20
+ id: z.string(),
21
+ slug: z.string(),
22
+ status: z.string(),
23
+ url: z.string().nullable(),
24
+ });
25
+ const DeployedSiteSchema = z.object({
26
+ deployment: z.object({ id: z.string() }),
27
+ promoted: z.boolean(),
28
+ site: z.object({ id: z.string(), slug: z.string() }),
29
+ url: z.string(),
30
+ });
31
+ const DeployedFunctionSchema = z.object({
32
+ deployment: z.object({ id: z.string(), preview_url: z.string() }),
33
+ dexto: z.object({ configured: z.boolean(), scopes: z.array(z.string()) }).nullable(),
34
+ function: z.object({ id: z.string(), slug: z.string() }),
35
+ promoted: z.boolean(),
36
+ url: z.string().nullable(),
37
+ });
38
+ const DEPLOY_OPTIONS = {
39
+ 'no-promote': {
40
+ description: 'Deploy a preview to promote later, instead of making it live.',
41
+ type: 'boolean',
42
+ },
43
+ provider: {
44
+ description: `Where its Function runs: ${PROVIDERS.join(' or ')}. Omit for the default.`,
45
+ type: 'string',
46
+ valueName: 'PROVIDER',
47
+ },
48
+ };
49
+ const deploySite = {
50
+ arguments: '[dir]',
51
+ options: DEPLOY_OPTIONS,
52
+ path: ['cloud', 'sites', 'deploy'],
53
+ summary: 'Pack the Site in dir (default: here) with its packer and deploy it to the Cloud project; it goes live unless --no-promote.',
54
+ async run(context, input) {
55
+ await requireLoginScopes(context, ['sites:write', 'cloud:write']);
56
+ // Options are checked before packing, which can build and rewrite project files.
57
+ const query = deployQuery(input, {});
58
+ const packed = await pack(context, input.positionals[0], 'site');
59
+ const deployed = DeployedSiteSchema.parse(await callV1(context, 'POST', `/v1/sites/deployments?${query}`, packed));
60
+ context.output.result(deployed, deployed.promoted
61
+ ? `Deployed ${deployed.site.slug} to ${deployed.url} (deployment ${deployed.deployment.id}).`
62
+ : `Deployed a preview of ${deployed.site.slug} at ${deployed.url}. Make it live with: dexto cloud api POST /v1/sites/${deployed.site.id}/deployments/${deployed.deployment.id}/promote`);
63
+ },
64
+ };
65
+ const deployFunction = {
66
+ arguments: '[dir]',
67
+ options: {
68
+ ...DEPLOY_OPTIONS,
69
+ public: {
70
+ description: 'Let anyone on the internet reach it. Functions are private by default.',
71
+ type: 'boolean',
72
+ },
73
+ },
74
+ path: ['cloud', 'functions', 'deploy'],
75
+ summary: 'Pack the Function in dir (default: here) with its packer and deploy it to the Cloud project; it goes live unless --no-promote.',
76
+ async run(context, input) {
77
+ await requireLoginScopes(context, ['functions:write', 'cloud:write']);
78
+ // Options are checked before packing, which can build and rewrite project files.
79
+ const query = deployQuery(input, {
80
+ access: flag(input, 'public') ? 'public' : 'private',
81
+ });
82
+ const packed = await pack(context, input.positionals[0], 'function');
83
+ const deployed = DeployedFunctionSchema.parse(await callV1(context, 'POST', `/v1/functions/deployments?${query}`, packed));
84
+ const key = deployed.dexto === null || deployed.dexto.configured
85
+ ? ''
86
+ : ` Its Dexto key was not bound: your sign-in lacks ${deployed.dexto.scopes.join(', ')}.`;
87
+ context.output.result(deployed, deployed.promoted
88
+ ? `Deployed ${deployed.function.slug}${deployed.url === null ? '' : ` to ${deployed.url}`} (deployment ${deployed.deployment.id}).${key}`
89
+ : `Deployed ${deployed.function.slug} without making it live; preview at ${deployed.deployment.preview_url}. Make it live with: dexto cloud api POST /v1/functions/${deployed.function.id}/deployments/${deployed.deployment.id}/promote${key}`);
90
+ },
91
+ };
92
+ const SITE_COLUMNS = [
93
+ { header: 'id', value: (site) => site.id },
94
+ { header: 'slug', value: (site) => site.slug },
95
+ { header: 'visibility', value: (site) => site.visibility },
96
+ { header: 'url', value: (site) => site.url },
97
+ ];
98
+ const FUNCTION_COLUMNS = [
99
+ { header: 'id', value: (deployed) => deployed.id },
100
+ { header: 'slug', value: (deployed) => deployed.slug },
101
+ { header: 'status', value: (deployed) => deployed.status },
102
+ { header: 'access', value: (deployed) => deployed.access },
103
+ { header: 'url', value: (deployed) => deployed.url },
104
+ ];
105
+ const listSites = {
106
+ path: ['cloud', 'sites', 'list'],
107
+ summary: "List the Cloud project's Sites.",
108
+ async run(context) {
109
+ await requireLoginScopes(context, ['sites:read']);
110
+ const page = z
111
+ .object({ data: z.array(SiteSchema) })
112
+ .parse(await callV1(context, 'GET', '/v1/sites', null));
113
+ context.output.list(page, SITE_COLUMNS);
114
+ },
115
+ };
116
+ const deleteSite = {
117
+ arguments: '<site>',
118
+ options: YES_OPTION,
119
+ path: ['cloud', 'sites', 'delete'],
120
+ summary: 'Delete a Site of the Cloud project, by id or slug, with its deployments and data; its slug is free again. Asks first.',
121
+ async run(context, input) {
122
+ // The Site is found by listing, which takes sites:read, before it is deleted.
123
+ await requireLoginScopes(context, ['sites:read', 'sites:write', 'cloud:write']);
124
+ const wanted = argument(input, 0, 'site');
125
+ const sites = z
126
+ .object({ data: z.array(SiteSchema) })
127
+ .parse(await callV1(context, 'GET', '/v1/sites', null)).data;
128
+ const site = sites.find((each) => each.id === wanted || each.slug === wanted);
129
+ if (site === undefined)
130
+ throw new CommandFailure('not_found', `The Cloud project has no Site ${wanted}.`, 'dexto cloud sites list');
131
+ await requireConsent(context, flag(input, 'yes'), `This deletes ${site.slug} (${site.url}) with its deployments and data. It can't be undone.`);
132
+ await callV1(context, 'DELETE', `/v1/sites/${encodeURIComponent(site.id)}`, null);
133
+ context.output.result({ deleted: true, id: site.id, slug: site.slug }, `Deleted ${site.slug}. Its slug is free to deploy again.`);
134
+ },
135
+ };
136
+ const listFunctions = {
137
+ path: ['cloud', 'functions', 'list'],
138
+ summary: "List the Cloud project's Functions.",
139
+ async run(context) {
140
+ await requireLoginScopes(context, ['functions:read']);
141
+ const page = z
142
+ .object({ data: z.array(FunctionSchema) })
143
+ .parse(await callV1(context, 'GET', '/v1/functions', null));
144
+ context.output.list(page, FUNCTION_COLUMNS);
145
+ },
146
+ };
147
+ /**
148
+ * A person's sign-in needs the kind's permission, and to deploy also `cloud:write`, which the API
149
+ * checks first; asking for every missing one at once lets a single sign-in cover the command. A
150
+ * deploy spends credits, so running one is asking for `cloud:write`. At a terminal the CLI then
151
+ * offers to sign in again for them. A key's permissions are checked by the API.
152
+ */
153
+ export async function requireLoginScopes(context, scopes) {
154
+ const connection = await context.connection();
155
+ if (connection.kind !== 'oauth')
156
+ return;
157
+ const missing = scopes.filter((scope) => !connection.login.scopes.includes(scope));
158
+ if (missing.length === 0)
159
+ return;
160
+ throw new MissingScopeFailure(context, missing.join(','), missing.length === 1
161
+ ? `This needs the ${missing[0]} permission, which your sign-in lacks.`
162
+ : `This needs the ${missing.join(' and ')} permissions, which your sign-in lacks.`);
163
+ }
164
+ function deployQuery(input, extra) {
165
+ const provider = stringOption(input, 'provider');
166
+ if (provider !== undefined && !PROVIDERS.some((each) => each === provider))
167
+ throw new UsageError(`--provider must be ${PROVIDERS.join(' or ')}.`);
168
+ return new URLSearchParams({
169
+ ...extra,
170
+ promote: flag(input, 'no-promote') ? 'false' : 'true',
171
+ ...(provider === undefined ? {} : { provider }),
172
+ });
173
+ }
174
+ /**
175
+ * Runs the project's own packer, `.dexto/pack.mjs`, or its `pack` script when it has none, into a
176
+ * temporary file, and returns the deploy request it wrote once it is the kind asked for.
177
+ */
178
+ async function pack(context, dir, kind) {
179
+ const projectDir = path.resolve(dir ?? '.');
180
+ const outputDir = await mkdtemp(path.join(tmpdir(), 'dexto-pack-'));
181
+ const outputPath = path.join(outputDir, 'deploy-request.json');
182
+ try {
183
+ const ownPacker = await exists(path.join(projectDir, PACKER));
184
+ const [command, args] = ownPacker
185
+ ? ['node', [PACKER, '.', '--out', outputPath]]
186
+ : ['pnpm', ['run', 'pack', '.', '--out', outputPath]];
187
+ context.output.note(`Packing ${projectDir} with ${ownPacker ? PACKER : 'pnpm run pack'}…`);
188
+ const packed = await context.runtime.runProcess(command, args, { cwd: projectDir });
189
+ if (packed.exitCode !== 0)
190
+ throw new CommandFailure('invalid_input', `Packing failed:\n${packed.output.trim()}`, null);
191
+ const text = await readFile(outputPath, 'utf8').catch(() => {
192
+ throw new CommandFailure('failed', `The packer wrote no deploy request to ${outputPath}.`, null);
193
+ });
194
+ const packedKind = packageKind(text);
195
+ if (packedKind !== kind)
196
+ throw new UsageError(`${projectDir} packs a ${packedKind}. Deploy it with dexto cloud ${packedKind}s deploy.`);
197
+ return text;
198
+ }
199
+ finally {
200
+ await rm(outputDir, { force: true, recursive: true });
201
+ }
202
+ }
203
+ /** A Site's deploy request has pages (`assets`); a Function's has none. */
204
+ function packageKind(text) {
205
+ const parsed = JSON.parse(text);
206
+ return typeof parsed === 'object' && parsed !== null && 'assets' in parsed
207
+ ? 'site'
208
+ : 'function';
209
+ }
210
+ async function exists(file) {
211
+ try {
212
+ await access(file);
213
+ return true;
214
+ }
215
+ catch {
216
+ return false;
217
+ }
218
+ }
219
+ export const deployCommands = [
220
+ deploySite,
221
+ listSites,
222
+ deleteSite,
223
+ deployFunction,
224
+ listFunctions,
225
+ ];
@@ -0,0 +1,12 @@
1
+ import { type Command, type CommandContext } from '../command.js';
2
+ /**
3
+ * Uploads one local file into an app's own Drive folder, which gives the app the file to refer to
4
+ * as `drive:<id>`.
5
+ */
6
+ export declare function putAppFile(context: CommandContext, localPath: string, appId: string): Promise<{
7
+ id: string;
8
+ mimeType: string;
9
+ name: string;
10
+ }>;
11
+ export declare const driveCommands: readonly Command[];
12
+ //# sourceMappingURL=drive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/drive.ts"],"names":[],"mappings":"AAWA,OAAO,EAIH,KAAK,OAAO,EACZ,KAAK,cAAc,EACtB,MAAM,eAAe,CAAC;AA4VvB;;;GAGG;AACH,wBAAsB,UAAU,CAC5B,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAezD;AAwED,eAAO,MAAM,aAAa,EAAE,SAAS,OAAO,EAAU,CAAC"}