deepline 0.1.311 → 0.1.313

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.
@@ -157,7 +157,7 @@ export const SDK_RELEASE = {
157
157
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
158
158
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
159
159
  // Operators use the checkout-local deepline-admin binary instead.
160
- version: '0.1.311',
160
+ version: '0.1.313',
161
161
  contracts: {
162
162
  api: {
163
163
  name: 'sdk-http-api',
@@ -1291,6 +1291,25 @@ function createPacingResolver(
1291
1291
  export class PlayContextImpl {
1292
1292
  private rowStates = new Map<number, RowState>();
1293
1293
  private toolCallQueue: ToolCallRequest[] = [];
1294
+ /**
1295
+ * Direct durable boundaries (including ctx.fetch) arrive independently from
1296
+ * concurrent map rows. Hold one microtask's worth so they can use the bulk
1297
+ * receipt gateway instead of serial remote claim requests.
1298
+ */
1299
+ private pendingRuntimeReceiptClaims = new Map<
1300
+ string,
1301
+ {
1302
+ scheduled: boolean;
1303
+ requests: Array<{
1304
+ key: string;
1305
+ reclaimRunning: boolean;
1306
+ forceRefresh: boolean;
1307
+ forceFailedRefresh: boolean;
1308
+ resolve: (receipt: RuntimeStepReceipt | null) => void;
1309
+ reject: (error: unknown) => void;
1310
+ }>;
1311
+ }
1312
+ >();
1294
1313
  /**
1295
1314
  * Fixed, non-resetting coalescing deadlines for ready scheduling lanes. A
1296
1315
  * deadline starts when the first request enters an empty batch bucket. New
@@ -2002,6 +2021,14 @@ export class PlayContextImpl {
2002
2021
  forceRefresh = false,
2003
2022
  forceFailedRefresh = false,
2004
2023
  ): Promise<RuntimeStepReceipt | null> {
2024
+ if (this.#options.claimRuntimeStepReceipts) {
2025
+ return await this.enqueueRuntimeStepReceiptClaim({
2026
+ key,
2027
+ reclaimRunning,
2028
+ forceRefresh,
2029
+ forceFailedRefresh,
2030
+ });
2031
+ }
2005
2032
  if (!this.#options.claimRuntimeStepReceipt) {
2006
2033
  return null;
2007
2034
  }
@@ -2025,6 +2052,71 @@ export class PlayContextImpl {
2025
2052
  };
2026
2053
  }
2027
2054
 
2055
+ private async enqueueRuntimeStepReceiptClaim(input: {
2056
+ key: string;
2057
+ reclaimRunning: boolean;
2058
+ forceRefresh: boolean;
2059
+ forceFailedRefresh: boolean;
2060
+ }): Promise<RuntimeStepReceipt | null> {
2061
+ const batchKey = [
2062
+ input.reclaimRunning ? 'reclaim' : 'ordinary',
2063
+ input.forceRefresh ? 'force' : 'cached',
2064
+ input.forceFailedRefresh ? 'failed-force' : 'failed-cached',
2065
+ ].join(':');
2066
+ let batch = this.pendingRuntimeReceiptClaims.get(batchKey);
2067
+ if (!batch) {
2068
+ batch = { scheduled: false, requests: [] };
2069
+ this.pendingRuntimeReceiptClaims.set(batchKey, batch);
2070
+ }
2071
+ return await new Promise<RuntimeStepReceipt | null>((resolve, reject) => {
2072
+ batch!.requests.push({ ...input, resolve, reject });
2073
+ if (batch!.scheduled) return;
2074
+ batch!.scheduled = true;
2075
+ queueMicrotask(
2076
+ () => void this.flushRuntimeStepReceiptClaimBatch(batchKey),
2077
+ );
2078
+ });
2079
+ }
2080
+
2081
+ private async flushRuntimeStepReceiptClaimBatch(
2082
+ batchKey: string,
2083
+ ): Promise<void> {
2084
+ const batch = this.pendingRuntimeReceiptClaims.get(batchKey);
2085
+ if (!batch) return;
2086
+ this.pendingRuntimeReceiptClaims.delete(batchKey);
2087
+ const requests = batch.requests;
2088
+ const first = requests[0];
2089
+ const claimReceipts = this.#options.claimRuntimeStepReceipts;
2090
+ if (!first || !claimReceipts) {
2091
+ for (const request of requests) request.resolve(null);
2092
+ return;
2093
+ }
2094
+ try {
2095
+ const receipts = await this.dispatchChunkedRuntimeReceiptRequest(
2096
+ requests,
2097
+ (chunk) =>
2098
+ claimReceipts({
2099
+ keys: chunk.map((request) => request.key),
2100
+ leaseIds: chunk.map(() => `receipt-lease:${crypto.randomUUID()}`),
2101
+ runId: this.currentReceiptOwnerRunId,
2102
+ runAttempt: this.currentRunAttempt,
2103
+ leaseAware: true,
2104
+ ...(first.reclaimRunning ? { reclaimRunning: true } : {}),
2105
+ ...(first.forceRefresh ? { forceRefresh: true } : {}),
2106
+ ...(first.forceFailedRefresh ? { forceFailedRefresh: true } : {}),
2107
+ }),
2108
+ );
2109
+ for (let index = 0; index < requests.length; index += 1) {
2110
+ const request = requests[index]!;
2111
+ request.resolve(
2112
+ this.normalizeRuntimeStepReceipt(request.key, receipts[index]),
2113
+ );
2114
+ }
2115
+ } catch (error) {
2116
+ for (const request of requests) request.reject(error);
2117
+ }
2118
+ }
2119
+
2028
2120
  private async completeRuntimeStepReceipt(
2029
2121
  key: string,
2030
2122
  _runId: string,
@@ -7671,6 +7763,7 @@ export class PlayContextImpl {
7671
7763
  )
7672
7764
  : options?.semanticKey,
7673
7765
  staleAfterSeconds: options?.staleAfterSeconds,
7766
+ force: this.#options.cachePolicy?.forceStepRefresh === true,
7674
7767
  markSkipped: (output) => {
7675
7768
  assertJsonSerializableStepOutput(normalizedKey, output);
7676
7769
  },
@@ -563,11 +563,14 @@ export interface ContextOptions {
563
563
  durableBoundaries?: boolean;
564
564
  /**
565
565
  * Run-level cache policy.
566
+ * forceStepRefresh bypasses completed ctx.step receipts while preserving
567
+ * completed provider-call receipts.
566
568
  * forceToolRefresh bypasses all ctx.tools.execute receipts.
567
569
  * forceFailedToolRefresh reclaims only failed receipts, preserving completed
568
570
  * provider-call idempotency while allowing forced repair runs to make progress.
569
571
  */
570
572
  cachePolicy?: {
573
+ forceStepRefresh?: boolean;
571
574
  forceToolRefresh?: boolean;
572
575
  forceFailedToolRefresh?: boolean;
573
576
  };
@@ -1,4 +1,9 @@
1
- import type { Daytona } from '@daytonaio/sdk';
1
+ import {
2
+ Image,
3
+ type CreateSandboxFromImageParams,
4
+ type Daytona,
5
+ } from '@daytonaio/sdk';
6
+ import { DAYTONA_DEFAULT_WORKDIR } from '@shared_libs/play-runtime/daytona-runtime-config';
2
7
  import type {
3
8
  PlayRunnerExecutionConfig,
4
9
  PlayRunnerResult,
@@ -8,14 +13,18 @@ import { PLAY_RUNNER_TIMEOUT_SECONDS } from '@shared_libs/play-runtime/runtime-c
8
13
  import { resolvePlaySandboxRuntimeLimits } from '@shared_libs/play-runtime/sandbox-runtime-limits';
9
14
 
10
15
  const DAYTONA_CREATE_TIMEOUT_SECONDS = 10;
16
+ const DAYTONA_CUSTOM_RESOURCE_CREATE_TIMEOUT_SECONDS = 120;
11
17
  const DAYTONA_CREATE_RETRY_DELAYS_MS = [0, 500, 1_500] as const;
12
18
  // Explicit runner deadline + scheduler GC own the normal lifecycle. Daytona's
13
19
  // inactivity stop is a wider crash backstop measured from sandbox creation, so
14
20
  // setup time cannot consume the terminal-flush grace.
15
21
  const DAYTONA_AUTO_ARCHIVE_INTERVAL_MINUTES = 15;
16
22
  const DAYTONA_SANDBOX_LABEL_SOURCE = 'deepline-play-runner';
17
- // Daytona's default image is the fast path. Non-standard resources are applied
18
- // during acquisition, before customer code and before the billing clock starts.
23
+ const DAYTONA_CUSTOM_RESOURCE_IMAGE = Image.base(
24
+ 'node:20-bookworm-slim',
25
+ ).workdir(DAYTONA_DEFAULT_WORKDIR);
26
+ // Daytona's default image is the fast path. Resources are pinned at creation
27
+ // and verified during acquisition, before customer code or billing starts.
19
28
  export const DAYTONA_SANDBOX_CPU = 1;
20
29
  export const DAYTONA_SANDBOX_MEMORY_GIB = 1;
21
30
  export const DAYTONA_SANDBOX_DISK_GIB = 3;
@@ -204,26 +213,47 @@ async function createOneShotDaytonaSandbox(input: {
204
213
  runtimeSchedulerSchema: input.context.runtimeSchedulerSchema ?? null,
205
214
  });
206
215
 
207
- // Intentionally omit image/snapshot so Daytona uses its default fast sandbox
208
- // image; custom images would add build/pull tax to one-shot cold starts.
209
- return input.daytona.create(
210
- {
211
- labels,
212
- ephemeral: true,
213
- autoStopInterval: Math.ceil(
214
- (limits.timeoutSeconds + PLAY_RUNNER_TIMEOUT_SECONDS - 30 * 60) / 60,
215
- ),
216
- autoArchiveInterval: DAYTONA_AUTO_ARCHIVE_INTERVAL_MINUTES,
217
- // A non-empty `networkAllowList` IS the "block all egress except these
218
- // CIDRs" control; Daytona rejects create when `networkBlockAll: true` is
219
- // combined with a non-empty allow-list ("networkBlockAll: true cannot be
220
- // combined with a non-empty networkAllowList or domainAllowList"). Pass
221
- // the allow-list alone so the egress restriction holds without the
222
- // contradictory flag.
223
- ...(networkAllowList ? { networkAllowList } : {}),
224
- },
225
- { timeout: DAYTONA_CREATE_TIMEOUT_SECONDS },
226
- );
216
+ const hasCustomResources =
217
+ limits.cpu !== DAYTONA_SANDBOX_CPU ||
218
+ limits.memoryGiB !== DAYTONA_SANDBOX_MEMORY_GIB ||
219
+ limits.diskGiB !== DAYTONA_SANDBOX_DISK_GIB;
220
+ const commonParams = {
221
+ labels,
222
+ ephemeral: true,
223
+ autoStopInterval: Math.ceil(
224
+ (limits.timeoutSeconds + PLAY_RUNNER_TIMEOUT_SECONDS - 30 * 60) / 60,
225
+ ),
226
+ autoArchiveInterval: DAYTONA_AUTO_ARCHIVE_INTERVAL_MINUTES,
227
+ // A non-empty `networkAllowList` IS the "block all egress except these
228
+ // CIDRs" control; Daytona rejects create when `networkBlockAll: true` is
229
+ // combined with a non-empty allow-list ("networkBlockAll: true cannot be
230
+ // combined with a non-empty networkAllowList or domainAllowList"). Pass
231
+ // the allow-list alone so the egress restriction holds without the
232
+ // contradictory flag.
233
+ ...(networkAllowList ? { networkAllowList } : {}),
234
+ };
235
+ if (hasCustomResources) {
236
+ // Daytona fixes resources into snapshots and rejects a resources field on
237
+ // snapshot/default-image creates. Its supported custom-resource path
238
+ // builds from an OCI image and applies CPU, memory, and disk at creation.
239
+ const createParams: CreateSandboxFromImageParams = {
240
+ ...commonParams,
241
+ image: DAYTONA_CUSTOM_RESOURCE_IMAGE,
242
+ resources: {
243
+ cpu: limits.cpu,
244
+ memory: limits.memoryGiB,
245
+ disk: limits.diskGiB,
246
+ },
247
+ };
248
+ return input.daytona.create(createParams, {
249
+ timeout: DAYTONA_CUSTOM_RESOURCE_CREATE_TIMEOUT_SECONDS,
250
+ });
251
+ }
252
+ // Keep the fast default snapshot for standard resources, including plays
253
+ // that override timeout only.
254
+ return input.daytona.create(commonParams, {
255
+ timeout: DAYTONA_CREATE_TIMEOUT_SECONDS,
256
+ });
227
257
  }
228
258
 
229
259
  async function createRetriedOneShotDaytonaSandbox(input: {
@@ -304,9 +334,9 @@ async function acquireOneShotDaytonaSandbox(input: {
304
334
  diskGiB: result.sandbox.disk,
305
335
  gpu: result.sandbox.gpu ?? 0,
306
336
  };
307
- // Daytona's SDK only accepts resources when a custom image is supplied.
308
- // We deliberately retain the provider's fast default image, then resize
309
- // before any customer code or billing window begins.
337
+ // Compatibility fallback for Daytona targets that ignore create-time
338
+ // resources but still support resize. The hosted target should normally
339
+ // match immediately; either path is verified before code or billing starts.
310
340
  if (
311
341
  typeof result.sandbox.resize === 'function' &&
312
342
  (granted.cpu !== limits.cpu ||
package/dist/cli/index.js CHANGED
@@ -1037,7 +1037,7 @@ var SDK_RELEASE = {
1037
1037
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
1038
1038
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
1039
1039
  // Operators use the checkout-local deepline-admin binary instead.
1040
- version: "0.1.311",
1040
+ version: "0.1.313",
1041
1041
  contracts: {
1042
1042
  api: {
1043
1043
  name: "sdk-http-api",
@@ -1022,7 +1022,7 @@ var SDK_RELEASE = {
1022
1022
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
1023
1023
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
1024
1024
  // Operators use the checkout-local deepline-admin binary instead.
1025
- version: "0.1.311",
1025
+ version: "0.1.313",
1026
1026
  contracts: {
1027
1027
  api: {
1028
1028
  name: "sdk-http-api",
package/dist/index.js CHANGED
@@ -760,7 +760,7 @@ var SDK_RELEASE = {
760
760
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
761
761
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
762
762
  // Operators use the checkout-local deepline-admin binary instead.
763
- version: "0.1.311",
763
+ version: "0.1.313",
764
764
  contracts: {
765
765
  api: {
766
766
  name: "sdk-http-api",
package/dist/index.mjs CHANGED
@@ -686,7 +686,7 @@ var SDK_RELEASE = {
686
686
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
687
687
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
688
688
  // Operators use the checkout-local deepline-admin binary instead.
689
- version: "0.1.311",
689
+ version: "0.1.313",
690
690
  contracts: {
691
691
  api: {
692
692
  name: "sdk-http-api",
@@ -1,30 +1,27 @@
1
1
 
2
2
  :root {
3
- --bg: var(--background);
4
- --bg-secondary: var(--background-secondary);
5
- --bg-tertiary: var(--background-tertiary);
6
- --text: var(--foreground);
7
- --text-dim: var(--foreground-secondary);
8
- --text-dimmer: var(--foreground-muted);
9
- --green: var(--status-success-foreground);
10
- --red: var(--status-error-foreground);
11
- --yellow: var(--status-warning-foreground);
12
- --blue: var(--primary-text);
13
- --purple: var(--color-silver-400);
14
- --orange: var(--status-warning-foreground);
15
- --cyan: var(--status-info-foreground);
3
+ --bg: #0d1117;
4
+ --bg-secondary: #161b22;
5
+ --bg-tertiary: #21262d;
6
+ --border: #30363d;
7
+ --text: #e6edf3;
8
+ --text-dim: #8b949e;
9
+ --text-dimmer: #6e7681;
10
+ --green: #3fb950;
11
+ --red: #f85149;
12
+ --yellow: #d29922;
13
+ --blue: #58a6ff;
14
+ --purple: #bc8cff;
15
+ --orange: #f0883e;
16
+ --cyan: #39d2c0;
16
17
  }
17
18
  * { margin: 0; padding: 0; box-sizing: border-box; }
18
19
  body {
19
20
  background: var(--bg);
20
21
  color: var(--text);
21
- font-family: var(--font-base);
22
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
22
23
  font-size: 14px;
23
24
  line-height: 1.5;
24
- letter-spacing: -0.011em;
25
- -webkit-font-smoothing: antialiased;
26
- -moz-osx-font-smoothing: grayscale;
27
- text-rendering: optimizeLegibility;
28
25
  }
29
26
  .layout { display: flex; height: 100vh; }
30
27
  .sidebar {
@@ -39,7 +36,7 @@ body {
39
36
  padding: 10px 16px;
40
37
  cursor: pointer;
41
38
  border-left: 3px solid transparent;
42
- transition: background-color var(--duration-normal) var(--ease-standard);
39
+ transition: background 0.15s;
43
40
  font-size: 13px;
44
41
  }
45
42
  .sidebar-item:hover { background: var(--bg-tertiary); }
@@ -57,7 +54,7 @@ body {
57
54
  .sidebar-compare kbd {
58
55
  background: var(--bg-tertiary);
59
56
  border: 1px solid var(--border);
60
- border-radius: var(--radius-icon);
57
+ border-radius: 3px;
61
58
  padding: 0 4px;
62
59
  font-size: 10px;
63
60
  font-family: inherit;
@@ -67,7 +64,7 @@ body {
67
64
  .header {
68
65
  background: var(--bg-secondary);
69
66
  border: 1px solid var(--border);
70
- border-radius: var(--radius-lg);
67
+ border-radius: 8px;
71
68
  padding: 20px 24px;
72
69
  margin-bottom: 20px;
73
70
  }
@@ -102,7 +99,7 @@ body {
102
99
  gap: 4px;
103
100
  background: var(--bg);
104
101
  border: 1px solid var(--border);
105
- border-radius: var(--radius-sm);
102
+ border-radius: 4px;
106
103
  padding: 2px 8px;
107
104
  font-size: 12px;
108
105
  }
@@ -153,7 +150,7 @@ body {
153
150
  line-height: 1.6;
154
151
  white-space: pre-wrap;
155
152
  word-break: break-word;
156
- background: color-mix(in srgb, var(--status-success-accent) 4%, transparent);
153
+ background: rgba(63,185,80,0.04);
157
154
  }
158
155
  .user-message.collapsed { max-height: 100px; overflow: hidden; position: relative; }
159
156
  .user-message.collapsed::after {
@@ -187,7 +184,7 @@ body {
187
184
  white-space: pre-wrap;
188
185
  word-break: break-word;
189
186
  font-style: italic;
190
- background: color-mix(in srgb, var(--color-silver-400) 3%, transparent);
187
+ background: rgba(188,140,255,0.03);
191
188
  }
192
189
  .thinking.collapsed { max-height: 100px; overflow: hidden; position: relative; }
193
190
  .thinking.collapsed::after {
@@ -234,10 +231,10 @@ body {
234
231
  align-items: center;
235
232
  gap: 12px;
236
233
  padding: 6px 12px;
237
- border-radius: var(--radius-md);
234
+ border-radius: 6px;
238
235
  cursor: pointer;
239
- transition: background-color var(--duration-normal) var(--ease-standard);
240
- font-family: var(--font-mono);
236
+ transition: background 0.15s;
237
+ font-family: 'SF Mono', 'Fira Code', 'Fira Mono', Menlo, Consolas, monospace;
241
238
  font-size: 13px;
242
239
  }
243
240
  .tool-row:hover { background: var(--bg-secondary); }
@@ -247,15 +244,15 @@ body {
247
244
  .tool-status {
248
245
  display: inline-block;
249
246
  padding: 1px 8px;
250
- border-radius: var(--radius-control);
247
+ border-radius: 10px;
251
248
  font-size: 11px;
252
249
  font-weight: 600;
253
250
  min-width: 42px;
254
251
  text-align: center;
255
252
  }
256
- .tool-status.ok { background: color-mix(in srgb, var(--status-success-accent) 15%, transparent); color: var(--green); }
257
- .tool-status.fail { background: color-mix(in srgb, var(--status-error-accent) 15%, transparent); color: var(--red); }
258
- .tool-status.unknown { background: color-mix(in srgb, var(--foreground-muted) 15%, transparent); color: var(--text-dim); }
253
+ .tool-status.ok { background: rgba(63,185,80,0.15); color: var(--green); }
254
+ .tool-status.fail { background: rgba(248,81,73,0.15); color: var(--red); }
255
+ .tool-status.unknown { background: rgba(139,148,158,0.15); color: var(--text-dim); }
259
256
  .tool-name {
260
257
  font-weight: 600;
261
258
  min-width: 70px;
@@ -277,22 +274,22 @@ body {
277
274
  color: var(--text-dimmer);
278
275
  background: var(--bg-tertiary);
279
276
  border: 1px solid var(--border);
280
- border-radius: var(--radius-sm);
277
+ border-radius: 4px;
281
278
  padding: 0 5px;
282
279
  white-space: nowrap;
283
280
  }
284
281
  .loop-badge {
285
282
  color: var(--yellow);
286
- border-color: color-mix(in srgb, var(--status-warning-accent) 40%, transparent);
287
- background: color-mix(in srgb, var(--status-warning-accent) 8%, transparent);
283
+ border-color: rgba(210,153,34,0.4);
284
+ background: rgba(210,153,34,0.08);
288
285
  }
289
286
  .repeat-badge {
290
287
  margin-left: 6px;
291
288
  font-size: 10px;
292
289
  color: var(--text-dimmer);
293
- background: color-mix(in srgb, var(--color-silver-400) 8%, transparent);
294
- border: 1px solid color-mix(in srgb, var(--color-silver-400) 30%, transparent);
295
- border-radius: var(--radius-sm);
290
+ background: rgba(120,120,180,0.08);
291
+ border: 1px solid rgba(120,120,180,0.3);
292
+ border-radius: 4px;
296
293
  padding: 0 5px;
297
294
  white-space: nowrap;
298
295
  cursor: help;
@@ -322,7 +319,7 @@ body {
322
319
  margin-left: 48px;
323
320
  margin-bottom: 12px;
324
321
  border: 1px solid var(--border);
325
- border-radius: var(--radius-md);
322
+ border-radius: 6px;
326
323
  overflow: hidden;
327
324
  }
328
325
  .tool-detail.open { display: block; }
@@ -340,12 +337,12 @@ body {
340
337
  }
341
338
  .tool-detail-section pre {
342
339
  background: var(--bg);
343
- border-radius: var(--radius-sm);
340
+ border-radius: 4px;
344
341
  padding: 10px 14px;
345
342
  overflow-x: auto;
346
343
  font-size: 12px;
347
344
  line-height: 1.5;
348
- font-family: var(--font-mono);
345
+ font-family: 'SF Mono', 'Fira Code', 'Fira Mono', Menlo, Consolas, monospace;
349
346
  white-space: pre-wrap;
350
347
  word-break: break-word;
351
348
  max-height: 400px;
@@ -354,13 +351,13 @@ body {
354
351
  }
355
352
  .tool-detail-section pre.error-content {
356
353
  border: 1px solid var(--red);
357
- background: color-mix(in srgb, var(--status-error-accent) 6%, transparent);
354
+ background: rgba(248,81,73,0.06);
358
355
  }
359
356
  .tool-detail-toggle {
360
357
  margin-top: 8px;
361
358
  background: var(--bg-tertiary);
362
359
  border: 1px solid var(--border);
363
- border-radius: var(--radius-sm);
360
+ border-radius: 4px;
364
361
  color: var(--blue);
365
362
  cursor: pointer;
366
363
  font-size: 12px;
@@ -372,7 +369,7 @@ body {
372
369
  .result-card {
373
370
  background: var(--bg-secondary);
374
371
  border: 1px solid var(--border);
375
- border-radius: var(--radius-lg);
372
+ border-radius: 8px;
376
373
  padding: 20px 24px;
377
374
  margin-top: 20px;
378
375
  }
@@ -395,7 +392,7 @@ body {
395
392
  flex: 1;
396
393
  background: var(--bg-secondary);
397
394
  border: 1px solid var(--border);
398
- border-radius: var(--radius-md);
395
+ border-radius: 6px;
399
396
  padding: 8px 12px;
400
397
  color: var(--text);
401
398
  font-size: 13px;
@@ -407,7 +404,7 @@ body {
407
404
  .filter-btn {
408
405
  background: var(--bg-secondary);
409
406
  border: 1px solid var(--border);
410
- border-radius: var(--radius-md);
407
+ border-radius: 6px;
411
408
  padding: 8px 12px;
412
409
  color: var(--text-dim);
413
410
  font-size: 12px;
@@ -420,7 +417,7 @@ body {
420
417
  .prompt-card {
421
418
  background: var(--bg-secondary);
422
419
  border: 1px solid var(--border);
423
- border-radius: var(--radius-lg);
420
+ border-radius: 8px;
424
421
  padding: 16px 20px;
425
422
  margin-bottom: 16px;
426
423
  }
@@ -443,11 +440,11 @@ body {
443
440
  font-size: 11px;
444
441
  font-weight: 600;
445
442
  padding: 2px 8px;
446
- border-radius: var(--radius-control);
443
+ border-radius: 10px;
447
444
  vertical-align: middle;
448
445
  }
449
- .timing-badge.exact { background: color-mix(in srgb, var(--status-success-accent) 15%, transparent); color: var(--green); }
450
- .timing-badge.estimated { background: color-mix(in srgb, var(--status-warning-accent) 15%, transparent); color: var(--yellow); }
446
+ .timing-badge.exact { background: rgba(63,185,80,0.15); color: var(--green); }
447
+ .timing-badge.estimated { background: rgba(210,153,34,0.15); color: var(--yellow); }
451
448
 
452
449
  /* Live badge */
453
450
  .live-badge {
@@ -455,8 +452,8 @@ body {
455
452
  font-size: 11px;
456
453
  font-weight: 700;
457
454
  padding: 2px 10px;
458
- border-radius: var(--radius-control);
459
- background: color-mix(in srgb, var(--status-error-accent) 15%, transparent);
455
+ border-radius: 10px;
456
+ background: rgba(248,81,73,0.15);
460
457
  color: var(--red);
461
458
  animation: live-pulse 2s ease-in-out infinite;
462
459
  letter-spacing: 0.5px;
@@ -464,7 +461,7 @@ body {
464
461
  user-select: none;
465
462
  }
466
463
  .live-badge.paused {
467
- background: color-mix(in srgb, var(--foreground-muted) 15%, transparent);
464
+ background: rgba(139,148,158,0.15);
468
465
  color: var(--text-dim);
469
466
  animation: none;
470
467
  }
@@ -476,7 +473,7 @@ body {
476
473
  .download-btn {
477
474
  background: var(--bg-secondary);
478
475
  border: 1px solid var(--border);
479
- border-radius: var(--radius-md);
476
+ border-radius: 6px;
480
477
  padding: 4px 10px;
481
478
  color: var(--text-dim);
482
479
  font-size: 12px;
@@ -490,7 +487,7 @@ body {
490
487
  .file-map-card {
491
488
  background: var(--bg-secondary);
492
489
  border: 1px solid var(--border);
493
- border-radius: var(--radius-lg);
490
+ border-radius: 8px;
494
491
  margin-bottom: 16px;
495
492
  overflow: hidden;
496
493
  }
@@ -503,7 +500,7 @@ body {
503
500
  font-size: 13px;
504
501
  font-weight: 600;
505
502
  color: var(--text-dim);
506
- transition: background-color var(--duration-normal) var(--ease-standard);
503
+ transition: background 0.15s;
507
504
  }
508
505
  .file-map-header:hover { background: var(--bg-tertiary); }
509
506
  .file-map-toggle {
@@ -520,7 +517,7 @@ body {
520
517
  width: 100%;
521
518
  border-collapse: collapse;
522
519
  font-size: 12px;
523
- font-family: var(--font-mono);
520
+ font-family: 'SF Mono', 'Fira Code', Menlo, monospace;
524
521
  }
525
522
  .file-map-table th {
526
523
  background: var(--bg-tertiary);
@@ -539,13 +536,13 @@ body {
539
536
  color: var(--text-dim);
540
537
  }
541
538
  .file-map-table td:first-child { color: var(--text); }
542
- .file-map-table tr:hover { background: color-mix(in srgb, var(--primary) 4%, transparent); }
539
+ .file-map-table tr:hover { background: rgba(88,166,255,0.04); }
543
540
 
544
541
  /* Comparison view */
545
542
  .comparison-table-wrap {
546
543
  background: var(--bg-secondary);
547
544
  border: 1px solid var(--border);
548
- border-radius: var(--radius-lg);
545
+ border-radius: 8px;
549
546
  overflow: hidden;
550
547
  }
551
548
  .comparison-table {
@@ -574,7 +571,7 @@ body {
574
571
  font-weight: 500;
575
572
  min-width: 140px;
576
573
  }
577
- .comparison-table tr:hover { background: color-mix(in srgb, var(--primary) 4%, transparent); }
574
+ .comparison-table tr:hover { background: rgba(88,166,255,0.04); }
578
575
  .compare-dim { color: var(--text-dimmer); font-size: 11px; }
579
576
  .compare-best { color: var(--green); font-weight: 600; }
580
577
  .compare-worst { color: var(--red); }
@@ -596,8 +593,8 @@ body {
596
593
  .md-rendered p { margin-bottom: 8px; }
597
594
  .md-rendered strong { color: var(--text); font-weight: 600; }
598
595
  .md-rendered code {
599
- background: var(--bg-tertiary); border-radius: var(--radius-icon); padding: 1px 5px;
600
- font-family: var(--font-mono); font-size: 12px;
596
+ background: var(--bg-tertiary); border-radius: 3px; padding: 1px 5px;
597
+ font-family: 'SF Mono', 'Fira Code', Menlo, monospace; font-size: 12px;
601
598
  }
602
599
  .md-rendered table {
603
600
  border-collapse: collapse; margin: 8px 0; width: 100%; font-size: 12px;
@@ -609,7 +606,7 @@ body {
609
606
  background: var(--bg-tertiary); color: var(--text-dim); font-weight: 600;
610
607
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.3px;
611
608
  }
612
- .md-rendered tr:hover { background: color-mix(in srgb, var(--primary) 4%, transparent); }
609
+ .md-rendered tr:hover { background: rgba(88,166,255,0.04); }
613
610
  .md-rendered a { color: var(--blue); text-decoration: none; }
614
611
  .md-rendered a:hover { text-decoration: underline; }
615
612
  .md-rendered h1, .md-rendered h2, .md-rendered h3 {
@@ -621,9 +618,9 @@ body {
621
618
  .md-rendered ul, .md-rendered ol { margin: 4px 0 8px 20px; }
622
619
  .md-rendered li { margin-bottom: 2px; }
623
620
  .md-rendered pre {
624
- background: var(--bg); border-radius: var(--radius-sm); padding: 10px 14px;
621
+ background: var(--bg); border-radius: 4px; padding: 10px 14px;
625
622
  font-size: 12px; line-height: 1.5; overflow-x: auto;
626
- font-family: var(--font-mono);
623
+ font-family: 'SF Mono', 'Fira Code', Menlo, monospace;
627
624
  margin: 8px 0;
628
625
  white-space: pre-wrap;
629
626
  word-break: break-word;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.311",
3
+ "version": "0.1.313",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {