@cat-factory/contracts 0.6.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/LICENSE +21 -0
- package/dist/accounts.d.ts +103 -0
- package/dist/accounts.d.ts.map +1 -0
- package/dist/accounts.js +102 -0
- package/dist/accounts.js.map +1 -0
- package/dist/agent-config.d.ts +77 -0
- package/dist/agent-config.d.ts.map +1 -0
- package/dist/agent-config.js +78 -0
- package/dist/agent-config.js.map +1 -0
- package/dist/api-keys.d.ts +44 -0
- package/dist/api-keys.d.ts.map +1 -0
- package/dist/api-keys.js +49 -0
- package/dist/api-keys.js.map +1 -0
- package/dist/auth.d.ts +24 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +15 -0
- package/dist/auth.js.map +1 -0
- package/dist/board-scan.d.ts +89 -0
- package/dist/board-scan.d.ts.map +1 -0
- package/dist/board-scan.js +122 -0
- package/dist/board-scan.js.map +1 -0
- package/dist/bootstrap.d.ts +168 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +148 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/clarity.d.ts +75 -0
- package/dist/clarity.d.ts.map +1 -0
- package/dist/clarity.js +66 -0
- package/dist/clarity.js.map +1 -0
- package/dist/companion.d.ts +32 -0
- package/dist/companion.d.ts.map +1 -0
- package/dist/companion.js +43 -0
- package/dist/companion.js.map +1 -0
- package/dist/consensus.d.ts +195 -0
- package/dist/consensus.d.ts.map +1 -0
- package/dist/consensus.js +164 -0
- package/dist/consensus.js.map +1 -0
- package/dist/documents.d.ts +197 -0
- package/dist/documents.d.ts.map +1 -0
- package/dist/documents.js +161 -0
- package/dist/documents.js.map +1 -0
- package/dist/entities.d.ts +1691 -0
- package/dist/entities.d.ts.map +1 -0
- package/dist/entities.js +853 -0
- package/dist/entities.js.map +1 -0
- package/dist/environments.d.ts +426 -0
- package/dist/environments.d.ts.map +1 -0
- package/dist/environments.js +190 -0
- package/dist/environments.js.map +1 -0
- package/dist/events.d.ts +98 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +2 -0
- package/dist/events.js.map +1 -0
- package/dist/fragment-library.d.ts +123 -0
- package/dist/fragment-library.d.ts.map +1 -0
- package/dist/fragment-library.js +88 -0
- package/dist/fragment-library.js.map +1 -0
- package/dist/github.d.ts +215 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +204 -0
- package/dist/github.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/iteration-cap.d.ts +17 -0
- package/dist/iteration-cap.d.ts.map +1 -0
- package/dist/iteration-cap.js +25 -0
- package/dist/iteration-cap.js.map +1 -0
- package/dist/localModels.d.ts +54 -0
- package/dist/localModels.d.ts.map +1 -0
- package/dist/localModels.js +79 -0
- package/dist/localModels.js.map +1 -0
- package/dist/merge.d.ts +106 -0
- package/dist/merge.d.ts.map +1 -0
- package/dist/merge.js +129 -0
- package/dist/merge.js.map +1 -0
- package/dist/model-defaults.d.ts +23 -0
- package/dist/model-defaults.d.ts.map +1 -0
- package/dist/model-defaults.js +34 -0
- package/dist/model-defaults.js.map +1 -0
- package/dist/notifications.d.ts +136 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/notifications.js +125 -0
- package/dist/notifications.js.map +1 -0
- package/dist/observability.d.ts +271 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +152 -0
- package/dist/observability.js.map +1 -0
- package/dist/personal-subscriptions.d.ts +66 -0
- package/dist/personal-subscriptions.d.ts.map +1 -0
- package/dist/personal-subscriptions.js +70 -0
- package/dist/personal-subscriptions.js.map +1 -0
- package/dist/primitives.d.ts +57 -0
- package/dist/primitives.d.ts.map +1 -0
- package/dist/primitives.js +66 -0
- package/dist/primitives.js.map +1 -0
- package/dist/provisioning.d.ts +46 -0
- package/dist/provisioning.d.ts.map +1 -0
- package/dist/provisioning.js +107 -0
- package/dist/provisioning.js.map +1 -0
- package/dist/recurring.d.ts +117 -0
- package/dist/recurring.d.ts.map +1 -0
- package/dist/recurring.js +99 -0
- package/dist/recurring.js.map +1 -0
- package/dist/release.d.ts +60 -0
- package/dist/release.d.ts.map +1 -0
- package/dist/release.js +75 -0
- package/dist/release.js.map +1 -0
- package/dist/requests.d.ts +451 -0
- package/dist/requests.d.ts.map +1 -0
- package/dist/requests.js +231 -0
- package/dist/requests.js.map +1 -0
- package/dist/requirements.d.ts +127 -0
- package/dist/requirements.d.ts.map +1 -0
- package/dist/requirements.js +137 -0
- package/dist/requirements.js.map +1 -0
- package/dist/runners.d.ts +387 -0
- package/dist/runners.d.ts.map +1 -0
- package/dist/runners.js +117 -0
- package/dist/runners.js.map +1 -0
- package/dist/sandbox.d.ts +300 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +243 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/service-fragment-defaults.d.ts +16 -0
- package/dist/service-fragment-defaults.d.ts.map +1 -0
- package/dist/service-fragment-defaults.js +23 -0
- package/dist/service-fragment-defaults.js.map +1 -0
- package/dist/services.d.ts +81 -0
- package/dist/services.d.ts.map +1 -0
- package/dist/services.js +77 -0
- package/dist/services.js.map +1 -0
- package/dist/slack.d.ts +104 -0
- package/dist/slack.d.ts.map +1 -0
- package/dist/slack.js +98 -0
- package/dist/slack.js.map +1 -0
- package/dist/snapshot.d.ts +522 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +104 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/spec.d.ts +174 -0
- package/dist/spec.d.ts.map +1 -0
- package/dist/spec.js +173 -0
- package/dist/spec.js.map +1 -0
- package/dist/tasks.d.ts +150 -0
- package/dist/tasks.d.ts.map +1 -0
- package/dist/tasks.js +146 -0
- package/dist/tasks.js.map +1 -0
- package/dist/testing.d.ts +67 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +64 -0
- package/dist/testing.js.map +1 -0
- package/dist/tracker.d.ts +18 -0
- package/dist/tracker.d.ts.map +1 -0
- package/dist/tracker.js +24 -0
- package/dist/tracker.js.map +1 -0
- package/dist/vendor-credentials.d.ts +37 -0
- package/dist/vendor-credentials.d.ts.map +1 -0
- package/dist/vendor-credentials.js +40 -0
- package/dist/vendor-credentials.js.map +1 -0
- package/dist/workspace-settings.d.ts +36 -0
- package/dist/workspace-settings.d.ts.map +1 -0
- package/dist/workspace-settings.js +41 -0
- package/dist/workspace-settings.js.map +1 -0
- package/package.json +31 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
import { subscriptionVendorSchema } from './vendor-credentials.js';
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Personal (individual-usage) subscription wire contracts.
|
|
5
|
+
//
|
|
6
|
+
// Some subscriptions are licensed for INDIVIDUAL use only (Anthropic's consumer
|
|
7
|
+
// Claude subscription). Those are NOT pooled per workspace like the commercial
|
|
8
|
+
// coding-plan vendors; instead each user stores their OWN credential, and only
|
|
9
|
+
// that user's runs may use it. To make "only the user can use it" true even
|
|
10
|
+
// against an operator with the database + system key, the credential is
|
|
11
|
+
// **double-encrypted**: the raw token is sealed under a key derived from the
|
|
12
|
+
// user's PERSONAL PASSWORD (never stored), then encrypted again with the system
|
|
13
|
+
// key. The password is supplied at task start/retry — carried on the ambient
|
|
14
|
+
// `X-Personal-Password` header (not a body field) and cached client-side with a TTL to
|
|
15
|
+
// stay low-friction — to mint a short-lived, per-run activation the async container steps
|
|
16
|
+
// use (re-minted transparently while the run is tended; see the docs).
|
|
17
|
+
//
|
|
18
|
+
// The password layer's purpose is preventing ACCIDENTAL misuse (a credential can't be
|
|
19
|
+
// silently pooled), not defending against a system-key holder — the system encryption is
|
|
20
|
+
// the primary at-rest protection. See docs/individual-subscription-usage.md §3 for the
|
|
21
|
+
// honest threat model + the full safeguards.
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
/**
|
|
24
|
+
* The personal password that gates the second encryption layer (8–256 chars). Restricted
|
|
25
|
+
* to printable ASCII so the same value can ride **raw** in the `X-Personal-Password`
|
|
26
|
+
* request header (see below) when unlocking a run — HTTP header values must be Latin-1, so
|
|
27
|
+
* a non-ASCII password could not be sent without encoding. Never stored server-side.
|
|
28
|
+
*/
|
|
29
|
+
export const personalPasswordSchema = v.pipe(v.string(), v.minLength(8), v.maxLength(256), v.regex(/^[\x20-\x7e]+$/, 'Password must use printable ASCII characters (no tabs/newlines).'));
|
|
30
|
+
/**
|
|
31
|
+
* HTTP header carrying the personal password to unlock a run's individual-usage
|
|
32
|
+
* credential(s). It is an AMBIENT credential — like the bearer token, the client attaches
|
|
33
|
+
* it on the gated calls (start / retry / resolve / approve / request-changes) rather than
|
|
34
|
+
* baking it into each request body — so it never appears in a wire-contract payload. The
|
|
35
|
+
* server reads it, unlocks, and mints/re-mints the per-run activation; absent + required ⇒
|
|
36
|
+
* `428 credential_required`.
|
|
37
|
+
*/
|
|
38
|
+
export const PERSONAL_PASSWORD_HEADER = 'X-Personal-Password';
|
|
39
|
+
/** Store (or replace) the signed-in user's personal subscription for a vendor. */
|
|
40
|
+
export const storePersonalSubscriptionSchema = v.object({
|
|
41
|
+
vendor: subscriptionVendorSchema,
|
|
42
|
+
label: v.pipe(v.string(), v.trim(), v.minLength(1), v.maxLength(120)),
|
|
43
|
+
/** The raw secret (write-only): the `claude setup-token` OAuth token for `claude`. */
|
|
44
|
+
token: v.pipe(v.string(), v.trim(), v.minLength(1)),
|
|
45
|
+
/** Personal password that gates the second encryption layer. Never stored. */
|
|
46
|
+
password: personalPasswordSchema,
|
|
47
|
+
/**
|
|
48
|
+
* Epoch ms the subscription itself expires (so we can warn well in advance and
|
|
49
|
+
* block runs once lapsed). Optional — omit if the plan has no fixed end date.
|
|
50
|
+
*/
|
|
51
|
+
expiresAt: v.optional(v.nullable(v.number())),
|
|
52
|
+
});
|
|
53
|
+
/** Read-only status of one personal subscription — metadata only, never the secret. */
|
|
54
|
+
export const personalSubscriptionStatusSchema = v.object({
|
|
55
|
+
vendor: subscriptionVendorSchema,
|
|
56
|
+
label: v.string(),
|
|
57
|
+
createdAt: v.number(),
|
|
58
|
+
updatedAt: v.number(),
|
|
59
|
+
lastUsedAt: v.nullable(v.number()),
|
|
60
|
+
/** Subscription's own expiry (null = no fixed end date). */
|
|
61
|
+
expiresAt: v.nullable(v.number()),
|
|
62
|
+
/** Whole days until `expiresAt` (negative once lapsed; null when no expiry). */
|
|
63
|
+
expiresInDays: v.nullable(v.number()),
|
|
64
|
+
/** Whether the subscription's expiry has already passed. */
|
|
65
|
+
expired: v.boolean(),
|
|
66
|
+
/** Whether renewal should be surfaced now (expiry within the warning window). */
|
|
67
|
+
renewSoon: v.boolean(),
|
|
68
|
+
});
|
|
69
|
+
export const personalSubscriptionListSchema = v.array(personalSubscriptionStatusSchema);
|
|
70
|
+
//# sourceMappingURL=personal-subscriptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"personal-subscriptions.js","sourceRoot":"","sources":["../src/personal-subscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAElE,8EAA8E;AAC9E,2DAA2D;AAC3D,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,6EAA6E;AAC7E,gFAAgF;AAChF,6EAA6E;AAC7E,uFAAuF;AACvF,0FAA0F;AAC1F,uEAAuE;AACvE,EAAE;AACF,sFAAsF;AACtF,yFAAyF;AACzF,uFAAuF;AACvF,6CAA6C;AAC7C,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,IAAI,CAC1C,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACd,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAChB,CAAC,CAAC,KAAK,CAAC,gBAAgB,EAAE,kEAAkE,CAAC,CAC9F,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,qBAAqB,CAAA;AAE7D,kFAAkF;AAClF,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC,MAAM,CAAC;IACtD,MAAM,EAAE,wBAAwB;IAChC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACrE,sFAAsF;IACtF,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACnD,8EAA8E;IAC9E,QAAQ,EAAE,sBAAsB;IAChC;;;OAGG;IACH,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;CAC9C,CAAC,CAAA;AAGF,uFAAuF;AACvF,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,CAAC,MAAM,CAAC;IACvD,MAAM,EAAE,wBAAwB;IAChC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAClC,4DAA4D;IAC5D,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACjC,gFAAgF;IAChF,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACrC,4DAA4D;IAC5D,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,iFAAiF;IACjF,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;CACvB,CAAC,CAAA;AAGF,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
export declare const blockTypeSchema: v.PicklistSchema<["frontend", "service", "api", "database", "queue", "integration", "external", "environment"], undefined>;
|
|
3
|
+
export type BlockType = v.InferOutput<typeof blockTypeSchema>;
|
|
4
|
+
export declare const blockStatusSchema: v.PicklistSchema<["planned", "ready", "in_progress", "blocked", "pr_ready", "done"], undefined>;
|
|
5
|
+
export type BlockStatus = v.InferOutput<typeof blockStatusSchema>;
|
|
6
|
+
export declare const blockLevelSchema: v.PicklistSchema<["frame", "module", "task"], undefined>;
|
|
7
|
+
export type BlockLevel = v.InferOutput<typeof blockLevelSchema>;
|
|
8
|
+
/**
|
|
9
|
+
* The kind of work a task represents, chosen by the human at creation. Drives the
|
|
10
|
+
* task card's icon/badge, per-type creation fields, and (optionally) the per-service
|
|
11
|
+
* running-task limit's bucketing. `recurring` is special: such tasks are NOT created
|
|
12
|
+
* through `addTask` — they are the reused on-board block of a recurring-pipeline
|
|
13
|
+
* schedule, stamped with this type so the board renders them consistently.
|
|
14
|
+
*/
|
|
15
|
+
export declare const taskTypeSchema: v.PicklistSchema<["feature", "bug", "document", "spike", "recurring"], undefined>;
|
|
16
|
+
export type TaskType = v.InferOutput<typeof taskTypeSchema>;
|
|
17
|
+
/** The task types a human can pick in the create-task form (recurring is created via a schedule). */
|
|
18
|
+
export declare const createTaskTypeSchema: v.PicklistSchema<["feature", "bug", "document", "spike"], undefined>;
|
|
19
|
+
export type CreateTaskType = v.InferOutput<typeof createTaskTypeSchema>;
|
|
20
|
+
/**
|
|
21
|
+
* Small, additive, per-type fields collected on the create-task form. All optional;
|
|
22
|
+
* which ones are shown depends on the chosen {@link TaskType}. Stored verbatim on the
|
|
23
|
+
* block as a sparse object so adding a field never needs a schema migration.
|
|
24
|
+
*/
|
|
25
|
+
export declare const taskTypeFieldsSchema: v.ObjectSchema<{
|
|
26
|
+
/** Bug: how severe the defect is. */
|
|
27
|
+
readonly severity: v.OptionalSchema<v.PicklistSchema<["low", "medium", "high", "critical"], undefined>, undefined>;
|
|
28
|
+
/** Bug: reproduction steps / observed-vs-expected. */
|
|
29
|
+
readonly stepsToReproduce: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 4000, undefined>]>, undefined>;
|
|
30
|
+
/** Spike: the investigation time-box, in hours. */
|
|
31
|
+
readonly timeboxHours: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1000, undefined>]>, undefined>;
|
|
32
|
+
/** Document: what kind of document this task produces. */
|
|
33
|
+
readonly docKind: v.OptionalSchema<v.PicklistSchema<["prd", "rfc", "runbook", "reference", "other"], undefined>, undefined>;
|
|
34
|
+
}, undefined>;
|
|
35
|
+
export type TaskTypeFields = v.InferOutput<typeof taskTypeFieldsSchema>;
|
|
36
|
+
export declare const agentStateSchema: v.PicklistSchema<["pending", "working", "waiting_decision", "done"], undefined>;
|
|
37
|
+
export type AgentState = v.InferOutput<typeof agentStateSchema>;
|
|
38
|
+
/** Agent kinds are an open set — custom agents get free-form ids. */
|
|
39
|
+
export declare const agentKindSchema: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
40
|
+
export type AgentKind = v.InferOutput<typeof agentKindSchema>;
|
|
41
|
+
export declare const positionSchema: v.ObjectSchema<{
|
|
42
|
+
readonly x: v.NumberSchema<undefined>;
|
|
43
|
+
readonly y: v.NumberSchema<undefined>;
|
|
44
|
+
}, undefined>;
|
|
45
|
+
export type Position = v.InferOutput<typeof positionSchema>;
|
|
46
|
+
/**
|
|
47
|
+
* An explicit pixel size for a resizable block (a service frame today). Optional
|
|
48
|
+
* on a block: when absent the board auto-sizes the frame from its contents; when
|
|
49
|
+
* present it is the user's dragged size, clamped client-side to never shrink below
|
|
50
|
+
* the content's natural extent. Strictly positive.
|
|
51
|
+
*/
|
|
52
|
+
export declare const sizeSchema: v.ObjectSchema<{
|
|
53
|
+
readonly w: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>]>;
|
|
54
|
+
readonly h: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>]>;
|
|
55
|
+
}, undefined>;
|
|
56
|
+
export type Size = v.InferOutput<typeof sizeSchema>;
|
|
57
|
+
//# sourceMappingURL=primitives.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../src/primitives.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAM5B,eAAO,MAAM,eAAe,4HAS1B,CAAA;AACF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,eAAe,CAAC,CAAA;AAE7D,eAAO,MAAM,iBAAiB,iGAO5B,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAEjE,eAAO,MAAM,gBAAgB,0DAA0C,CAAA;AACvE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAE/D;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,mFAAmE,CAAA;AAC9F,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D,qGAAqG;AACrG,eAAO,MAAM,oBAAoB,sEAAsD,CAAA;AACvF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEvE;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;IAC/B,qCAAqC;;IAErC,sDAAsD;;IAEtD,mDAAmD;;IAEnD,0DAA0D;;aAE1D,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEvE,eAAO,MAAM,gBAAgB,iFAAiE,CAAA;AAC9F,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAE/D,qEAAqE;AACrE,eAAO,MAAM,eAAe,iGAAqC,CAAA;AACjE,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,eAAe,CAAC,CAAA;AAE7D,eAAO,MAAM,cAAc;;;aAGzB,CAAA;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,UAAU;;;aAGrB,CAAA;AACF,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,UAAU,CAAC,CAAA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
// Shared scalar schemas. Picklists mirror the frontend's `app/types/domain.ts`
|
|
3
|
+
// unions exactly, so a payload that validates here drops straight into the Pinia
|
|
4
|
+
// stores without translation.
|
|
5
|
+
export const blockTypeSchema = v.picklist([
|
|
6
|
+
'frontend',
|
|
7
|
+
'service',
|
|
8
|
+
'api',
|
|
9
|
+
'database',
|
|
10
|
+
'queue',
|
|
11
|
+
'integration',
|
|
12
|
+
'external',
|
|
13
|
+
'environment',
|
|
14
|
+
]);
|
|
15
|
+
export const blockStatusSchema = v.picklist([
|
|
16
|
+
'planned',
|
|
17
|
+
'ready',
|
|
18
|
+
'in_progress',
|
|
19
|
+
'blocked',
|
|
20
|
+
'pr_ready',
|
|
21
|
+
'done',
|
|
22
|
+
]);
|
|
23
|
+
export const blockLevelSchema = v.picklist(['frame', 'module', 'task']);
|
|
24
|
+
/**
|
|
25
|
+
* The kind of work a task represents, chosen by the human at creation. Drives the
|
|
26
|
+
* task card's icon/badge, per-type creation fields, and (optionally) the per-service
|
|
27
|
+
* running-task limit's bucketing. `recurring` is special: such tasks are NOT created
|
|
28
|
+
* through `addTask` — they are the reused on-board block of a recurring-pipeline
|
|
29
|
+
* schedule, stamped with this type so the board renders them consistently.
|
|
30
|
+
*/
|
|
31
|
+
export const taskTypeSchema = v.picklist(['feature', 'bug', 'document', 'spike', 'recurring']);
|
|
32
|
+
/** The task types a human can pick in the create-task form (recurring is created via a schedule). */
|
|
33
|
+
export const createTaskTypeSchema = v.picklist(['feature', 'bug', 'document', 'spike']);
|
|
34
|
+
/**
|
|
35
|
+
* Small, additive, per-type fields collected on the create-task form. All optional;
|
|
36
|
+
* which ones are shown depends on the chosen {@link TaskType}. Stored verbatim on the
|
|
37
|
+
* block as a sparse object so adding a field never needs a schema migration.
|
|
38
|
+
*/
|
|
39
|
+
export const taskTypeFieldsSchema = v.object({
|
|
40
|
+
/** Bug: how severe the defect is. */
|
|
41
|
+
severity: v.optional(v.picklist(['low', 'medium', 'high', 'critical'])),
|
|
42
|
+
/** Bug: reproduction steps / observed-vs-expected. */
|
|
43
|
+
stepsToReproduce: v.optional(v.pipe(v.string(), v.maxLength(4000))),
|
|
44
|
+
/** Spike: the investigation time-box, in hours. */
|
|
45
|
+
timeboxHours: v.optional(v.pipe(v.number(), v.minValue(0), v.maxValue(1000))),
|
|
46
|
+
/** Document: what kind of document this task produces. */
|
|
47
|
+
docKind: v.optional(v.picklist(['prd', 'rfc', 'runbook', 'reference', 'other'])),
|
|
48
|
+
});
|
|
49
|
+
export const agentStateSchema = v.picklist(['pending', 'working', 'waiting_decision', 'done']);
|
|
50
|
+
/** Agent kinds are an open set — custom agents get free-form ids. */
|
|
51
|
+
export const agentKindSchema = v.pipe(v.string(), v.minLength(1));
|
|
52
|
+
export const positionSchema = v.object({
|
|
53
|
+
x: v.number(),
|
|
54
|
+
y: v.number(),
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* An explicit pixel size for a resizable block (a service frame today). Optional
|
|
58
|
+
* on a block: when absent the board auto-sizes the frame from its contents; when
|
|
59
|
+
* present it is the user's dragged size, clamped client-side to never shrink below
|
|
60
|
+
* the content's natural extent. Strictly positive.
|
|
61
|
+
*/
|
|
62
|
+
export const sizeSchema = v.object({
|
|
63
|
+
w: v.pipe(v.number(), v.minValue(1)),
|
|
64
|
+
h: v.pipe(v.number(), v.minValue(1)),
|
|
65
|
+
});
|
|
66
|
+
//# sourceMappingURL=primitives.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../src/primitives.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,+EAA+E;AAC/E,iFAAiF;AACjF,8BAA8B;AAE9B,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,QAAQ,CAAC;IACxC,UAAU;IACV,SAAS;IACT,KAAK;IACL,UAAU;IACV,OAAO;IACP,aAAa;IACb,UAAU;IACV,aAAa;CACd,CAAC,CAAA;AAGF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC1C,SAAS;IACT,OAAO;IACP,aAAa;IACb,SAAS;IACT,UAAU;IACV,MAAM;CACP,CAAC,CAAA;AAGF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;AAGvE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAA;AAG9F,qGAAqG;AACrG,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAA;AAGvF;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,qCAAqC;IACrC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACvE,sDAAsD;IACtD,gBAAgB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACnE,mDAAmD;IACnD,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7E,0DAA0D;IAC1D,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;CACjF,CAAC,CAAA;AAGF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAA;AAG9F,qEAAqE;AACrE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;AAGjE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IACb,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;CACd,CAAC,CAAA;AAGF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;CACrC,CAAC,CAAA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
/**
|
|
3
|
+
* Where a service's container jobs run. `cloudflare` is the built-in per-run
|
|
4
|
+
* Container backend; `docker` is the local Docker/Podman daemon the local-mode
|
|
5
|
+
* facade drives directly (no cloud at all — the abstract size maps to container
|
|
6
|
+
* resource limits, and the Tester stands its infra up with Docker-in-Docker);
|
|
7
|
+
* `aws`/`gcp`/`azure`/`custom` all route to a self-hosted runner pool that
|
|
8
|
+
* provisions on that cloud — we only forward the resolved instance-type id, we
|
|
9
|
+
* never call those clouds' APIs directly.
|
|
10
|
+
*/
|
|
11
|
+
export declare const cloudProviderSchema: v.PicklistSchema<["cloudflare", "docker", "aws", "gcp", "azure", "custom"], undefined>;
|
|
12
|
+
export type CloudProvider = v.InferOutput<typeof cloudProviderSchema>;
|
|
13
|
+
/** Abstract, cloud-neutral instance size selectable per service. */
|
|
14
|
+
export declare const instanceSizeSchema: v.PicklistSchema<["small", "medium", "large", "xlarge"], undefined>;
|
|
15
|
+
export type InstanceSize = v.InferOutput<typeof instanceSizeSchema>;
|
|
16
|
+
/** The default size used when a service has not picked one. */
|
|
17
|
+
export declare const DEFAULT_INSTANCE_SIZE: InstanceSize;
|
|
18
|
+
/** The default provider used when neither the service nor its account has picked one. */
|
|
19
|
+
export declare const DEFAULT_CLOUD_PROVIDER: CloudProvider;
|
|
20
|
+
/**
|
|
21
|
+
* Map each `(provider, size)` to the concrete instance-type id the target expects.
|
|
22
|
+
* Cloudflare ids are real Container instance types (see `wrangler.toml`); the other
|
|
23
|
+
* clouds carry conventional defaults a self-hosted pool can honour or override. For
|
|
24
|
+
* `custom` the abstract size IS the id — a custom pool's manifest maps it to its own
|
|
25
|
+
* sizing (so an org with bespoke orchestration plugs its definitions in there).
|
|
26
|
+
*/
|
|
27
|
+
export declare const INSTANCE_TYPE_IDS: Record<CloudProvider, Record<InstanceSize, string>>;
|
|
28
|
+
/** Resolve the concrete instance-type id to send to the transport for a service. */
|
|
29
|
+
export declare function resolveInstanceTypeId(provider?: CloudProvider, size?: InstanceSize): string;
|
|
30
|
+
/**
|
|
31
|
+
* Concrete container resource limits per abstract size, used by the local
|
|
32
|
+
* Docker/Podman runner backend (`--memory` / `--cpus` on `docker run`). The
|
|
33
|
+
* local facade never provisions cloud instances — it sizes the per-job container
|
|
34
|
+
* on the host daemon — so the abstract `InstanceSize` maps straight to limits here
|
|
35
|
+
* rather than to a cloud instance-type id.
|
|
36
|
+
*/
|
|
37
|
+
export interface DockerResourceLimits {
|
|
38
|
+
/** `--memory` value (e.g. `2g`). */
|
|
39
|
+
memory: string;
|
|
40
|
+
/** `--cpus` value (e.g. `2`). */
|
|
41
|
+
cpus: string;
|
|
42
|
+
}
|
|
43
|
+
export declare const DOCKER_RESOURCE_LIMITS: Record<InstanceSize, DockerResourceLimits>;
|
|
44
|
+
/** Resolve the local container resource limits for a service's abstract size. */
|
|
45
|
+
export declare function resolveDockerResources(size?: InstanceSize): DockerResourceLimits;
|
|
46
|
+
//# sourceMappingURL=provisioning.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provisioning.d.ts","sourceRoot":"","sources":["../src/provisioning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAuB5B;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,wFAO9B,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAErE,oEAAoE;AACpE,eAAO,MAAM,kBAAkB,qEAAqD,CAAA;AACpF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAEnE,+DAA+D;AAC/D,eAAO,MAAM,qBAAqB,EAAE,YAAuB,CAAA;AAE3D,yFAAyF;AACzF,eAAO,MAAM,sBAAsB,EAAE,aAA4B,CAAA;AAEjE;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAwCjF,CAAA;AAED,oFAAoF;AACpF,wBAAgB,qBAAqB,CACnC,QAAQ,GAAE,aAAsC,EAChD,IAAI,GAAE,YAAoC,GACzC,MAAM,CAER;AAED;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAA;CACb;AAED,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,YAAY,EAAE,oBAAoB,CAK7E,CAAA;AAED,iFAAiF;AACjF,wBAAgB,sBAAsB,CACpC,IAAI,GAAE,YAAoC,GACzC,oBAAoB,CAEtB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Container provisioning vocabulary.
|
|
4
|
+
//
|
|
5
|
+
// We do NOT provision compute on AWS/GCP/Azure ourselves — an org's self-hosted
|
|
6
|
+
// runner pool does that. What we own is a small, cloud-neutral vocabulary:
|
|
7
|
+
// - a `CloudProvider` selecting which target a service's jobs run on, and
|
|
8
|
+
// - an abstract t-shirt `InstanceSize` per service.
|
|
9
|
+
// At dispatch we resolve `(provider, size)` to the concrete instance-type id the
|
|
10
|
+
// target understands (the id string a custom pool expects) and hand it to the
|
|
11
|
+
// transport: a custom pool provisions itself from the id, and the local Docker
|
|
12
|
+
// backend maps the abstract size to `--memory`/`--cpus` limits. The provider is
|
|
13
|
+
// chosen per service and, when unset, falls back to the owning account's
|
|
14
|
+
// `defaultCloudProvider` (the engine resolves this at dispatch).
|
|
15
|
+
//
|
|
16
|
+
// Per-service sizing applies only to the backends that can honour it (the
|
|
17
|
+
// self-hosted pool and local Docker). The Cloudflare Container backend has a FIXED
|
|
18
|
+
// instance type per container class — set by `[[containers]] instance_type` in
|
|
19
|
+
// `wrangler.toml`, applying to every run — with no per-dispatch override, so it
|
|
20
|
+
// ignores these hints. Pick `cloudflare` when you don't need per-service sizing.
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
/**
|
|
23
|
+
* Where a service's container jobs run. `cloudflare` is the built-in per-run
|
|
24
|
+
* Container backend; `docker` is the local Docker/Podman daemon the local-mode
|
|
25
|
+
* facade drives directly (no cloud at all — the abstract size maps to container
|
|
26
|
+
* resource limits, and the Tester stands its infra up with Docker-in-Docker);
|
|
27
|
+
* `aws`/`gcp`/`azure`/`custom` all route to a self-hosted runner pool that
|
|
28
|
+
* provisions on that cloud — we only forward the resolved instance-type id, we
|
|
29
|
+
* never call those clouds' APIs directly.
|
|
30
|
+
*/
|
|
31
|
+
export const cloudProviderSchema = v.picklist([
|
|
32
|
+
'cloudflare',
|
|
33
|
+
'docker',
|
|
34
|
+
'aws',
|
|
35
|
+
'gcp',
|
|
36
|
+
'azure',
|
|
37
|
+
'custom',
|
|
38
|
+
]);
|
|
39
|
+
/** Abstract, cloud-neutral instance size selectable per service. */
|
|
40
|
+
export const instanceSizeSchema = v.picklist(['small', 'medium', 'large', 'xlarge']);
|
|
41
|
+
/** The default size used when a service has not picked one. */
|
|
42
|
+
export const DEFAULT_INSTANCE_SIZE = 'medium';
|
|
43
|
+
/** The default provider used when neither the service nor its account has picked one. */
|
|
44
|
+
export const DEFAULT_CLOUD_PROVIDER = 'cloudflare';
|
|
45
|
+
/**
|
|
46
|
+
* Map each `(provider, size)` to the concrete instance-type id the target expects.
|
|
47
|
+
* Cloudflare ids are real Container instance types (see `wrangler.toml`); the other
|
|
48
|
+
* clouds carry conventional defaults a self-hosted pool can honour or override. For
|
|
49
|
+
* `custom` the abstract size IS the id — a custom pool's manifest maps it to its own
|
|
50
|
+
* sizing (so an org with bespoke orchestration plugs its definitions in there).
|
|
51
|
+
*/
|
|
52
|
+
export const INSTANCE_TYPE_IDS = {
|
|
53
|
+
cloudflare: {
|
|
54
|
+
small: 'standard-1',
|
|
55
|
+
medium: 'standard-2',
|
|
56
|
+
large: 'standard-3',
|
|
57
|
+
xlarge: 'standard-4',
|
|
58
|
+
},
|
|
59
|
+
aws: {
|
|
60
|
+
small: 't3.small',
|
|
61
|
+
medium: 't3.large',
|
|
62
|
+
large: 'm5.xlarge',
|
|
63
|
+
xlarge: 'm5.2xlarge',
|
|
64
|
+
},
|
|
65
|
+
gcp: {
|
|
66
|
+
small: 'e2-small',
|
|
67
|
+
medium: 'e2-standard-2',
|
|
68
|
+
large: 'e2-standard-4',
|
|
69
|
+
xlarge: 'e2-standard-8',
|
|
70
|
+
},
|
|
71
|
+
azure: {
|
|
72
|
+
small: 'Standard_B2s',
|
|
73
|
+
medium: 'Standard_D2s_v5',
|
|
74
|
+
large: 'Standard_D4s_v5',
|
|
75
|
+
xlarge: 'Standard_D8s_v5',
|
|
76
|
+
},
|
|
77
|
+
// Pass-through: the abstract size id is forwarded verbatim (to the custom pool's
|
|
78
|
+
// manifest, or — for `docker` — to the local transport, which maps it to concrete
|
|
79
|
+
// container resource limits via `DOCKER_RESOURCE_LIMITS`).
|
|
80
|
+
custom: {
|
|
81
|
+
small: 'small',
|
|
82
|
+
medium: 'medium',
|
|
83
|
+
large: 'large',
|
|
84
|
+
xlarge: 'xlarge',
|
|
85
|
+
},
|
|
86
|
+
docker: {
|
|
87
|
+
small: 'small',
|
|
88
|
+
medium: 'medium',
|
|
89
|
+
large: 'large',
|
|
90
|
+
xlarge: 'xlarge',
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
/** Resolve the concrete instance-type id to send to the transport for a service. */
|
|
94
|
+
export function resolveInstanceTypeId(provider = DEFAULT_CLOUD_PROVIDER, size = DEFAULT_INSTANCE_SIZE) {
|
|
95
|
+
return INSTANCE_TYPE_IDS[provider][size];
|
|
96
|
+
}
|
|
97
|
+
export const DOCKER_RESOURCE_LIMITS = {
|
|
98
|
+
small: { memory: '1g', cpus: '1' },
|
|
99
|
+
medium: { memory: '2g', cpus: '2' },
|
|
100
|
+
large: { memory: '4g', cpus: '4' },
|
|
101
|
+
xlarge: { memory: '8g', cpus: '8' },
|
|
102
|
+
};
|
|
103
|
+
/** Resolve the local container resource limits for a service's abstract size. */
|
|
104
|
+
export function resolveDockerResources(size = DEFAULT_INSTANCE_SIZE) {
|
|
105
|
+
return DOCKER_RESOURCE_LIMITS[size];
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=provisioning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provisioning.js","sourceRoot":"","sources":["../src/provisioning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,8EAA8E;AAC9E,qCAAqC;AACrC,EAAE;AACF,gFAAgF;AAChF,2EAA2E;AAC3E,4EAA4E;AAC5E,sDAAsD;AACtD,iFAAiF;AACjF,8EAA8E;AAC9E,+EAA+E;AAC/E,gFAAgF;AAChF,yEAAyE;AACzE,iEAAiE;AACjE,EAAE;AACF,0EAA0E;AAC1E,mFAAmF;AACnF,+EAA+E;AAC/E,gFAAgF;AAChF,iFAAiF;AACjF,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC5C,YAAY;IACZ,QAAQ;IACR,KAAK;IACL,KAAK;IACL,OAAO;IACP,QAAQ;CACT,CAAC,CAAA;AAGF,oEAAoE;AACpE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;AAGpF,+DAA+D;AAC/D,MAAM,CAAC,MAAM,qBAAqB,GAAiB,QAAQ,CAAA;AAE3D,yFAAyF;AACzF,MAAM,CAAC,MAAM,sBAAsB,GAAkB,YAAY,CAAA;AAEjE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAwD;IACpF,UAAU,EAAE;QACV,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,YAAY;QACpB,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,YAAY;KACrB;IACD,GAAG,EAAE;QACH,KAAK,EAAE,UAAU;QACjB,MAAM,EAAE,UAAU;QAClB,KAAK,EAAE,WAAW;QAClB,MAAM,EAAE,YAAY;KACrB;IACD,GAAG,EAAE;QACH,KAAK,EAAE,UAAU;QACjB,MAAM,EAAE,eAAe;QACvB,KAAK,EAAE,eAAe;QACtB,MAAM,EAAE,eAAe;KACxB;IACD,KAAK,EAAE;QACL,KAAK,EAAE,cAAc;QACrB,MAAM,EAAE,iBAAiB;QACzB,KAAK,EAAE,iBAAiB;QACxB,MAAM,EAAE,iBAAiB;KAC1B;IACD,iFAAiF;IACjF,kFAAkF;IAClF,2DAA2D;IAC3D,MAAM,EAAE;QACN,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;KACjB;IACD,MAAM,EAAE;QACN,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;KACjB;CACF,CAAA;AAED,oFAAoF;AACpF,MAAM,UAAU,qBAAqB,CACnC,QAAQ,GAAkB,sBAAsB,EAChD,IAAI,GAAiB,qBAAqB;IAE1C,OAAO,iBAAiB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAA;AAC1C,CAAC;AAgBD,MAAM,CAAC,MAAM,sBAAsB,GAA+C;IAChF,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;IAClC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;IACnC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;IAClC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;CACpC,CAAA;AAED,iFAAiF;AACjF,MAAM,UAAU,sBAAsB,CACpC,IAAI,GAAiB,qBAAqB;IAE1C,OAAO,sBAAsB,CAAC,IAAI,CAAC,CAAA;AACrC,CAAC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
/** Template a schedule was created from; drives the seeded block description. */
|
|
3
|
+
export declare const scheduleTemplateSchema: v.PicklistSchema<["dep-update", "tech-debt", "custom"], undefined>;
|
|
4
|
+
export type ScheduleTemplate = v.InferOutput<typeof scheduleTemplateSchema>;
|
|
5
|
+
/**
|
|
6
|
+
* How often a schedule fires and when it is allowed to. `intervalHours` is the
|
|
7
|
+
* base cadence; `weekdays` (0=Sunday..6=Saturday; empty = every day) and the
|
|
8
|
+
* `windowStartHour`/`windowEndHour` range (both null = any hour) gate which
|
|
9
|
+
* instants are eligible, evaluated in `timezone` (an IANA zone, e.g.
|
|
10
|
+
* "Europe/Helsinki"; default "UTC").
|
|
11
|
+
*/
|
|
12
|
+
export declare const recurrenceSchema: v.ObjectSchema<{
|
|
13
|
+
readonly intervalHours: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, number, undefined>]>;
|
|
14
|
+
/** Allowed weekdays (0–6). Empty means every day. */
|
|
15
|
+
readonly weekdays: v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 6, undefined>]>, undefined>;
|
|
16
|
+
/** Inclusive start of the allowed hour-of-day window, or null for no lower bound. */
|
|
17
|
+
readonly windowStartHour: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 23, undefined>]>, undefined>;
|
|
18
|
+
/** Exclusive end of the allowed hour-of-day window, or null for no upper bound. */
|
|
19
|
+
readonly windowEndHour: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 23, undefined>]>, undefined>;
|
|
20
|
+
/** IANA timezone the weekday/hour window is evaluated in. */
|
|
21
|
+
readonly timezone: v.StringSchema<undefined>;
|
|
22
|
+
}, undefined>;
|
|
23
|
+
export type Recurrence = v.InferOutput<typeof recurrenceSchema>;
|
|
24
|
+
/**
|
|
25
|
+
* A recurring pipeline attached to a service. `blockId` is the reused on-board
|
|
26
|
+
* task block the pipeline runs against; `frameId` is the service frame it lives
|
|
27
|
+
* in. `nextRunAt` is the computed epoch-ms of the next eligible fire (the global
|
|
28
|
+
* sweeper queries `enabled AND nextRunAt <= now`).
|
|
29
|
+
*/
|
|
30
|
+
export declare const pipelineScheduleSchema: v.ObjectSchema<{
|
|
31
|
+
readonly id: v.StringSchema<undefined>;
|
|
32
|
+
/**
|
|
33
|
+
* The account-owned service this schedule belongs to (in-org sharing): a schedule on a
|
|
34
|
+
* shared service is visible on every workspace that mounts it and fires once per org.
|
|
35
|
+
* Null for a legacy schedule not yet associated with a service.
|
|
36
|
+
*/
|
|
37
|
+
readonly serviceId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
38
|
+
readonly blockId: v.StringSchema<undefined>;
|
|
39
|
+
readonly frameId: v.StringSchema<undefined>;
|
|
40
|
+
readonly pipelineId: v.StringSchema<undefined>;
|
|
41
|
+
readonly template: v.PicklistSchema<["dep-update", "tech-debt", "custom"], undefined>;
|
|
42
|
+
readonly name: v.StringSchema<undefined>;
|
|
43
|
+
readonly recurrence: v.ObjectSchema<{
|
|
44
|
+
readonly intervalHours: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, number, undefined>]>;
|
|
45
|
+
/** Allowed weekdays (0–6). Empty means every day. */
|
|
46
|
+
readonly weekdays: v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 6, undefined>]>, undefined>;
|
|
47
|
+
/** Inclusive start of the allowed hour-of-day window, or null for no lower bound. */
|
|
48
|
+
readonly windowStartHour: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 23, undefined>]>, undefined>;
|
|
49
|
+
/** Exclusive end of the allowed hour-of-day window, or null for no upper bound. */
|
|
50
|
+
readonly windowEndHour: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 23, undefined>]>, undefined>;
|
|
51
|
+
/** IANA timezone the weekday/hour window is evaluated in. */
|
|
52
|
+
readonly timezone: v.StringSchema<undefined>;
|
|
53
|
+
}, undefined>;
|
|
54
|
+
readonly enabled: v.BooleanSchema<undefined>;
|
|
55
|
+
readonly lastRunAt: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
|
|
56
|
+
readonly nextRunAt: v.NumberSchema<undefined>;
|
|
57
|
+
readonly createdAt: v.NumberSchema<undefined>;
|
|
58
|
+
}, undefined>;
|
|
59
|
+
export type PipelineSchedule = v.InferOutput<typeof pipelineScheduleSchema>;
|
|
60
|
+
/** One historical fire of a schedule (retained ~1 week), surfaced in the inspector. */
|
|
61
|
+
export declare const scheduleRunSchema: v.ObjectSchema<{
|
|
62
|
+
readonly id: v.StringSchema<undefined>;
|
|
63
|
+
readonly scheduleId: v.StringSchema<undefined>;
|
|
64
|
+
/** The execution this fire started, or null if the start was skipped/failed. */
|
|
65
|
+
readonly executionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
66
|
+
readonly status: v.PicklistSchema<["running", "done", "failed", "skipped"], undefined>;
|
|
67
|
+
readonly startedAt: v.NumberSchema<undefined>;
|
|
68
|
+
readonly finishedAt: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
|
|
69
|
+
/** Short outcome line (e.g. a PR URL or "merged"), or null while running. */
|
|
70
|
+
readonly outcome: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
71
|
+
}, undefined>;
|
|
72
|
+
export type ScheduleRun = v.InferOutput<typeof scheduleRunSchema>;
|
|
73
|
+
/** Create a recurring pipeline on a service frame. */
|
|
74
|
+
export declare const createScheduleSchema: v.ObjectSchema<{
|
|
75
|
+
readonly frameId: v.StringSchema<undefined>;
|
|
76
|
+
readonly pipelineId: v.StringSchema<undefined>;
|
|
77
|
+
readonly template: v.OptionalSchema<v.PicklistSchema<["dep-update", "tech-debt", "custom"], undefined>, "custom">;
|
|
78
|
+
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 80, undefined>]>;
|
|
79
|
+
readonly recurrence: v.ObjectSchema<{
|
|
80
|
+
readonly intervalHours: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, number, undefined>]>;
|
|
81
|
+
/** Allowed weekdays (0–6). Empty means every day. */
|
|
82
|
+
readonly weekdays: v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 6, undefined>]>, undefined>;
|
|
83
|
+
/** Inclusive start of the allowed hour-of-day window, or null for no lower bound. */
|
|
84
|
+
readonly windowStartHour: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 23, undefined>]>, undefined>;
|
|
85
|
+
/** Exclusive end of the allowed hour-of-day window, or null for no upper bound. */
|
|
86
|
+
readonly windowEndHour: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 23, undefined>]>, undefined>;
|
|
87
|
+
/** IANA timezone the weekday/hour window is evaluated in. */
|
|
88
|
+
readonly timezone: v.StringSchema<undefined>;
|
|
89
|
+
}, undefined>;
|
|
90
|
+
readonly enabled: v.OptionalSchema<v.BooleanSchema<undefined>, true>;
|
|
91
|
+
/**
|
|
92
|
+
* The prompt/description for the reused on-board task block — the same free-text a
|
|
93
|
+
* normal task carries, fed to every agent step. Omitted/empty ⇒ the template's seed
|
|
94
|
+
* description. This is what lets a `custom` recurring task say what it should do.
|
|
95
|
+
*/
|
|
96
|
+
readonly description: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MaxLengthAction<string, 2000, undefined>]>, undefined>;
|
|
97
|
+
}, undefined>;
|
|
98
|
+
export type CreateScheduleInput = v.InferOutput<typeof createScheduleSchema>;
|
|
99
|
+
/** Patch an existing schedule (all fields optional). */
|
|
100
|
+
export declare const updateScheduleSchema: v.ObjectSchema<{
|
|
101
|
+
readonly name: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 80, undefined>]>, undefined>;
|
|
102
|
+
readonly pipelineId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
103
|
+
readonly recurrence: v.OptionalSchema<v.ObjectSchema<{
|
|
104
|
+
readonly intervalHours: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, number, undefined>]>;
|
|
105
|
+
/** Allowed weekdays (0–6). Empty means every day. */
|
|
106
|
+
readonly weekdays: v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 6, undefined>]>, undefined>;
|
|
107
|
+
/** Inclusive start of the allowed hour-of-day window, or null for no lower bound. */
|
|
108
|
+
readonly windowStartHour: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 23, undefined>]>, undefined>;
|
|
109
|
+
/** Exclusive end of the allowed hour-of-day window, or null for no upper bound. */
|
|
110
|
+
readonly windowEndHour: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 23, undefined>]>, undefined>;
|
|
111
|
+
/** IANA timezone the weekday/hour window is evaluated in. */
|
|
112
|
+
readonly timezone: v.StringSchema<undefined>;
|
|
113
|
+
}, undefined>, undefined>;
|
|
114
|
+
readonly enabled: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
115
|
+
}, undefined>;
|
|
116
|
+
export type UpdateScheduleInput = v.InferOutput<typeof updateScheduleSchema>;
|
|
117
|
+
//# sourceMappingURL=recurring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recurring.d.ts","sourceRoot":"","sources":["../src/recurring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAiB5B,iFAAiF;AACjF,eAAO,MAAM,sBAAsB,oEAAoD,CAAA;AACvF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAK3E;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;;IAE3B,qDAAqD;;IAErD,qFAAqF;;IAErF,mFAAmF;;IAEnF,6DAA6D;;aAE7D,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;IAEjC;;;;OAIG;;;;;;;;;QAvBH,qDAAqD;;QAErD,qFAAqF;;QAErF,mFAAmF;;QAEnF,6DAA6D;;;;;;;aA6B7D,CAAA;AACF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAE3E,uFAAuF;AACvF,eAAO,MAAM,iBAAiB;;;IAG5B,gFAAgF;;;;;IAKhF,6EAA6E;;aAE7E,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAMjE,sDAAsD;AACtD,eAAO,MAAM,oBAAoB;;;;;;;QAzD/B,qDAAqD;;QAErD,qFAAqF;;QAErF,mFAAmF;;QAEnF,6DAA6D;;;;IA0D7D;;;;OAIG;;aAEH,CAAA;AACF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAE5E,wDAAwD;AACxD,eAAO,MAAM,oBAAoB;;;;;QA1E/B,qDAAqD;;QAErD,qFAAqF;;QAErF,mFAAmF;;QAEnF,6DAA6D;;;;aAyE7D,CAAA;AACF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAA"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Recurring-pipeline wire contracts. A *pipeline schedule* attaches a reusable
|
|
4
|
+
// pipeline to a service (a `frame` block) and re-runs it on a recurring cadence —
|
|
5
|
+
// e.g. weekly dependency updates, or a tech-debt remediation pass. Each schedule
|
|
6
|
+
// owns exactly one reused on-board block (a `task` leaf inside the service frame);
|
|
7
|
+
// every time the schedule fires it starts the pipeline against that block, so the
|
|
8
|
+
// board shows a single recurring task whose live status and run history a human
|
|
9
|
+
// can inspect.
|
|
10
|
+
//
|
|
11
|
+
// The cadence is "run every `intervalHours`", optionally constrained to an
|
|
12
|
+
// allowed window — a set of weekdays plus an hour-of-day range (e.g. business
|
|
13
|
+
// hours) evaluated in the schedule's timezone. The engine rolls the computed next
|
|
14
|
+
// run forward until it lands inside an allowed window.
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
/** Template a schedule was created from; drives the seeded block description. */
|
|
17
|
+
export const scheduleTemplateSchema = v.picklist(['dep-update', 'tech-debt', 'custom']);
|
|
18
|
+
const hourOfDaySchema = v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(23));
|
|
19
|
+
const weekdaySchema = v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(6));
|
|
20
|
+
/**
|
|
21
|
+
* How often a schedule fires and when it is allowed to. `intervalHours` is the
|
|
22
|
+
* base cadence; `weekdays` (0=Sunday..6=Saturday; empty = every day) and the
|
|
23
|
+
* `windowStartHour`/`windowEndHour` range (both null = any hour) gate which
|
|
24
|
+
* instants are eligible, evaluated in `timezone` (an IANA zone, e.g.
|
|
25
|
+
* "Europe/Helsinki"; default "UTC").
|
|
26
|
+
*/
|
|
27
|
+
export const recurrenceSchema = v.object({
|
|
28
|
+
intervalHours: v.pipe(v.number(), v.integer(), v.minValue(1), v.maxValue(24 * 365)),
|
|
29
|
+
/** Allowed weekdays (0–6). Empty means every day. */
|
|
30
|
+
weekdays: v.array(weekdaySchema),
|
|
31
|
+
/** Inclusive start of the allowed hour-of-day window, or null for no lower bound. */
|
|
32
|
+
windowStartHour: v.nullable(hourOfDaySchema),
|
|
33
|
+
/** Exclusive end of the allowed hour-of-day window, or null for no upper bound. */
|
|
34
|
+
windowEndHour: v.nullable(hourOfDaySchema),
|
|
35
|
+
/** IANA timezone the weekday/hour window is evaluated in. */
|
|
36
|
+
timezone: v.string(),
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* A recurring pipeline attached to a service. `blockId` is the reused on-board
|
|
40
|
+
* task block the pipeline runs against; `frameId` is the service frame it lives
|
|
41
|
+
* in. `nextRunAt` is the computed epoch-ms of the next eligible fire (the global
|
|
42
|
+
* sweeper queries `enabled AND nextRunAt <= now`).
|
|
43
|
+
*/
|
|
44
|
+
export const pipelineScheduleSchema = v.object({
|
|
45
|
+
id: v.string(),
|
|
46
|
+
/**
|
|
47
|
+
* The account-owned service this schedule belongs to (in-org sharing): a schedule on a
|
|
48
|
+
* shared service is visible on every workspace that mounts it and fires once per org.
|
|
49
|
+
* Null for a legacy schedule not yet associated with a service.
|
|
50
|
+
*/
|
|
51
|
+
serviceId: v.nullable(v.string()),
|
|
52
|
+
blockId: v.string(),
|
|
53
|
+
frameId: v.string(),
|
|
54
|
+
pipelineId: v.string(),
|
|
55
|
+
template: scheduleTemplateSchema,
|
|
56
|
+
name: v.string(),
|
|
57
|
+
recurrence: recurrenceSchema,
|
|
58
|
+
enabled: v.boolean(),
|
|
59
|
+
lastRunAt: v.nullable(v.number()),
|
|
60
|
+
nextRunAt: v.number(),
|
|
61
|
+
createdAt: v.number(),
|
|
62
|
+
});
|
|
63
|
+
/** One historical fire of a schedule (retained ~1 week), surfaced in the inspector. */
|
|
64
|
+
export const scheduleRunSchema = v.object({
|
|
65
|
+
id: v.string(),
|
|
66
|
+
scheduleId: v.string(),
|
|
67
|
+
/** The execution this fire started, or null if the start was skipped/failed. */
|
|
68
|
+
executionId: v.nullable(v.string()),
|
|
69
|
+
status: v.picklist(['running', 'done', 'failed', 'skipped']),
|
|
70
|
+
startedAt: v.number(),
|
|
71
|
+
finishedAt: v.nullable(v.number()),
|
|
72
|
+
/** Short outcome line (e.g. a PR URL or "merged"), or null while running. */
|
|
73
|
+
outcome: v.nullable(v.string()),
|
|
74
|
+
});
|
|
75
|
+
// ---- Request bodies -------------------------------------------------------
|
|
76
|
+
const scheduleNameSchema = v.pipe(v.string(), v.trim(), v.minLength(1), v.maxLength(80));
|
|
77
|
+
/** Create a recurring pipeline on a service frame. */
|
|
78
|
+
export const createScheduleSchema = v.object({
|
|
79
|
+
frameId: v.string(),
|
|
80
|
+
pipelineId: v.string(),
|
|
81
|
+
template: v.optional(scheduleTemplateSchema, 'custom'),
|
|
82
|
+
name: scheduleNameSchema,
|
|
83
|
+
recurrence: recurrenceSchema,
|
|
84
|
+
enabled: v.optional(v.boolean(), true),
|
|
85
|
+
/**
|
|
86
|
+
* The prompt/description for the reused on-board task block — the same free-text a
|
|
87
|
+
* normal task carries, fed to every agent step. Omitted/empty ⇒ the template's seed
|
|
88
|
+
* description. This is what lets a `custom` recurring task say what it should do.
|
|
89
|
+
*/
|
|
90
|
+
description: v.optional(v.pipe(v.string(), v.trim(), v.maxLength(2000))),
|
|
91
|
+
});
|
|
92
|
+
/** Patch an existing schedule (all fields optional). */
|
|
93
|
+
export const updateScheduleSchema = v.object({
|
|
94
|
+
name: v.optional(scheduleNameSchema),
|
|
95
|
+
pipelineId: v.optional(v.string()),
|
|
96
|
+
recurrence: v.optional(recurrenceSchema),
|
|
97
|
+
enabled: v.optional(v.boolean()),
|
|
98
|
+
});
|
|
99
|
+
//# sourceMappingURL=recurring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recurring.js","sourceRoot":"","sources":["../src/recurring.ts"],"names":[],"mappings":"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"}
|