@intentic/sandbox-contract 1.155.0 → 1.156.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 (50) hide show
  1. package/dist/agent-catalog.d.ts +2 -1
  2. package/dist/agent-catalog.d.ts.map +1 -1
  3. package/dist/agent-catalog.js +6 -5
  4. package/dist/agent-catalog.js.map +1 -1
  5. package/dist/contracts/agent.contract.d.ts +24 -0
  6. package/dist/contracts/agent.contract.d.ts.map +1 -1
  7. package/dist/contracts/agents.contract.d.ts +266 -0
  8. package/dist/contracts/agents.contract.d.ts.map +1 -1
  9. package/dist/contracts/agents.contract.js +6 -1
  10. package/dist/contracts/agents.contract.js.map +1 -1
  11. package/dist/contracts/claude.contract.d.ts +12 -16
  12. package/dist/contracts/claude.contract.d.ts.map +1 -1
  13. package/dist/contracts/grok.contract.d.ts +6 -8
  14. package/dist/contracts/grok.contract.d.ts.map +1 -1
  15. package/dist/contracts/kimi.contract.d.ts +12 -16
  16. package/dist/contracts/kimi.contract.d.ts.map +1 -1
  17. package/dist/contracts/sessions.contract.d.ts +37 -0
  18. package/dist/contracts/sessions.contract.d.ts.map +1 -1
  19. package/dist/contracts/sessions.contract.js +2 -1
  20. package/dist/contracts/sessions.contract.js.map +1 -1
  21. package/dist/contracts/settings.contract.d.ts +2 -0
  22. package/dist/contracts/settings.contract.d.ts.map +1 -1
  23. package/dist/contracts/system.contract.d.ts +4 -0
  24. package/dist/contracts/system.contract.d.ts.map +1 -1
  25. package/dist/contracts/vpn.contract.d.ts.map +1 -1
  26. package/dist/contracts/vpn.contract.js +4 -1
  27. package/dist/contracts/vpn.contract.js.map +1 -1
  28. package/dist/contracts/workspace.contract.d.ts +23 -0
  29. package/dist/contracts/workspace.contract.d.ts.map +1 -1
  30. package/dist/contracts/workspace.contract.js +3 -1
  31. package/dist/contracts/workspace.contract.js.map +1 -1
  32. package/dist/events.d.ts +156 -0
  33. package/dist/events.d.ts.map +1 -1
  34. package/dist/events.js +19 -1
  35. package/dist/events.js.map +1 -1
  36. package/dist/index.d.ts +386 -40
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/schemas.d.ts +131 -33
  39. package/dist/schemas.d.ts.map +1 -1
  40. package/dist/schemas.js +27 -2
  41. package/dist/schemas.js.map +1 -1
  42. package/package.json +2 -2
  43. package/src/agent-catalog.ts +16 -8
  44. package/src/contracts/agents.contract.ts +16 -0
  45. package/src/contracts/sessions.contract.ts +6 -4
  46. package/src/contracts/vpn.contract.ts +4 -1
  47. package/src/contracts/workspace.contract.ts +9 -0
  48. package/src/events.ts +49 -3
  49. package/src/schemas.test.ts +4 -1
  50. package/src/schemas.ts +78 -10
