@with-logic/elwood 0.1.1 → 0.1.2

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 (118) hide show
  1. package/CHANGELOG.md +17 -3
  2. package/CONTRIBUTING.md +104 -0
  3. package/README.md +23 -17
  4. package/SECURITY.md +42 -0
  5. package/dist/claude/model-picker.d.ts.map +1 -1
  6. package/dist/claude/model-picker.js +4 -3
  7. package/dist/claude/model-picker.js.map +1 -1
  8. package/dist/claude/model-switch-confirmation.js +9 -1
  9. package/dist/claude/model-switch-confirmation.js.map +1 -1
  10. package/dist/claude/screen-table.js +1 -1
  11. package/dist/claude/screen-table.js.map +1 -1
  12. package/dist/claude/session/build.d.ts.map +1 -1
  13. package/dist/claude/session/build.js +3 -0
  14. package/dist/claude/session/build.js.map +1 -1
  15. package/dist/claude/session/start-or-resume.js +1 -0
  16. package/dist/claude/session/start-or-resume.js.map +1 -1
  17. package/dist/cli/interactive/spawn.d.ts.map +1 -1
  18. package/dist/cli/interactive/spawn.js +30 -9
  19. package/dist/cli/interactive/spawn.js.map +1 -1
  20. package/dist/cli/models/index.d.ts.map +1 -1
  21. package/dist/cli/models/index.js +6 -3
  22. package/dist/cli/models/index.js.map +1 -1
  23. package/dist/cli/request/layers.d.ts +2 -0
  24. package/dist/cli/request/layers.d.ts.map +1 -1
  25. package/dist/cli/request/layers.js +9 -5
  26. package/dist/cli/request/layers.js.map +1 -1
  27. package/dist/cli/sessions/index.d.ts +9 -2
  28. package/dist/cli/sessions/index.d.ts.map +1 -1
  29. package/dist/cli/sessions/index.js +2 -6
  30. package/dist/cli/sessions/index.js.map +1 -1
  31. package/dist/cli/sessions/settings.d.ts +11 -0
  32. package/dist/cli/sessions/settings.d.ts.map +1 -0
  33. package/dist/cli/sessions/settings.js +26 -0
  34. package/dist/cli/sessions/settings.js.map +1 -0
  35. package/dist/codex/model-picker.d.ts.map +1 -1
  36. package/dist/codex/model-picker.js +3 -2
  37. package/dist/codex/model-picker.js.map +1 -1
  38. package/dist/codex/session/build.d.ts.map +1 -1
  39. package/dist/codex/session/build.js +5 -7
  40. package/dist/codex/session/build.js.map +1 -1
  41. package/dist/codex/session/start-or-resume.js +1 -0
  42. package/dist/codex/session/start-or-resume.js.map +1 -1
  43. package/dist/core/input/index.d.ts.map +1 -1
  44. package/dist/core/input/index.js +15 -3
  45. package/dist/core/input/index.js.map +1 -1
  46. package/dist/core/models/input.d.ts +3 -0
  47. package/dist/core/models/input.d.ts.map +1 -0
  48. package/dist/core/models/input.js +9 -0
  49. package/dist/core/models/input.js.map +1 -0
  50. package/dist/core/models/picker.d.ts +2 -1
  51. package/dist/core/models/picker.d.ts.map +1 -1
  52. package/dist/core/models/picker.js +6 -5
  53. package/dist/core/models/picker.js.map +1 -1
  54. package/dist/core/models/tui-screen.d.ts +1 -1
  55. package/dist/core/models/tui-screen.d.ts.map +1 -1
  56. package/dist/core/models/tui-screen.js +26 -3
  57. package/dist/core/models/tui-screen.js.map +1 -1
  58. package/dist/runtime/session/base.d.ts.map +1 -1
  59. package/dist/runtime/session/base.js +4 -1
  60. package/dist/runtime/session/base.js.map +1 -1
  61. package/dist/runtime/session/commands.d.ts +2 -1
  62. package/dist/runtime/session/commands.d.ts.map +1 -1
  63. package/dist/runtime/session/commands.js +10 -4
  64. package/dist/runtime/session/commands.js.map +1 -1
  65. package/dist/runtime/session/lifecycle.d.ts +3 -4
  66. package/dist/runtime/session/lifecycle.d.ts.map +1 -1
  67. package/dist/runtime/session/lifecycle.js +6 -5
  68. package/dist/runtime/session/lifecycle.js.map +1 -1
  69. package/dist/state/directories.d.ts +4 -0
  70. package/dist/state/directories.d.ts.map +1 -0
  71. package/dist/state/directories.js +41 -0
  72. package/dist/state/directories.js.map +1 -0
  73. package/dist/state/files.d.ts.map +1 -1
  74. package/dist/state/files.js +25 -11
  75. package/dist/state/files.js.map +1 -1
  76. package/dist/state/private-session.d.ts.map +1 -1
  77. package/dist/state/private-session.js +2 -0
  78. package/dist/state/private-session.js.map +1 -1
  79. package/dist/state/store.d.ts.map +1 -1
  80. package/dist/state/store.js +7 -1
  81. package/dist/state/store.js.map +1 -1
  82. package/docs/cli-behavior.md +1 -1
  83. package/docs/codex/cli.md +57 -0
  84. package/docs/codex/config.md +47 -0
  85. package/docs/codex/hooks.md +70 -0
  86. package/examples/README.md +56 -0
  87. package/examples/full.ts +113 -0
  88. package/examples/minimal.ts +15 -0
  89. package/examples/stream.ts +39 -0
  90. package/examples/support.ts +71 -0
  91. package/package.json +10 -5
  92. package/prd/01-overview.md +21 -0
  93. package/prd/02-goals.md +47 -0
  94. package/prd/03-terminology.md +32 -0
  95. package/prd/04-architecture.md +121 -0
  96. package/prd/05-api/5.1-starting-claude.md +108 -0
  97. package/prd/05-api/5.2-resuming-claude.md +86 -0
  98. package/prd/05-api/5.3-claude-session-api.md +658 -0
  99. package/prd/05-api/5.4-events.md +145 -0
  100. package/prd/05-api/5.5-starting-codex.md +106 -0
  101. package/prd/05-api/5.6-resuming-codex.md +48 -0
  102. package/prd/05-api/5.7-codex-session-api.md +425 -0
  103. package/prd/05-api/5.8-session-api.md +122 -0
  104. package/prd/05-api/5.9-loops.md +170 -0
  105. package/prd/05-api/README.md +19 -0
  106. package/prd/06-claude-hook-bridge.md +164 -0
  107. package/prd/07-claude-policy.md +15 -0
  108. package/prd/07a-codex-hook-bridge.md +76 -0
  109. package/prd/08-state.md +127 -0
  110. package/prd/09-lifecycle.md +222 -0
  111. package/prd/10-errors.md +55 -0
  112. package/prd/11-test-app.md +53 -0
  113. package/prd/12-e2e.md +23 -0
  114. package/prd/12a-cli.md +375 -0
  115. package/prd/13-latitude.md +12 -0
  116. package/prd/14-conformance.md +333 -0
  117. package/prd/15-open-notes.md +8 -0
  118. package/prd/README.md +45 -0
