@shipfox/api-logs 9.3.0 → 10.1.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 (52) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +35 -0
  3. package/dist/core/append-logs.d.ts.map +1 -1
  4. package/dist/core/append-logs.js +100 -12
  5. package/dist/core/append-logs.js.map +1 -1
  6. package/dist/core/close-stream.d.ts +6 -5
  7. package/dist/core/close-stream.d.ts.map +1 -1
  8. package/dist/core/close-stream.js +25 -7
  9. package/dist/core/close-stream.js.map +1 -1
  10. package/dist/core/entities/attempt-stream.d.ts +5 -0
  11. package/dist/core/entities/attempt-stream.d.ts.map +1 -1
  12. package/dist/core/entities/attempt-stream.js +1 -1
  13. package/dist/core/entities/attempt-stream.js.map +1 -1
  14. package/dist/core/session/claude/rows.d.ts +4 -2
  15. package/dist/core/session/claude/rows.d.ts.map +1 -1
  16. package/dist/core/session/claude/rows.js +137 -10
  17. package/dist/core/session/claude/rows.js.map +1 -1
  18. package/dist/core/session/claude-parser.d.ts +8 -1
  19. package/dist/core/session/claude-parser.d.ts.map +1 -1
  20. package/dist/core/session/claude-parser.js +30 -4
  21. package/dist/core/session/claude-parser.js.map +1 -1
  22. package/dist/core/session/parse-session.d.ts +6 -1
  23. package/dist/core/session/parse-session.d.ts.map +1 -1
  24. package/dist/core/session/parse-session.js +2 -2
  25. package/dist/core/session/parse-session.js.map +1 -1
  26. package/dist/db/db.d.ts +94 -0
  27. package/dist/db/db.d.ts.map +1 -1
  28. package/dist/db/schema/attempt-streams.d.ts +94 -0
  29. package/dist/db/schema/attempt-streams.d.ts.map +1 -1
  30. package/dist/db/schema/attempt-streams.js +9 -1
  31. package/dist/db/schema/attempt-streams.js.map +1 -1
  32. package/dist/db/streams.d.ts +17 -6
  33. package/dist/db/streams.d.ts.map +1 -1
  34. package/dist/db/streams.js +21 -6
  35. package/dist/db/streams.js.map +1 -1
  36. package/dist/tsconfig.test.tsbuildinfo +1 -1
  37. package/drizzle/0001_strong_major_mapleleaf.sql +4 -0
  38. package/drizzle/meta/0001_snapshot.json +555 -0
  39. package/drizzle/meta/_journal.json +7 -0
  40. package/package.json +5 -5
  41. package/src/core/append-logs.test.ts +144 -4
  42. package/src/core/append-logs.ts +158 -6
  43. package/src/core/close-stream.ts +26 -7
  44. package/src/core/entities/attempt-stream.ts +6 -0
  45. package/src/core/finalize-attempt-stream.test.ts +57 -0
  46. package/src/core/session/claude/rows.ts +176 -7
  47. package/src/core/session/claude-parser.test.ts +279 -2
  48. package/src/core/session/claude-parser.ts +55 -4
  49. package/src/core/session/parse-session.ts +10 -1
  50. package/src/db/schema/attempt-streams.ts +10 -0
  51. package/src/db/streams.ts +43 -7
  52. package/tsconfig.build.tsbuildinfo +1 -1
package/src/db/streams.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type {SessionViewLifecycleRow} from '@shipfox/api-logs-dto';
1
2
  import {and, asc, eq, getTableColumns, isNull, lt, notInArray, sql} from 'drizzle-orm';
2
3
  import type {AttemptStream, StreamCloseReason} from '#core/entities/attempt-stream.js';
3
4
  import {LeaseStreamMismatchError} from '#core/errors.js';
@@ -160,17 +161,46 @@ export async function setDeclaredTotalBytes(
160
161
  .where(eq(attemptStreams.id, params.streamId));
161
162
  }
162
163
 
164
+ export async function setClaudeParseContext(
165
+ tx: Transaction,
166
+ params: {
167
+ streamId: string;
168
+ hasInit: boolean;
169
+ sessionId: string | null;
170
+ turn: number;
171
+ pendingResult: SessionViewLifecycleRow | null;
172
+ },
173
+ ): Promise<void> {
174
+ await tx
175
+ .update(attemptStreams)
176
+ .set({
177
+ claudeHasInit: params.hasInit,
178
+ claudeSessionId: params.sessionId,
179
+ claudeTurn: params.turn,
180
+ claudePendingResult: params.pendingResult,
181
+ updatedAt: sql`now()`,
182
+ })
183
+ .where(eq(attemptStreams.id, params.streamId));
184
+ }
185
+
163
186
  /**
164
- * Guarded close: flips `open → closed` and stamps `closed_at` iff the stream is
165
- * still open, returning the closed row (or null when another path already closed
166
- * it). The `WHERE state='open'` predicate is both the row lock and the
167
- * exactly-once gate. `committed_length` is left untouched; it stays equal to the
168
- * runner spool bytes. `truncated` is set only on the timeout path.
187
+ * Guarded close: locks the open row, flips `open → closed`, clears any pending Claude result,
188
+ * and stamps `closed_at`. The pending result is returned separately so the caller can
189
+ * materialize it before publishing the close event. Returns null when another path already
190
+ * closed the stream. `committed_length` is left untouched; it stays equal to the runner spool
191
+ * bytes. `truncated` is set only on the timeout path.
169
192
  */
170
193
  export async function markStreamClosed(
171
194
  tx: Transaction,
172
195
  params: {streamId: string; reason: StreamCloseReason; markTruncated: boolean},
173
- ): Promise<AttemptStream | null> {
196
+ ): Promise<{stream: AttemptStream; pendingClaudeResult: SessionViewLifecycleRow | null} | null> {
197
+ const [open] = await tx
198
+ .select()
199
+ .from(attemptStreams)
200
+ .where(and(eq(attemptStreams.id, params.streamId), eq(attemptStreams.state, 'open')))
201
+ .for('update');
202
+ if (!open) return null;
203
+
174
204
  const [row] = await tx
175
205
  .update(attemptStreams)
176
206
  .set({
@@ -178,12 +208,18 @@ export async function markStreamClosed(
178
208
  closeReason: params.reason,
179
209
  closedAt: sql`now()`,
180
210
  updatedAt: sql`now()`,
211
+ claudePendingResult: null,
181
212
  ...(params.markTruncated ? {truncated: true} : {}),
182
213
  })
183
214
  .where(and(eq(attemptStreams.id, params.streamId), eq(attemptStreams.state, 'open')))
184
215
  .returning();
185
216
 
186
- return row ? toAttemptStream(row) : null;
217
+ return row
218
+ ? {
219
+ stream: toAttemptStream(row),
220
+ pendingClaudeResult: open.claudePendingResult ?? null,
221
+ }
222
+ : null;
187
223
  }
188
224
 
189
225
  /** Open streams of a job, for the timeout sweep to force-close after the grace period. */