@agent-native/core 0.131.7 → 0.132.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +123 -0
  3. package/corpus/core/docs/content/durable-background-runs.mdx +15 -6
  4. package/corpus/core/docs/design/durable-agent-runs.md +15 -11
  5. package/corpus/core/package.json +1 -1
  6. package/corpus/core/src/a2a/activity.ts +127 -10
  7. package/corpus/core/src/a2a/index.ts +3 -0
  8. package/corpus/core/src/agent/durable-background.ts +38 -28
  9. package/corpus/core/src/agent/harness/background.ts +12 -2
  10. package/corpus/core/src/agent/production-agent.ts +18 -15
  11. package/corpus/core/src/agent/run-store.ts +45 -3
  12. package/corpus/core/src/application-state/handlers.ts +45 -0
  13. package/corpus/core/src/application-state/index.ts +3 -0
  14. package/corpus/core/src/application-state/store.ts +38 -34
  15. package/corpus/core/src/audit/redact.ts +104 -18
  16. package/corpus/core/src/cli/create.ts +115 -16
  17. package/corpus/core/src/client/AgentPanel.tsx +2 -7
  18. package/corpus/core/src/client/AssistantChat.tsx +10 -2
  19. package/corpus/core/src/client/MultiTabAssistantChat.tsx +3 -0
  20. package/corpus/core/src/client/RunStuckBanner.tsx +29 -6
  21. package/corpus/core/src/client/agent-chat.ts +4 -9
  22. package/corpus/core/src/client/application-state.ts +115 -12
  23. package/corpus/core/src/client/dynamic-suggestions.ts +4 -12
  24. package/corpus/core/src/client/frame-protocol.ts +5 -1
  25. package/corpus/core/src/client/guided-questions.tsx +12 -23
  26. package/corpus/core/src/db/client.ts +148 -28
  27. package/corpus/core/src/db/create-get-db.ts +39 -6
  28. package/corpus/core/src/db/runtime-diagnostics.ts +41 -6
  29. package/corpus/core/src/deploy/build.ts +26 -33
  30. package/corpus/core/src/feature-flags/store.ts +10 -5
  31. package/corpus/core/src/integrations/a2a-continuations-store.ts +11 -0
  32. package/corpus/core/src/integrations/config-store.ts +13 -0
  33. package/corpus/core/src/integrations/google-docs-poller.ts +26 -2
  34. package/corpus/core/src/mcp-client/routes.ts +33 -2
  35. package/corpus/core/src/onboarding/plugin.ts +31 -25
  36. package/corpus/core/src/org/accept-pending.ts +2 -0
  37. package/corpus/core/src/org/auto-join-domain.ts +2 -0
  38. package/corpus/core/src/org/context.ts +35 -10
  39. package/corpus/core/src/org/handlers.ts +6 -0
  40. package/corpus/core/src/org/request-org-cache.ts +71 -0
  41. package/corpus/core/src/resources/store.ts +10 -9
  42. package/corpus/core/src/scripts/runner.ts +6 -3
  43. package/corpus/core/src/secrets/storage.ts +97 -5
  44. package/corpus/core/src/server/action-change.ts +33 -0
  45. package/corpus/core/src/server/action-routes.ts +11 -9
  46. package/corpus/core/src/server/agent-teams.ts +10 -2
  47. package/corpus/core/src/server/better-auth-instance.ts +39 -12
  48. package/corpus/core/src/server/core-routes-plugin.ts +19 -2
  49. package/corpus/core/src/server/credential-provider.ts +57 -14
  50. package/corpus/core/src/server/http-response-telemetry.ts +1 -0
  51. package/corpus/core/src/server/poll.ts +95 -57
  52. package/corpus/core/src/server/voice-providers-status.ts +19 -4
  53. package/corpus/core/src/workspace-files/tool.ts +18 -11
  54. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +38 -0
  55. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +1 -1
  56. package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +299 -0
  57. package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +34 -0
  58. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +82 -0
  59. package/corpus/templates/analytics/app/components/layout/NewDashboardDialog.tsx +2 -2
  60. package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +40 -34
  61. package/corpus/templates/analytics/app/hooks/use-user-pref.ts +3 -3
  62. package/corpus/templates/analytics/app/i18n-data.ts +40 -0
  63. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +18 -10
  64. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +14 -0
  65. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +1 -0
  66. package/corpus/templates/analytics/app/routes/chart.tsx +3 -0
  67. package/corpus/templates/analytics/changelog/2026-07-30-analytics-dashboards-now-expose-native-funnel-heatmap-callou.md +6 -0
  68. package/corpus/templates/analytics/changelog/2026-07-30-analytics-now-ships-reusable-native-v2-dashboard-manifests-w.md +6 -0
  69. package/corpus/templates/analytics/server/lib/dashboard-report-render.ts +81 -1
  70. package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +457 -0
  71. package/corpus/templates/analytics/server/lib/report-chart-svg.ts +73 -2
  72. package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -1
  73. package/corpus/templates/analytics/shared/dashboard-funnel.ts +83 -0
  74. package/corpus/templates/clips/actions/generate-workflow.ts +6 -4
  75. package/corpus/templates/clips/actions/reconcile-workflow-generation.ts +257 -0
  76. package/corpus/templates/clips/app/hooks/use-auto-title.ts +166 -4
  77. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -1
  78. package/corpus/templates/clips/changelog/2026-07-27-stopped-agent-runs-no-longer-leave-generated-workflow-cards-.md +6 -0
  79. package/corpus/templates/clips/changelog/2026-07-30-workflow-generation-now-stops-retrying-after-repeated-failur.md +6 -0
  80. package/corpus/templates/clips/shared/workflow.ts +5 -0
  81. package/corpus/templates/content/changelog/2026-07-30-long-running-delegated-requests-now-continue-reliably.md +6 -0
  82. package/corpus/templates/content/netlify.toml +3 -0
  83. package/corpus/templates/content/server/plugins/agent-chat.ts +1 -0
  84. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +2 -1
  85. package/corpus/templates/slides/actions/patch-deck.ts +25 -1
  86. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +17 -4
  87. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +9 -1
  88. package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -1
  89. package/corpus/templates/slides/app/context/DeckContext.tsx +11 -3
  90. package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +39 -11
  91. package/corpus/templates/slides/app/pages/Index.tsx +2 -2
  92. package/corpus/templates/slides/changelog/2026-07-30-slide-previews-keep-their-aspect-ratio-isolate-embedded-styl.md +6 -0
  93. package/corpus/templates/slides/changelog/2026-07-30-slides-no-longer-lose-decks-while-organization-access-is-loa.md +6 -0
  94. package/corpus/toolkit/CHANGELOG.md +8 -0
  95. package/corpus/toolkit/package.json +1 -1
  96. package/corpus/toolkit/src/composer/runtime-adapters.tsx +16 -11
  97. package/dist/a2a/activity.d.ts +22 -4
  98. package/dist/a2a/activity.d.ts.map +1 -1
  99. package/dist/a2a/activity.js +97 -11
  100. package/dist/a2a/activity.js.map +1 -1
  101. package/dist/a2a/index.d.ts +1 -1
  102. package/dist/a2a/index.d.ts.map +1 -1
  103. package/dist/a2a/index.js +1 -1
  104. package/dist/a2a/index.js.map +1 -1
  105. package/dist/agent/durable-background.d.ts +13 -8
  106. package/dist/agent/durable-background.d.ts.map +1 -1
  107. package/dist/agent/durable-background.js +36 -28
  108. package/dist/agent/durable-background.js.map +1 -1
  109. package/dist/agent/harness/background.d.ts.map +1 -1
  110. package/dist/agent/harness/background.js +12 -2
  111. package/dist/agent/harness/background.js.map +1 -1
  112. package/dist/agent/production-agent.d.ts.map +1 -1
  113. package/dist/agent/production-agent.js +18 -15
  114. package/dist/agent/production-agent.js.map +1 -1
  115. package/dist/agent/run-store.d.ts +2 -0
  116. package/dist/agent/run-store.d.ts.map +1 -1
  117. package/dist/agent/run-store.js +44 -3
  118. package/dist/agent/run-store.js.map +1 -1
  119. package/dist/application-state/handlers.d.ts +15 -0
  120. package/dist/application-state/handlers.d.ts.map +1 -1
  121. package/dist/application-state/handlers.js +42 -2
  122. package/dist/application-state/handlers.js.map +1 -1
  123. package/dist/application-state/index.d.ts +2 -2
  124. package/dist/application-state/index.d.ts.map +1 -1
  125. package/dist/application-state/index.js +2 -2
  126. package/dist/application-state/index.js.map +1 -1
  127. package/dist/application-state/store.d.ts +11 -0
  128. package/dist/application-state/store.d.ts.map +1 -1
  129. package/dist/application-state/store.js +37 -40
  130. package/dist/application-state/store.js.map +1 -1
  131. package/dist/audit/redact.d.ts +25 -2
  132. package/dist/audit/redact.d.ts.map +1 -1
  133. package/dist/audit/redact.js +85 -21
  134. package/dist/audit/redact.js.map +1 -1
  135. package/dist/cli/create.d.ts +8 -1
  136. package/dist/cli/create.d.ts.map +1 -1
  137. package/dist/cli/create.js +98 -16
  138. package/dist/cli/create.js.map +1 -1
  139. package/dist/client/AgentPanel.d.ts.map +1 -1
  140. package/dist/client/AgentPanel.js +2 -7
  141. package/dist/client/AgentPanel.js.map +1 -1
  142. package/dist/client/AssistantChat.d.ts.map +1 -1
  143. package/dist/client/AssistantChat.js +10 -2
  144. package/dist/client/AssistantChat.js.map +1 -1
  145. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  146. package/dist/client/MultiTabAssistantChat.js +1 -1
  147. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  148. package/dist/client/RunStuckBanner.d.ts +11 -1
  149. package/dist/client/RunStuckBanner.d.ts.map +1 -1
  150. package/dist/client/RunStuckBanner.js +20 -7
  151. package/dist/client/RunStuckBanner.js.map +1 -1
  152. package/dist/client/agent-chat.d.ts.map +1 -1
  153. package/dist/client/agent-chat.js +4 -6
  154. package/dist/client/agent-chat.js.map +1 -1
  155. package/dist/client/application-state.d.ts +11 -0
  156. package/dist/client/application-state.d.ts.map +1 -1
  157. package/dist/client/application-state.js +87 -9
  158. package/dist/client/application-state.js.map +1 -1
  159. package/dist/client/dynamic-suggestions.d.ts.map +1 -1
  160. package/dist/client/dynamic-suggestions.js +4 -13
  161. package/dist/client/dynamic-suggestions.js.map +1 -1
  162. package/dist/client/frame-protocol.d.ts +1 -0
  163. package/dist/client/frame-protocol.d.ts.map +1 -1
  164. package/dist/client/frame-protocol.js.map +1 -1
  165. package/dist/client/guided-questions.d.ts.map +1 -1
  166. package/dist/client/guided-questions.js +6 -22
  167. package/dist/client/guided-questions.js.map +1 -1
  168. package/dist/collab/awareness.d.ts +2 -2
  169. package/dist/collab/awareness.d.ts.map +1 -1
  170. package/dist/collab/routes.d.ts +1 -1
  171. package/dist/db/client.d.ts +57 -10
  172. package/dist/db/client.d.ts.map +1 -1
  173. package/dist/db/client.js +122 -31
  174. package/dist/db/client.js.map +1 -1
  175. package/dist/db/create-get-db.d.ts.map +1 -1
  176. package/dist/db/create-get-db.js +31 -7
  177. package/dist/db/create-get-db.js.map +1 -1
  178. package/dist/db/runtime-diagnostics.d.ts +1 -0
  179. package/dist/db/runtime-diagnostics.d.ts.map +1 -1
  180. package/dist/db/runtime-diagnostics.js +31 -6
  181. package/dist/db/runtime-diagnostics.js.map +1 -1
  182. package/dist/deploy/build.d.ts +5 -20
  183. package/dist/deploy/build.d.ts.map +1 -1
  184. package/dist/deploy/build.js +18 -30
  185. package/dist/deploy/build.js.map +1 -1
  186. package/dist/feature-flags/store.d.ts.map +1 -1
  187. package/dist/feature-flags/store.js +10 -5
  188. package/dist/feature-flags/store.js.map +1 -1
  189. package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
  190. package/dist/integrations/a2a-continuations-store.js +12 -0
  191. package/dist/integrations/a2a-continuations-store.js.map +1 -1
  192. package/dist/integrations/config-store.d.ts +1 -0
  193. package/dist/integrations/config-store.d.ts.map +1 -1
  194. package/dist/integrations/config-store.js +11 -0
  195. package/dist/integrations/config-store.js.map +1 -1
  196. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  197. package/dist/integrations/google-docs-poller.js +19 -2
  198. package/dist/integrations/google-docs-poller.js.map +1 -1
  199. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  200. package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
  201. package/dist/mcp-client/routes.d.ts.map +1 -1
  202. package/dist/mcp-client/routes.js +30 -2
  203. package/dist/mcp-client/routes.js.map +1 -1
  204. package/dist/notifications/routes.d.ts +6 -6
  205. package/dist/onboarding/plugin.d.ts.map +1 -1
  206. package/dist/onboarding/plugin.js +12 -8
  207. package/dist/onboarding/plugin.js.map +1 -1
  208. package/dist/org/accept-pending.d.ts.map +1 -1
  209. package/dist/org/accept-pending.js +2 -0
  210. package/dist/org/accept-pending.js.map +1 -1
  211. package/dist/org/auto-join-domain.d.ts.map +1 -1
  212. package/dist/org/auto-join-domain.js +2 -0
  213. package/dist/org/auto-join-domain.js.map +1 -1
  214. package/dist/org/context.d.ts.map +1 -1
  215. package/dist/org/context.js +29 -9
  216. package/dist/org/context.js.map +1 -1
  217. package/dist/org/handlers.d.ts.map +1 -1
  218. package/dist/org/handlers.js +5 -0
  219. package/dist/org/handlers.js.map +1 -1
  220. package/dist/org/request-org-cache.d.ts +16 -0
  221. package/dist/org/request-org-cache.d.ts.map +1 -0
  222. package/dist/org/request-org-cache.js +62 -0
  223. package/dist/org/request-org-cache.js.map +1 -0
  224. package/dist/progress/routes.d.ts +1 -1
  225. package/dist/resources/handlers.d.ts +1 -1
  226. package/dist/resources/store.d.ts.map +1 -1
  227. package/dist/resources/store.js +11 -9
  228. package/dist/resources/store.js.map +1 -1
  229. package/dist/scripts/runner.d.ts.map +1 -1
  230. package/dist/scripts/runner.js +3 -3
  231. package/dist/scripts/runner.js.map +1 -1
  232. package/dist/secrets/storage.d.ts.map +1 -1
  233. package/dist/secrets/storage.js +82 -5
  234. package/dist/secrets/storage.js.map +1 -1
  235. package/dist/server/action-change.d.ts +20 -0
  236. package/dist/server/action-change.d.ts.map +1 -1
  237. package/dist/server/action-change.js +29 -0
  238. package/dist/server/action-change.js.map +1 -1
  239. package/dist/server/action-routes.d.ts.map +1 -1
  240. package/dist/server/action-routes.js +7 -8
  241. package/dist/server/action-routes.js.map +1 -1
  242. package/dist/server/agent-teams.d.ts.map +1 -1
  243. package/dist/server/agent-teams.js +10 -2
  244. package/dist/server/agent-teams.js.map +1 -1
  245. package/dist/server/better-auth-instance.d.ts.map +1 -1
  246. package/dist/server/better-auth-instance.js +31 -14
  247. package/dist/server/better-auth-instance.js.map +1 -1
  248. package/dist/server/core-routes-plugin.d.ts +1 -0
  249. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  250. package/dist/server/core-routes-plugin.js +18 -4
  251. package/dist/server/core-routes-plugin.js.map +1 -1
  252. package/dist/server/credential-provider.d.ts +16 -0
  253. package/dist/server/credential-provider.d.ts.map +1 -1
  254. package/dist/server/credential-provider.js +49 -13
  255. package/dist/server/credential-provider.js.map +1 -1
  256. package/dist/server/http-response-telemetry.d.ts.map +1 -1
  257. package/dist/server/http-response-telemetry.js +1 -0
  258. package/dist/server/http-response-telemetry.js.map +1 -1
  259. package/dist/server/poll.d.ts +6 -0
  260. package/dist/server/poll.d.ts.map +1 -1
  261. package/dist/server/poll.js +84 -47
  262. package/dist/server/poll.js.map +1 -1
  263. package/dist/server/realtime-token.d.ts +1 -1
  264. package/dist/server/voice-providers-status.d.ts.map +1 -1
  265. package/dist/server/voice-providers-status.js +12 -3
  266. package/dist/server/voice-providers-status.js.map +1 -1
  267. package/dist/workspace-files/tool.d.ts.map +1 -1
  268. package/dist/workspace-files/tool.js +18 -11
  269. package/dist/workspace-files/tool.js.map +1 -1
  270. package/docs/content/durable-background-runs.mdx +15 -6
  271. package/docs/design/durable-agent-runs.md +15 -11
  272. package/package.json +3 -3
  273. package/src/a2a/activity.ts +127 -10
  274. package/src/a2a/index.ts +3 -0
  275. package/src/agent/durable-background.ts +38 -28
  276. package/src/agent/harness/background.ts +12 -2
  277. package/src/agent/production-agent.ts +18 -15
  278. package/src/agent/run-store.ts +45 -3
  279. package/src/application-state/handlers.ts +45 -0
  280. package/src/application-state/index.ts +3 -0
  281. package/src/application-state/store.ts +38 -34
  282. package/src/audit/redact.ts +104 -18
  283. package/src/cli/create.ts +115 -16
  284. package/src/client/AgentPanel.tsx +2 -7
  285. package/src/client/AssistantChat.tsx +10 -2
  286. package/src/client/MultiTabAssistantChat.tsx +3 -0
  287. package/src/client/RunStuckBanner.tsx +29 -6
  288. package/src/client/agent-chat.ts +4 -9
  289. package/src/client/application-state.ts +115 -12
  290. package/src/client/dynamic-suggestions.ts +4 -12
  291. package/src/client/frame-protocol.ts +5 -1
  292. package/src/client/guided-questions.tsx +12 -23
  293. package/src/db/client.ts +148 -28
  294. package/src/db/create-get-db.ts +39 -6
  295. package/src/db/runtime-diagnostics.ts +41 -6
  296. package/src/deploy/build.ts +26 -33
  297. package/src/feature-flags/store.ts +10 -5
  298. package/src/integrations/a2a-continuations-store.ts +11 -0
  299. package/src/integrations/config-store.ts +13 -0
  300. package/src/integrations/google-docs-poller.ts +26 -2
  301. package/src/mcp-client/routes.ts +33 -2
  302. package/src/onboarding/plugin.ts +31 -25
  303. package/src/org/accept-pending.ts +2 -0
  304. package/src/org/auto-join-domain.ts +2 -0
  305. package/src/org/context.ts +35 -10
  306. package/src/org/handlers.ts +6 -0
  307. package/src/org/request-org-cache.ts +71 -0
  308. package/src/resources/store.ts +10 -9
  309. package/src/scripts/runner.ts +6 -3
  310. package/src/secrets/storage.ts +97 -5
  311. package/src/server/action-change.ts +33 -0
  312. package/src/server/action-routes.ts +11 -9
  313. package/src/server/agent-teams.ts +10 -2
  314. package/src/server/better-auth-instance.ts +39 -12
  315. package/src/server/core-routes-plugin.ts +19 -2
  316. package/src/server/credential-provider.ts +57 -14
  317. package/src/server/http-response-telemetry.ts +1 -0
  318. package/src/server/poll.ts +95 -57
  319. package/src/server/voice-providers-status.ts +19 -4
  320. package/src/workspace-files/tool.ts +18 -11
