praxis-agent 0.37.0 → 0.39.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 (227) hide show
  1. package/README.md +31 -53
  2. package/dist/application/background-agent-manager.js +7 -4
  3. package/dist/application/background-bash-manager.d.ts +2 -2
  4. package/dist/application/background-bash-manager.js +6 -6
  5. package/dist/application/claude-project-purge.js +36 -74
  6. package/dist/application/native-session-transcript.d.ts +14 -3
  7. package/dist/application/native-session-transcript.js +30 -9
  8. package/dist/application/scheduled-prompt-manager.d.ts +2 -2
  9. package/dist/application/scheduled-prompt-manager.js +3 -3
  10. package/dist/application/session-memory.d.ts +2 -5
  11. package/dist/application/session-memory.js +4 -7
  12. package/dist/application/session-service.d.ts +18 -29
  13. package/dist/application/session-service.js +1084 -1784
  14. package/dist/application/session-worktree.d.ts +2 -3
  15. package/dist/application/session-worktree.js +3 -3
  16. package/dist/application/subagent-service.d.ts +2 -5
  17. package/dist/application/subagent-service.js +152 -319
  18. package/dist/application/team-agent-runtime.d.ts +3 -0
  19. package/dist/application/team-agent-runtime.js +20 -3
  20. package/dist/application/team-lead-decision-surface.d.ts +22 -0
  21. package/dist/application/team-lead-decision-surface.js +16 -0
  22. package/dist/application/team-observability.d.ts +113 -0
  23. package/dist/application/team-observability.js +312 -0
  24. package/dist/application/top-level-agent-manager.js +19 -37
  25. package/dist/application/transcript-projection.js +18 -2
  26. package/dist/application/workflow-manager.d.ts +1 -1
  27. package/dist/application/workflow-manager.js +11 -19
  28. package/dist/cli/controls.d.ts +10 -6
  29. package/dist/cli/controls.js +28 -6
  30. package/dist/cli/interactive.d.ts +4 -3
  31. package/dist/cli/interactive.js +461 -216
  32. package/dist/cli/protocol.d.ts +1 -1
  33. package/dist/cli/protocol.js +0 -13
  34. package/dist/cli/tui/btw-surface-model.d.ts +22 -0
  35. package/dist/cli/tui/btw-surface-model.js +10 -0
  36. package/dist/cli/tui/claude-style.d.ts +52 -90
  37. package/dist/cli/tui/claude-style.js +96 -79
  38. package/dist/cli/tui/command-palette-model.d.ts +33 -0
  39. package/dist/cli/tui/command-palette-model.js +44 -0
  40. package/dist/cli/tui/config-dashboard.d.ts +3 -9
  41. package/dist/cli/tui/config-dashboard.js +2 -1
  42. package/dist/cli/tui/config-settings.js +5 -14
  43. package/dist/cli/tui/config-surface-model.d.ts +24 -0
  44. package/dist/cli/tui/config-surface-model.js +16 -0
  45. package/dist/cli/tui/diff-surface-model.d.ts +83 -0
  46. package/dist/cli/tui/diff-surface-model.js +142 -0
  47. package/dist/cli/tui/doctor-dashboard.d.ts +3 -4
  48. package/dist/cli/tui/doctor-dashboard.js +3 -2
  49. package/dist/cli/tui/doctor-surface-model.d.ts +13 -0
  50. package/dist/cli/tui/doctor-surface-model.js +9 -0
  51. package/dist/cli/tui/hook-settings.d.ts +2 -2
  52. package/dist/cli/tui/hooks-surface-model.d.ts +18 -0
  53. package/dist/cli/tui/hooks-surface-model.js +11 -0
  54. package/dist/cli/tui/leaf-surface-model.d.ts +68 -0
  55. package/dist/cli/tui/leaf-surface-model.js +55 -0
  56. package/dist/cli/tui/list-surface-model.d.ts +27 -0
  57. package/dist/cli/tui/list-surface-model.js +22 -0
  58. package/dist/cli/tui/mcp-elicitation-surface-model.d.ts +27 -0
  59. package/dist/cli/tui/mcp-elicitation-surface-model.js +25 -0
  60. package/dist/cli/tui/mcp-elicitation.d.ts +7 -1
  61. package/dist/cli/tui/mcp-elicitation.js +6 -2
  62. package/dist/cli/tui/mcp-panel.d.ts +3 -6
  63. package/dist/cli/tui/mcp-panel.js +6 -8
  64. package/dist/cli/tui/mcp-surface-model.d.ts +11 -0
  65. package/dist/cli/tui/mcp-surface-model.js +4 -0
  66. package/dist/cli/tui/memory-files.d.ts +3 -5
  67. package/dist/cli/tui/memory-files.js +12 -30
  68. package/dist/cli/tui/memory-surface-model.d.ts +20 -0
  69. package/dist/cli/tui/memory-surface-model.js +12 -0
  70. package/dist/cli/tui/mention-picker-model.d.ts +41 -0
  71. package/dist/cli/tui/mention-picker-model.js +53 -0
  72. package/dist/cli/tui/model-effort-surface-model.d.ts +29 -0
  73. package/dist/cli/tui/model-effort-surface-model.js +38 -0
  74. package/dist/cli/tui/permission-settings.d.ts +6 -9
  75. package/dist/cli/tui/permission-settings.js +9 -15
  76. package/dist/cli/tui/rewind-surface-model.d.ts +53 -0
  77. package/dist/cli/tui/rewind-surface-model.js +54 -0
  78. package/dist/cli/tui/sandbox-dashboard.d.ts +3 -4
  79. package/dist/cli/tui/sandbox-dashboard.js +2 -1
  80. package/dist/cli/tui/sandbox-settings.d.ts +3 -5
  81. package/dist/cli/tui/sandbox-settings.js +5 -9
  82. package/dist/cli/tui/sandbox-surface-model.d.ts +13 -0
  83. package/dist/cli/tui/sandbox-surface-model.js +4 -0
  84. package/dist/cli/tui/session-picker-model.d.ts +41 -0
  85. package/dist/cli/tui/session-picker-model.js +69 -0
  86. package/dist/cli/tui/slash-commands.js +1 -1
  87. package/dist/cli/tui/status-line.d.ts +5 -5
  88. package/dist/cli/tui/status-line.js +12 -30
  89. package/dist/cli/tui/task-panel.d.ts +3 -3
  90. package/dist/cli/tui/task-panel.js +2 -1
  91. package/dist/cli/tui/task-surface-model.d.ts +11 -0
  92. package/dist/cli/tui/task-surface-model.js +4 -0
  93. package/dist/cli/tui/terminal-setup.js +2 -4
  94. package/dist/cli/tui/theme-surface-model.d.ts +85 -0
  95. package/dist/cli/tui/theme-surface-model.js +52 -0
  96. package/dist/cli/tui/theme.d.ts +2 -2
  97. package/dist/cli/tui/tool-permission.d.ts +1 -1
  98. package/dist/cli/tui/tool-permission.js +13 -15
  99. package/dist/cli-runtime.d.ts +1 -1
  100. package/dist/cli-runtime.js +163 -317
  101. package/dist/{compatibility/claude → core}/agent-color.d.ts +1 -2
  102. package/dist/core/project-memory.d.ts +4 -3
  103. package/dist/core/project-memory.js +2 -4
  104. package/dist/core/runtime.d.ts +2 -0
  105. package/dist/core/transcript-event.d.ts +4 -0
  106. package/dist/core/transcript-event.js +11 -1
  107. package/dist/extensions/claude-extensions.d.ts +5 -6
  108. package/dist/extensions/claude-extensions.js +13 -27
  109. package/dist/extensions/claude-init-command.d.ts +2 -3
  110. package/dist/extensions/claude-init-command.js +7 -70
  111. package/dist/hooks/claude-file-change-watcher.d.ts +3 -0
  112. package/dist/hooks/claude-file-change-watcher.js +70 -8
  113. package/dist/hooks/claude-hook-tools.js +6 -1
  114. package/dist/hooks/claude-hooks.d.ts +4 -4
  115. package/dist/maintenance/doctor-diagnostic.d.ts +0 -1
  116. package/dist/maintenance/doctor-diagnostic.js +0 -4
  117. package/dist/maintenance/doctor.d.ts +8 -4
  118. package/dist/maintenance/doctor.js +10 -63
  119. package/dist/mcp/claude-mcp-management.d.ts +3 -3
  120. package/dist/mcp/claude-mcp-management.js +16 -37
  121. package/dist/mcp/claude-mcp-oauth.js +1 -1
  122. package/dist/mcp/claude-mcp-tools.d.ts +4 -4
  123. package/dist/mcp/claude-mcp-tools.js +1 -3
  124. package/dist/{compatibility/claude → native}/compaction.d.ts +4 -4
  125. package/dist/{compatibility/claude → native}/context.d.ts +6 -2
  126. package/dist/{compatibility/claude → native}/context.js +21 -9
  127. package/dist/native/file-history.d.ts +14 -0
  128. package/dist/{compatibility/claude → native}/fork.d.ts +3 -3
  129. package/dist/{compatibility/claude → native}/fork.js +4 -4
  130. package/dist/{compatibility/claude → native}/history.d.ts +6 -6
  131. package/dist/{compatibility/claude → native}/interruption.d.ts +3 -3
  132. package/dist/{compatibility/claude → native}/ownership.d.ts +17 -17
  133. package/dist/{compatibility/claude → native}/ownership.js +17 -17
  134. package/dist/{compatibility/claude → native}/paths.d.ts +8 -8
  135. package/dist/{compatibility/claude → native}/paths.js +23 -26
  136. package/dist/{compatibility/claude → native}/pr-links.d.ts +2 -2
  137. package/dist/{compatibility/claude → native}/projection.d.ts +8 -8
  138. package/dist/native/schema.d.ts +14 -0
  139. package/dist/native/schema.js +24 -0
  140. package/dist/{compatibility/claude → native}/session-metadata.d.ts +6 -6
  141. package/dist/{compatibility/claude → native}/sidechain.d.ts +4 -4
  142. package/dist/{compatibility/claude → native}/tool-links.d.ts +5 -5
  143. package/dist/{compatibility/claude → native}/translation.d.ts +10 -10
  144. package/dist/{compatibility/claude → native}/translation.js +17 -7
  145. package/dist/permissions/bash-path-safety.js +2 -4
  146. package/dist/permissions/bypass-immune-paths.d.ts +0 -2
  147. package/dist/permissions/bypass-immune-paths.js +2 -2
  148. package/dist/permissions/claude-auto-classifier.d.ts +2 -2
  149. package/dist/permissions/claude-permission-resolver.d.ts +3 -3
  150. package/dist/permissions/claude-permission-resolver.js +9 -13
  151. package/dist/persistence/claude-cost-state-store.js +1 -2
  152. package/dist/persistence/claude-workflow-store.d.ts +26 -4
  153. package/dist/persistence/claude-workflow-store.js +47 -2
  154. package/dist/persistence/data-plane-adapter.d.ts +1 -2
  155. package/dist/persistence/data-plane.d.ts +2 -3
  156. package/dist/persistence/data-plane.js +15 -12
  157. package/dist/persistence/in-memory-sidechain-store.d.ts +24 -7
  158. package/dist/persistence/in-memory-sidechain-store.js +23 -19
  159. package/dist/persistence/in-memory-transcript-store.d.ts +13 -6
  160. package/dist/persistence/in-memory-transcript-store.js +38 -58
  161. package/dist/persistence/native-resources.js +63 -7
  162. package/dist/persistence/{claude-scheduled-task-store.d.ts → native-scheduled-task-store.d.ts} +10 -10
  163. package/dist/persistence/{claude-scheduled-task-store.js → native-scheduled-task-store.js} +14 -14
  164. package/dist/persistence/native-transcript-reader.d.ts +6 -6
  165. package/dist/persistence/native-transcript-reader.js +2 -2
  166. package/dist/persistence/native-transcript-store.d.ts +9 -0
  167. package/dist/persistence/native-transcript-store.js +47 -5
  168. package/dist/persistence/subagent-lifecycle-store.js +3 -4
  169. package/dist/persistence/unknown-cost-sidecar.d.ts +2 -2
  170. package/dist/persistence/unknown-cost-sidecar.js +2 -2
  171. package/dist/platform/project-memory-paths.d.ts +3 -4
  172. package/dist/platform/project-memory-paths.js +4 -5
  173. package/dist/plugins/claude-plugin-marketplace.js +3 -2
  174. package/dist/plugins/claude-plugin-mcpb.js +3 -4
  175. package/dist/plugins/claude-plugin-runtime.d.ts +6 -6
  176. package/dist/providers/anthropic-prompt-cache.d.ts +1 -1
  177. package/dist/providers/anthropic-prompt-cache.js +3 -26
  178. package/dist/sandbox/claude-sandbox-settings.d.ts +5 -6
  179. package/dist/sandbox/claude-sandbox-settings.js +5 -5
  180. package/dist/tools/claude-interactive-tools.d.ts +1 -2
  181. package/dist/tools/claude-interactive-tools.js +3 -1
  182. package/dist/tools/claude-scheduled-tools.js +6 -7
  183. package/dist/tools/claude-workflow-tools.d.ts +0 -2
  184. package/dist/tools/claude-workflow-tools.js +4 -4
  185. package/dist/tools/claude-worktree-tools.js +3 -5
  186. package/dist/tools/local-tools.d.ts +2 -1
  187. package/dist/tools/local-tools.js +11 -5
  188. package/dist/tools/team-lead-tools.d.ts +1 -1
  189. package/dist/tools/team-lead-tools.js +0 -1
  190. package/package.json +8 -65
  191. package/dist/compatibility/claude/data-plane-adapter.d.ts +0 -9
  192. package/dist/compatibility/claude/data-plane-adapter.js +0 -44
  193. package/dist/compatibility/claude/file-history.d.ts +0 -14
  194. package/dist/compatibility/claude/schema.d.ts +0 -26
  195. package/dist/compatibility/claude/schema.js +0 -1071
  196. package/dist/compatibility/claude/shared-resources.d.ts +0 -27
  197. package/dist/compatibility/claude/shared-resources.js +0 -459
  198. package/dist/compatibility/claude/transcript-codec.d.ts +0 -21
  199. package/dist/compatibility/claude/transcript-codec.js +0 -518
  200. package/dist/persistence/claude-migration.d.ts +0 -5
  201. package/dist/persistence/claude-migration.js +0 -225
  202. package/dist/persistence/claude-session-index.d.ts +0 -39
  203. package/dist/persistence/claude-session-index.js +0 -175
  204. package/dist/persistence/claude-sidechain-store.d.ts +0 -18
  205. package/dist/persistence/claude-sidechain-store.js +0 -123
  206. package/dist/persistence/claude-transcript-store.d.ts +0 -90
  207. package/dist/persistence/claude-transcript-store.js +0 -469
  208. package/dist/platform/claude-version.d.ts +0 -5
  209. package/dist/platform/claude-version.js +0 -18
  210. /package/dist/{compatibility/claude → core}/agent-color.js +0 -0
  211. /package/dist/{compatibility/claude → native}/compaction.js +0 -0
  212. /package/dist/{compatibility/claude → native}/dynamic-context.d.ts +0 -0
  213. /package/dist/{compatibility/claude → native}/dynamic-context.js +0 -0
  214. /package/dist/{compatibility/claude → native}/file-history.js +0 -0
  215. /package/dist/{compatibility/claude → native}/file-resources.d.ts +0 -0
  216. /package/dist/{compatibility/claude → native}/file-resources.js +0 -0
  217. /package/dist/{compatibility/claude → native}/history.js +0 -0
  218. /package/dist/{compatibility/claude → native}/interruption.js +0 -0
  219. /package/dist/{compatibility/claude → native}/pr-links.js +0 -0
  220. /package/dist/{compatibility/claude → native}/projection.js +0 -0
  221. /package/dist/{compatibility/claude → native}/session-metadata.js +0 -0
  222. /package/dist/{compatibility/claude → native}/sidechain.js +0 -0
  223. /package/dist/{compatibility/claude → native}/tool-links.js +0 -0
  224. /package/dist/{compatibility/claude → native}/workflow-replay.d.ts +0 -0
  225. /package/dist/{compatibility/claude → native}/workflow-replay.js +0 -0
  226. /package/dist/{compatibility/claude → native}/workflow.d.ts +0 -0
  227. /package/dist/{compatibility/claude → native}/workflow.js +0 -0
