@intentic/sandbox-contract 1.172.0 → 1.174.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.
- package/dist/chores/chores.js +1 -1
- package/dist/chores/chores.js.map +1 -1
- package/dist/contracts/capabilities.contract.d.ts +18 -0
- package/dist/contracts/capabilities.contract.d.ts.map +1 -1
- package/dist/contracts/komodo.contract.d.ts +107 -0
- package/dist/contracts/komodo.contract.d.ts.map +1 -0
- package/dist/contracts/komodo.contract.js +13 -0
- package/dist/contracts/komodo.contract.js.map +1 -0
- package/dist/contracts/workspace.contract.d.ts +2 -0
- package/dist/contracts/workspace.contract.d.ts.map +1 -1
- package/dist/index.d.ts +127 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/schemas.d.ts +231 -0
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +77 -2
- package/dist/schemas.js.map +1 -1
- package/dist/workspace-state.d.ts.map +1 -1
- package/dist/workspace-state.js +10 -0
- package/dist/workspace-state.js.map +1 -1
- package/package.json +2 -2
- package/src/chores/chores.ts +1 -1
- package/src/contracts/komodo.contract.ts +32 -0
- package/src/index.ts +3 -0
- package/src/schemas.test.ts +10 -1
- package/src/schemas.ts +177 -2
- package/src/workspace-state.ts +10 -0
package/src/schemas.ts
CHANGED
|
@@ -1394,7 +1394,14 @@ export const WorkspaceSearchHitSchema = z.object({
|
|
|
1394
1394
|
context: z.string().optional(),
|
|
1395
1395
|
});
|
|
1396
1396
|
export type WorkspaceSearchHit = z.infer<typeof WorkspaceSearchHitSchema>;
|
|
1397
|
-
export const WorkspaceSearchGroupSchema = z.object({
|
|
1397
|
+
export const WorkspaceSearchGroupSchema = z.object({
|
|
1398
|
+
path: z.string(),
|
|
1399
|
+
score: z.number(),
|
|
1400
|
+
hits: z.array(WorkspaceSearchHitSchema),
|
|
1401
|
+
// This file had more matching lines than the engine keeps per file, so `hits` is a floor — a panel showing a
|
|
1402
|
+
// per-file count has to say "50+" rather than "50".
|
|
1403
|
+
capped: z.boolean().optional(),
|
|
1404
|
+
});
|
|
1398
1405
|
export type WorkspaceSearchGroup = z.infer<typeof WorkspaceSearchGroupSchema>;
|
|
1399
1406
|
// `building` = index still filling (progress 0..1, e.g. embeddings pending); `stale` = revalidation was skipped
|
|
1400
1407
|
// (cursor replay). ageMs = time since the index last matched the disk state.
|
|
@@ -1417,6 +1424,9 @@ export const WorkspaceSearchResultSchema = z.object({
|
|
|
1417
1424
|
groups: z.array(WorkspaceSearchGroupSchema),
|
|
1418
1425
|
freshness: WorkspaceSearchFreshnessSchema,
|
|
1419
1426
|
truncated: z.boolean(),
|
|
1427
|
+
// `total` is a FLOOR: at least one file had more matches than the engine keeps per file. Distinct from
|
|
1428
|
+
// `truncated`, which is about this PAGE — a result can be complete on the page and still count partially.
|
|
1429
|
+
partial: z.boolean().optional(),
|
|
1420
1430
|
cursor: z.string().optional(),
|
|
1421
1431
|
hint: z.string().optional(),
|
|
1422
1432
|
// What the engine did with the query that the query did not ask for — a pattern rerun as literal text
|
|
@@ -1913,7 +1923,20 @@ export const CapabilitySummarySchema = z.object({
|
|
|
1913
1923
|
status: CapabilityStatusSchema,
|
|
1914
1924
|
config: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])),
|
|
1915
1925
|
});
|
|
1916
|
-
|
|
1926
|
+
// A capability the WORKSPACE asks for but the manifest doesn't carry — derived from what is checked out under
|
|
1927
|
+
// /work, not from anything the user configured. It exists because the failure it prevents is illegible: a
|
|
1928
|
+
// compose-backed dev database (`pnpm db:up`) dies on a missing /var/run/docker.sock, and nothing on that error
|
|
1929
|
+
// points at the one-time privileged rebuild that fixes it. `evidence` is the workspace-relative path that
|
|
1930
|
+
// triggered it, rendered verbatim so the claim is checkable rather than magic.
|
|
1931
|
+
export const CapabilityRecommendationSchema = z.object({ kind: CapabilityKindSchema, evidence: z.string() });
|
|
1932
|
+
export type CapabilityRecommendation = z.infer<typeof CapabilityRecommendationSchema>;
|
|
1933
|
+
export const CapabilitiesListSchema = z.object({
|
|
1934
|
+
capabilities: z.array(CapabilitySummarySchema),
|
|
1935
|
+
// Defaulted for the daemon-older-than-browser seam: the platform's web app talks to whichever sandbox
|
|
1936
|
+
// version the user has, and a required field here would fail the parse — taking the whole Capabilities page
|
|
1937
|
+
// down on every sandbox predating this route, to hide a badge.
|
|
1938
|
+
recommendations: z.array(CapabilityRecommendationSchema).default([]),
|
|
1939
|
+
});
|
|
1917
1940
|
export const CapabilityIdParamSchema = z.object({ id: z.string() });
|
|
1918
1941
|
// POST /capabilities/{id}/secret body: replace just the capability's secret field (its key is per-kind, see the
|
|
1919
1942
|
// sandbox's secretField) and re-run its idempotent apply — the /secrets page's edit path.
|
|
@@ -2435,6 +2458,158 @@ export type CiRunParam = z.infer<typeof CiRunParamSchema>;
|
|
|
2435
2458
|
export const CiFixResponseSchema = z.object({ conversationId: z.string() });
|
|
2436
2459
|
export type CiFixResponse = z.infer<typeof CiFixResponseSchema>;
|
|
2437
2460
|
|
|
2461
|
+
/* ---- Komodo deployments: the Deployments rail view's wire shape ----
|
|
2462
|
+
*
|
|
2463
|
+
* The daemon does the VENDOR translation (Komodo's tagged unions and enums → the flat shapes below); the
|
|
2464
|
+
* extension does the ATTENTION model on top of them (which alerts are incidents, which have been seen, what
|
|
2465
|
+
* the rail says). Same split as CI, and for the same reason: what a breakage MEANS is a UI decision that has
|
|
2466
|
+
* to be unit-testable without a daemon, while what Komodo's `ContainerStateChange` variant looks like is a
|
|
2467
|
+
* detail no view should ever learn.
|
|
2468
|
+
*
|
|
2469
|
+
* Routes are per-connection (`/komodo/{capability}/…`): a sandbox can hold two Komodo capabilities, and the
|
|
2470
|
+
* credential the daemon resolves per call is the one the path names. The browser never holds either half of
|
|
2471
|
+
* the API key — that is the whole reason these routes exist rather than the view calling Komodo directly. */
|
|
2472
|
+
|
|
2473
|
+
// Every Komodo container state (DeploymentState ∪ StackState — eleven words between them) collapsed onto the
|
|
2474
|
+
// five a view can tone. `stopped` swallows exited/stopped/paused/created/down/not_deployed on purpose: being
|
|
2475
|
+
// down is a LEVEL and says nothing about whether it was meant to be. What says a running thing STOPPED is the
|
|
2476
|
+
// alert log, which is why the badge reads alerts and this enum only colours a chip.
|
|
2477
|
+
export const DeployStateSchema = z.enum(["running", "deploying", "stopped", "unhealthy", "unknown"]);
|
|
2478
|
+
export type DeployState = z.infer<typeof DeployStateSchema>;
|
|
2479
|
+
|
|
2480
|
+
// Stacks and deployments are one row type in the view: a stack is a compose project, a deployment a single
|
|
2481
|
+
// container, and an operator looking for what is down does not want them in separate lists.
|
|
2482
|
+
export const DeployResourceKindSchema = z.enum(["deployment", "stack"]);
|
|
2483
|
+
export type DeployResourceKind = z.infer<typeof DeployResourceKindSchema>;
|
|
2484
|
+
|
|
2485
|
+
// One service inside a stack — free of extra calls (Komodo's ListStacks already returns them under `info`),
|
|
2486
|
+
// so a stack row can expand without a per-row fetch.
|
|
2487
|
+
export const DeployServiceSchema = z.object({
|
|
2488
|
+
name: z.string(),
|
|
2489
|
+
image: z.string(),
|
|
2490
|
+
updateAvailable: z.boolean(),
|
|
2491
|
+
});
|
|
2492
|
+
export type DeployService = z.infer<typeof DeployServiceSchema>;
|
|
2493
|
+
|
|
2494
|
+
export const DeployResourceSchema = z.object({
|
|
2495
|
+
kind: DeployResourceKindSchema,
|
|
2496
|
+
// Komodo's resource id — what the action routes address (names collide across resource types, ids don't).
|
|
2497
|
+
id: z.string(),
|
|
2498
|
+
name: z.string(),
|
|
2499
|
+
state: DeployStateSchema,
|
|
2500
|
+
// Komodo's own status prose ("Up 4 days", "Exited (1) 20 minutes ago"). Passed through rather than
|
|
2501
|
+
// regenerated: docker's phrasing is more precise than anything we would compose from a state word.
|
|
2502
|
+
status: z.string().optional(),
|
|
2503
|
+
// The host it runs on — the grouping key of the whole view. Absent on a resource Komodo has not placed yet.
|
|
2504
|
+
server: z.string().optional(),
|
|
2505
|
+
image: z.string().optional(),
|
|
2506
|
+
// A newer image exists at the same tag. An opportunity, never a breakage — see the tone table in
|
|
2507
|
+
// ext-deployments' incidents.ts for why this may not reach the rail as `danger`.
|
|
2508
|
+
updateAvailable: z.boolean(),
|
|
2509
|
+
// Stacks only, and empty when the stack has none deployed yet.
|
|
2510
|
+
services: z.array(DeployServiceSchema),
|
|
2511
|
+
// Deep link into Komodo's own UI for this resource — we do not reimplement Komodo, we get you there.
|
|
2512
|
+
url: z.string(),
|
|
2513
|
+
});
|
|
2514
|
+
export type DeployResource = z.infer<typeof DeployResourceSchema>;
|
|
2515
|
+
|
|
2516
|
+
export const DeployServerStateSchema = z.enum(["ok", "unreachable", "disabled"]);
|
|
2517
|
+
export type DeployServerState = z.infer<typeof DeployServerStateSchema>;
|
|
2518
|
+
|
|
2519
|
+
// A host, with the three gauges that explain a large share of deployment failures. All three ride ListServers'
|
|
2520
|
+
// own `info.stats`, so the strip costs nothing extra; absent when the server is unreachable (no stats to have).
|
|
2521
|
+
export const DeployServerSchema = z.object({
|
|
2522
|
+
id: z.string(),
|
|
2523
|
+
name: z.string(),
|
|
2524
|
+
state: DeployServerStateSchema,
|
|
2525
|
+
cpuPercent: z.number().optional(),
|
|
2526
|
+
memPercent: z.number().optional(),
|
|
2527
|
+
diskPercent: z.number().optional(),
|
|
2528
|
+
url: z.string(),
|
|
2529
|
+
});
|
|
2530
|
+
export type DeployServer = z.infer<typeof DeployServerSchema>;
|
|
2531
|
+
|
|
2532
|
+
// One entry from Komodo's alert log — an EDGE, already timestamped and resolve-flagged server-side. This is
|
|
2533
|
+
// what makes the rail badge possible without keeping any local history: Komodo records the transition, we only
|
|
2534
|
+
// decide whether the owner has seen it. `type` stays the raw AlertData variant tag (ContainerStateChange,
|
|
2535
|
+
// ServerUnreachable, DeploymentImageUpdateAvailable, BuildFailed…) — a variant we have not met yet is exactly
|
|
2536
|
+
// the one worth surfacing, so it passes through instead of being dropped into an "other" bucket.
|
|
2537
|
+
export const DeployAlertSchema = z.object({
|
|
2538
|
+
id: z.string(),
|
|
2539
|
+
type: z.string(),
|
|
2540
|
+
level: z.enum(["ok", "warning", "critical"]),
|
|
2541
|
+
// Komodo closes an alert when the condition clears; a resolved container-state alert IS the recovery.
|
|
2542
|
+
resolved: z.boolean(),
|
|
2543
|
+
// Epoch ms the alert OPENED — compared against seenAt, so further trouble inside one open alert can't re-badge.
|
|
2544
|
+
ts: z.number(),
|
|
2545
|
+
// The resource it is about, when the variant names one, and the host it sits on.
|
|
2546
|
+
resource: z.string().optional(),
|
|
2547
|
+
server: z.string().optional(),
|
|
2548
|
+
// The container/stack state transition, on the variants that carry one ("running" → "restarting").
|
|
2549
|
+
from: z.string().optional(),
|
|
2550
|
+
to: z.string().optional(),
|
|
2551
|
+
});
|
|
2552
|
+
export type DeployAlert = z.infer<typeof DeployAlertSchema>;
|
|
2553
|
+
|
|
2554
|
+
export const DeployOverviewResponseSchema = z.object({
|
|
2555
|
+
komodoUrl: z.string(),
|
|
2556
|
+
// FALSE means Komodo did not answer — the view says so loudly and the badge must not read `danger`.
|
|
2557
|
+
// "We cannot see production" is not "production is broken", the same line ciAttention draws when it
|
|
2558
|
+
// leaves the last known state standing rather than blanking the tile.
|
|
2559
|
+
reachable: z.boolean(),
|
|
2560
|
+
// Why it did not answer, in Komodo's own words — the view shows it instead of a bare "unavailable".
|
|
2561
|
+
unreachableReason: z.string().optional(),
|
|
2562
|
+
resources: z.array(DeployResourceSchema),
|
|
2563
|
+
servers: z.array(DeployServerSchema),
|
|
2564
|
+
// Newest first. Unresolved and resolved both: the view shows recent history, the badge reads only the
|
|
2565
|
+
// unresolved half.
|
|
2566
|
+
alerts: z.array(DeployAlertSchema),
|
|
2567
|
+
// When the owner last opened THIS connection's view. Rides the response so the rail decides what is new
|
|
2568
|
+
// without a second call. Absent ⇒ never opened, so everything counts as unseen.
|
|
2569
|
+
seenAt: z.number().optional(),
|
|
2570
|
+
});
|
|
2571
|
+
export type DeployOverviewResponse = z.infer<typeof DeployOverviewResponseSchema>;
|
|
2572
|
+
|
|
2573
|
+
// Which Komodo connection a call addresses — the capability id, which is also the rail tile's key.
|
|
2574
|
+
export const DeployCapabilityParamSchema = z.object({ capability: z.string() });
|
|
2575
|
+
export type DeployCapabilityParam = z.infer<typeof DeployCapabilityParamSchema>;
|
|
2576
|
+
|
|
2577
|
+
// The five state-changing operations the view offers. Deliberately no `write/*`: editing config from a
|
|
2578
|
+
// dashboard is how you get drift the desired-state repo then fights, so configuration stays in Komodo or in
|
|
2579
|
+
// the intent repo. `pull` pulls the newest image AND deploys — the routine version bump as one click.
|
|
2580
|
+
export const DeployActionSchema = z.enum(["deploy", "restart", "start", "stop", "pull"]);
|
|
2581
|
+
export type DeployAction = z.infer<typeof DeployActionSchema>;
|
|
2582
|
+
|
|
2583
|
+
export const DeployActionParamSchema = z.object({
|
|
2584
|
+
capability: z.string(),
|
|
2585
|
+
kind: DeployResourceKindSchema,
|
|
2586
|
+
// Komodo's resource id. Re-resolved to a live resource per call, so a stale card cannot act on something
|
|
2587
|
+
// that has since been deleted — the CI actions' "re-resolve per call" rule.
|
|
2588
|
+
id: z.string(),
|
|
2589
|
+
action: DeployActionSchema,
|
|
2590
|
+
});
|
|
2591
|
+
export type DeployActionParam = z.infer<typeof DeployActionParamSchema>;
|
|
2592
|
+
|
|
2593
|
+
export const DeployLogsParamSchema = z.object({
|
|
2594
|
+
capability: z.string(),
|
|
2595
|
+
kind: DeployResourceKindSchema,
|
|
2596
|
+
id: z.string(),
|
|
2597
|
+
});
|
|
2598
|
+
export type DeployLogsParam = z.infer<typeof DeployLogsParamSchema>;
|
|
2599
|
+
|
|
2600
|
+
// Komodo returns a `Log` with both channels; the view renders them together, newest at the bottom, the way a
|
|
2601
|
+
// terminal would.
|
|
2602
|
+
export const DeployLogsResponseSchema = z.object({ stdout: z.string(), stderr: z.string() });
|
|
2603
|
+
export type DeployLogsResponse = z.infer<typeof DeployLogsResponseSchema>;
|
|
2604
|
+
|
|
2605
|
+
// The fix route opens an isolated conversation seeded with the resource, its state, and its log tail — the
|
|
2606
|
+
// thing Komodo's own UI structurally cannot do, since the repo that holds the bug is open in the next tab.
|
|
2607
|
+
export const DeployFixResponseSchema = z.object({ conversationId: z.string() });
|
|
2608
|
+
export type DeployFixResponse = z.infer<typeof DeployFixResponseSchema>;
|
|
2609
|
+
|
|
2610
|
+
export const DeploySeenResponseSchema = z.object({ seenAt: z.number() });
|
|
2611
|
+
export type DeploySeenResponse = z.infer<typeof DeploySeenResponseSchema>;
|
|
2612
|
+
|
|
2438
2613
|
/* ---- the pre-push check: the workspace's own answer to "would this push go red" ----
|
|
2439
2614
|
*
|
|
2440
2615
|
* WHERE THIS SITS. A fleet of 5-20 agents lands work into the main tree, the user reviews and commits it by
|
package/src/workspace-state.ts
CHANGED
|
@@ -77,6 +77,11 @@ export const WORKSPACE_STATE_FILES: readonly WorkspaceStateFile[] = [
|
|
|
77
77
|
* Both entries below are outside that by design, so an empty set is the honest record — naming a key no
|
|
78
78
|
* query uses would put the drift this table exists to remove straight back into it. Each says which
|
|
79
79
|
* constraint would have to move first, so the next reader doesn't re-derive it. */
|
|
80
|
+
{
|
|
81
|
+
path: ".intentic/webchat-installs.json",
|
|
82
|
+
invalidates: [],
|
|
83
|
+
why: "Which origins have loaded a Doorbell's widget, written on a 30s flush timer while a customer's site serves page views. The install panel that renders it fetches on open and polls itself while it is on screen, which is the whole window in which the answer changes for anyone. Pushing instead would bill every connected browser a refetch per flush, for a panel almost nobody has open.",
|
|
84
|
+
},
|
|
80
85
|
{
|
|
81
86
|
path: ".intentic/webchat-sessions.json",
|
|
82
87
|
invalidates: [],
|
|
@@ -121,6 +126,11 @@ export const WORKSPACE_STATE_FILES: readonly WorkspaceStateFile[] = [
|
|
|
121
126
|
invalidates: [],
|
|
122
127
|
why: "Webhook secret + conclusion memory; the Pipelines view reads it through /ci/runs, not off disk.",
|
|
123
128
|
},
|
|
129
|
+
{
|
|
130
|
+
path: ".intentic/komodo.json",
|
|
131
|
+
invalidates: [],
|
|
132
|
+
why: "Per-connection 'when the owner last looked at Deployments'; the view reads it through /komodo/{capability}/overview, not off disk — and it is written BY that view being opened, so invalidating on it would refetch the board in answer to the browser's own click.",
|
|
133
|
+
},
|
|
124
134
|
{ path: ".intentic/bridge-tokens.json", invalidates: [], why: "Hashed ACP bridge tokens, listed on demand by the owner." },
|
|
125
135
|
{
|
|
126
136
|
path: ".intentic/owner.json",
|