create-walle 0.9.21 → 0.9.23

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 (500) hide show
  1. package/README.md +27 -5
  2. package/package.json +2 -2
  3. package/template/CLAUDE.md +2 -2
  4. package/template/LICENSE +1 -1
  5. package/template/bin/ctm-dev-cleanup.js +24 -3
  6. package/template/bin/ctm-launch.sh +13 -0
  7. package/template/bin/dev.sh +156 -18
  8. package/template/bin/node-bin.sh +84 -0
  9. package/template/bin/pin-node.sh +51 -0
  10. package/template/claude-task-manager/api-prompts.js +1203 -182
  11. package/template/claude-task-manager/api-reviews.js +109 -15
  12. package/template/claude-task-manager/approval-agent.js +1360 -280
  13. package/template/claude-task-manager/bin/restart-ctm.sh +64 -23
  14. package/template/claude-task-manager/bin/storage-migration-supervisor.js +338 -0
  15. package/template/claude-task-manager/db.js +4417 -295
  16. package/template/claude-task-manager/docs/app-update-refresh-protocol.md +69 -0
  17. package/template/claude-task-manager/docs/approval-ai-refinement.md +138 -0
  18. package/template/claude-task-manager/docs/approval-rescue-loop.md +74 -0
  19. package/template/claude-task-manager/docs/codex-operational-warning-health.md +107 -0
  20. package/template/claude-task-manager/docs/codex-resume-state-guard-design.md +17 -12
  21. package/template/claude-task-manager/docs/codex-terminal-render-controller-handoff.md +311 -0
  22. package/template/claude-task-manager/docs/coding-agent-hooks-architecture.md +418 -0
  23. package/template/claude-task-manager/docs/conversation-import-freshness.md +20 -0
  24. package/template/claude-task-manager/docs/google-workspace-auth-health.md +77 -0
  25. package/template/claude-task-manager/docs/image-paste-ux.md +13 -0
  26. package/template/claude-task-manager/docs/ipad-web-preview.md +88 -0
  27. package/template/claude-task-manager/docs/main-loop-offload-architecture.md +66 -0
  28. package/template/claude-task-manager/docs/microsoft-dev-tunnel-phone-access-design.md +274 -519
  29. package/template/claude-task-manager/docs/mobile-live-streaming.md +27 -5
  30. package/template/claude-task-manager/docs/mobile-remote-submission-lifecycle.md +69 -0
  31. package/template/claude-task-manager/docs/phone-access-design.md +53 -15
  32. package/template/claude-task-manager/docs/phone-passkey-identity.md +122 -0
  33. package/template/claude-task-manager/docs/phone-setup.md +3 -0
  34. package/template/claude-task-manager/docs/prompt-editing-tree-design.md +25 -1
  35. package/template/claude-task-manager/docs/remote-desktop-access-design.md +268 -0
  36. package/template/claude-task-manager/docs/restart-lifecycle-architecture.md +95 -0
  37. package/template/claude-task-manager/docs/runtime-work-control-plane.md +53 -0
  38. package/template/claude-task-manager/docs/session-interactive-wait-surfaces.md +38 -0
  39. package/template/claude-task-manager/docs/session-needs-you-dismissal.md +84 -0
  40. package/template/claude-task-manager/docs/session-render-state-management-design.md +91 -3
  41. package/template/claude-task-manager/docs/session-standup-command-center-design.md +25 -1
  42. package/template/claude-task-manager/docs/session-title-authority.md +32 -0
  43. package/template/claude-task-manager/docs/session-workspace-binding.md +33 -0
  44. package/template/claude-task-manager/docs/skill-intent-resolution-design.md +72 -0
  45. package/template/claude-task-manager/docs/walle-mcp-supervisor-health.md +86 -0
  46. package/template/claude-task-manager/docs/walle-relay-phone-access-design.md +24 -15
  47. package/template/claude-task-manager/docs/walle-session-history-hydration.md +114 -0
  48. package/template/claude-task-manager/docs/walle-session-input-queue.md +104 -0
  49. package/template/claude-task-manager/docs/walle-session-model-catalog.md +90 -0
  50. package/template/claude-task-manager/docs/walle-session-model-preferences.md +15 -6
  51. package/template/claude-task-manager/git-utils.js +897 -27
  52. package/template/claude-task-manager/lib/agent-capabilities.js +33 -0
  53. package/template/claude-task-manager/lib/agent-cli-cache.js +37 -7
  54. package/template/claude-task-manager/lib/agent-hooks-installer.js +26 -2
  55. package/template/claude-task-manager/lib/agent-presets.js +17 -1
  56. package/template/claude-task-manager/lib/all-sessions-query.js +108 -0
  57. package/template/claude-task-manager/lib/approval-ai-refinement.js +488 -0
  58. package/template/claude-task-manager/lib/approval-self-adapt.js +168 -0
  59. package/template/claude-task-manager/lib/async-semaphore.js +44 -0
  60. package/template/claude-task-manager/lib/auth-context.js +5 -0
  61. package/template/claude-task-manager/lib/auth-rate-limit.js +47 -4
  62. package/template/claude-task-manager/lib/auth-rules.js +29 -2
  63. package/template/claude-task-manager/lib/auto-approval-verifier.js +129 -16
  64. package/template/claude-task-manager/lib/background-llm.js +144 -17
  65. package/template/claude-task-manager/lib/branch-inventory.js +212 -0
  66. package/template/claude-task-manager/lib/claude-desktop-sessions.js +15 -3
  67. package/template/claude-task-manager/lib/coalesce-sync-frames.js +151 -0
  68. package/template/claude-task-manager/lib/codex-launch-health.js +762 -0
  69. package/template/claude-task-manager/lib/codex-transcript-pager.js +51 -0
  70. package/template/claude-task-manager/lib/codex-zst.js +124 -0
  71. package/template/claude-task-manager/lib/coding-agent-models.js +233 -30
  72. package/template/claude-task-manager/lib/connection-health.js +232 -0
  73. package/template/claude-task-manager/lib/conversation-blob-parser.js +42 -0
  74. package/template/claude-task-manager/lib/conversation-tail-merge.js +89 -26
  75. package/template/claude-task-manager/lib/ctm-session-context-api.js +39 -10
  76. package/template/claude-task-manager/lib/cursor-conversation-store.js +354 -0
  77. package/template/claude-task-manager/lib/db-owner-worker-client.js +315 -0
  78. package/template/claude-task-manager/lib/document-review.js +141 -6
  79. package/template/claude-task-manager/lib/escalation-review.js +152 -0
  80. package/template/claude-task-manager/lib/graceful-shutdown.js +159 -0
  81. package/template/claude-task-manager/lib/headless-term-service.js +678 -0
  82. package/template/claude-task-manager/lib/heavy-worker-fallback.js +38 -0
  83. package/template/claude-task-manager/lib/jsonl-conversation-parser.js +542 -0
  84. package/template/claude-task-manager/lib/jsonl-range-reader.js +112 -0
  85. package/template/claude-task-manager/lib/main-db-census.js +216 -0
  86. package/template/claude-task-manager/lib/message-pagination.js +106 -4
  87. package/template/claude-task-manager/lib/microsoft-dev-tunnel-setup.js +750 -26
  88. package/template/claude-task-manager/lib/mobile-auth-api.js +274 -7
  89. package/template/claude-task-manager/lib/mobile-auth-store.js +592 -10
  90. package/template/claude-task-manager/lib/mobile-notification-dispatcher.js +15 -0
  91. package/template/claude-task-manager/lib/model-overview-brain-fallback.js +311 -0
  92. package/template/claude-task-manager/lib/model-overview-cache.js +141 -0
  93. package/template/claude-task-manager/lib/models-health-routing-notice.js +126 -0
  94. package/template/claude-task-manager/lib/node-pin-guard.js +93 -0
  95. package/template/claude-task-manager/lib/perf-tracker.js +242 -6
  96. package/template/claude-task-manager/lib/permission-match.js +76 -0
  97. package/template/claude-task-manager/lib/permission-sync.js +133 -20
  98. package/template/claude-task-manager/lib/process-title.js +35 -0
  99. package/template/claude-task-manager/lib/prompt-executions-query.js +25 -0
  100. package/template/claude-task-manager/lib/prompt-index-disk-cache.js +44 -0
  101. package/template/claude-task-manager/lib/prompt-intent.js +132 -0
  102. package/template/claude-task-manager/lib/provider-user-context.js +34 -0
  103. package/template/claude-task-manager/lib/read-pool-client.js +313 -0
  104. package/template/claude-task-manager/lib/readpool-breaker.js +31 -0
  105. package/template/claude-task-manager/lib/recent-sessions-breaker.js +12 -0
  106. package/template/claude-task-manager/lib/remote-feedback-client.js +72 -0
  107. package/template/claude-task-manager/lib/remote-relay-protocol.js +37 -4
  108. package/template/claude-task-manager/lib/remote-relay-store.js +159 -0
  109. package/template/claude-task-manager/lib/remote-submission-observer.js +278 -0
  110. package/template/claude-task-manager/lib/restart-guard.js +109 -0
  111. package/template/claude-task-manager/lib/restore-interruption-detector.js +439 -0
  112. package/template/claude-task-manager/lib/restore-policy.js +13 -0
  113. package/template/claude-task-manager/lib/restore-resume-batch.js +74 -0
  114. package/template/claude-task-manager/lib/restore-runtime.js +68 -0
  115. package/template/claude-task-manager/lib/restore-storm.js +34 -0
  116. package/template/claude-task-manager/lib/resume-cwd.js +36 -0
  117. package/template/claude-task-manager/lib/resume-preflight.js +313 -0
  118. package/template/claude-task-manager/lib/runtime-work-registry.js +444 -0
  119. package/template/claude-task-manager/lib/sanitize-openai-auth.js +31 -0
  120. package/template/claude-task-manager/lib/scheduler.js +21 -1
  121. package/template/claude-task-manager/lib/scrollback-snapshot-store.js +159 -0
  122. package/template/claude-task-manager/lib/serial-task-queue.js +64 -0
  123. package/template/claude-task-manager/lib/server-listeners.js +239 -0
  124. package/template/claude-task-manager/lib/session-capture.js +42 -7
  125. package/template/claude-task-manager/lib/session-content-backfill.js +131 -0
  126. package/template/claude-task-manager/lib/session-history.js +388 -43
  127. package/template/claude-task-manager/lib/session-host-manager.js +287 -0
  128. package/template/claude-task-manager/lib/session-image-refs.js +209 -0
  129. package/template/claude-task-manager/lib/session-jobs.js +399 -59
  130. package/template/claude-task-manager/lib/session-prompt-index.js +137 -0
  131. package/template/claude-task-manager/lib/session-restore.js +53 -0
  132. package/template/claude-task-manager/lib/session-standup.js +123 -23
  133. package/template/claude-task-manager/lib/session-state-bus.js +14 -0
  134. package/template/claude-task-manager/lib/session-stream.js +64 -16
  135. package/template/claude-task-manager/lib/session-timeline-summary.js +260 -0
  136. package/template/claude-task-manager/lib/session-token-usage.js +494 -0
  137. package/template/claude-task-manager/lib/session-workspace-binding.js +356 -0
  138. package/template/claude-task-manager/lib/setup-network-config.js +9 -0
  139. package/template/claude-task-manager/lib/size-cap.js +45 -0
  140. package/template/claude-task-manager/lib/size-cap.test.js +62 -0
  141. package/template/claude-task-manager/lib/skill-autocomplete.js +180 -1
  142. package/template/claude-task-manager/lib/skill-intent-resolver.js +304 -0
  143. package/template/claude-task-manager/lib/sqlite-driver.js +19 -3
  144. package/template/claude-task-manager/lib/standup-attention.js +7 -3
  145. package/template/claude-task-manager/lib/status-authority.js +39 -0
  146. package/template/claude-task-manager/lib/status-hooks.js +4 -0
  147. package/template/claude-task-manager/lib/storage-migration.js +235 -0
  148. package/template/claude-task-manager/lib/structured-capture.js +298 -0
  149. package/template/claude-task-manager/lib/sync-io-census.js +163 -0
  150. package/template/claude-task-manager/lib/tailscale-setup.js +6 -0
  151. package/template/claude-task-manager/lib/terminal-activity-evidence.js +33 -0
  152. package/template/claude-task-manager/lib/terminal-choice.js +364 -0
  153. package/template/claude-task-manager/lib/terminal-control-sanitize.js +17 -0
  154. package/template/claude-task-manager/lib/terminal-fingerprint.js +48 -0
  155. package/template/claude-task-manager/lib/terminal-output-flush.js +84 -0
  156. package/template/claude-task-manager/lib/timeline-order.js +122 -0
  157. package/template/claude-task-manager/lib/transcript-store.js +348 -43
  158. package/template/claude-task-manager/lib/transport-security.js +84 -1
  159. package/template/claude-task-manager/lib/wait-state.js +184 -0
  160. package/template/claude-task-manager/lib/walle-client.js +47 -5
  161. package/template/claude-task-manager/lib/walle-ctm-history.js +564 -4
  162. package/template/claude-task-manager/lib/walle-external-actions.js +135 -16
  163. package/template/claude-task-manager/lib/walle-history-hydration.js +46 -0
  164. package/template/claude-task-manager/lib/walle-native-health.js +403 -0
  165. package/template/claude-task-manager/lib/walle-repair.js +701 -0
  166. package/template/claude-task-manager/lib/walle-session-cache.js +109 -0
  167. package/template/claude-task-manager/lib/walle-session-context.js +57 -21
  168. package/template/claude-task-manager/lib/walle-session-model-catalog.js +34 -0
  169. package/template/claude-task-manager/lib/walle-supervisor.js +539 -63
  170. package/template/claude-task-manager/lib/walle-transcript.js +52 -0
  171. package/template/claude-task-manager/lib/worktree-active-sync.js +11 -7
  172. package/template/claude-task-manager/lib/worktree-cwd.js +32 -1
  173. package/template/claude-task-manager/package.json +1 -1
  174. package/template/claude-task-manager/prompt-harvest.js +89 -66
  175. package/template/claude-task-manager/providers/claude-code.js +51 -3
  176. package/template/claude-task-manager/providers/cursor.js +140 -45
  177. package/template/claude-task-manager/public/css/reviews.css +551 -61
  178. package/template/claude-task-manager/public/css/setup.css +191 -0
  179. package/template/claude-task-manager/public/css/walle-session.css +865 -10
  180. package/template/claude-task-manager/public/css/walle.css +154 -0
  181. package/template/claude-task-manager/public/designs/ai-providers-consolidation-v2.html +830 -0
  182. package/template/claude-task-manager/public/index.html +18516 -2058
  183. package/template/claude-task-manager/public/ipad.html +363 -0
  184. package/template/claude-task-manager/public/js/document-review-links.js +301 -0
  185. package/template/claude-task-manager/public/js/image-normalize.js +69 -36
  186. package/template/claude-task-manager/public/js/message-renderer.js +1265 -77
  187. package/template/claude-task-manager/public/js/prompts.js +66 -29
  188. package/template/claude-task-manager/public/js/reviews.js +901 -133
  189. package/template/claude-task-manager/public/js/session-activity-utils.js +11 -1
  190. package/template/claude-task-manager/public/js/session-search-utils.js +94 -10
  191. package/template/claude-task-manager/public/js/session-status-precedence.js +23 -5
  192. package/template/claude-task-manager/public/js/setup.js +1273 -176
  193. package/template/claude-task-manager/public/js/stream-view.js +691 -73
  194. package/template/claude-task-manager/public/js/terminal-reconciler.js +210 -0
  195. package/template/claude-task-manager/public/js/walle-session.js +2455 -158
  196. package/template/claude-task-manager/public/js/walle.js +455 -28
  197. package/template/claude-task-manager/public/m/app.css +2909 -262
  198. package/template/claude-task-manager/public/m/app.js +6601 -398
  199. package/template/claude-task-manager/public/m/claim.html +224 -17
  200. package/template/claude-task-manager/public/m/index.html +117 -21
  201. package/template/claude-task-manager/public/m/sw.js +3 -1
  202. package/template/claude-task-manager/public/manifest.json +2 -2
  203. package/template/claude-task-manager/public/prompts.html +30 -14
  204. package/template/claude-task-manager/queue-engine.js +507 -28
  205. package/template/claude-task-manager/scripts/repair-claude-session-images.js +27 -8
  206. package/template/claude-task-manager/server.js +14341 -2197
  207. package/template/claude-task-manager/session-integrity.js +160 -18
  208. package/template/claude-task-manager/session-search-ranking.js +1 -0
  209. package/template/claude-task-manager/session-utils.js +25 -5
  210. package/template/claude-task-manager/workers/approval-blocklist.js +96 -6
  211. package/template/claude-task-manager/workers/approval-widget-validator.js +14 -8
  212. package/template/claude-task-manager/workers/conversation-import-worker.js +11 -50
  213. package/template/claude-task-manager/workers/db-owner-worker.js +386 -0
  214. package/template/claude-task-manager/workers/harvest-worker.js +9 -55
  215. package/template/claude-task-manager/workers/headless-term-worker.js +9 -530
  216. package/template/claude-task-manager/workers/read-pool-worker.js +387 -0
  217. package/template/claude-task-manager/workers/scrollback-worker.js +11 -72
  218. package/template/claude-task-manager/workers/session-host-process.js +146 -0
  219. package/template/claude-task-manager/workers/session-integrity-worker.js +10 -54
  220. package/template/claude-task-manager/workers/state-detectors/base.js +18 -1
  221. package/template/claude-task-manager/workers/state-detectors/claude-code.js +182 -9
  222. package/template/claude-task-manager/workers/state-detectors/codex.js +150 -2
  223. package/template/claude-task-manager/workers/state-detectors/cursor.js +127 -0
  224. package/template/claude-task-manager/workers/state-detectors/gemini.js +21 -0
  225. package/template/claude-task-manager/workers/state-detectors/index.js +29 -0
  226. package/template/claude-task-manager/workers/state-detectors/opencode.js +103 -0
  227. package/template/docs/design/markdown-review-pane.md +206 -0
  228. package/template/docs/designs/2026-05-17-portkey-gateway-provider-ux.md +129 -38
  229. package/template/docs/designs/2026-05-20-mobile-worktree-finish-command.md +27 -0
  230. package/template/docs/designs/2026-05-22-ai-configuration-consolidation.md +248 -0
  231. package/template/docs/designs/ai-configuration-consolidation-mock.html +812 -0
  232. package/template/docs/private-memory-and-pii-policy.md +69 -0
  233. package/template/package.json +2 -1
  234. package/template/scripts/check-private-data.js +201 -0
  235. package/template/shared/sqlite-owner-guard.js +30 -0
  236. package/template/shared/sqlite-owner-write-queue.js +225 -0
  237. package/template/shared/sqlite-storage-policy.js +111 -0
  238. package/template/shared/sqlite-write-lock.js +428 -0
  239. package/template/wall-e/agent-runners/claude-code.js +5 -0
  240. package/template/wall-e/agent.js +166 -22
  241. package/template/wall-e/api-walle.js +524 -70
  242. package/template/wall-e/auth/provider-flows.js +11 -1
  243. package/template/wall-e/bin/walle-mcp-stdio.js +341 -17
  244. package/template/wall-e/brain.js +1614 -141
  245. package/template/wall-e/chat/attachment-blocks.js +96 -0
  246. package/template/wall-e/chat/attachments.js +2 -1
  247. package/template/wall-e/chat/capability-resolver.js +7 -7
  248. package/template/wall-e/chat/context-messages.js +28 -0
  249. package/template/wall-e/chat/conversation-frame.js +630 -0
  250. package/template/wall-e/chat/provider-messages.js +125 -0
  251. package/template/wall-e/chat.js +1002 -233
  252. package/template/wall-e/coding/acceptance-contract.js +170 -0
  253. package/template/wall-e/coding/acp-adapter.js +1 -1
  254. package/template/wall-e/coding/agent-catalog.js +3 -0
  255. package/template/wall-e/coding/artifact-store.js +93 -0
  256. package/template/wall-e/coding/capability-router.js +120 -0
  257. package/template/wall-e/coding/coding-run-controller.js +423 -0
  258. package/template/wall-e/coding/compaction-service.js +157 -12
  259. package/template/wall-e/coding/frontend-verification.js +258 -0
  260. package/template/wall-e/coding/lifecycle-hooks.js +75 -0
  261. package/template/wall-e/coding/local-preview-contract.js +157 -0
  262. package/template/wall-e/coding/permission-service.js +57 -13
  263. package/template/wall-e/coding/prompt-bundle.js +19 -1
  264. package/template/wall-e/coding/prompt-section-registry.js +227 -0
  265. package/template/wall-e/coding/provider-compat.js +15 -0
  266. package/template/wall-e/coding/runtime-events.js +224 -0
  267. package/template/wall-e/coding/runtime-mode.js +3 -0
  268. package/template/wall-e/coding/side-git-snapshot.js +160 -4
  269. package/template/wall-e/coding/snapshot-service.js +143 -1
  270. package/template/wall-e/coding/stream-processor.js +388 -34
  271. package/template/wall-e/coding/task-tool.js +141 -4
  272. package/template/wall-e/coding/tool-execution-controller.js +365 -0
  273. package/template/wall-e/coding/tool-registry.js +43 -5
  274. package/template/wall-e/coding/user-hooks.js +217 -0
  275. package/template/wall-e/coding-orchestrator.js +1330 -221
  276. package/template/wall-e/coding-prompts.js +20 -4
  277. package/template/wall-e/context/context-builder.js +15 -2
  278. package/template/wall-e/decision/confidence.js +1 -1
  279. package/template/wall-e/docs/coding-acceptance-contract.md +41 -0
  280. package/template/wall-e/docs/external-action-controller.md +26 -6
  281. package/template/wall-e/docs/telemetry-lifecycle.md +8 -2
  282. package/template/wall-e/embeddings.js +591 -53
  283. package/template/wall-e/external-action-controller.js +12 -0
  284. package/template/wall-e/http/auth.js +1 -0
  285. package/template/wall-e/http/chat-api.js +46 -11
  286. package/template/wall-e/http/model-admin.js +836 -34
  287. package/template/wall-e/lib/boot-profile.js +88 -0
  288. package/template/wall-e/lib/event-loop-monitor.js +93 -0
  289. package/template/wall-e/lib/service-health.js +194 -0
  290. package/template/wall-e/llm/anthropic.js +130 -5
  291. package/template/wall-e/llm/client.js +266 -63
  292. package/template/wall-e/llm/default-fallback.js +382 -0
  293. package/template/wall-e/llm/health.js +19 -0
  294. package/template/wall-e/llm/message-guard.js +78 -0
  295. package/template/wall-e/llm/model-catalog.js +252 -1
  296. package/template/wall-e/llm/openai.js +26 -4
  297. package/template/wall-e/llm/portkey-sync.js +654 -0
  298. package/template/wall-e/llm/provider-error.js +30 -2
  299. package/template/wall-e/llm/registry.js +5 -1
  300. package/template/wall-e/llm/request-compat.js +67 -0
  301. package/template/wall-e/loops/backfill.js +79 -23
  302. package/template/wall-e/loops/brain-optimize.js +67 -0
  303. package/template/wall-e/loops/ingest.js +25 -10
  304. package/template/wall-e/loops/question-digest.js +160 -0
  305. package/template/wall-e/loops/reflect.js +6 -4
  306. package/template/wall-e/loops/think.js +39 -12
  307. package/template/wall-e/mcp-server.js +318 -36
  308. package/template/wall-e/memory/ctm-context-client.js +52 -14
  309. package/template/wall-e/memory/ctm-operational-context.js +237 -0
  310. package/template/wall-e/memory/ctm-prompt-executions-client.js +128 -0
  311. package/template/wall-e/memory/ctm-session-context.js +111 -63
  312. package/template/wall-e/prompts/coding/deepseek.txt +3 -0
  313. package/template/wall-e/prompts/coding/gemini.txt +6 -0
  314. package/template/wall-e/prompts/coding/gpt.txt +6 -0
  315. package/template/wall-e/prompts/coding/local.txt +7 -0
  316. package/template/wall-e/runtime/decision-hooks.js +115 -0
  317. package/template/wall-e/runtime/devbox-gateway.js +82 -8
  318. package/template/wall-e/runtime/prompt-manifest.js +86 -0
  319. package/template/wall-e/runtime/tool-executor.js +269 -0
  320. package/template/wall-e/runtime/tool-result-envelope.js +138 -0
  321. package/template/wall-e/runtime/transcript-projection.js +60 -0
  322. package/template/wall-e/runtime/walle-runtime.js +224 -0
  323. package/template/wall-e/scripts/db-optimize/migrate.js +162 -0
  324. package/template/wall-e/scripts/db-optimize/recall-eval.js +117 -0
  325. package/template/wall-e/server.js +15 -0
  326. package/template/wall-e/session-files.js +9 -0
  327. package/template/wall-e/skills/_bundled/google-calendar/run.js +1 -1
  328. package/template/wall-e/skills/_bundled/gws-workspace/run.js +1 -1
  329. package/template/wall-e/skills/_bundled/slack-mentions/run.js +76 -6
  330. package/template/wall-e/skills/claude-code-reader.js +7 -3
  331. package/template/wall-e/skills/script-skill-runner.js +10 -0
  332. package/template/wall-e/skills/skill-planner.js +38 -0
  333. package/template/wall-e/tools/builtin-middleware.js +19 -9
  334. package/template/wall-e/tools/local-tools.js +1428 -16
  335. package/template/wall-e/tools/permission-checker.js +73 -5
  336. package/template/wall-e/tools/question-manager.js +117 -7
  337. package/template/wall-e/training/harvester.js +12 -28
  338. package/template/wall-e/training/replay.js +25 -80
  339. package/template/website/index.html +10 -10
  340. package/template/wall-e/eval/ab-test.js +0 -203
  341. package/template/wall-e/eval/agent-runner.js +0 -772
  342. package/template/wall-e/eval/agent-scorer.js +0 -461
  343. package/template/wall-e/eval/aggregator.js +0 -414
  344. package/template/wall-e/eval/allowed-test-commands.js +0 -34
  345. package/template/wall-e/eval/benchmark-generator.js +0 -113
  346. package/template/wall-e/eval/benchmarks/chat-eval.json +0 -1662
  347. package/template/wall-e/eval/benchmarks/chat.json +0 -82
  348. package/template/wall-e/eval/benchmarks/coding-agent-real.json +0 -1
  349. package/template/wall-e/eval/benchmarks/coding-agent.json +0 -1581
  350. package/template/wall-e/eval/benchmarks/coding.json +0 -122
  351. package/template/wall-e/eval/benchmarks/memory-retrieval.json +0 -234
  352. package/template/wall-e/eval/benchmarks/reasoning.json +0 -82
  353. package/template/wall-e/eval/benchmarks/swebench-lite-30.json +0 -212
  354. package/template/wall-e/eval/benchmarks.js +0 -669
  355. package/template/wall-e/eval/cc-replay.js +0 -719
  356. package/template/wall-e/eval/chat-eval.js +0 -525
  357. package/template/wall-e/eval/check-keys.js +0 -15
  358. package/template/wall-e/eval/check-providers.js +0 -42
  359. package/template/wall-e/eval/codex-cli-baseline.js +0 -669
  360. package/template/wall-e/eval/coding-agent-real.js +0 -570
  361. package/template/wall-e/eval/context-compactor.js +0 -251
  362. package/template/wall-e/eval/debug-agent003.js +0 -68
  363. package/template/wall-e/eval/diagnostics.js +0 -216
  364. package/template/wall-e/eval/eval-orchestrator.js +0 -642
  365. package/template/wall-e/eval/evaluate.js +0 -202
  366. package/template/wall-e/eval/evaluator.js +0 -373
  367. package/template/wall-e/eval/exporter.js +0 -212
  368. package/template/wall-e/eval/fixtures/express-basic/package.json +0 -9
  369. package/template/wall-e/eval/fixtures/express-basic/server.js +0 -115
  370. package/template/wall-e/eval/fixtures/express-basic/test.js +0 -83
  371. package/template/wall-e/eval/fixtures/express-buggy/package.json +0 -9
  372. package/template/wall-e/eval/fixtures/express-buggy/server.js +0 -113
  373. package/template/wall-e/eval/fixtures/express-buggy/test.js +0 -83
  374. package/template/wall-e/eval/fixtures/express-buggy-items/package.json +0 -9
  375. package/template/wall-e/eval/fixtures/express-buggy-items/server.js +0 -112
  376. package/template/wall-e/eval/fixtures/express-buggy-items/test.js +0 -83
  377. package/template/wall-e/eval/fixtures/express-buggy-search/package.json +0 -9
  378. package/template/wall-e/eval/fixtures/express-buggy-search/server.js +0 -121
  379. package/template/wall-e/eval/fixtures/express-buggy-search/test.js +0 -83
  380. package/template/wall-e/eval/fixtures/express-rename-data/data.js +0 -34
  381. package/template/wall-e/eval/fixtures/express-rename-data/package.json +0 -9
  382. package/template/wall-e/eval/fixtures/express-rename-data/server.js +0 -97
  383. package/template/wall-e/eval/fixtures/express-rename-data/test.js +0 -88
  384. package/template/wall-e/eval/fixtures/express-xss/package.json +0 -12
  385. package/template/wall-e/eval/fixtures/express-xss/server.js +0 -90
  386. package/template/wall-e/eval/fixtures/express-xss/test.js +0 -67
  387. package/template/wall-e/eval/fixtures/express-xss/views/profile.ejs +0 -9
  388. package/template/wall-e/eval/fixtures/fullstack-app/config/default.js +0 -9
  389. package/template/wall-e/eval/fixtures/fullstack-app/config/test.js +0 -13
  390. package/template/wall-e/eval/fixtures/fullstack-app/package.json +0 -11
  391. package/template/wall-e/eval/fixtures/fullstack-app/public/css/style.css +0 -137
  392. package/template/wall-e/eval/fixtures/fullstack-app/public/index.html +0 -46
  393. package/template/wall-e/eval/fixtures/fullstack-app/public/js/app.js +0 -121
  394. package/template/wall-e/eval/fixtures/fullstack-app/public/js/auth.js +0 -71
  395. package/template/wall-e/eval/fixtures/fullstack-app/public/js/items.js +0 -80
  396. package/template/wall-e/eval/fixtures/fullstack-app/public/js/users.js +0 -46
  397. package/template/wall-e/eval/fixtures/fullstack-app/public/login.html +0 -45
  398. package/template/wall-e/eval/fixtures/fullstack-app/public/register.html +0 -38
  399. package/template/wall-e/eval/fixtures/fullstack-app/scripts/migrate.js +0 -23
  400. package/template/wall-e/eval/fixtures/fullstack-app/scripts/seed.js +0 -46
  401. package/template/wall-e/eval/fixtures/fullstack-app/server/db.js +0 -99
  402. package/template/wall-e/eval/fixtures/fullstack-app/server/index.js +0 -94
  403. package/template/wall-e/eval/fixtures/fullstack-app/server/middleware/auth.js +0 -19
  404. package/template/wall-e/eval/fixtures/fullstack-app/server/middleware/logger.js +0 -19
  405. package/template/wall-e/eval/fixtures/fullstack-app/server/router.js +0 -50
  406. package/template/wall-e/eval/fixtures/fullstack-app/server/routes/auth.js +0 -69
  407. package/template/wall-e/eval/fixtures/fullstack-app/server/routes/health.js +0 -23
  408. package/template/wall-e/eval/fixtures/fullstack-app/server/routes/items.js +0 -88
  409. package/template/wall-e/eval/fixtures/fullstack-app/server/routes/users.js +0 -75
  410. package/template/wall-e/eval/fixtures/fullstack-app/server/test.js +0 -198
  411. package/template/wall-e/eval/fixtures/fullstack-app/server/utils/response.js +0 -34
  412. package/template/wall-e/eval/fixtures/fullstack-app/server/utils/validate.js +0 -26
  413. package/template/wall-e/eval/fixtures/fullstack-app/server.js +0 -8
  414. package/template/wall-e/eval/fixtures/fullstack-app/test.js +0 -12
  415. package/template/wall-e/eval/fixtures/monorepo-basic/package.json +0 -8
  416. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/data.js +0 -58
  417. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/middleware.js +0 -46
  418. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/package.json +0 -8
  419. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/routes.js +0 -64
  420. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/server.js +0 -56
  421. package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/test.js +0 -116
  422. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/commands.js +0 -61
  423. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/index.js +0 -62
  424. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/output.js +0 -43
  425. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/package.json +0 -11
  426. package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/test.js +0 -44
  427. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/formatters.js +0 -43
  428. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/index.js +0 -12
  429. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/package.json +0 -5
  430. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/test.js +0 -55
  431. package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/validators.js +0 -29
  432. package/template/wall-e/eval/fixtures/monorepo-basic/test.js +0 -46
  433. package/template/wall-e/eval/fixtures/node-cli/index.js +0 -78
  434. package/template/wall-e/eval/fixtures/node-cli/package.json +0 -10
  435. package/template/wall-e/eval/fixtures/node-cli/test.js +0 -57
  436. package/template/wall-e/eval/fixtures/node-typed/package.json +0 -8
  437. package/template/wall-e/eval/fixtures/node-typed/src/handlers.js +0 -31
  438. package/template/wall-e/eval/fixtures/node-typed/src/utils.js +0 -33
  439. package/template/wall-e/eval/fixtures/node-typed/test.js +0 -36
  440. package/template/wall-e/eval/fixtures/python-flask/app.py +0 -14
  441. package/template/wall-e/eval/fixtures/python-flask/requirements.txt +0 -2
  442. package/template/wall-e/eval/fixtures/python-flask/test_app.py +0 -25
  443. package/template/wall-e/eval/fixtures/wall-e-subset/brain.js +0 -105
  444. package/template/wall-e/eval/fixtures/wall-e-subset/eval/aggregator.js +0 -101
  445. package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks/chat.json +0 -20
  446. package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks/coding.json +0 -32
  447. package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks.js +0 -64
  448. package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/package.json +0 -6
  449. package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/server.js +0 -31
  450. package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/test.js +0 -18
  451. package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/utils.js +0 -34
  452. package/template/wall-e/eval/fixtures/wall-e-subset/eval/runner.js +0 -104
  453. package/template/wall-e/eval/fixtures/wall-e-subset/eval/scorer.js +0 -73
  454. package/template/wall-e/eval/fixtures/wall-e-subset/eval/test.js +0 -134
  455. package/template/wall-e/eval/fixtures/wall-e-subset/llm/client.js +0 -99
  456. package/template/wall-e/eval/fixtures/wall-e-subset/llm/providers.js +0 -63
  457. package/template/wall-e/eval/fixtures/wall-e-subset/llm/test.js +0 -70
  458. package/template/wall-e/eval/fixtures/wall-e-subset/package.json +0 -10
  459. package/template/wall-e/eval/fixtures/wall-e-subset/test.js +0 -86
  460. package/template/wall-e/eval/harvester.js +0 -685
  461. package/template/wall-e/eval/head-to-head.js +0 -388
  462. package/template/wall-e/eval/humaneval-adapter.js +0 -321
  463. package/template/wall-e/eval/list-models.js +0 -31
  464. package/template/wall-e/eval/livecodebench-adapter.js +0 -291
  465. package/template/wall-e/eval/mail-integration.js +0 -443
  466. package/template/wall-e/eval/manifest.js +0 -186
  467. package/template/wall-e/eval/meta-harness/adapters/coding-agent.js +0 -57
  468. package/template/wall-e/eval/meta-harness/bootstrap-snapshot.js +0 -149
  469. package/template/wall-e/eval/meta-harness/candidate-store.js +0 -117
  470. package/template/wall-e/eval/meta-harness/cli.js +0 -86
  471. package/template/wall-e/eval/meta-harness/domain-spec.js +0 -154
  472. package/template/wall-e/eval/meta-harness/domains/coding-agent.domain.json +0 -84
  473. package/template/wall-e/eval/meta-harness/examples/env-bootstrap-candidate.js +0 -29
  474. package/template/wall-e/eval/meta-harness/experience-store.js +0 -174
  475. package/template/wall-e/eval/meta-harness/frontier.js +0 -96
  476. package/template/wall-e/eval/meta-harness/harness-interface.js +0 -90
  477. package/template/wall-e/eval/meta-harness/leakage-guard.js +0 -80
  478. package/template/wall-e/eval/meta-harness/optimizer.js +0 -207
  479. package/template/wall-e/eval/meta-harness/proposer-runner.js +0 -110
  480. package/template/wall-e/eval/meta-harness/reporting.js +0 -58
  481. package/template/wall-e/eval/meta-harness/telemetry.js +0 -27
  482. package/template/wall-e/eval/meta-harness/validation.js +0 -81
  483. package/template/wall-e/eval/promoter.js +0 -228
  484. package/template/wall-e/eval/provider-normalizer.js +0 -33
  485. package/template/wall-e/eval/replay.js +0 -395
  486. package/template/wall-e/eval/run-agent-benchmarks.js +0 -386
  487. package/template/wall-e/eval/run-codex-cli-baseline.js +0 -177
  488. package/template/wall-e/eval/run-coding-agent-real.js +0 -187
  489. package/template/wall-e/eval/run-eval.js +0 -435
  490. package/template/wall-e/eval/run-model-comparison.js +0 -142
  491. package/template/wall-e/eval/session-evaluator.js +0 -187
  492. package/template/wall-e/eval/session-miner.js +0 -207
  493. package/template/wall-e/eval/session-retrieval-benchmark.js +0 -150
  494. package/template/wall-e/eval/session-transcripts.js +0 -509
  495. package/template/wall-e/eval/shadow.js +0 -161
  496. package/template/wall-e/eval/swebench-adapter.js +0 -345
  497. package/template/wall-e/eval/swebench-docker.js +0 -192
  498. package/template/wall-e/eval/train.py +0 -320
  499. package/template/wall-e/eval/trainer.js +0 -232
  500. package/template/wall-e/eval/weekly-eval-loop.js +0 -241
