@try-works/dsh-recursive-mode 0.1.9 → 0.1.10

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.
@@ -42,5 +42,23 @@ export declare function RecursiveLauncherGate({ useSessions }: {
42
42
  useSessions: SnapshotSelectorHook<SessionListStateLike>;
43
43
  }): ReactNode;
44
44
  export declare function registerSlots(ctx: ClientContext): () => void;
45
+ /**
46
+ * Board overlay: subscribes to the shared board store, gates on open + recursive
47
+ * preset, and swaps board <-> inspector (run 08 R1/R3).
48
+ *
49
+ * Run 10: consumes the full SessionListStateLike through the identity selector
50
+ * (useSessions((s) => s)); no fake {list:{getSnapshot}} wrapper.
51
+ */
52
+ export declare function RecursiveBoardOverlay({ useSessions }: {
53
+ useSessions: SnapshotSelectorHook<SessionListStateLike>;
54
+ }): ReactNode;
55
+ /**
56
+ * Strip gate: same preset gate, session-scoped sessionId; the strip renders
57
+ * nothing for a non-recursive session. Run 10: useSessions((s) => s) selector.
58
+ */
59
+ export declare function RecursiveStripGate({ useSessions, sessionId }: {
60
+ useSessions: SnapshotSelectorHook<SessionListStateLike>;
61
+ sessionId?: string;
62
+ }): ReactNode;
45
63
  /** Export the gate helpers for tests. */
46
64
  export { isRecursivePreset, currentSessionCwd };
package/lib/client.js CHANGED
@@ -844,12 +844,12 @@ window.__ModuleLoader__.load({
844
844
  const board = useBoardState();
845
845
  const list = useRecursiveSessions(useSessions);
846
846
  const content = overlayContent(board, list);
847
- if (content === "hidden") return null;
848
847
  const cwd = currentSessionCwd(list);
849
848
  const snapshot = useLiveProjection({
850
849
  sessionId: list.current,
851
850
  cwd
852
851
  });
852
+ if (content === "hidden") return null;
853
853
  if (content === "inspector" && board.selection !== null) return (0, react.createElement)(Inspector, {
854
854
  runId: board.selection.runId,
855
855
  worktreeRoot: board.selection.worktreeRoot,
@@ -869,11 +869,11 @@ window.__ModuleLoader__.load({
869
869
  */
870
870
  function RecursiveStripGate({ useSessions, sessionId }) {
871
871
  const list = useRecursiveSessions(useSessions);
872
- if (!isRecursivePreset(list)) return null;
873
872
  const snapshot = useLiveProjection({
874
873
  sessionId,
875
874
  cwd: currentSessionCwd(list)
876
875
  });
876
+ if (!isRecursivePreset(list)) return null;
877
877
  return (0, react.createElement)(StatusStrip, { snapshot });
878
878
  }
879
879
  //#endregion
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@try-works/dsh-recursive-mode",
3
3
  "description": "recursive-mode workflow as a DeepSeek Harness bundle: RecursiveRuntime service + recursive_status tool",
4
- "version": "0.1.9",
4
+ "version": "0.1.10",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
@@ -45,10 +45,10 @@
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@deepseek-ai/cordis": "^4.0.1",
48
- "@deepseek-ai/dsh-tools": "0.1.0-rc.5",
49
- "@deepseek-ai/dsh-system-prompt": "0.1.0-rc.5",
50
- "@deepseek-ai/dsh-session-projection": "0.1.0-rc.5",
51
48
  "@deepseek-ai/dsh-session": "0.1.0-rc.5",
49
+ "@deepseek-ai/dsh-session-projection": "0.1.0-rc.5",
50
+ "@deepseek-ai/dsh-system-prompt": "0.1.0-rc.5",
51
+ "@deepseek-ai/dsh-tools": "0.1.0-rc.5",
52
52
  "react": "^18.2.0"
53
53
  },
54
54
  "devDependencies": {
@@ -71,7 +71,9 @@
71
71
  "@types/node": "^20.0.0",
72
72
  "@types/react": "^18.2.0",
73
73
  "@types/react-dom": "^18.2.0",
74
+ "@types/react-test-renderer": "18.3.0",
74
75
  "react": "^18.2.0",
76
+ "react-test-renderer": "18.3.1",
75
77
  "tsdown": "^0.22.2",
76
78
  "tsx": "^4.19.0",
77
79
  "typescript": "^5.6.0",
@@ -129,14 +129,17 @@ export function registerSlots(ctx: ClientContext): () => void {
129
129
  * Run 10: consumes the full SessionListStateLike through the identity selector
130
130
  * (useSessions((s) => s)); no fake {list:{getSnapshot}} wrapper.
131
131
  */
132
- function RecursiveBoardOverlay({ useSessions }: { useSessions: SnapshotSelectorHook<SessionListStateLike> }): ReactNode {
132
+ export function RecursiveBoardOverlay({ useSessions }: { useSessions: SnapshotSelectorHook<SessionListStateLike> }): ReactNode {
133
133
  const board = useBoardState()
134
134
  const list = useRecursiveSessions(useSessions)
135
135
  const content = overlayContent(board, list)
136
- if (content === 'hidden') return null
137
136
  const cwd = currentSessionCwd(list)
138
137
  const scope = { sessionId: list.current, cwd }
138
+ // Run 13 (LIVE BUG): ALWAYS call useLiveProjection — a conditional hook (after the
139
+ // hidden early return) changed the hook count across renders and threw
140
+ // 'Rendered more hooks than during the previous render'.
139
141
  const snapshot = useLiveProjection(scope)
142
+ if (content === 'hidden') return null
140
143
  if (content === 'inspector' && board.selection !== null) {
141
144
  return createElement(Inspector, {
142
145
  runId: board.selection.runId,
@@ -153,12 +156,13 @@ function RecursiveBoardOverlay({ useSessions }: { useSessions: SnapshotSelectorH
153
156
  * Strip gate: same preset gate, session-scoped sessionId; the strip renders
154
157
  * nothing for a non-recursive session. Run 10: useSessions((s) => s) selector.
155
158
  */
156
- function RecursiveStripGate({ useSessions, sessionId }: { useSessions: SnapshotSelectorHook<SessionListStateLike>; sessionId?: string }): ReactNode {
159
+ export function RecursiveStripGate({ useSessions, sessionId }: { useSessions: SnapshotSelectorHook<SessionListStateLike>; sessionId?: string }): ReactNode {
157
160
  const list = useRecursiveSessions(useSessions)
158
- if (!isRecursivePreset(list)) return null
159
161
  const cwd = currentSessionCwd(list)
160
162
  const scope = { sessionId, cwd }
163
+ // Run 13: ALWAYS call useLiveProjection BEFORE the preset early return.
161
164
  const snapshot = useLiveProjection(scope)
165
+ if (!isRecursivePreset(list)) return null
162
166
  return createElement(StatusStrip, { snapshot })
163
167
  }
164
168