package/src/schemas.ts CHANGED
@@ -181,6 +181,11 @@ export const AgentSummarySchema = z.object({
181
181
  // Present while a turn runs: its start, ms since epoch.
182
182
  startedAt: z.number().optional(),
183
183
  updatedAt: z.number(),
184
+ // When the agent was last OPENED, ms since epoch — the unread badge's reference point (`updatedAt >
185
+ // seenAt` ⇒ the agent has done something you haven't looked at). Absent ⇒ never opened. Daemon-side on
186
+ // purpose: read state is a fact about the WORK, not about one browser profile, so clearing site data or
187
+ // picking up the phone must not resurrect every badge.
188
+ seenAt: z.number().optional(),
184
189
  attention: AgentAttentionSchema,
185
190
  // Completed turns and lifetime tool calls — the card's msgs/tools counters.
186
191
  turns: z.number().optional(),
@@ -188,10 +193,23 @@ export const AgentSummarySchema = z.object({
188
193
  // The agent's cumulative output (base → branch tip across every repo), refreshed on each land —
189
194
  // the card's "12 files · +412 −96" readout. Independent of what has landed.
190
195
  diff: z.object({ files: z.number(), insertions: z.number(), deletions: z.number() }).optional(),
196
+ // When the agent was ARCHIVED (ms epoch) — off the board, but nothing lost: its checkout was retired
197
+ // (worktree removed) while the agent/<id> branch, the transcript, and every counter stayed. Absent ⇒ live
198
+ // on the board. Archived agents are excluded from the roster the fleet renders; `agents.archived` lists
199
+ // them, `agents.unarchive` brings one back, and the next turn re-attaches its worktree from the branch.
200
+ archivedAt: z.number().optional(),
191
201
  });
192
202
  export type AgentSummary = z.infer<typeof AgentSummarySchema>;
193
203
  export const AgentsListSchema = z.object({ agents: z.array(AgentSummarySchema) });
194
204
  export const AgentIdSchema = z.object({ id: z.string().min(1) });
205
+ // archive's input: the agents to take off the board. Absent `ids` ⇒ every finished agent that is archivable
206
+ // right now (the lane header's "Clear"); unarchive always names its ids (a restore, or a bulk archive's undo).
207
+ export const AgentArchiveSchema = z.object({ ids: z.array(z.string().min(1)).max(500).optional() });
208
+ export const AgentIdsSchema = z.object({ ids: z.array(z.string().min(1)).min(1).max(500) });
209
+ // The roster after the change PLUS the ids that actually moved — the board needs those to offer "Undo",
210
+ // since "archive everything finished" can't be inverted by re-reading the list afterwards.
211
+ export const AgentArchiveResultSchema = z.object({ agents: z.array(AgentSummarySchema), archived: z.array(z.string()) });
212
+ export type AgentArchiveResult = z.infer<typeof AgentArchiveResultSchema>;
195
213
  // rename's input: the user-chosen display title (bounded like sanitizeTitle's cap).
196
214
  export const AgentRenameSchema = z.object({ id: z.string().min(1), title: z.string().trim().min(1).max(80) });
197
215
  export const AgentFileDiffQuerySchema = z.object({ id: z.string().min(1), repo: z.string().min(1), path: z.string().min(1) });
@@ -262,10 +280,11 @@ export const SteerSchema = z.object({ conversationId: z.string().min(1), text: z
262
280
  export const StopTurnSchema = z.object({ conversationId: z.string().min(1) });
263
281
 
264
282
  // ---- claude subscription usage ----
265
- // Which usage window is active for a Claude account, how much of it is spent, and when it resets. Two readers,
266
- // so it lives here rather than beside the stream frames: the SDK's rate_limit_event rides it out on the agent
267
- // stream (see the `rate_limit_info` frame in events.ts), and the daemon persists the latest snapshot per
268
- // account so `/claude/accounts` can answer "how much is left on each" without spending a turn to find out.
283
+ // The GATE signal: whether the provider is letting turns through right now, and when it is refusing — which
284
+ // window is binding and when it lifts. This is the SDK's rate_limit_event, mapped one-to-one, and it is only
285
+ // ever about the CURRENT moment. It is deliberately NOT the thing the headroom displays read: the event names a
286
+ // single window (whichever the CLI considered binding), which is how "weekly 1%" ended up standing in for an
287
+ // account that was really at 98% on another weekly pool.
269
288
  export const RateLimitInfoSchema = z.object({
270
289
  status: z.enum(["allowed", "allowed_warning", "rejected"]),
271
290
  resetsAt: z.number().optional(), // epoch seconds
@@ -274,11 +293,32 @@ export const RateLimitInfoSchema = z.object({
274
293
  });
275
294
  export type RateLimitInfo = z.infer<typeof RateLimitInfoSchema>;
276
295
 
277
- // The persisted view: a snapshot plus when it was taken. Within one window utilization only climbs, so a
278
- // snapshot stays a valid FLOOR until `resetsAt` passes after that the window has rolled over and the store
279
- // drops it rather than reporting a stale number. `measuredAt` is epoch MS (matching connectedAt), while
280
- // `resetsAt` stays epoch SECONDS (matching the SDK frame) they are deliberately different units.
281
- export const AccountUsageSchema = RateLimitInfoSchema.extend({ measuredAt: z.number() });
296
+ // One plan-limit pool. `kind` is the provider's own key ('five_hour' | 'seven_day' | 'seven_day_opus' |
297
+ // 'seven_day_sonnet' | 'model:Fable' | …) rather than an enum we'd have to keep in step with the provider: an
298
+ // unrecognised pool is shown under its raw key, which is far better than being silently folded into a
299
+ // neighbour. `label` is the provider's OWN display name where it supplies one (the per-model buckets do) — it
300
+ // wins over anything we'd infer, because the model names in a plan's limits are the provider's to rename.
301
+ // `resetsAt` is epoch SECONDS (matching the SDK's frame).
302
+ export const UsageWindowSchema = z.object({
303
+ kind: z.string(),
304
+ label: z.string().optional(),
305
+ utilization: z.number(), // 0-100
306
+ resetsAt: z.number().optional(),
307
+ });
308
+ export type UsageWindow = z.infer<typeof UsageWindowSchema>;
309
+
310
+ // An account's headroom: EVERY window the provider reports, read together, plus when the reading was taken.
311
+ // All of them, not the binding one, because "which pool is binding" changes between turns and a reader
312
+ // comparing accounts needs the same pools on every row. Sourced from the CLI's own usage endpoint at turn end
313
+ // (see claudeUsageWindows) — a control request, so it costs no tokens.
314
+ //
315
+ // Within one window utilization only climbs, so an un-reset window stays a valid FLOOR however old it is; past
316
+ // its `resetsAt` it describes a pool that no longer exists and the store drops it. `measuredAt` is epoch MS
317
+ // (matching connectedAt) — deliberately a different unit from the windows' seconds.
318
+ export const AccountUsageSchema = z.object({
319
+ windows: z.array(UsageWindowSchema),
320
+ measuredAt: z.number(),
321
+ });
282
322
  export type AccountUsage = z.infer<typeof AccountUsageSchema>;
283
323
 
284
324
  // ---- provider oauth ----
@@ -376,7 +416,6 @@ export const ModelsSchema = z.object({ models: z.array(ModelSchema), default: z.
376
416
  export const SessionIdParamSchema = z.object({ id: z.string() });
377
417
  export const SessionSummarySchema = z.object({ id: z.string(), title: z.string(), updatedAt: z.number() });
378
418
  export const SessionsListSchema = z.object({ sessions: z.array(SessionSummarySchema) });
379
- export const SessionTranscriptSchema = z.object({ messages: z.array(SessionTranscriptMessageSchema) });
380
419
 
381
420
  // ---- settings: per-sandbox agent settings (.intentic/settings.json) ----
382
421
  // Small user-owned config the /settings routes edit and streamAgent reads — all opt-in booleans the owner
@@ -422,6 +461,11 @@ export const SandboxSettingsSchema = z.object({
422
461
  outputCleaners: z.string().default("off"),
423
462
  outputHoldout: z.number().min(0).max(1).default(0),
424
463
  filterBackend: z.enum(["native", "rtk"]).default("native"),
464
+ // How long a finished agent stays on the board before it is archived automatically (days; 0 ⇒ never).
465
+ // Unlike every other flag here this one defaults ON, because the lane it governs is the board's only
466
+ // terminal state: without a sweep the Finished lane grows for the life of the sandbox, and each card it
467
+ // holds is a live worktree checkout, not just a row.
468
+ agentRetentionDays: z.number().min(0).max(365).default(3),
425
469
  });
426
470
  export type SandboxSettings = z.infer<typeof SandboxSettingsSchema>;
427
471
 
@@ -806,6 +850,30 @@ export const WorkspaceSearchResultSchema = z.object({
806
850
  });
807
851
  export type WorkspaceSearchResult = z.infer<typeof WorkspaceSearchResultSchema>;
808
852
 
853
+ // ---- workspace setup (dependency readiness) ----
854
+
855
+ // One project under /work and whether its dependencies are actually installed. A drop omits node_modules/.venv
856
+ // on purpose, so a freshly imported project is present-but-unusable until this says "ready" — the import UI,
857
+ // the agent's post-edit type-check, and the agent's turn context all gate on it.
858
+ // `dir` is root-relative ("" = the workspace root itself); `manager` is the real binary (pnpm/npm/uv/…);
859
+ // `evidence` is the file that decided it ("pnpm-lock.yaml"), so the UI can show WHY, not just what.
860
+ // state: ready | installing | needs-setup | unsupported (manager absent from this sandbox — `manager` names it).
861
+ export const ProjectSetupSchema = z.object({
862
+ dir: z.string(),
863
+ ecosystem: z.enum(["node", "python"]),
864
+ manager: z.string(),
865
+ command: z.string(),
866
+ evidence: z.string(),
867
+ state: z.enum(["ready", "installing", "needs-setup", "unsupported"]),
868
+ });
869
+ export type ProjectSetup = z.infer<typeof ProjectSetupSchema>;
870
+ export const WorkspaceSetupSchema = z.object({ projects: z.array(ProjectSetupSchema) });
871
+ export type WorkspaceSetup = z.infer<typeof WorkspaceSetupSchema>;
872
+ // Install these projects' dependencies. Dirs already ready, already installing, or whose manager is missing are
873
+ // skipped server-side, so a stale client list can't spawn redundant installs — `started` is what actually ran.
874
+ export const WorkspaceInstallSchema = z.object({ dirs: z.array(z.string()).min(1) });
875
+ export const WorkspaceInstallResultSchema = z.object({ started: z.array(z.string()) });
876
+
809
877
  // ---- workspace repos ----
810
878
 
811
879
  // Every discovered repo's id (root-relative dir under /work), sorted — roles included.