@@ -0,0 +1,69 @@
1
+ # Private Memory And PII Policy
2
+
3
+ This repository must not contain personal memory, private user projects, local
4
+ workspace data, real contact information, or provider/account-specific
5
+ credentials. Wall-E memory and CTM session context are runtime data, not source
6
+ artifacts.
7
+
8
+ ## Keep Out Of Git
9
+
10
+ - Private journals, including `builder-journal.md`.
11
+ - CTM and Wall-E databases, WAL/SHM files, logs, screenshots, and JSONL
12
+ transcripts.
13
+ - Personal project artifacts generated for one user, including A/B screenshots,
14
+ review outputs, and generated site drafts.
15
+ - Real names, email addresses, phone numbers, home/work addresses, company names,
16
+ private gateway hostnames, and local machine paths in source, tests, and docs.
17
+ - OAuth tokens, API keys, Portkey/custom gateway headers, and `.env` files.
18
+
19
+ ## Use Safe Fixtures
20
+
21
+ Use generic fixture names such as `Test Owner`, `Student Example`, `Jordan
22
+ Example`, `ExampleCorp`, `example.com`, `gateway.example.internal`, and
23
+ `/Users/example/...`.
24
+
25
+ Do not use a real user's current personal project as a regression fixture. If a
26
+ regression needs that shape, reduce it to a generic minimal fixture and remove
27
+ the original names, paths, generated assets, and project-specific copy.
28
+
29
+ ## Builder Journal
30
+
31
+ The builder journal is private memory. The canonical local copy lives outside
32
+ this repository:
33
+
34
+ ```text
35
+ ~/.codex/memories/builder-journal.md
36
+ ```
37
+
38
+ If a copy appears in the repo, move or merge it into the private location, then
39
+ delete it from the Git worktree before committing.
40
+
41
+ ## Pre-Commit Guard
42
+
43
+ Run:
44
+
45
+ ```bash
46
+ node scripts/check-private-data.js
47
+ ```
48
+
49
+ The scanner checks tracked files only. It also reads optional local denylist
50
+ files that are intentionally ignored by Git:
51
+
52
+ ```text
53
+ .private-data-denylist
54
+ .private-data-denylist.local
55
+ ~/.codex/private-data-denylist
56
+ ~/.codex/memories/private-data-denylist
57
+ ```
58
+
59
+ Put user-specific terms in one of those local files, one term per line. Do not
60
+ commit the denylist itself. The built-in scanner is intentionally
61
+ high-confidence to avoid blocking generic fixtures; user-specific names,
62
+ projects, domains, and private organizations belong in the local denylist.
63
+
64
+ ## Git History
65
+
66
+ A forward cleanup removes the data from the current tree. Purging old commits is
67
+ a separate destructive operation because it rewrites history and changes commit
68
+ IDs. Use a dedicated history-rewrite plan, coordinate with all clones/remotes,
69
+ and validate that no needed private-only material is lost.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "walle",
3
- "version": "0.9.21",
3
+ "version": "0.9.23",
4
4
  "private": true,