@@ -10,13 +10,18 @@
10
10
  * This mirrors the framework's standing rule that credential-looking literals
11
11
  * never land in source, logs, or fixtures.
12
12
  */
13
- const SENSITIVE_KEY = /(pass(word|phrase)?|secret|token|api[_-]?key|apikey|authorization|bearer|credential|cookie|session[_-]?(id|token)|private[_-]?key|client[_-]?secret|signing[_-]?secret|access[_-]?key|refresh[_-]?token|webhook[_-]?(url|secret))/i;
13
+ const SENSITIVE_KEY = /(?:pass(?:word|phrase)?|secret|token|api[_-]?key|apikey|authorization|bearer|credential|cookie|session[_-]?(?:id|token)|private[_-]?key|client[_-]?secret|signing[_-]?secret|access[_-]?key|refresh[_-]?token|webhook[_-]?(?:url|secret))/i;
14
14
  const REDACTED = "[redacted]";
15
15
  const MAX_STRING = 2000;
16
16
  const MAX_DEPTH = 6;
17
17
  const MAX_KEYS = 100;
18
18
  const MAX_ARRAY = 100;
19
19
  const MAX_JSON = 8000;
20
+ /**
21
+ * Head room reserved for the `…(N more chars)` marker so a truncated summary
22
+ * still fits its caller's cap. Callers below this cannot carry a marker at all.
23
+ */
24
+ const MARKER_SLACK = 32;
20
25
  /** Heuristic: does a bare string value look like a secret? */