package/README.md CHANGED
@@ -17,15 +17,10 @@ Anthropic/OpenAI-compatible model access. Praxis deliberately excludes
17
17
  accounts, organizations, billing, managed enterprise policy, remote control,
18
18
  IDE surfaces, and telemetry control planes.
19
19
 
20
- Claude Code 2.1.208 remains the architecture, design, and observable
21
- compatibility baseline for included and required single-user developer
22
- capabilities. Only entries classified `required` block developer-core
23
- closure; `deferred` entries are optional and demand-driven. Exclusions cover
24
- the existing enterprise, authentication, hosted, and client surfaces plus the
25
- explicitly classified subscription-bound integration, campaign, hidden
26
- maintainer diagnostic, and build-experimental commands. A similar Praxis
27
- surface is not a substitute for the corresponding Claude command or runtime
28
- contract.
20
+ Claude Code 2.1.208 remains a clean-room behavioral reference for the
21
+ developer-facing CLI surface. It is not a runtime dependency or a data source:
22
+ Praxis runs one native data plane and does not read or write Claude Code
23
+ sessions, configuration, or compatibility directories.
29
24
 
30
25
  ## Requirements
31
26
 
@@ -34,9 +29,12 @@ contract.
34
29
  - [`ripgrep`](https://github.com/BurntSushi/ripgrep) (`rg`) for the Grep tool
35
30
  - an API key and model ID for an Anthropic or OpenAI-compatible provider
36
31
 
37
- Praxis does not use Claude subscription authentication. Claude Code
38
- interoperability covers local sessions, configuration, permissions, memory,
39
- skills, hooks, agents, plugins, and MCP data.
32
+ Praxis does not use Claude subscription authentication. Claude-shaped message,
33
+ tool, and CLI protocol forms remain supported where they are part of the
34
+ public surface, while all persisted state is Praxis-native.
35
+
36
+ Team operations are local-only and opt-in. Unsupported or lossy Team payloads
37
+ are rejected rather than silently simplified.
40
38
 
41
39
  ## Install
42
40
 
@@ -85,7 +83,7 @@ praxis doctor
85
83
 
86
84
  See
87
85
  [Getting Started](https://github.com/Forest-Isle/Praxis/blob/main/docs/GETTING_STARTED.md)
88
- for provider setup, shared Claude state, permissions, updating, and
86
+ for provider setup, shared Praxis state, permissions, updating, and
89
87
  troubleshooting. Run `praxis --help` for the authoritative command surface.
90
88
 
91
89
  ## What Praxis provides
@@ -112,7 +110,7 @@ troubleshooting. Run `praxis --help` for the authoritative command surface.
112
110
  context/status/skill/task dashboards, prompt stash and continuation shortcuts,
113
111
  filterable `@` file and agent references, composer undo, `Ctrl+G` external
114
112
  editing, shared `/keybindings` creation/editing and supported-action remapping,
115
- shared built-in and Claude-compatible custom `/theme` profiles with immediate
113
+ shared built-in and custom `/theme` profiles with immediate
116
114
  semantic recoloring, token editing/reset, deletion, and persisted syntax
117
115
  toggles across transcript code and diff views,
118
116
  shared runtime preferences for reduced motion, spinner tips, progress and
@@ -123,7 +121,9 @@ troubleshooting. Run `praxis --help` for the authoritative command surface.
123
121
  `Ctrl+V` text/image clipboard paste, `Ctrl+Z` shell suspension and `fg`
124
122
  recovery, permission-gated `!` shell turns, navigable current/per-turn Git
125
123
  diff views, semantic plan/question decision panels with complete
126
- screen-reader actions, and measured context budgets; print mode,
124
+ screen-reader actions, semantic screen projection across selectable surfaces,
125
+ deterministic resize-aware URL/form elicitation rendering, and measured
126
+ context budgets; print mode,
127
127
  structured JSON/JSONL, context compaction, tool loops, and bounded execution.
128
128
  - **Built-in tools** — read, write, edit, glob, search, shell, notebook, PDF,
129
129
  image, web, scheduled prompts, workflows, and worktrees.
@@ -166,10 +166,14 @@ troubleshooting. Run `praxis --help` for the authoritative command surface.
166
166
  and shutdown-drain budgets.
167
167
  Child permissions can only tighten the parent; concurrent asks form one FIFO
168
168
  Lead Decision queue with provenance. Coordinator leads are restricted to
169
- orchestration, and custom Team agents receive no MCP capability.
170
- - **Claude-compatible ecosystem** shared instructions with recursive `@`
169
+ orchestration, and custom Team agents receive no MCP capability. The native
170
+ CLI also exposes `praxis team status`, `logs`, and `attach` in human or JSON
171
+ form; durable-local attach does not require tmux. Native task, notification,
172
+ context, and Team resume/inbox seams are implemented with fail-closed
173
+ validation for unsupported payloads.
174
+ - **Native resource ecosystem** — shared Praxis instructions with recursive `@`
171
175
  imports, memory, skills, commands, agents, hooks, settings, MCP servers,
172
- plugins, and transcript data.
176
+ plugins, and append-only `praxis.transcript` JSONL sessions under `~/.praxis`.
173
177
  - **Provider-neutral models** — native Anthropic Messages and OpenAI-compatible
174
178
  streaming adapters with explicit capability checks and metering controls.
175
179
 
@@ -177,39 +181,6 @@ Detailed feature status and executable evidence live in the
177
181
  [parity matrix](https://github.com/Forest-Isle/Praxis/blob/main/docs/PARITY_MATRIX.md),
178
182
  not in this entry-point README.
179
183
 
180
- ## Claude Code interoperability
181
-
182
- Praxis uses an independent local data plane by default:
183
-
184
- ```text
185
- Praxis ─── ~/.praxis (or PRAXIS_HOME)
186
- ```
187
-
188
- Use `praxis --data-plane claude` when you need the legacy shared Claude Code
189
- layout (`~/.claude` or `CLAUDE_CONFIG_DIR`). Praxis can resume Claude Code
190
- sessions in that mode, and Claude Code can resume compatible sessions written
191
- there. Every semver-like Claude Code producer version is
192
- structurally validated and is read/write compatible when its entry shape is
193
- supported; schema adapters are selected from transcript entry structure rather
194
- than an installed or fixed producer version, and malformed or unsupported
195
- shapes fail closed before any write. Each transcript record keeps its original
196
- producer version, so supported shapes may be mixed across versions in one
197
- session. Native fork creation is a separate restricted lossless copy path that
198
- preserves each existing source record's producer version, so it can copy
199
- specific black-box-verified foreign shapes such as the observed Claude Code
200
- 2.1.233 records; unsupported record shapes and unverified versions still fail
201
- closed and remain read-only. Maintainers can prove mixed-version Claude JSONL interoperability with
202
- `npm run test:cross-version-session-compat`, `test:cross-version-fork-compat`,
203
- `test:cross-version-sidechain-compat`, `test:cross-version-compaction-compat`,
204
- and `test:cross-version-resume-at-compat`, covering linear resume, native fork,
205
- foreground sidechain, compaction, and `--resume-session-at` branch projection.
206
- Each requires `PRAXIS_CLAUDE_BINARY` (Claude Code 2.1.208) and
207
- `PRAXIS_CLAUDE_CROSS_VERSION_BINARY` (a different Claude Code version).
208
-
209
- See the
210
- [compatibility contract](https://github.com/Forest-Isle/Praxis/blob/main/docs/COMPATIBILITY.md)
211
- for exact shared data, version boundaries, exclusions, and verification gates.
212
-
213
184
  ## Documentation
214
185
 
215
186
  | Need | Document |
@@ -254,9 +225,16 @@ npm ci
254
225
  npm run check
255
226
  ```
256
227
 
257
- `npm run build:native` compiles the current Praxis-owned core, provider
258
- adapters, and native data-plane slice without the Claude compatibility adapter.
228
+ `npm run build:native` compiles the Praxis-owned core, provider, native
229
+ transcript, and session profile.
230
+ `npm run test:native:deletion` adds an emitted-output deletion gate. These are
231
+ implemented profile checks, not qualification of the full native package.
232
+ `npm run test:performance` runs the native projection scaling and regression
233
+ budgets; the retained-render p95 budget remains 50 ms.
259
234
  `npm run check` also enforces the corresponding source dependency direction.
235
+ `npm run test:core-completion` runs the 56-story #402 audit and reports
236
+ implemented, qualified, blocked, deferred, and out-of-scope states separately;
237
+ it never treats missing live prerequisites as a pass.
260
238
 
261
239
  Contributions use Conventional Commit pull-request titles and the protected
262
240
  squash-merge workflow. Read
@@ -1,8 +1,11 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { isTerminalLifecycleState, } from '../core/agent-orchestration.js';
3
- import { isClaudeAgentId } from '../compatibility/claude/sidechain.js';
4
3
  const MAX_TIMEOUT_MS = 600_000;
5
4
  const DEFAULT_CLOSE_DRAIN_MS = 5_000;
5
+ const NATIVE_AGENT_ID_PATTERN = /^a[0-9a-f]{16}$/u;
6
+ function isNativeAgentId(agentId) {
7
+ return NATIVE_AGENT_ID_PATTERN.test(agentId);
8
+ }
6
9
  export class BackgroundAgentRunError extends Error {
7
10
  result;
8
11
  constructor(message, result, cause) {
@@ -37,7 +40,7 @@ function notificationWireStatus(status) {
37
40
  return null;
38
41
  }
39
42
  function assertAgentId(agentId) {
40
- if (!isClaudeAgentId(agentId)) {
43
+ if (!isNativeAgentId(agentId)) {
41
44
  throw new Error(`Invalid background agent ID: ${agentId}`);
42
45
  }
43
46
  }
@@ -625,7 +628,7 @@ export class BackgroundAgentManager {
625
628
  return { task, created: true };
626
629
  }
627
630
  resolveOptional(identifier) {
628
- if (isClaudeAgentId(identifier))
631
+ if (isNativeAgentId(identifier))
629
632
  return identifier;
630
633
  return this.names.get(identifier);
631
634
  }
@@ -669,7 +672,7 @@ export class BackgroundAgentManager {
669
672
  }
670
673
  resolveRequired(identifier) {
671
674
  const resolved = this.resolveOptional(identifier);
672
- if (!isClaudeAgentId(identifier) &&
675
+ if (!isNativeAgentId(identifier) &&
673
676
  !/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/u.test(identifier)) {
674
677
  assertAgentId(identifier);
675
678
  }
@@ -32,8 +32,8 @@ export interface BackgroundBashToolResult {
32
32
  task?: Record<string, unknown>;
33
33
  };
34
34
  }
35
- export declare function claudeBackgroundTaskParent(cwd: string): string;
36
- export declare function claudeBackgroundTaskRoot(cwd: string, sessionId: string): string;
35
+ export declare function nativeBackgroundTaskParent(cwd: string): string;
36
+ export declare function nativeBackgroundTaskRoot(cwd: string, sessionId: string): string;
37
37
  export declare class BackgroundBashManager {
38
38
  private readonly options;
39
39
  private readonly tasks;
@@ -1,16 +1,16 @@
1
1
  import { mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises';
2
2
  import { resolve } from 'node:path';
3
- import { sanitizeClaudeProjectPath } from '../compatibility/claude/paths.js';
3
+ import { sanitizeProjectPath } from '../platform/project-path-key.js';
4
4
  import { writeFileAtomically } from '../platform/atomic-write.js';
5
5
  import { BoundedProcessRunner, } from '../platform/bounded-process-runner.js';
6
6
  import { commandShell, commandShellArguments, } from '../platform/command-shell.js';
7
7
  import { assertBackgroundBashTaskId, backgroundBashTaskIdFromStateFile, createBackgroundBashTaskId, } from './background-task-id.js';
8
- export function claudeBackgroundTaskParent(cwd) {
8
+ export function nativeBackgroundTaskParent(cwd) {
9
9
  const uid = process.getuid?.() ?? 'unknown';
10
- return resolve('/tmp', `claude-${uid}`, sanitizeClaudeProjectPath(resolve(cwd)));
10
+ return resolve('/tmp', `praxis-${uid}`, sanitizeProjectPath(resolve(cwd)));
11
11
  }
12
- export function claudeBackgroundTaskRoot(cwd, sessionId) {
13
- return resolve(claudeBackgroundTaskParent(cwd), sessionId, 'tasks');
12
+ export function nativeBackgroundTaskRoot(cwd, sessionId) {
13
+ return resolve(nativeBackgroundTaskParent(cwd), sessionId, 'tasks');
14
14
  }
15
15
  function parsePersistedTask(source, taskId, outputFile) {
16
16
  let value;
@@ -65,7 +65,7 @@ export class BackgroundBashManager {
65
65
  cwd: options.cwd,
66
66
  maxOutputBytes: options.maxOutputBytes ?? 128 * 1024,
67
67
  });
68
- this.outputRoot = claudeBackgroundTaskRoot(options.cwd, options.sessionId);
68
+ this.outputRoot = nativeBackgroundTaskRoot(options.cwd, options.sessionId);
69
69
  this.sessionStateRoot = resolve(options.stateRoot, options.sessionId);
70
70
  }
71
71
  has(taskId) {
@@ -1,9 +1,10 @@
1
1
  import { lstat, readFile, readdir, realpath, rm } from 'node:fs/promises';
2
2
  import { homedir } from 'node:os';
3
3
  import { basename, dirname, isAbsolute, join, relative, resolve, sep, } from 'node:path';
4
- import { isClaudeSessionId, sanitizeClaudeProjectPath, } from '../compatibility/claude/paths.js';
5
- import { resolveClaudeProjectIdentity } from '../compatibility/claude/shared-resources.js';
4
+ import { isSessionId } from '../core/session.js';
6
5
  import { writeFileAtomically } from '../platform/atomic-write.js';
6
+ import { resolveProjectIdentity } from '../platform/project-identity.js';
7
+ import { sanitizeProjectPath } from '../platform/project-path-key.js';
7
8
  const MAX_ATOMIC_UPDATE_RETRIES = 8;
8
9
  function errorCode(error) {
9
10
  return error.code;
@@ -182,17 +183,17 @@ async function discoverSessionIds(projectRoot) {
182
183
  for (const entry of entries) {
183
184
  if (entry.isFile() && entry.name.endsWith('.jsonl')) {
184
185
  const sessionId = entry.name.slice(0, -'.jsonl'.length);
185
- if (isClaudeSessionId(sessionId))
186
+ if (isSessionId(sessionId))
186
187
  sessionIds.add(sessionId);
187
188
  }
188
- if (entry.isDirectory() && isClaudeSessionId(entry.name)) {
189
+ if (entry.isDirectory() && isSessionId(entry.name)) {
189
190
  sessionIds.add(entry.name);
190
191
  }
191
192
  }
192
193
  return [...sessionIds].sort();
193
194
  }
194
- async function discoverProjectRoots(configRoot, targetPaths, dataPlane) {
195
- const projectsRoot = join(configRoot, dataPlane === 'native' ? 'sessions' : 'projects');
195
+ async function discoverProjectRoots(configRoot, targetPaths) {
196
+ const projectsRoot = join(configRoot, 'sessions');
196
197
  if (!(await pathExists(projectsRoot)))
197
198
  return [];
198
199
  await assertSafePurgePath(configRoot, projectsRoot);
@@ -206,8 +207,8 @@ async function discoverProjectRoots(configRoot, targetPaths, dataPlane) {
206
207
  }
207
208
  throw error;
208
209
  }
209
- const targetKeys = targetPaths.map(sanitizeClaudeProjectPath);
210
- const worktreeSegment = dataPlane === 'native' ? '--praxis-worktrees-' : '--claude-worktrees-';
210
+ const targetKeys = targetPaths.map(sanitizeProjectPath);
211
+ const worktreeSegment = '--praxis-worktrees-';
211
212
  return entries
212
213
  .filter((entry) => targetKeys.some((targetKey) => entry.name === targetKey ||
213
214
  entry.name.startsWith(`${targetKey}${worktreeSegment}`)))
@@ -231,32 +232,18 @@ async function addExistingPath(items, configRoot, item) {
231
232
  items.push(item);
232
233
  }
233
234
  export async function planClaudeProjectPurge(options) {
235
+ void options.dataPlane;
234
236
  if (options.all && options.path !== undefined) {
235
237
  throw new Error('Cannot specify both a path and --all');
236
238
  }
237
239
  const configuredRoot = options.configRoot ??
238
- (process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude'));
240
+ (process.env.PRAXIS_HOME || join(homedir(), '.praxis'));
239
241
  const configRoot = await canonicalPath(configuredRoot);
240
- const dataPlane = options.dataPlane ?? 'claude';
241
- const homeDirectory = options.homeDirectory ?? homedir();
242
- const legacyClaudeStatePath = resolve(homeDirectory, '.claude.json');
243
- const legacyClaudeConfigRoot = await canonicalPath(resolve(homeDirectory, '.claude'));
244
- const defaultStatePath = dataPlane === 'native'
245
- ? join(configRoot, 'state.json')
246
- : options.configRoot !== undefined ||
247
- Boolean(process.env.CLAUDE_CONFIG_DIR)
248
- ? join(configRoot, '.claude.json')
249
- : legacyClaudeStatePath;
242
+ const defaultStatePath = join(configRoot, 'state.json');
250
243
  const statePath = resolve(options.statePath ?? defaultStatePath);
251
- const usesLegacyDefaultClaudeState = dataPlane === 'claude' &&
252
- !process.env.CLAUDE_CONFIG_DIR &&
253
- configRoot === legacyClaudeConfigRoot &&
254
- statePath === legacyClaudeStatePath;
255
244
  const canonicalStateParent = await canonicalPath(dirname(statePath));
256
- if (!usesLegacyDefaultClaudeState) {
257
- assertLexicallyContained(configRoot, join(canonicalStateParent, basename(statePath)));
258
- }
259
- await assertMutableRegularFile(statePath, usesLegacyDefaultClaudeState ? canonicalStateParent : configRoot);
245
+ assertLexicallyContained(configRoot, join(canonicalStateParent, basename(statePath)));
246
+ await assertMutableRegularFile(statePath, configRoot);
260
247
  const state = parseState(await readOptionalFile(statePath), statePath);
261
248
  const projects = stateProjects(state);
262
249
  const items = [];
@@ -264,30 +251,22 @@ export async function planClaudeProjectPurge(options) {
264
251
  const roots = [
265
252
  {
266
253
  kind: 'project',
267
- name: dataPlane === 'native' ? 'sessions' : 'projects',
268
- description: dataPlane === 'native'
269
- ? 'all project transcripts'
270
- : 'all project transcripts and memory',
254
+ name: 'sessions',
255
+ description: 'all project transcripts',
256
+ },
257
+ {
258
+ kind: 'memory',
259
+ name: 'memory',
260
+ description: 'all project memory',
261
+ },
262
+ {
263
+ kind: 'scheduled',
264
+ name: 'scheduled',
265
+ description: 'all project scheduled prompts',
271
266
  },
272
- ...(dataPlane === 'native'
273
- ? [
274
- {
275
- kind: 'memory',
276
- name: 'memory',
277
- description: 'all project memory',
278
- },
279
- {
280
- kind: 'scheduled',
281
- name: 'scheduled',
282
- description: 'all project scheduled prompts',
283
- },
284
- ]
285
- : []),
286
267
  {
287
268
  kind: 'memory',
288
- name: dataPlane === 'native'
289
- ? join('state', 'project-memory')
290
- : join('praxis', 'project-memory'),
269
+ name: join('state', 'project-memory'),
291
270
  description: 'all private Project-memory operational state',
292
271
  },
293
272
  {
@@ -330,9 +309,6 @@ export async function planClaudeProjectPurge(options) {
330
309
  mode: 'all',
331
310
  configRoot,
332
311
  statePath,
333
- ...(usesLegacyDefaultClaudeState
334
- ? { allowStateOutsideConfigRoot: true }
335
- : {}),
336
312
  projectRootPaths: [],
337
313
  sessionIds: [],
338
314
  items,
@@ -341,10 +317,8 @@ export async function planClaudeProjectPurge(options) {
341
317
  const requestedPath = resolve(options.path ?? options.cwd);
342
318
  const targetPath = await canonicalPath(requestedPath);
343
319
  const targetPaths = [...new Set([requestedPath, targetPath])];
344
- const projectIdentity = await resolveClaudeProjectIdentity({
345
- cwd: targetPath,
346
- });
347
- const projectRootPaths = await discoverProjectRoots(configRoot, targetPaths, dataPlane);
320
+ const projectIdentity = await resolveProjectIdentity(targetPath);
321
+ const projectRootPaths = await discoverProjectRoots(configRoot, targetPaths);
348
322
  const sessionIdSet = new Set();
349
323
  for (const projectRoot of projectRootPaths) {
350
324
  await assertSafePurgePath(configRoot, projectRoot);
@@ -359,26 +333,17 @@ export async function planClaudeProjectPurge(options) {
359
333
  await addExistingPath(items, configRoot, removePathItem('file-history', join(configRoot, 'file-history', sessionId), `file edit history for session ${sessionId}`));
360
334
  }
361
335
  const projectKeys = new Set([
362
- ...targetPaths.map(sanitizeClaudeProjectPath),
336
+ ...targetPaths.map(sanitizeProjectPath),
363
337
  ...projectRootPaths.map((path) => basename(path)),
364
- sanitizeClaudeProjectPath(projectIdentity),
338
+ sanitizeProjectPath(projectIdentity),
365
339
  ]);
366
- if (dataPlane === 'native') {
367
- for (const projectKey of projectKeys) {
368
- await addExistingPath(items, configRoot, removePathItem('memory', join(configRoot, 'memory', projectKey), `memory for project ${projectKey}`));
369
- await addExistingPath(items, configRoot, removePathItem('memory', join(configRoot, 'state', 'project-memory', projectKey), `private Project-memory state for project ${projectKey}`));
370
- await addExistingPath(items, configRoot, removePathItem('scheduled', join(configRoot, 'scheduled', `${projectKey}.json`), `scheduled prompts for project ${projectKey}`));
371
- }
372
- }
373
- else {
374
- for (const projectKey of projectKeys) {
375
- await addExistingPath(items, configRoot, removePathItem('memory', join(configRoot, 'praxis', 'project-memory', projectKey), `private Project-memory state for project ${projectKey}`));
376
- }
340
+ for (const projectKey of projectKeys) {
341
+ await addExistingPath(items, configRoot, removePathItem('memory', join(configRoot, 'memory', projectKey), `memory for project ${projectKey}`));
342
+ await addExistingPath(items, configRoot, removePathItem('memory', join(configRoot, 'state', 'project-memory', projectKey), `private Project-memory state for project ${projectKey}`));
343
+ await addExistingPath(items, configRoot, removePathItem('scheduled', join(configRoot, 'scheduled', `${projectKey}.json`), `scheduled prompts for project ${projectKey}`));
377
344
  }
378
345
  for (const projectRoot of projectRootPaths) {
379
- await addExistingPath(items, configRoot, removePathItem('project', projectRoot, dataPlane === 'native'
380
- ? 'project transcripts'
381
- : 'project transcripts and memory'));
346
+ await addExistingPath(items, configRoot, removePathItem('project', projectRoot, 'project transcripts'));
382
347
  }
383
348
  const historyPath = join(configRoot, 'history.jsonl');
384
349
  const historyExists = await pathExists(historyPath);
@@ -420,9 +385,6 @@ export async function planClaudeProjectPurge(options) {
420
385
  mode: 'project',
421
386
  configRoot,
422
387
  statePath,
423
- ...(usesLegacyDefaultClaudeState
424
- ? { allowStateOutsideConfigRoot: true }
425
- : {}),
426
388
  targetPath,
427
389
  projectIdentity,
428
390
  projectRootPaths,
@@ -1,6 +1,10 @@
1
1
  import type { ModelMessage, ModelToolCall, ToolExecutionResult } from '../core/runtime.js';
2
- import type { TranscriptMessagesEvent } from '../core/transcript-event.js';
3
- import type { NativeTranscriptStore } from '../persistence/native-transcript-store.js';
2
+ import type { TranscriptEvent, TranscriptMessagesEvent } from '../core/transcript-event.js';
3
+ import type { NativeTranscriptLease, NativeTranscriptLeaseResult } from '../persistence/native-transcript-store.js';
4
+ /** Minimal transcript-store contract required by the native session facade. */
5
+ export interface NativeSessionTranscriptStore {
6
+ withLease<T>(operation: (lease: NativeTranscriptLease) => Promise<T>): Promise<NativeTranscriptLeaseResult<T>>;
7
+ }
4
8
  export type NativeTranscriptActivation = {
5
9
  readonly kind: 'start';
6
10
  } | {
@@ -19,6 +23,11 @@ export interface NativeCompactionAppend {
19
23
  readonly postTokens: number;
20
24
  readonly durationMs: number;
21
25
  readonly preservedMessages?: readonly ModelMessage[];
26
+ /** Optional parent in the active branch when compacting a selected range. */
27
+ readonly logicalParentId?: string;
28
+ readonly direction?: 'from' | 'up_to';
29
+ readonly messagesSummarized?: number;
30
+ readonly preservePrefix?: boolean;
22
31
  }
23
32
  export type NativeInterruption = {
24
33
  readonly kind: 'complete' | 'none';
@@ -35,6 +44,8 @@ export type NativeInterruption = {
35
44
  readonly callIds: readonly string[];
36
45
  };
37
46
  export interface NativeSessionTranscriptLease {
47
+ /** Events on the currently selected active branch, in parent order. */
48
+ activeEvents(): TranscriptEvent[];
38
49
  activeMessages(): ModelMessage[];
39
50
  interruption(): NativeInterruption;
40
51
  beginToolExecution(callId: string): Promise<void>;
@@ -56,7 +67,7 @@ export interface NativeForkOptions {
56
67
  }
57
68
  export interface NativeSessionTranscriptOptions {
58
69
  readonly sessionId: string;
59
- readonly store: NativeTranscriptStore;
70
+ readonly store: NativeSessionTranscriptStore;
60
71
  readonly createId?: () => string;
61
72
  readonly now?: () => string;
62
73
  }
@@ -83,6 +83,14 @@ export class NativeSessionTranscript {
83
83
  const initial = prepared;
84
84
  const currentId = selectedId ?? initial.records.at(-1)?.event.id ?? null;
85
85
  const records = [...initial.records];
86
+ const usedIds = new Set(records.map((record) => record.event.id));
87
+ const createUniqueId = () => {
88
+ let id = this.createId();
89
+ while (usedIds.has(id))
90
+ id = this.createId();
91
+ usedIds.add(id);
92
+ return id;
93
+ };
86
94
  let tail = currentId === null
87
95
  ? initial.tail
88
96
  : { ...initial.tail, branchParentId: currentId };
@@ -94,6 +102,7 @@ export class NativeSessionTranscript {
94
102
  return result;
95
103
  };
96
104
  const lease = {
105
+ activeEvents: () => activeEvents(records.map((record) => record.event), activeId ?? undefined).slice(),
97
106
  activeMessages: () => projectActiveMessages(records.map((record) => record.event), activeId ?? undefined).slice(),
98
107
  interruption: () => {
99
108
  const events = activeEvents(records.map((record) => record.event), activeId ?? undefined);
@@ -166,7 +175,7 @@ export class NativeSessionTranscript {
166
175
  throw new Error(`Native tool call already claimed: ${callId}`);
167
176
  const event = {
168
177
  kind: 'tool-execution-started',
169
- id: this.createId(),
178
+ id: createUniqueId(),
170
179
  parentId: activeId,
171
180
  sessionId: this.sessionId,
172
181
  timestamp: this.now(),
@@ -196,7 +205,7 @@ export class NativeSessionTranscript {
196
205
  throw new Error(`Native tool call is already resolved: ${callId}`);
197
206
  const event = {
198
207
  kind: 'messages',
199
- id: this.createId(),
208
+ id: createUniqueId(),
200
209
  parentId: activeId,
201
210
  sessionId: this.sessionId,
202
211
  timestamp: this.now(),
@@ -232,7 +241,7 @@ export class NativeSessionTranscript {
232
241
  throw new Error('native transcript cannot append empty messages');
233
242
  const event = {
234
243
  kind: 'messages',
235
- id: this.createId(),
244
+ id: createUniqueId(),
236
245
  parentId: activeId,
237
246
  sessionId: this.sessionId,
238
247
  timestamp: this.now(),
@@ -266,19 +275,28 @@ export class NativeSessionTranscript {
266
275
  const events = records.map((record) => record.event);
267
276
  if (unresolvedActiveToolCallIds(projectActiveMessages(events, activeId)).length > 0)
268
277
  throw new Error('Cannot compact a native transcript with unresolved tool calls');
269
- const boundaryId = this.createId();
270
- const summaryId = this.createId();
278
+ const boundaryId = createUniqueId();
279
+ const summaryId = createUniqueId();
271
280
  const boundary = {
272
281
  kind: 'context-boundary',
273
282
  id: boundaryId,
274
283
  parentId: null,
275
284
  sessionId: this.sessionId,
276
285
  timestamp: this.now(),
277
- logicalParentId: activeId,
286
+ logicalParentId: input.logicalParentId ?? activeId,
278
287
  trigger: input.trigger,
279
288
  preTokens: input.preTokens,
280
289
  postTokens: input.postTokens,
281
290
  durationMs: input.durationMs,
291
+ ...(input.direction === undefined
292
+ ? {}
293
+ : { direction: input.direction }),
294
+ ...(input.messagesSummarized === undefined
295
+ ? {}
296
+ : { messagesSummarized: input.messagesSummarized }),
297
+ ...(input.preservePrefix === undefined
298
+ ? {}
299
+ : { preservePrefix: input.preservePrefix }),
282
300
  };
283
301
  const summary = {
284
302
  kind: 'context-summary',
@@ -294,9 +312,12 @@ export class NativeSessionTranscript {
294
312
  if (message.role !== 'assistant')
295
313
  continue;
296
314
  for (const call of message.toolCalls ?? [])
297
- replayToolCallIds.set(call.id, this.createId());
315
+ replayToolCallIds.set(call.id, createUniqueId());
298
316
  }
299
- const replaySuffix = suffix.map((message) => {
317
+ const replaySuffix = suffix
318
+ .filter((message) => message.role !== 'tool' ||
319
+ replayToolCallIds.has(message.toolCallId))
320
+ .map((message) => {
300
321
  if (message.role === 'assistant')
301
322
  return {
302
323
  ...message,
@@ -320,7 +341,7 @@ export class NativeSessionTranscript {
320
341
  const suffixEvent = replaySuffix.length
321
342
  ? {
322
343
  kind: 'messages',
323
- id: this.createId(),
344
+ id: createUniqueId(),
324
345
  parentId: summaryId,
325
346
  sessionId: this.sessionId,
326
347
  timestamp: this.now(),
@@ -1,4 +1,4 @@
1
- import { type ClaudeScheduledTask } from '../persistence/claude-scheduled-task-store.js';
1
+ import { type NativeScheduledTask } from '../persistence/native-scheduled-task-store.js';
2
2
  export declare const MAX_JOBS = 50;
3
3
  export declare class ScheduledJobLimitError extends Error {
4
4
  readonly maxJobs: number;
@@ -24,7 +24,7 @@ export interface ScheduledPrompt {
24
24
  id: string;
25
25
  prompt: string;
26
26
  }
27
- export interface ListedScheduledPrompt extends ClaudeScheduledTask {
27
+ export interface ListedScheduledPrompt extends NativeScheduledTask {
28
28
  durable: boolean;
29
29
  }
30
30
  export interface DynamicWakeupResult {
@@ -2,7 +2,7 @@ import { execFile } from 'node:child_process';
2
2
  import { randomBytes } from 'node:crypto';
3
3
  import { promisify } from 'node:util';
4
4
  import { CronExpressionParser } from 'cron-parser';
5
- import { ClaudeScheduledTaskLimitError, ClaudeScheduledTaskStore, } from '../persistence/claude-scheduled-task-store.js';
5
+ import { NativeScheduledTaskLimitError, NativeScheduledTaskStore, } from '../persistence/native-scheduled-task-store.js';
6
6
  const execFileAsync = promisify(execFile);
7
7
  const RECURRING_LIFETIME_MS = 7 * 24 * 60 * 60 * 1_000;
8
8
  const MIN_DYNAMIC_WAKEUP_SECONDS = 60;
@@ -111,7 +111,7 @@ export class ScheduledPromptManager {
111
111
  initialization;
112
112
  closed = false;
113
113
  constructor(options) {
114
- this.store = new ClaudeScheduledTaskStore({
114
+ this.store = new NativeScheduledTaskStore({
115
115
  filePath: options.filePath,
116
116
  lockFile: options.lockFile,
117
117
  });
@@ -145,7 +145,7 @@ export class ScheduledPromptManager {
145
145
  task = await this.store.create(base, { maxJobs: MAX_JOBS });
146
146
  }
147
147
  catch (error) {
148
- if (error instanceof ClaudeScheduledTaskLimitError) {
148
+ if (error instanceof NativeScheduledTaskLimitError) {
149
149
  throw new ScheduledJobLimitError(MAX_JOBS);
150
150
  }
151
151
  throw error;
@@ -34,11 +34,8 @@ export interface SessionMemoryStoreOptions {
34
34
  sidecarRoot?: string;
35
35
  }
36
36
  /**
37
- * Durable sidecar for one session's extracted memory. Claude compatibility
38
- * defaults to `<configRoot>/praxis/session-memory/<sessionId>/`; callers may
39
- * select another data plane with
40
- * `<sidecarRoot>/session-memory/<sessionId>/` (for example, native
41
- * `<configRoot>/state/session-memory/<sessionId>/`). All writes are atomic
37
+ * Durable sidecar for one session's extracted memory. Native callers place it
38
+ * under `<configRoot>/state/session-memory/<sessionId>/`. All writes are atomic
42
39
  * (same-directory temp file, fsync, then rename) and version-checked. Never
43
40
  * touches shared Claude transcript entries.
44
41
  */