@@ -0,0 +1,86 @@
1
+ ## 5.2 Resuming Claude
2
+
3
+ ```ts
4
+ type ResumeClaudeOptions = {
5
+ readonly elwoodSessionId: string;
6
+ readonly cwd?: string;
7
+ readonly stateDir?: string;
8
+ readonly hooks?: ClaudeHookHandlers;
9
+ readonly initialSize?: TerminalSize;
10
+ readonly reasoningEffort?: ClaudeReasoningEffort;
11
+ readonly permissionMode?: ClaudePermissionMode;
12
+ readonly allowedTools?: readonly ClaudeToolRule[];
13
+ readonly disallowedTools?: readonly ClaudeToolRule[];
14
+ readonly tools?: readonly ClaudeToolRule[];
15
+ readonly highTrust?: boolean;
16
+ readonly autoupdate?: boolean;
17
+ readonly autotrust?: boolean;
18
+ readonly hookTimeoutMs?: number;
19
+ readonly strictVersionCheck?: boolean;
20
+ };
21
+
22
+ declare function resumeClaude(options: ResumeClaudeOptions): Promise<ClaudeSessionApi>;
23
+ ```
24
+
25
+ Resume uses Elwood's minimal persisted session record (§8.2) to relaunch or
26
+ reattach the wrapped Claude session through Claude Code's own resume mechanism. Callers should
27
+ not need Claude's session ID. Because the default state store is project-local,
28
+ callers that resume from a different process working directory must pass the
29
+ original `cwd` or the explicit `stateDir` used at start time. Calling
30
+ `resumeClaude({ elwoodSessionId })` without `cwd` or `stateDir` uses the current
31
+ process working directory to discover the project-local state store.
32
+
33
+ `resumeClaude` must verify that the persisted Elwood session record belongs to
34
+ the Claude adapter before launching. Passing a Codex session ID to `resumeClaude`
35
+ must fail with a typed error instead of launching a Claude process.
36
+ If Elwood has not observed and persisted Claude Code's internal session id from
37
+ `SessionStart`, `resumeClaude` must fail explicitly with `resume_unavailable`.
38
+ It must not silently launch a fresh Claude conversation under the same Elwood
39
+ session ID.
40
+
41
+ Decision note: MVP resume re-establishes the Elwood wrapper, hook routing, and the
42
+ agent's internal conversation resume id. It does NOT restore a persisted terminal
43
+ size — that is not persisted (§8.2); the caller passes
44
+ `initialSize` on resume (it otherwise falls back to the default). The launch
45
+ posture (privilege and tool policy) is persisted in the session record at
46
+ start, and resume defaults to it: a bare `resumeClaude` relaunches with the
47
+ same `permissionMode`, `allowedTools`, `disallowedTools`, and `tools` the
48
+ session started with, so tool restrictions cannot silently loosen across a
49
+ resume. Explicit resume options override the persisted posture field by
50
+ field, and the effective posture is re-persisted. Other adapter launch policy
51
+ such as model, reasoning effort, and caller config overrides remains
52
+ caller-supplied-per-call and is intentionally not persisted yet — a resumed
53
+ session that wants a non-default reasoning effort must re-supply `reasoningEffort`,
54
+ exactly as it must re-supply `model`. `highTrust: true` on resume expands to the
55
+ same explicit `permissionMode: "bypassPermissions"` override as on start (and
56
+ conflicts with an explicit `permissionMode` the same way); a bare resume keeps
57
+ the persisted posture, including one that a high-trust start persisted.
58
+
59
+ Because every persisting parent writes the same try-resume-else-start dance,
60
+ Elwood provides it directly:
61
+
62
+ ```ts
63
+ type StartOrResumeClaudeOptions = StartClaudeOptions & {
64
+ readonly elwoodSessionId?: string;
65
+ };
66
+
67
+ declare function startOrResumeClaude(
68
+ options: StartOrResumeClaudeOptions,
69
+ ): Promise<{ readonly session: ClaudeSessionApi; readonly resumed: boolean }>;
70
+ ```
71
+
72
+ When `elwoodSessionId` is set, `startOrResumeClaude` attempts a resume,
73
+ forwarding every start option the resume entry point accepts: `cwd`,
74
+ `stateDir`, `hooks`, `initialSize`, `reasoningEffort`, `permissionMode`,
75
+ `allowedTools`, `disallowedTools`, `tools`, `autoupdate`, `autotrust`,
76
+ `highTrust`, `hookTimeoutMs`, and `strictVersionCheck` (for Codex: the same shared options
77
+ plus `sandbox` and `approvalPolicy`). Non-persisted per-call policy such as
78
+ `reasoningEffort` therefore reaches a resumed session exactly as it reaches a
79
+ fresh one. It falls back to a fresh `startClaude` only for the
80
+ error names that mean "no resumable session": `state_not_found`,
81
+ `resume_unavailable`, and `adapter_mismatch`. Every other error — including
82
+ `state_corrupt` — is a real failure and is rethrown, so data problems are
83
+ never silently papered over by a fresh session. The result reports which path
84
+ ran so callers can re-persist a new `elwoodSessionId` after a fallback.
85
+ `startOrResumeCodex` behaves identically for Codex. `persona` follows its
86
+ normal rules: delivered on a fresh start, never re-sent on resume.