21
26
  function looksSecret(value) {
22
27
  if (/^bearer\s+\S/i.test(value))
@@ -35,25 +40,32 @@ function looksSecret(value) {
35
40
  }
36
41
  return false;
37
42
  }
38
- function redactString(value) {
43
+ function redactString(value, maxString) {
39
44
  if (looksSecret(value))
40
45
  return REDACTED;
41
- if (value.length > MAX_STRING) {
42
- return `${value.slice(0, MAX_STRING)}…(${value.length - MAX_STRING} more chars)`;
46
+ if (value.length > maxString) {
47
+ return `${value.slice(0, maxString)}…(${value.length - maxString} more chars)`;
43
48
  }
44
49
  return value;
45
50
  }
46
- function redact(value, depth) {
51
+ function redactEmbeddedSecrets(value) {
52
+ const bearer = value.replace(/\b(bearer\s+)([^\s"',}]+)/gi, `$1${REDACTED}`);
53
+ const credentialField = new RegExp(`(["']?\\b${SENSITIVE_KEY.source}\\b["']?\\s*[:=]\\s*)(["']?)(?!bearer\\b)([^"'\\s,}]+)\\2`, "gi");
54
+ return bearer.replace(credentialField, `$1$2${REDACTED}$2`);
55
+ }
56
+ function redact(value, depth, maxString) {
47
57
  if (value == null)
48
58
  return value;
49
59
  if (typeof value === "string")
50
- return redactString(value);
60
+ return redactString(value, maxString);
51
61
  if (typeof value === "number" || typeof value === "boolean")
52
62
  return value;
53
63
  if (depth >= MAX_DEPTH)
54
64
  return "[…]";
55
65
  if (Array.isArray(value)) {
56
- const out = value.slice(0, MAX_ARRAY).map((v) => redact(v, depth + 1));
66
+ const out = value
67
+ .slice(0, MAX_ARRAY)
68
+ .map((v) => redact(v, depth + 1, maxString));
57
69
  if (value.length > MAX_ARRAY)
58
70
  out.push(`…(${value.length - MAX_ARRAY} more)`);
59
71
  return out;
@@ -67,7 +79,9 @@ function redact(value, depth) {
67
79
  break;
68
80
  }
69
81
  n += 1;
70
- out[k] = SENSITIVE_KEY.test(k) ? REDACTED : redact(v, depth + 1);
82
+ out[k] = SENSITIVE_KEY.test(k)
83
+ ? REDACTED
84
+ : redact(v, depth + 1, maxString);
71
85
  }
72
86
  return out;
73
87
  }
@@ -78,32 +92,82 @@ function redact(value, depth) {
78
92
  * Redact and serialize call arguments to a capped JSON string, or `null` when
79
93
  * there is nothing to record. Never throws.
80
94
  */
81
- export function redactArgsToJson(args) {
95
+ export function redactArgsToJson(args, limits) {
96
+ const maxJson = Math.max(MARKER_SLACK * 4, limits?.maxJson ?? MAX_JSON);
97
+ const maxString = limits?.maxString ?? MAX_STRING;
82
98
  try {
83
99
  if (args == null)
84
100
  return null;
85
- const redacted = redact(args, 0);
101
+ const redacted = redact(args, 0, maxString);
86
102
  if (redacted === undefined)
87
103
  return null;
88
104
  const json = JSON.stringify(redacted);
89
105
  if (json == null)
90
106
  return null;
91
- if (json.length > MAX_JSON) {
92
- // Slicing the serialized JSON would yield an unparseable string. Wrap a
93
- // preview in a valid envelope so `get-audit-event` can always JSON.parse
94
- // the stored `input`.
95
- return JSON.stringify({
96
- _auditTruncated: true,
97
- originalBytes: json.length,
98
- preview: json.slice(0, MAX_JSON),
99
- });
107
+ if (json.length <= maxJson)
108
+ return json;
109
+ // Slicing the serialized JSON would yield an unparseable string. Wrap a
110
+ // preview in a valid envelope so `get-audit-event` can always JSON.parse
111
+ // the stored `input`. JSON escaping makes the envelope overhead
112
+ // content-dependent, so shrink the preview until the whole thing measures
113
+ // under the cap rather than guessing at the overhead.
114
+ const envelope = (preview) => JSON.stringify({
115
+ _auditTruncated: true,
116
+ originalBytes: json.length,
117
+ preview,
118
+ });
119
+ let take = maxJson;
120
+ let out = envelope(json.slice(0, take));
121
+ while (out.length > maxJson && take > 0) {
122
+ take = Math.max(0, take - Math.max(1, out.length - maxJson));
123
+ out = envelope(json.slice(0, take));
100
124
  }
101
- return json;
125
+ return out;
102
126
  }
103
127
  catch {
104
128
  return null;
105
129
  }
106
130
  }
131
+ /**
132
+ * Same bounds as `redactArgsToJson`, returned as a structural value for
133
+ * surfaces whose consumers expect an object (transcript `metadata.input`).
134
+ */
135
+ export function redactArgsToValue(args, limits) {
136
+ const json = redactArgsToJson(args, limits);
137
+ if (json == null)
138
+ return null;
139
+ try {
140
+ return JSON.parse(json);
141
+ }
142
+ catch {
143
+ return null;
144
+ }
145
+ }
146
+ /**
147
+ * Bounded, redacted plain-text summary of a tool result. Oversized text keeps
148
+ * its head and gains an explicit `…(N more chars)` marker, so a reader can
149
+ * always tell a short result from a clipped one.
150
+ */
151
+ export function redactTextToSummary(text, maxChars = MAX_STRING) {
152
+ if (!text)
153
+ return null;
154
+ // Only ever walk a bounded head: a multi-megabyte tool result must not be
155
+ // scanned in full just to produce a preview of it.
156
+ const head = text.slice(0, maxChars + MARKER_SLACK);
157
+ const redactedHead = redactEmbeddedSecrets(head);
158
+ if (looksSecret(redactedHead.trim()))
159
+ return REDACTED;
160
+ if (text.length <= maxChars && redactedHead.length <= maxChars) {
161
+ return redactedHead;
162
+ }
163
+ const keep = Math.max(0, maxChars - MARKER_SLACK);
164
+ return `${redactedHead.slice(0, keep)}…(${text.length - keep} more chars)`;
165
+ }
107
166
  /** Exposed for tests. */
108
- export const __test = { looksSecret, redact, SENSITIVE_KEY };
167
+ export const __test = {
168
+ looksSecret,
169
+ redact,
170
+ redactEmbeddedSecrets,
171
+ SENSITIVE_KEY,
172
+ };
109
173
  //# sourceMappingURL=redact.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/audit/redact.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Redaction for audit-captured arguments.\n *\n * The audit log must never become a secondary store of secrets. Before any\n * call arguments are persisted we:\n * - drop values under credential-looking keys (token, secret, password, …),\n * - redact string values that look like bearer tokens / long opaque keys,\n * - truncate oversized strings and cap the serialized payload size.\n *\n * This mirrors the framework's standing rule that credential-looking literals\n * never land in source, logs, or fixtures.\n */\n\nconst SENSITIVE_KEY =\n /(pass(word|phrase)?|secret|token|api[_-]?key|apikey|authorization|bearer|credential|cookie|session[_-]?(id|token)|private[_-]?key|client[_-]?secret|signing[_-]?secret|access[_-]?key|refresh[_-]?token|webhook[_-]?(url|secret))/i;\n\nconst REDACTED = \"[redacted]\";\nconst MAX_STRING = 2000;\nconst MAX_DEPTH = 6;\nconst MAX_KEYS = 100;\nconst MAX_ARRAY = 100;\nconst MAX_JSON = 8000;\n\n/** Heuristic: does a bare string value look like a secret? */\nfunction looksSecret(value: string): boolean {\n if (/^bearer\\s+\\S/i.test(value)) return true;\n // Long, unbroken, high-entropy-ish opaque token (hex/base64url, no spaces).\n if (value.length >= 32 && /^[A-Za-z0-9_\\-+/=.]+$/.test(value)) return true;\n // Common secret prefixes (Stripe, GitHub, OpenAI, Slack, AWS, …).\n if (/^(sk|pk|rk|ghp|gho|xox[baprs]|AKIA|AIza|ya29)[-_]/i.test(value)) {\n return true;\n }\n // Webhook URLs carry their secret in the path — redact regardless of the key\n // they arrive under (e.g. a generic `value` field holding a Slack webhook).\n if (\n /^https?:\\/\\/(hooks\\.slack\\.com\\/|[^/]*\\.webhook\\.office\\.com\\/|(canary\\.|ptb\\.)?discord(app)?\\.com\\/api\\/webhooks\\/|hooks\\.zapier\\.com\\/|maker\\.ifttt\\.com\\/|discord\\.com\\/api\\/webhooks\\/)/i.test(\n value,\n )\n ) {\n return true;\n }\n return false;\n}\n\nfunction redactString(value: string): string {\n if (looksSecret(value)) return REDACTED;\n if (value.length > MAX_STRING) {\n return `${value.slice(0, MAX_STRING)}…(${value.length - MAX_STRING} more chars)`;\n }\n return value;\n}\n\nfunction redact(value: unknown, depth: number): unknown {\n if (value == null) return value;\n if (typeof value === \"string\") return redactString(value);\n if (typeof value === \"number\" || typeof value === \"boolean\") return value;\n if (depth >= MAX_DEPTH) return \"[…]\";\n if (Array.isArray(value)) {\n const out = value.slice(0, MAX_ARRAY).map((v) => redact(v, depth + 1));\n if (value.length > MAX_ARRAY)\n out.push(`…(${value.length - MAX_ARRAY} more)`);\n return out;\n }\n if (typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n let n = 0;\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (n >= MAX_KEYS) {\n out[\"…\"] = \"(truncated)\";\n break;\n }\n n += 1;\n out[k] = SENSITIVE_KEY.test(k) ? REDACTED : redact(v, depth + 1);\n }\n return out;\n }\n // Functions, symbols, bigint, etc. — not serializable / not interesting.\n return undefined;\n}\n\n/**\n * Redact and serialize call arguments to a capped JSON string, or `null` when\n * there is nothing to record. Never throws.\n */\nexport function redactArgsToJson(args: unknown): string | null {\n try {\n if (args == null) return null;\n const redacted = redact(args, 0);\n if (redacted === undefined) return null;\n const json = JSON.stringify(redacted);\n if (json == null) return null;\n if (json.length > MAX_JSON) {\n // Slicing the serialized JSON would yield an unparseable string. Wrap a\n // preview in a valid envelope so `get-audit-event` can always JSON.parse\n // the stored `input`.\n return JSON.stringify({\n _auditTruncated: true,\n originalBytes: json.length,\n preview: json.slice(0, MAX_JSON),\n });\n }\n return json;\n } catch {\n return null;\n }\n}\n\n/** Exposed for tests. */\nexport const __test = { looksSecret, redact, SENSITIVE_KEY };\n"]}
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/audit/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,aAAa,GACjB,4OAA4O,CAAC;AAE/O,MAAM,QAAQ,GAAG,YAAY,CAAC;AAC9B,MAAM,UAAU,GAAG,IAAI,CAAC;AACxB,MAAM,SAAS,GAAG,CAAC,CAAC;AACpB,MAAM,QAAQ,GAAG,GAAG,CAAC;AACrB,MAAM,SAAS,GAAG,GAAG,CAAC;AACtB,MAAM,QAAQ,GAAG,IAAI,CAAC;AACtB;;;GAGG;AACH,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,8DAA8D;AAC9D,SAAS,WAAW,CAAC,KAAa;IAChC,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,4EAA4E;IAC5E,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,IAAI,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3E,kEAAkE;IAClE,IAAI,oDAAoD,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,6EAA6E;IAC7E,4EAA4E;IAC5E,IACE,8LAA8L,CAAC,IAAI,CACjM,KAAK,CACN,EACD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,KAAa,EAAE,SAAiB;IACpD,IAAI,WAAW,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IACxC,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QAC7B,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,SAAS,cAAc,CAAC;IACjF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAa;IAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,6BAA6B,EAAE,KAAK,QAAQ,EAAE,CAAC,CAAC;IAC7E,MAAM,eAAe,GAAG,IAAI,MAAM,CAChC,YAAY,aAAa,CAAC,MAAM,2DAA2D,EAC3F,IAAI,CACL,CAAC;IACF,OAAO,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE,OAAO,QAAQ,IAAI,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,MAAM,CAAC,KAAc,EAAE,KAAa,EAAE,SAAiB;IAC9D,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACrE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC1E,IAAI,KAAK,IAAI,SAAS;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,KAAK;aACd,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC;aACnB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QAC/C,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS;YAC1B,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,SAAS,QAAQ,CAAC,CAAC;QAClD,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;YACtE,IAAI,CAAC,IAAI,QAAQ,EAAE,CAAC;gBAClB,GAAG,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC;gBACzB,MAAM;YACR,CAAC;YACD,CAAC,IAAI,CAAC,CAAC;YACP,GAAG,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC5B,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IACD,yEAAyE;IACzE,OAAO,SAAS,CAAC;AACnB,CAAC;AAaD;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAa,EACb,MAAqB;IAErB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,IAAI,QAAQ,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,MAAM,EAAE,SAAS,IAAI,UAAU,CAAC;IAClD,IAAI,CAAC;QACH,IAAI,IAAI,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;QAC5C,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,IAAI,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;QAC9B,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO;YAAE,OAAO,IAAI,CAAC;QACxC,wEAAwE;QACxE,yEAAyE;QACzE,gEAAgE;QAChE,0EAA0E;QAC1E,sDAAsD;QACtD,MAAM,QAAQ,GAAG,CAAC,OAAe,EAAE,EAAE,CACnC,IAAI,CAAC,SAAS,CAAC;YACb,eAAe,EAAE,IAAI;YACrB,aAAa,EAAE,IAAI,CAAC,MAAM;YAC1B,OAAO;SACR,CAAC,CAAC;QACL,IAAI,IAAI,GAAG,OAAO,CAAC;QACnB,IAAI,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QACxC,OAAO,GAAG,CAAC,MAAM,GAAG,OAAO,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACxC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;YAC7D,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAa,EACb,MAAqB;IAErB,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5C,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,QAAQ,GAAG,UAAU;IAErB,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,0EAA0E;IAC1E,mDAAmD;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,YAAY,CAAC,CAAC;IACpD,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,WAAW,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAAE,OAAO,QAAQ,CAAC;IACtD,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ,IAAI,YAAY,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC/D,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,YAAY,CAAC,CAAC;IAClD,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,IAAI,cAAc,CAAC;AAC7E,CAAC;AAED,yBAAyB;AACzB,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,WAAW;IACX,MAAM;IACN,qBAAqB;IACrB,aAAa;CACd,CAAC","sourcesContent":["/**\n * Redaction for audit-captured arguments.\n *\n * The audit log must never become a secondary store of secrets. Before any\n * call arguments are persisted we:\n * - drop values under credential-looking keys (token, secret, password, …),\n * - redact string values that look like bearer tokens / long opaque keys,\n * - truncate oversized strings and cap the serialized payload size.\n *\n * This mirrors the framework's standing rule that credential-looking literals\n * never land in source, logs, or fixtures.\n */\n\nconst SENSITIVE_KEY =\n /(?:pass(?:word|phrase)?|secret|token|api[_-]?key|apikey|authorization|bearer|credential|cookie|session[_-]?(?:id|token)|private[_-]?key|client[_-]?secret|signing[_-]?secret|access[_-]?key|refresh[_-]?token|webhook[_-]?(?:url|secret))/i;\n\nconst REDACTED = \"[redacted]\";\nconst MAX_STRING = 2000;\nconst MAX_DEPTH = 6;\nconst MAX_KEYS = 100;\nconst MAX_ARRAY = 100;\nconst MAX_JSON = 8000;\n/**\n * Head room reserved for the `…(N more chars)` marker so a truncated summary\n * still fits its caller's cap. Callers below this cannot carry a marker at all.\n */\nconst MARKER_SLACK = 32;\n\n/** Heuristic: does a bare string value look like a secret? */\nfunction looksSecret(value: string): boolean {\n if (/^bearer\\s+\\S/i.test(value)) return true;\n // Long, unbroken, high-entropy-ish opaque token (hex/base64url, no spaces).\n if (value.length >= 32 && /^[A-Za-z0-9_\\-+/=.]+$/.test(value)) return true;\n // Common secret prefixes (Stripe, GitHub, OpenAI, Slack, AWS, …).\n if (/^(sk|pk|rk|ghp|gho|xox[baprs]|AKIA|AIza|ya29)[-_]/i.test(value)) {\n return true;\n }\n // Webhook URLs carry their secret in the path — redact regardless of the key\n // they arrive under (e.g. a generic `value` field holding a Slack webhook).\n if (\n /^https?:\\/\\/(hooks\\.slack\\.com\\/|[^/]*\\.webhook\\.office\\.com\\/|(canary\\.|ptb\\.)?discord(app)?\\.com\\/api\\/webhooks\\/|hooks\\.zapier\\.com\\/|maker\\.ifttt\\.com\\/|discord\\.com\\/api\\/webhooks\\/)/i.test(\n value,\n )\n ) {\n return true;\n }\n return false;\n}\n\nfunction redactString(value: string, maxString: number): string {\n if (looksSecret(value)) return REDACTED;\n if (value.length > maxString) {\n return `${value.slice(0, maxString)}…(${value.length - maxString} more chars)`;\n }\n return value;\n}\n\nfunction redactEmbeddedSecrets(value: string): string {\n const bearer = value.replace(/\\b(bearer\\s+)([^\\s\"',}]+)/gi, `$1${REDACTED}`);\n const credentialField = new RegExp(\n `([\"']?\\\\b${SENSITIVE_KEY.source}\\\\b[\"']?\\\\s*[:=]\\\\s*)([\"']?)(?!bearer\\\\b)([^\"'\\\\s,}]+)\\\\2`,\n \"gi\",\n );\n return bearer.replace(credentialField, `$1$2${REDACTED}$2`);\n}\n\nfunction redact(value: unknown, depth: number, maxString: number): unknown {\n if (value == null) return value;\n if (typeof value === \"string\") return redactString(value, maxString);\n if (typeof value === \"number\" || typeof value === \"boolean\") return value;\n if (depth >= MAX_DEPTH) return \"[…]\";\n if (Array.isArray(value)) {\n const out = value\n .slice(0, MAX_ARRAY)\n .map((v) => redact(v, depth + 1, maxString));\n if (value.length > MAX_ARRAY)\n out.push(`…(${value.length - MAX_ARRAY} more)`);\n return out;\n }\n if (typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n let n = 0;\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (n >= MAX_KEYS) {\n out[\"…\"] = \"(truncated)\";\n break;\n }\n n += 1;\n out[k] = SENSITIVE_KEY.test(k)\n ? REDACTED\n : redact(v, depth + 1, maxString);\n }\n return out;\n }\n // Functions, symbols, bigint, etc. — not serializable / not interesting.\n return undefined;\n}\n\nexport interface RedactLimits {\n /**\n * Hard cap on the serialized output, INCLUDING the truncation envelope.\n * Surfaces with their own wire budget (the A2A activity snapshot) pass a\n * tighter cap than the audit-log default.\n */\n maxJson?: number;\n /** Cap on any single string value before it gets a truncation marker. */\n maxString?: number;\n}\n\n/**\n * Redact and serialize call arguments to a capped JSON string, or `null` when\n * there is nothing to record. Never throws.\n */\nexport function redactArgsToJson(\n args: unknown,\n limits?: RedactLimits,\n): string | null {\n const maxJson = Math.max(MARKER_SLACK * 4, limits?.maxJson ?? MAX_JSON);\n const maxString = limits?.maxString ?? MAX_STRING;\n try {\n if (args == null) return null;\n const redacted = redact(args, 0, maxString);\n if (redacted === undefined) return null;\n const json = JSON.stringify(redacted);\n if (json == null) return null;\n if (json.length <= maxJson) return json;\n // Slicing the serialized JSON would yield an unparseable string. Wrap a\n // preview in a valid envelope so `get-audit-event` can always JSON.parse\n // the stored `input`. JSON escaping makes the envelope overhead\n // content-dependent, so shrink the preview until the whole thing measures\n // under the cap rather than guessing at the overhead.\n const envelope = (preview: string) =>\n JSON.stringify({\n _auditTruncated: true,\n originalBytes: json.length,\n preview,\n });\n let take = maxJson;\n let out = envelope(json.slice(0, take));\n while (out.length > maxJson && take > 0) {\n take = Math.max(0, take - Math.max(1, out.length - maxJson));\n out = envelope(json.slice(0, take));\n }\n return out;\n } catch {\n return null;\n }\n}\n\n/**\n * Same bounds as `redactArgsToJson`, returned as a structural value for\n * surfaces whose consumers expect an object (transcript `metadata.input`).\n */\nexport function redactArgsToValue(\n args: unknown,\n limits?: RedactLimits,\n): unknown {\n const json = redactArgsToJson(args, limits);\n if (json == null) return null;\n try {\n return JSON.parse(json);\n } catch {\n return null;\n }\n}\n\n/**\n * Bounded, redacted plain-text summary of a tool result. Oversized text keeps\n * its head and gains an explicit `…(N more chars)` marker, so a reader can\n * always tell a short result from a clipped one.\n */\nexport function redactTextToSummary(\n text: string,\n maxChars = MAX_STRING,\n): string | null {\n if (!text) return null;\n // Only ever walk a bounded head: a multi-megabyte tool result must not be\n // scanned in full just to produce a preview of it.\n const head = text.slice(0, maxChars + MARKER_SLACK);\n const redactedHead = redactEmbeddedSecrets(head);\n if (looksSecret(redactedHead.trim())) return REDACTED;\n if (text.length <= maxChars && redactedHead.length <= maxChars) {\n return redactedHead;\n }\n const keep = Math.max(0, maxChars - MARKER_SLACK);\n return `${redactedHead.slice(0, keep)}…(${text.length - keep} more chars)`;\n}\n\n/** Exposed for tests. */\nexport const __test = {\n looksSecret,\n redact,\n redactEmbeddedSecrets,\n SENSITIVE_KEY,\n};\n"]}
@@ -23,6 +23,11 @@ export interface CreateAppOptions {
23
23
  * unconditional workspace scaffold.
24
24
  */
25
25
  forceWorkspace?: boolean;
26
+ /**
27
+ * Internal: scaffold into the current directory instead of a new subfolder.
28
+ * Set when the name argument is `.`/`./` (see `createApp`).
29
+ */
30
+ inPlace?: boolean;
26
31
  }
27
32
  /**
28
33
  * Main entry for `agent-native create [name]`.
@@ -211,6 +216,8 @@ declare function rewriteAgentChatAppId(appDir: string, appName: string, template
211
216
  declare function rewriteTrackingAppId(appDir: string, appName: string, templateName?: string, sourceIdentity?: ScaffoldSourceIdentity): void;
212
217
  declare function renameGitignore(dir: string): void;
213
218
  declare function replacePlaceholders(dir: string, appName: string, appTitle: string, workspaceName?: string): void;
214
- declare function copyDir(src: string, dest: string, root?: string): void;
219
+ declare function copyDir(src: string, dest: string, root?: string, opts?: {
220
+ skipExisting?: boolean;
221
+ }): void;
215
222
  declare function shouldSkipScaffoldEntry(name: string, srcPath?: string): boolean;
216
223
  //# sourceMappingURL=create.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/cli/create.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/cli/create.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,18 @@ const FIRST_PARTY_TARBALL_SYMLINK_EXCLUDES = [
39
39
  "*/.claude/skills",
40
40
  ];
41
41
  const localPackageTarballs = new Map();
42
+ /** VCS/editor files that don't count as "not empty" for an in-place scaffold. */
43
+ const IN_PLACE_ALLOWLIST = new Set([
44
+ ".git",
45
+ ".gitignore",
46
+ ".gitattributes",
47
+ ".DS_Store",
48
+ ".idea",
49
+ ".vscode",
50
+ "LICENSE",
51
+ "README.md",
52
+ "Thumbs.db",
53
+ ]);
42
54
  /**
43
55
  * Tagged error for input that fails CLI-level validation (repo names, app
44
56
  * names, etc.). The Sentry `beforeSend` hook in cli/index.ts drops events
@@ -89,6 +101,12 @@ const COMMUNITY_OPTION = {
89
101
  */
90
102
  export async function createApp(name, opts) {
91
103
  const clack = await import("@clack/prompts");
104
+ // `create .` (or `./`) means "scaffold into the current folder" — derive the
105
+ // project name from the folder's basename, like create-react-app / npm init.
106
+ if (name === "." || name === "./") {
107
+ name = path.basename(process.cwd());
108
+ opts = { ...opts, inPlace: true };
109
+ }
92
110
  // Reject an invalid provided name before any interactive prompt so bad input
93
111
  // fails fast instead of blocking on the start-shape picker below.
94
112
  if (name !== undefined) {
@@ -260,6 +278,38 @@ function assertValidProjectName(name, clack) {
260
278
  process.exit(1);
261
279
  }
262
280
  }
281
+ /**
282
+ * Resolve where a scaffold writes and guard the target. A named project writes
283
+ * to a new sibling subfolder that must not already exist; `create .` writes
284
+ * into the current directory, which must be empty apart from benign VCS/editor
285
+ * files (a pre-existing repo is allowed).
286
+ *
287
+ * For an in-place scaffold we do NOT return the current directory: we build
288
+ * into a private staging directory and `finalizeScaffold` copies the result
289
+ * in afterward. Staging keeps the whole scaffold atomic — a mid-scaffold
290
+ * failure's cleanup can only ever delete the staging dir, never the user's
291
+ * current directory (including its `.git`).
292
+ */
293
+ function resolveScaffoldTarget(name, inPlace, clack) {
294
+ if (inPlace) {
295
+ const conflicting = fs
296
+ .readdirSync(process.cwd())
297
+ .filter((entry) => !IN_PLACE_ALLOWLIST.has(entry));
298
+ if (conflicting.length > 0) {
299
+ const shown = conflicting.slice(0, 3).join(", ");
300
+ const more = conflicting.length > 3 ? ", …" : "";
301
+ clack.cancel(`Current directory is not empty (${shown}${more}). Scaffold into an empty folder, or run \`create <name>\` to make a new one.`);
302
+ process.exit(1);
303
+ }
304
+ return fs.mkdtempSync(path.join(os.tmpdir(), "agent-native-create-"));
305
+ }
306
+ const targetDir = path.resolve(process.cwd(), name);
307
+ if (fs.existsSync(targetDir)) {
308
+ clack.cancel(`Directory "${name}" already exists.`);
309
+ process.exit(1);
310
+ }
311
+ return targetDir;
312
+ }
263
313
  /* ─────────────────────────────────────────────────────────────────────────
264
314
  * Workspace creation (new default)
265
315
  * ───────────────────────────────────────────────────────────────────────── */
@@ -289,11 +339,7 @@ async function createWorkspaceInteractive(name, opts, clack) {
289
339
  excludeNames: ["dispatch"],
290
340
  });
291
341
  const templates = ["dispatch", ...optionalPicks];
292
- const targetDir = path.resolve(process.cwd(), name);
293
- if (fs.existsSync(targetDir)) {
294
- clack.cancel(`Directory "${name}" already exists.`);
295
- process.exit(1);
296
- }
342
+ const targetDir = resolveScaffoldTarget(name, opts?.inPlace, clack);
297
343
  const s = clack.spinner();
298
344
  for (const template of templates) {
299
345
  showCommunityTemplateTrustNote(template, clack);
@@ -362,12 +408,14 @@ async function createWorkspaceInteractive(name, opts, clack) {
362
408
  catch (err) {
363
409
  s.stop("Failed to scaffold workspace.");
364
410
  // Remove the partially-scaffolded workspace so a retry of `agent-native
365
- // create <name>` doesn't trip the "Directory already exists" guard.
411
+ // create <name>` doesn't trip the "Directory already exists" guard. For an
412
+ // in-place scaffold `targetDir` is the private staging dir, so this never
413
+ // touches the user's current directory.
366
414
  cleanupOnFailure(targetDir);
367
415
  clack.cancel(err?.message ?? String(err));
368
416
  process.exit(1);
369
417
  }
370
- tryGitInit(targetDir);
418
+ finalizeScaffold(targetDir, opts?.inPlace);
371
419
  // Show the user the tree we just built so the workspace/app distinction is
372
420
  // visible, not just described. First-time users routinely expect their
373
421
  // workspace name to be the app — seeing apps/<template>/ subdirectories
@@ -630,11 +678,7 @@ async function scaffoldOneAppIntoWorkspace(workspace, appName, templateName, cla
630
678
  async function createStandaloneApp(name, opts, clack) {
631
679
  clack.intro("Create a new standalone agent-native app");
632
680
  name = await promptNameIfMissing(name, clack, "app", "my-app");
633
- const targetDir = path.resolve(process.cwd(), name);
634
- if (fs.existsSync(targetDir)) {
635
- clack.cancel(`Directory "${name}" already exists.`);
636
- process.exit(1);
637
- }
681
+ const targetDir = resolveScaffoldTarget(name, opts?.inPlace, clack);
638
682
  // Standalone is single-select — pick one template.
639
683
  let template = opts?.template && !opts.template.includes(",") ? opts.template : undefined;
640
684
  if (!template) {
@@ -666,11 +710,13 @@ async function createStandaloneApp(name, opts, clack) {
666
710
  }
667
711
  catch (err) {
668
712
  s.stop("Failed to create app.");
713
+ // `targetDir` is the private staging dir for an in-place scaffold, so this
714
+ // only ever removes the staging copy, never the user's current directory.
669
715
  cleanupOnFailure(targetDir);
670
716
  clack.cancel(err?.message ?? String(err));
671
717
  process.exit(1);
672
718
  }
673
- tryGitInit(targetDir);
719
+ finalizeScaffold(targetDir, opts?.inPlace);
674
720
  if (template === "headless") {
675
721
  clack.outro([
676
722
  "Done! Next steps:",
@@ -724,6 +770,35 @@ function cleanupOnFailure(targetDir) {
724
770
  // Ignore — original error is more useful than a cleanup failure.
725
771
  }
726
772
  }
773
+ /**
774
+ * Land a finished scaffold in its final home and initialize git. A named
775
+ * scaffold is already in place, so this only inits git. An in-place scaffold
776
+ * (`create .`) was built in `scaffoldDir` (a staging dir); copy only the files
777
+ * that don't already exist into the current directory so pre-existing files
778
+ * (`.git`, `README.md`, `.gitignore`, editor configs) are preserved, then drop
779
+ * the staging dir. Git init/commit is skipped when the current directory is
780
+ * already a repo so we never write an unexpected commit into the user's
781
+ * history.
782
+ */
783
+ function finalizeScaffold(scaffoldDir, inPlace) {
784
+ if (!inPlace) {
785
+ tryGitInitUnlessRepo(scaffoldDir);
786
+ return;
787
+ }
788
+ const dest = process.cwd();
789
+ try {
790
+ copyDir(scaffoldDir, dest, undefined, { skipExisting: true });
791
+ }
792
+ finally {
793
+ cleanupOnFailure(scaffoldDir);
794
+ }
795
+ tryGitInitUnlessRepo(dest);
796
+ }
797
+ function tryGitInitUnlessRepo(dir) {
798
+ if (fs.existsSync(path.join(dir, ".git")))
799
+ return;
800
+ tryGitInit(dir);
801
+ }
727
802
  /**
728
803
  * Scaffold a single app template into `targetDir`. Resolves:
729
804
  * - "headless" / legacy "blank" → bundled action-first template
@@ -2538,14 +2613,21 @@ function replacePlaceholders(dir, appName, appTitle, workspaceName) {
2538
2613
  fs.writeFileSync(p, next);
2539
2614
  }
2540
2615
  }
2541
- function copyDir(src, dest, root) {
2616
+ function copyDir(src, dest, root, opts) {
2542
2617
  const resolvedRoot = root ?? path.resolve(src);
2618
+ const skipExisting = opts?.skipExisting ?? false;
2543
2619
  fs.mkdirSync(dest, { recursive: true });
2544
2620
  for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
2545
2621
  const srcPath = path.join(src, entry.name);
2546
2622
  if (shouldSkipScaffoldEntry(entry.name, srcPath))
2547
2623
  continue;
2548
2624
  const destPath = path.join(dest, entry.name);
2625
+ // Preserve anything already at the destination (in-place scaffold merges
2626
+ // into a directory the user may already own). Directories still recurse so
2627
+ // new files land inside a pre-existing folder.
2628
+ if (skipExisting && !entry.isDirectory() && fs.existsSync(destPath)) {
2629
+ continue;
2630
+ }
2549
2631
  if (entry.isSymbolicLink()) {
2550
2632
  const target = fs.readlinkSync(srcPath);
2551
2633
  const resolvedTarget = path.resolve(path.dirname(srcPath), target);
@@ -2556,7 +2638,7 @@ function copyDir(src, dest, root) {
2556
2638
  try {
2557
2639
  const stat = fs.statSync(srcPath);
2558
2640
  if (stat.isDirectory()) {
2559
- copyDir(srcPath, destPath, resolvedRoot);
2641
+ copyDir(srcPath, destPath, resolvedRoot, opts);
2560
2642
  }
2561
2643
  else {
2562
2644
  fs.copyFileSync(srcPath, destPath);
@@ -2568,7 +2650,7 @@ function copyDir(src, dest, root) {
2568
2650
  }
2569
2651
  }
2570
2652
  else if (entry.isDirectory()) {
2571
- copyDir(srcPath, destPath, resolvedRoot);
2653
+ copyDir(srcPath, destPath, resolvedRoot, opts);
2572
2654
  }
2573
2655
  else {
2574
2656
  fs.copyFileSync(srcPath, destPath);