5
5
  "description": "Wall-E — your personal digital twin",
6
6
  "scripts": {
@@ -9,6 +9,7 @@
9
9
  "setup": "node bin/setup.js",
10
10
  "clean:dev": "node bin/ctm-dev-cleanup.js --kill --stale --max-age-min 1440",
11
11
  "doctor:dev": "node bin/ctm-dev-cleanup.js --stale --max-age-min 1440",
12
+ "scan:private": "node scripts/check-private-data.js",
12
13
  "dev": "bash bin/dev.sh",
13
14
  "dev:fresh": "bash bin/dev.sh --fresh",
14
15
  "dev:refresh": "bash bin/dev.sh --refresh"
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const os = require('os');
6
+ const path = require('path');
7
+ const { execFileSync } = require('child_process');
8
+
9
+ const ROOT = execFileSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf8' }).trim();
10
+
11
+ const TEXT_EXTENSIONS = new Set([
12
+ '.cjs', '.css', '.csv', '.env', '.example', '.html', '.js', '.json', '.jsonl',
13
+ '.jsx', '.mjs', '.md', '.py', '.rb', '.sh', '.sql', '.svg', '.test', '.toml',
14
+ '.ts', '.tsx', '.txt', '.xml', '.yaml', '.yml',
15
+ ]);
16
+
17
+ const RESERVED_EMAIL_DOMAINS = new Set([
18
+ 'b.com',
19
+ 'domain.co',
20
+ 'example.com',
21
+ 'example.net',
22
+ 'example.org',
23
+ 'github.com',
24
+ 'new.com',
25
+ 'openai.com',
26
+ 'saved.example.com',
27
+ 'test',
28
+ 'test.com',
29
+ 'test.org',
30
+ 'test.invalid',
31
+ 'vendor.com',
32
+ 'localhost',
33
+ ]);
34
+
35
+ const RESERVED_USER_PATHS = new Set([
36
+ '...',
37
+ 'alice',
38
+ 'bob',
39
+ 'example',
40
+ 'foo',
41
+ 'me',
42
+ 'someone',
43
+ 'test',
44
+ 'tester',
45
+ 'runner',
46
+ 'u',
47
+ 'user',
48
+ 'x',
49
+ 'you',
50
+ ]);
51
+
52
+ const CONSUMER_EMAIL_DOMAINS = new Set([
53
+ 'gmail.com',
54
+ 'googlemail.com',
55
+ 'hotmail.com',
56
+ 'icloud.com',
57
+ 'live.com',
58
+ 'me.com',
59
+ 'outlook.com',
60
+ 'yahoo.com',
61
+ ]);
62
+
63
+ const BLOCKED_TRACKED_PATHS = [
64
+ /^builder-journal\.md$/,
65
+ /(^|\/)builder-journal\.md$/,
66
+ /^wall-e\/docs\/ab-screenshots\//,
67
+ ];
68
+
69
+ const SECRET_PATTERNS = [
70
+ { name: 'hardcoded Anthropic key', regex: /\bsk-ant-[A-Za-z0-9_-]{12,}\b/g },
71
+ { name: 'hardcoded OpenAI key', regex: /\bsk-proj-[A-Za-z0-9_-]{12,}\b|\bsk-[A-Za-z0-9_-]{24,}\b/g },
72
+ { name: 'Slack token', regex: /\bxox[baprs]-[A-Za-z0-9-]{12,}\b/g },
73
+ { name: 'GitHub token', regex: /\bgh[pousr]_[A-Za-z0-9_]{20,}\b/g },
74
+ { name: 'private key block', regex: /-----BEGIN [A-Z ]*PRIVATE KEY-----/g },
75
+ { name: 'JWT-like token', regex: /\beyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g },
76
+ ];
77
+
78
+ function gitFiles() {
79
+ const out = execFileSync('git', ['ls-files', '-z'], { cwd: ROOT });
80
+ return out.toString('utf8').split('\0').filter(Boolean);
81
+ }
82
+
83
+ function isProbablyText(file) {
84
+ const ext = path.extname(file).toLowerCase();
85
+ if (TEXT_EXTENSIONS.has(ext)) return true;
86
+ if (file.endsWith('LICENSE') || file.endsWith('Makefile') || file.endsWith('.gitignore')) return true;
87
+ return false;
88
+ }
89
+
90
+ function readOptionalDenylist(file) {
91
+ try {
92
+ return fs.readFileSync(file, 'utf8')
93
+ .split(/\r?\n/)
94
+ .map((line) => line.trim())
95
+ .filter((line) => line && !line.startsWith('#'));
96
+ } catch {
97
+ return [];
98
+ }
99
+ }
100
+
101
+ function loadPrivateTerms() {
102
+ const files = [
103
+ path.join(ROOT, '.private-data-denylist'),
104
+ path.join(ROOT, '.private-data-denylist.local'),
105
+ path.join(os.homedir(), '.codex', 'private-data-denylist'),
106
+ path.join(os.homedir(), '.codex', 'memories', 'private-data-denylist'),
107
+ ];
108
+ return files.flatMap(readOptionalDenylist);
109
+ }
110
+
111
+ function lineColumn(text, index) {
112
+ const before = text.slice(0, index);
113
+ const lines = before.split(/\n/);
114
+ return { line: lines.length, column: lines[lines.length - 1].length + 1 };
115
+ }
116
+
117
+ function addFinding(findings, file, reason, text, index = 0) {
118
+ const loc = lineColumn(text, index);
119
+ findings.push({ file, line: loc.line, column: loc.column, reason });
120
+ }
121
+
122
+ function scanEmails(findings, file, text) {
123
+ const emailRe = /\b[A-Z0-9._%+-]+@([A-Z0-9.-]+\.[A-Z]{2,}|localhost|test)\b/gi;
124
+ for (const match of text.matchAll(emailRe)) {
125
+ const domain = match[1].toLowerCase();
126
+ if (RESERVED_EMAIL_DOMAINS.has(domain)) continue;
127
+ if (domain.endsWith('.example')) continue;
128
+ if (domain.endsWith('.example.com') || domain.endsWith('.example.net') || domain.endsWith('.example.org')) continue;
129
+ if (domain.endsWith('.invalid')) continue;
130
+ if (CONSUMER_EMAIL_DOMAINS.has(domain)) {
131
+ addFinding(findings, file, `consumer email address: ${match[0]}`, text, match.index);
132
+ }
133
+ }
134
+ }
135
+
136
+ function scanLocalPaths(findings, file, text) {
137
+ const pathRe = /\/Users\/([A-Za-z0-9._-]+)(?=\/)/g;
138
+ for (const match of text.matchAll(pathRe)) {
139
+ if (RESERVED_USER_PATHS.has(match[1])) continue;
140
+ addFinding(findings, file, `non-generic local user path: /Users/${match[1]}`, text, match.index);
141
+ }
142
+ }
143
+
144
+ function scanSecrets(findings, file, text) {
145
+ for (const pattern of SECRET_PATTERNS) {
146
+ for (const match of text.matchAll(pattern.regex)) {
147
+ const normalized = match[0].toLowerCase();
148
+ if (match[0] === 'sk-ant-...') continue;
149
+ if (/fake|test|unused|example|dummy|placeholder|redacted|bearer|from|token|key|stale|rotated/.test(normalized)) continue;
150
+ if (/abc|123/.test(normalized)) continue;
151
+ addFinding(findings, file, pattern.name, text, match.index);
152
+ }
153
+ }
154
+ }
155
+
156
+ function scanPrivateTerms(findings, file, text, terms) {
157
+ for (const term of terms) {
158
+ const idx = text.toLowerCase().indexOf(term.toLowerCase());
159
+ if (idx !== -1) addFinding(findings, file, `local private denylist term: ${term}`, text, idx);
160
+ }
161
+ }
162
+
163
+ function main() {
164
+ const files = gitFiles();
165
+ const privateTerms = loadPrivateTerms();
166
+ const findings = [];
167
+
168
+ for (const file of files) {
169
+ for (const pattern of BLOCKED_TRACKED_PATHS) {
170
+ if (pattern.test(file)) {
171
+ findings.push({ file, line: 1, column: 1, reason: 'blocked private/generated path is tracked' });
172
+ }
173
+ }
174
+
175
+ if (!isProbablyText(file)) continue;
176
+
177
+ let text = '';
178
+ try {
179
+ text = fs.readFileSync(path.join(ROOT, file), 'utf8');
180
+ } catch {
181
+ continue;
182
+ }
183
+
184
+ scanEmails(findings, file, text);
185
+ scanLocalPaths(findings, file, text);
186
+ scanSecrets(findings, file, text);
187
+ scanPrivateTerms(findings, file, text, privateTerms);
188
+ }
189
+
190
+ if (findings.length) {
191
+ console.error('Private-data scan failed:');
192
+ for (const finding of findings) {
193
+ console.error(`- ${finding.file}:${finding.line}:${finding.column} ${finding.reason}`);
194
+ }
195
+ process.exit(1);
196
+ }
197
+
198
+ console.log(`Private-data scan passed (${files.length} tracked files checked).`);
199
+ }
200
+
201
+ main();
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ function _truthy(value) {
4
+ return /^(1|true|yes|on)$/i.test(String(value || '').trim());
5
+ }
6
+
7
+ function assertNoForeignSqliteOwner({
8
+ blockedEnv,
9
+ overrideEnv,
10
+ databaseLabel,
11
+ ownerLabel,
12
+ } = {}) {
13
+ const blockedRole = blockedEnv ? process.env[blockedEnv] : '';
14
+ if (!blockedRole || (overrideEnv && _truthy(process.env[overrideEnv]))) return;
15
+
16
+ const err = new Error(
17
+ `${databaseLabel || 'SQLite database'} must be accessed through its ${ownerLabel || 'owner'} API; ` +
18
+ `refusing direct access inside process role ${blockedEnv}=${blockedRole}.` +
19
+ (overrideEnv ? ` Set ${overrideEnv}=1 only for explicit standalone repair.` : '')
20
+ );
21
+ err.code = 'SQLITE_OWNER_VIOLATION';
22
+ err.blockedEnv = blockedEnv;
23
+ err.blockedRole = blockedRole;
24
+ err.overrideEnv = overrideEnv || '';
25
+ throw err;
26
+ }
27
+
28
+ module.exports = {
29
+ assertNoForeignSqliteOwner,
30
+ };
@@ -0,0 +1,225 @@
1
+ 'use strict';
2
+
3
+ const DEFAULT_MAX_DEPTH = 1000;
4
+ const DEFAULT_DRAIN_TIMEOUT_MS = 5000;
5
+
6
+ function _durationMs(value, fallback) {
7
+ const n = Number(value);
8
+ return Number.isFinite(n) ? Math.max(0, Math.trunc(n)) : fallback;
9
+ }
10
+
11
+ function _queueError(code, message, extra = {}) {
12
+ const err = new Error(message);
13
+ err.code = code;
14
+ for (const [key, value] of Object.entries(extra)) err[key] = value;
15
+ return err;
16
+ }
17
+
18
+ class SqliteOwnerWriteQueue {
19
+ constructor(options = {}) {
20
+ this.name = options.name || options.label || 'sqlite-owner-write-queue';
21
+ this.maxDepth = Math.max(1, Math.trunc(Number(options.maxDepth) || DEFAULT_MAX_DEPTH));
22
+ this._queue = [];
23
+ this._running = false;
24
+ this._active = null;
25
+ this._accepting = true;
26
+ this._closed = false;
27
+ this._enqueued = 0;
28
+ this._completed = 0;
29
+ this._failed = 0;
30
+ this._idleWaiters = [];
31
+ }
32
+
33
+ enqueue(fn, options = {}) {
34
+ if (typeof fn !== 'function') {
35
+ throw new TypeError('SqliteOwnerWriteQueue.enqueue requires a function');
36
+ }
37
+ if (!this._accepting || this._closed) {
38
+ return Promise.reject(_queueError(
39
+ 'SQLITE_OWNER_WRITE_QUEUE_CLOSED',
40
+ `${this.name} is closed`
41
+ ));
42
+ }
43
+ if (this._queue.length >= this.maxDepth) {
44
+ return Promise.reject(_queueError(
45
+ 'SQLITE_OWNER_WRITE_QUEUE_FULL',
46
+ `${this.name} is full`,
47
+ { pending: this._queue.length, maxDepth: this.maxDepth }
48
+ ));
49
+ }
50
+
51
+ const signal = options.signal || null;
52
+ if (signal?.aborted) {
53
+ return Promise.reject(_queueError(
54
+ 'SQLITE_OWNER_WRITE_QUEUE_ABORTED',
55
+ `${this.name} task aborted before enqueue`
56
+ ));
57
+ }
58
+
59
+ const label = options.label || 'write';
60
+ let task;
61
+ const promise = new Promise((resolve, reject) => {
62
+ task = {
63
+ fn,
64
+ label,
65
+ resolve,
66
+ reject,
67
+ enqueuedAt: Date.now(),
68
+ started: false,
69
+ signal,
70
+ abortListener: null,
71
+ };
72
+ });
73
+
74
+ if (signal) {
75
+ task.abortListener = () => {
76
+ if (task.started) return;
77
+ const idx = this._queue.indexOf(task);
78
+ if (idx >= 0) this._queue.splice(idx, 1);
79
+ task.reject(_queueError(
80
+ 'SQLITE_OWNER_WRITE_QUEUE_ABORTED',
81
+ `${this.name} task aborted while queued`,
82
+ { label }
83
+ ));
84
+ this._notifyIdleIfNeeded();
85
+ };
86
+ signal.addEventListener('abort', task.abortListener, { once: true });
87
+ }
88
+
89
+ this._enqueued += 1;
90
+ this._queue.push(task);
91
+ this._pump();
92
+ return promise;
93
+ }
94
+
95
+ getStatus() {
96
+ return {
97
+ name: this.name,
98
+ active: this._active,
99
+ running: this._running,
100
+ pending: this._queue.length,
101
+ accepting: this._accepting,
102
+ closed: this._closed,
103
+ maxDepth: this.maxDepth,
104
+ enqueued: this._enqueued,
105
+ completed: this._completed,
106
+ failed: this._failed,
107
+ idle: !this._running && this._queue.length === 0,
108
+ };
109
+ }
110
+
111
+ async drain(options = {}) {
112
+ const timeoutMs = _durationMs(options.timeoutMs, DEFAULT_DRAIN_TIMEOUT_MS);
113
+ if (!this._running && this._queue.length === 0) {
114
+ return { ok: true, timedOut: false, ...this.getStatus() };
115
+ }
116
+
117
+ if (timeoutMs === 0) {
118
+ await new Promise((resolve) => this._idleWaiters.push(resolve));
119
+ return { ok: true, timedOut: false, ...this.getStatus() };
120
+ }
121
+
122
+ let timer = null;
123
+ let idleWaiter = null;
124
+ try {
125
+ return await Promise.race([
126
+ new Promise((resolve) => {
127
+ idleWaiter = () => resolve({
128
+ ok: true,
129
+ timedOut: false,
130
+ ...this.getStatus(),
131
+ });
132
+ this._idleWaiters.push(idleWaiter);
133
+ }),
134
+ new Promise((resolve) => {
135
+ timer = setTimeout(() => resolve({
136
+ ok: false,
137
+ timedOut: true,
138
+ ...this.getStatus(),
139
+ }), timeoutMs);
140
+ if (typeof timer.unref === 'function') timer.unref();
141
+ }),
142
+ ]);
143
+ } finally {
144
+ if (timer) clearTimeout(timer);
145
+ if (idleWaiter) {
146
+ const idx = this._idleWaiters.indexOf(idleWaiter);
147
+ if (idx >= 0) this._idleWaiters.splice(idx, 1);
148
+ }
149
+ }
150
+ }
151
+
152
+ async close(options = {}) {
153
+ const drain = !!options.drain;
154
+ this._accepting = false;
155
+ this._closed = true;
156
+ if (!drain) {
157
+ this._rejectPending(_queueError(
158
+ 'SQLITE_OWNER_WRITE_QUEUE_CLOSED',
159
+ `${this.name} closed with pending writes rejected`
160
+ ));
161
+ return { ok: true, drained: false, ...this.getStatus() };
162
+ }
163
+ const result = await this.drain({ timeoutMs: options.timeoutMs });
164
+ return { ...result, drained: !result.timedOut };
165
+ }
166
+
167
+ _pump() {
168
+ if (this._running) return;
169
+ const task = this._queue.shift();
170
+ if (!task) {
171
+ this._notifyIdleIfNeeded();
172
+ return;
173
+ }
174
+
175
+ this._running = true;
176
+ this._active = task.label;
177
+ task.started = true;
178
+ if (task.signal && task.abortListener) {
179
+ task.signal.removeEventListener('abort', task.abortListener);
180
+ task.abortListener = null;
181
+ }
182
+
183
+ Promise.resolve()
184
+ .then(() => task.fn())
185
+ .then((value) => {
186
+ this._completed += 1;
187
+ task.resolve(value);
188
+ }, (err) => {
189
+ this._failed += 1;
190
+ task.reject(err);
191
+ })
192
+ .finally(() => {
193
+ this._running = false;
194
+ this._active = null;
195
+ this._pump();
196
+ });
197
+ }
198
+
199
+ _rejectPending(err) {
200
+ const pending = this._queue.splice(0);
201
+ for (const task of pending) {
202
+ if (task.signal && task.abortListener) {
203
+ task.signal.removeEventListener('abort', task.abortListener);
204
+ task.abortListener = null;
205
+ }
206
+ task.reject(err);
207
+ }
208
+ this._notifyIdleIfNeeded();
209
+ }
210
+
211
+ _notifyIdleIfNeeded() {
212
+ if (this._running || this._queue.length > 0) return;
213
+ const waiters = this._idleWaiters.splice(0);
214
+ for (const resolve of waiters) resolve();
215
+ }
216
+ }
217
+
218
+ function createSqliteOwnerWriteQueue(options = {}) {
219
+ return new SqliteOwnerWriteQueue(options);
220
+ }
221
+
222
+ module.exports = {
223
+ SqliteOwnerWriteQueue,
224
+ createSqliteOwnerWriteQueue,
225
+ };
@@ -0,0 +1,111 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
+
6
+ const CLOUD_STORAGE_PATTERNS = Object.freeze([
7
+ { id: 'dropbox', label: 'Dropbox', regex: /(^|[\\/])(?:Dropbox|CloudStorage[\\/][^\\/]*Dropbox[^\\/]*)([\\/]|$)/i },
8
+ { id: 'icloud', label: 'iCloud Drive', regex: /(^|[\\/])(?:Mobile Documents|CloudStorage[\\/][^\\/]*iCloud[^\\/]*)([\\/]|$)/i },
9
+ { id: 'onedrive', label: 'OneDrive', regex: /(^|[\\/])(?:OneDrive|CloudStorage[\\/][^\\/]*OneDrive[^\\/]*)([\\/]|$)/i },
10
+ { id: 'google-drive', label: 'Google Drive', regex: /(^|[\\/])(?:Google Drive|CloudStorage[\\/][^\\/]*GoogleDrive[^\\/]*)([\\/]|$)/i },
11
+ { id: 'box', label: 'Box Drive', regex: /(^|[\\/])(?:Box|CloudStorage[\\/][^\\/]*Box[^\\/]*)([\\/]|$)/i },
12
+ ]);
13
+
14
+ const VALID_POLICY_MODES = new Set(['off', 'warn', 'error']);
15
+ const warnedKeys = new Set();
16
+
17
+ function _normalizePath(value) {
18
+ const raw = String(value || '').trim();
19
+ if (!raw) return '';
20
+ try {
21
+ const dir = path.dirname(raw);
22
+ const base = path.basename(raw);
23
+ const realDir = fs.existsSync(dir) ? fs.realpathSync(dir) : path.resolve(dir);
24
+ return path.join(realDir, base);
25
+ } catch {
26
+ return path.resolve(raw);
27
+ }
28
+ }
29
+
30
+ function _truthy(value) {
31
+ return /^(1|true|yes|on)$/i.test(String(value || '').trim());
32
+ }
33
+
34
+ function sqliteStoragePolicyMode({ env = process.env, prefix = '' } = {}) {
35
+ const normalizedPrefix = String(prefix || '').trim().replace(/[^A-Z0-9_]/gi, '_').toUpperCase();
36
+ if (normalizedPrefix && _truthy(env[`${normalizedPrefix}_ALLOW_UNSAFE_CLOUD_SQLITE`])) return 'off';
37
+ if (_truthy(env.ALLOW_UNSAFE_CLOUD_SQLITE)) return 'off';
38
+
39
+ const raw = String(
40
+ (normalizedPrefix && env[`${normalizedPrefix}_SQLITE_STORAGE_POLICY`])
41
+ || env.SQLITE_STORAGE_POLICY
42
+ || 'warn'
43
+ ).trim().toLowerCase();
44
+ return VALID_POLICY_MODES.has(raw) ? raw : 'warn';
45
+ }
46
+
47
+ function classifySqlitePathRisk(dbPath) {
48
+ const normalizedPath = _normalizePath(dbPath);
49
+ const normalizedForMatch = normalizedPath.replace(/\\/g, '/');
50
+ const match = CLOUD_STORAGE_PATTERNS.find((candidate) => candidate.regex.test(normalizedForMatch));
51
+ if (!match) {
52
+ return {
53
+ risky: false,
54
+ reason: '',
55
+ provider: '',
56
+ providerLabel: '',
57
+ dbPath: normalizedPath,
58
+ message: '',
59
+ };
60
+ }
61
+ return {
62
+ risky: true,
63
+ reason: 'cloud_sync_sqlite_wal',
64
+ provider: match.id,
65
+ providerLabel: match.label,
66
+ dbPath: normalizedPath,
67
+ message:
68
+ `${match.label} sync storage is unsafe for a live SQLite WAL database. `
69
+ + 'Move the live DB directory to a local disk path and sync backups/exports instead.',
70
+ };
71
+ }
72
+
73
+ function enforceSqliteStoragePolicy(dbPath, {
74
+ env = process.env,
75
+ prefix = '',
76
+ label = 'SQLite database',
77
+ logger = console,
78
+ } = {}) {
79
+ const risk = classifySqlitePathRisk(dbPath);
80
+ const mode = sqliteStoragePolicyMode({ env, prefix });
81
+ const result = { ...risk, mode, blocked: false, label };
82
+ if (!risk.risky || mode === 'off') return result;
83
+
84
+ const message = `${label}: ${risk.message} Path: ${risk.dbPath}`;
85
+ if (mode === 'error') {
86
+ const err = new Error(message);
87
+ err.code = 'SQLITE_UNSAFE_CLOUD_STORAGE';
88
+ err.storageRisk = result;
89
+ throw err;
90
+ }
91
+
92
+ const warnKey = `${label}:${risk.provider}:${risk.dbPath}`;
93
+ if (!warnedKeys.has(warnKey)) {
94
+ warnedKeys.add(warnKey);
95
+ try {
96
+ logger.warn(`[sqlite-storage] ${message}`);
97
+ } catch {}
98
+ }
99
+ return result;
100
+ }
101
+
102
+ function resetSqliteStoragePolicyWarnings() {
103
+ warnedKeys.clear();
104
+ }
105
+
106
+ module.exports = {
107
+ classifySqlitePathRisk,
108
+ enforceSqliteStoragePolicy,
109
+ resetSqliteStoragePolicyWarnings,
110
+ sqliteStoragePolicyMode,
111
+ };