@cat-factory/contracts 0.233.0 → 0.234.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.
@@ -55,12 +55,25 @@ export declare const notificationWebhookSchema: v.ObjectSchema<{
55
55
  }, undefined>;
56
56
  export type NotificationWebhook = v.InferOutput<typeof notificationWebhookSchema>;
57
57
  /**
58
- * Register or update the workspace's notification webhook. `secret` is write-only: omit it to keep
59
- * the stored one, pass a new value to rotate it. An `https:` URL is required — deliveries carry a
60
- * signed payload describing internal work, and plaintext HTTP would leak it on the wire.
58
+ * Register or update the workspace's notification webhook. EVERY field is keep-on-omit: what the
59
+ * body leaves out retains its stored value, so subscribing an existing endpoint to a new event
60
+ * family is a one-field write.
61
+ *
62
+ * That uniformity is the point, and `url` is optional for it. A mandatory re-send would make the
63
+ * common edit carry a value the caller did not intend to change, and a caller re-sending a URL it
64
+ * cached before someone else rotated the endpoint would silently redirect the workspace's
65
+ * deliveries back to the old receiver while appearing to only add a subscription. The first `PUT`
66
+ * on a workspace with nothing registered still needs one, and the service refuses with
67
+ * `reason: 'webhook_url_required'` rather than storing a half-endpoint.
68
+ *
69
+ * When supplied it must be `https:`: deliveries carry a signed payload describing internal work,
70
+ * and plaintext HTTP would leak it on the wire.
71
+ *
72
+ * `secret` is write-only: omit it to keep the stored one, pass a new value to rotate it.
61
73
  */
62
74
  export declare const putNotificationWebhookSchema: v.ObjectSchema<{
63
- readonly url: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.UrlAction<string, undefined>, v.StartsWithAction<string, "https://", "The webhook endpoint must be an https:// URL">, v.MaxLengthAction<string, 2000, undefined>]>;
75
+ /** Omit keep the registered endpoint (required only when registering the first one). */
76
+ readonly url: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.UrlAction<string, undefined>, v.StartsWithAction<string, "https://", "The webhook endpoint must be an https:// URL">, v.MaxLengthAction<string, 2000, undefined>]>, undefined>;
64
77
  /** Omit ⇒ deliver the default parking types. */
65
78
  readonly types: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "key_drift", "merge_tag_request"], undefined>, undefined>, undefined>;
66
79
  /** Omit ⇒ keep the current run-event subscription (none, for an endpoint that never set one). */
@@ -72,6 +85,50 @@ export declare const putNotificationWebhookSchema: v.ObjectSchema<{
72
85
  readonly secret: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 16, undefined>, v.MaxLengthAction<string, 200, undefined>]>, undefined>;
73
86
  }, undefined>;
74
87
  export type PutNotificationWebhookInput = v.InferOutput<typeof putNotificationWebhookSchema>;
88
+ /**
89
+ * What `GET /api/v1/notification-webhook` answers: the registered endpoint, or `null` when the
90
+ * workspace has none. Both the session surface and the public one project the SAME
91
+ * {@link notificationWebhookSchema}, because the projection is already the client-facing shape
92
+ * with the secret reduced to a boolean, and a second near-identical DTO would be one more thing
93
+ * to keep in step for no caller-visible gain.
94
+ *
95
+ * The WRAPPER, though, is public-surface-only, and it is not decoration. A bare nullable body is
96
+ * an honest wire shape but a poor generated one: the SDK emitters model a null at the top level of
97
+ * a response far less faithfully than a null on a FIELD (Go decodes a `null` body into a
98
+ * zero-valued struct, so "no endpoint registered" would arrive as an endpoint whose URL is the
99
+ * empty string). Wrapping keeps "none is registered" a value every client reads the same way, and
100
+ * leaves room to add a sibling field later without changing the response type.
101
+ */
102
+ export declare const publicNotificationWebhookSchema: v.ObjectSchema<{
103
+ /** The registered endpoint, or `null` when the workspace has none. */
104
+ readonly webhook: v.NullableSchema<v.ObjectSchema<{
105
+ /** The HTTPS endpoint deliveries are POSTed to. */
106
+ readonly url: v.StringSchema<undefined>;
107
+ /**
108
+ * Which notification types are delivered. EMPTY means "the parking types" — the defaults a
109
+ * headless overseer cares about — rather than "everything", so registering an endpoint can't
110
+ * accidentally fire-hose every card at an integration that only wanted to hear about parks.
111
+ */
112
+ readonly types: v.ArraySchema<v.PicklistSchema<["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "key_drift", "merge_tag_request"], undefined>, undefined>;
113
+ /**
114
+ * Which run-lifecycle events are delivered. EMPTY means NONE — the opposite of `types` above,
115
+ * deliberately: an endpoint registered before this existed must not start receiving a new event
116
+ * family it never asked for, so subscribing is explicit.
117
+ */
118
+ readonly runEvents: v.ArraySchema<v.PicklistSchema<["run.started", "run.completed", "run.failed"], undefined>, undefined>;
119
+ /**
120
+ * Which platform-health transitions are delivered. EMPTY means NONE, like {@link runEvents}:
121
+ * subscribing a receiver to alerts about the deployment itself is always an explicit choice.
122
+ */
123
+ readonly alertEvents: v.ArraySchema<v.PicklistSchema<["platform_health.firing", "platform_health.resolved"], undefined>, undefined>;
124
+ /** Whether deliveries are currently attempted. Registering an endpoint enables it. */
125
+ readonly enabled: v.BooleanSchema<undefined>;
126
+ /** Whether a signing secret is set (the secret itself is never returned). */
127
+ readonly hasSecret: v.BooleanSchema<undefined>;
128
+ readonly updatedAt: v.NumberSchema<undefined>;
129
+ }, undefined>, undefined>;
130
+ }, undefined>;
131
+ export type PublicNotificationWebhook = v.InferOutput<typeof publicNotificationWebhookSchema>;
75
132
  /**
76
133
  * The JSON body of one webhook delivery. Deliberately a thin envelope over the SAME
77
134
  * `notificationSchema` the in-app inbox and the public `GET /api/v1/notifications` already expose
@@ -1 +1 @@
1
- {"version":3,"file":"notification-webhooks.d.ts","sourceRoot":"","sources":["../src/notification-webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAoB5B;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,6EAA6D,CAAA;AACjG,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAEjF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,qFAGnC,CAAA;AACF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAA;AAEnF,+FAA+F;AAC/F,eAAO,MAAM,yBAAyB;IACpC,mDAAmD;;IAEnD;;;;OAIG;;IAEH;;;;OAIG;;IAEH;;;OAGG;;IAEH,sFAAsF;;IAEtF,6EAA6E;;;aAG7E,CAAA;AACF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAEjF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B;;IAQvC,gDAAgD;;IAEhD,iGAAiG;;IAEjG,uGAAuG;;;IAGvG,wDAAwD;;aAExD,CAAA;AACF,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAE5F;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iCAAiC;;IAE5C,kGAAkG;;;IAGlG,4DAA4D;;IAE5D,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAGnE,CAAA;AACF,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,iCAAiC,CAAC,CAAA;AAEjG;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,wBAAwB;;IAEnC,kGAAkG;;;;;;QAMhG,8FAA8F;;;;;QAK9F,sFAAsF;;;QAGtF;;;WAGG;;QAEH,oCAAoC;;;;;;;aAStC,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAA;AAE/E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mCAAmC;IAC9C,oEAAoE;;IAEpE,6FAA6F;;IAE7F,8EAA8E;;IAE9E;;;;;OAKG;;aAEH,CAAA;AACF,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,WAAW,CACvD,OAAO,mCAAmC,CAC3C,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,kCAAkC;;IAE7C,kGAAkG;;;;;QAKhG;;;WAGG;;QAEH;;;;WAIG;;QAEH;;;WAGG;;YArEL,oEAAoE;;YAEpE,6FAA6F;;YAE7F,8EAA8E;;YAE9E;;;;;eAKG;;;QA4DD;;;;WAIG;;QAEH;;;;;WAKG;;;;;;;QAEH;;;;WAIG;;;aAGL,CAAA;AACF,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,kCAAkC,CAAC,CAAA;AAEnG;;;;;;;;GAQG;AACH,eAAO,MAAM,kCAAkC,kKAS6B,CAAA"}
1
+ {"version":3,"file":"notification-webhooks.d.ts","sourceRoot":"","sources":["../src/notification-webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAoB5B;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,6EAA6D,CAAA;AACjG,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAEjF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,qFAGnC,CAAA;AACF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAA;AAEnF,+FAA+F;AAC/F,eAAO,MAAM,yBAAyB;IACpC,mDAAmD;;IAEnD;;;;OAIG;;IAEH;;;;OAIG;;IAEH;;;OAGG;;IAEH,sFAAsF;;IAEtF,6EAA6E;;;aAG7E,CAAA;AACF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAEjF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,4BAA4B;IACvC,0FAA0F;;IAU1F,gDAAgD;;IAEhD,iGAAiG;;IAEjG,uGAAuG;;;IAGvG,wDAAwD;;aAExD,CAAA;AACF,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAE5F;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,+BAA+B;IAC1C,sEAAsE;;QAlFtE,mDAAmD;;QAEnD;;;;WAIG;;QAEH;;;;WAIG;;QAEH;;;WAGG;;QAEH,sFAAsF;;QAEtF,6EAA6E;;;;aA+D7E,CAAA;AACF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,+BAA+B,CAAC,CAAA;AAE7F;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iCAAiC;;IAE5C,kGAAkG;;;IAGlG,4DAA4D;;IAE5D,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAGnE,CAAA;AACF,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,iCAAiC,CAAC,CAAA;AAEjG;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,wBAAwB;;IAEnC,kGAAkG;;;;;;QAMhG,8FAA8F;;;;;QAK9F,sFAAsF;;;QAGtF;;;WAGG;;QAEH,oCAAoC;;;;;;;aAStC,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAA;AAE/E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mCAAmC;IAC9C,oEAAoE;;IAEpE,6FAA6F;;IAE7F,8EAA8E;;IAE9E;;;;;OAKG;;aAEH,CAAA;AACF,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,WAAW,CACvD,OAAO,mCAAmC,CAC3C,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,kCAAkC;;IAE7C,kGAAkG;;;;;QAKhG;;;WAGG;;QAEH;;;;WAIG;;QAEH;;;WAGG;;YArEL,oEAAoE;;YAEpE,6FAA6F;;YAE7F,8EAA8E;;YAE9E;;;;;eAKG;;;QA4DD;;;;WAIG;;QAEH;;;;;WAKG;;;;;;;QAEH;;;;WAIG;;;aAGL,CAAA;AACF,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,kCAAkC,CAAC,CAAA;AAEnG;;;;;;;;GAQG;AACH,eAAO,MAAM,kCAAkC,kKAS6B,CAAA"}
@@ -72,12 +72,25 @@ export const notificationWebhookSchema = v.object({
72
72
  updatedAt: v.number(),
73
73
  });
74
74
  /**
75
- * Register or update the workspace's notification webhook. `secret` is write-only: omit it to keep
76
- * the stored one, pass a new value to rotate it. An `https:` URL is required — deliveries carry a
77
- * signed payload describing internal work, and plaintext HTTP would leak it on the wire.
75
+ * Register or update the workspace's notification webhook. EVERY field is keep-on-omit: what the
76
+ * body leaves out retains its stored value, so subscribing an existing endpoint to a new event
77
+ * family is a one-field write.
78
+ *
79
+ * That uniformity is the point, and `url` is optional for it. A mandatory re-send would make the
80
+ * common edit carry a value the caller did not intend to change, and a caller re-sending a URL it
81
+ * cached before someone else rotated the endpoint would silently redirect the workspace's
82
+ * deliveries back to the old receiver while appearing to only add a subscription. The first `PUT`
83
+ * on a workspace with nothing registered still needs one, and the service refuses with
84
+ * `reason: 'webhook_url_required'` rather than storing a half-endpoint.
85
+ *
86
+ * When supplied it must be `https:`: deliveries carry a signed payload describing internal work,
87
+ * and plaintext HTTP would leak it on the wire.
88
+ *
89
+ * `secret` is write-only: omit it to keep the stored one, pass a new value to rotate it.
78
90
  */
79
91
  export const putNotificationWebhookSchema = v.object({
80
- url: v.pipe(v.string(), v.trim(), v.url(), v.startsWith('https://', 'The webhook endpoint must be an https:// URL'), v.maxLength(2000)),
92
+ /** Omit keep the registered endpoint (required only when registering the first one). */
93
+ url: v.optional(v.pipe(v.string(), v.trim(), v.url(), v.startsWith('https://', 'The webhook endpoint must be an https:// URL'), v.maxLength(2000))),
81
94
  /** Omit ⇒ deliver the default parking types. */
82
95
  types: v.optional(v.array(notificationTypeSchema)),
83
96
  /** Omit ⇒ keep the current run-event subscription (none, for an endpoint that never set one). */
@@ -88,6 +101,24 @@ export const putNotificationWebhookSchema = v.object({
88
101
  /** New signing secret; omit to keep the current one. */
89
102
  secret: v.optional(v.pipe(v.string(), v.trim(), v.minLength(16), v.maxLength(200))),
90
103
  });
104
+ /**
105
+ * What `GET /api/v1/notification-webhook` answers: the registered endpoint, or `null` when the
106
+ * workspace has none. Both the session surface and the public one project the SAME
107
+ * {@link notificationWebhookSchema}, because the projection is already the client-facing shape
108
+ * with the secret reduced to a boolean, and a second near-identical DTO would be one more thing
109
+ * to keep in step for no caller-visible gain.
110
+ *
111
+ * The WRAPPER, though, is public-surface-only, and it is not decoration. A bare nullable body is
112
+ * an honest wire shape but a poor generated one: the SDK emitters model a null at the top level of
113
+ * a response far less faithfully than a null on a FIELD (Go decodes a `null` body into a
114
+ * zero-valued struct, so "no endpoint registered" would arrive as an endpoint whose URL is the
115
+ * empty string). Wrapping keeps "none is registered" a value every client reads the same way, and
116
+ * leaves room to add a sibling field later without changing the response type.
117
+ */
118
+ export const publicNotificationWebhookSchema = v.object({
119
+ /** The registered endpoint, or `null` when the workspace has none. */
120
+ webhook: v.nullable(notificationWebhookSchema),
121
+ });
91
122
  /**
92
123
  * The JSON body of one webhook delivery. Deliberately a thin envelope over the SAME
93
124
  * `notificationSchema` the in-app inbox and the public `GET /api/v1/notifications` already expose
@@ -1 +1 @@
1
- {"version":3,"file":"notification-webhooks.js","sourceRoot":"","sources":["../src/notification-webhooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"notification-webhooks.js","sourceRoot":"","sources":["../src/notification-webhooks.ts"],"names":[],"mappings":"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"}
@@ -43,7 +43,7 @@ export declare const putNotificationWebhookContract: {
43
43
  readonly method: "put";
44
44
  readonly pathResolver: () => string;
45
45
  readonly requestBodySchema: v.ObjectSchema<{
46
- readonly url: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.UrlAction<string, undefined>, v.StartsWithAction<string, "https://", "The webhook endpoint must be an https:// URL">, v.MaxLengthAction<string, 2000, undefined>]>;
46
+ readonly url: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.UrlAction<string, undefined>, v.StartsWithAction<string, "https://", "The webhook endpoint must be an https:// URL">, v.MaxLengthAction<string, 2000, undefined>]>, undefined>;
47
47
  readonly types: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "key_drift", "merge_tag_request"], undefined>, undefined>, undefined>;
48
48
  readonly runEvents: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["run.started", "run.completed", "run.failed"], undefined>, undefined>, undefined>;
49
49
  readonly alertEvents: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["platform_health.firing", "platform_health.resolved"], undefined>, undefined>, undefined>;
@@ -114,4 +114,132 @@ export declare const deleteNotificationWebhookContract: {
114
114
  readonly 204: typeof ContractNoBody;
115
115
  };
116
116
  };
117
+ /**
118
+ * Read the workspace's registered endpoint. `{ webhook: null }` when none is registered: a real
119
+ * answer rather than a 404, so a caller's startup self-check ("am I already wired up?") reads one
120
+ * response shape instead of branching on a status the surface also uses for a bad path.
121
+ */
122
+ export declare const getPublicNotificationWebhookContract: {
123
+ readonly method: "get";
124
+ readonly pathResolver: () => string;
125
+ readonly responsesByStatusCode: {
126
+ readonly '4xx': v.ObjectSchema<{
127
+ readonly error: v.ObjectSchema<{
128
+ readonly code: v.StringSchema<undefined>;
129
+ readonly message: v.StringSchema<undefined>;
130
+ readonly details: v.OptionalSchema<v.UnknownSchema, undefined>;
131
+ readonly issues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
132
+ readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
133
+ readonly message: v.StringSchema<undefined>;
134
+ }, undefined>, undefined>, undefined>;
135
+ }, undefined>;
136
+ }, undefined>;
137
+ readonly '5xx': v.ObjectSchema<{
138
+ readonly error: v.ObjectSchema<{
139
+ readonly code: v.StringSchema<undefined>;
140
+ readonly message: v.StringSchema<undefined>;
141
+ readonly details: v.OptionalSchema<v.UnknownSchema, undefined>;
142
+ readonly issues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
143
+ readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
144
+ readonly message: v.StringSchema<undefined>;
145
+ }, undefined>, undefined>, undefined>;
146
+ }, undefined>;
147
+ }, undefined>;
148
+ readonly 200: v.ObjectSchema<{
149
+ readonly webhook: v.NullableSchema<v.ObjectSchema<{
150
+ readonly url: v.StringSchema<undefined>;
151
+ readonly types: v.ArraySchema<v.PicklistSchema<["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "key_drift", "merge_tag_request"], undefined>, undefined>;
152
+ readonly runEvents: v.ArraySchema<v.PicklistSchema<["run.started", "run.completed", "run.failed"], undefined>, undefined>;
153
+ readonly alertEvents: v.ArraySchema<v.PicklistSchema<["platform_health.firing", "platform_health.resolved"], undefined>, undefined>;
154
+ readonly enabled: v.BooleanSchema<undefined>;
155
+ readonly hasSecret: v.BooleanSchema<undefined>;
156
+ readonly updatedAt: v.NumberSchema<undefined>;
157
+ }, undefined>, undefined>;
158
+ }, undefined>;
159
+ };
160
+ };
161
+ /**
162
+ * Register or update the endpoint. Returns the stored projection directly (not the `webhook`
163
+ * wrapper the read uses): a successful write always has an endpoint to describe, so wrapping it
164
+ * would hand every client a null to check that cannot occur.
165
+ *
166
+ * `secret` is write-only on this surface exactly as it is on the session one: supplied here,
167
+ * never returned by the read. An `admin` key can therefore ROTATE the signing secret but can
168
+ * never exfiltrate the one already stored.
169
+ */
170
+ export declare const putPublicNotificationWebhookContract: {
171
+ readonly method: "put";
172
+ readonly pathResolver: () => string;
173
+ readonly requestBodySchema: v.ObjectSchema<{
174
+ readonly url: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.UrlAction<string, undefined>, v.StartsWithAction<string, "https://", "The webhook endpoint must be an https:// URL">, v.MaxLengthAction<string, 2000, undefined>]>, undefined>;
175
+ readonly types: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "key_drift", "merge_tag_request"], undefined>, undefined>, undefined>;
176
+ readonly runEvents: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["run.started", "run.completed", "run.failed"], undefined>, undefined>, undefined>;
177
+ readonly alertEvents: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["platform_health.firing", "platform_health.resolved"], undefined>, undefined>, undefined>;
178
+ readonly enabled: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
179
+ readonly secret: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 16, undefined>, v.MaxLengthAction<string, 200, undefined>]>, undefined>;
180
+ }, undefined>;
181
+ readonly responsesByStatusCode: {
182
+ readonly '4xx': v.ObjectSchema<{
183
+ readonly error: v.ObjectSchema<{
184
+ readonly code: v.StringSchema<undefined>;
185
+ readonly message: v.StringSchema<undefined>;
186
+ readonly details: v.OptionalSchema<v.UnknownSchema, undefined>;
187
+ readonly issues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
188
+ readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
189
+ readonly message: v.StringSchema<undefined>;
190
+ }, undefined>, undefined>, undefined>;
191
+ }, undefined>;
192
+ }, undefined>;
193
+ readonly '5xx': v.ObjectSchema<{
194
+ readonly error: v.ObjectSchema<{
195
+ readonly code: v.StringSchema<undefined>;
196
+ readonly message: v.StringSchema<undefined>;
197
+ readonly details: v.OptionalSchema<v.UnknownSchema, undefined>;
198
+ readonly issues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
199
+ readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
200
+ readonly message: v.StringSchema<undefined>;
201
+ }, undefined>, undefined>, undefined>;
202
+ }, undefined>;
203
+ }, undefined>;
204
+ readonly 200: v.ObjectSchema<{
205
+ readonly url: v.StringSchema<undefined>;
206
+ readonly types: v.ArraySchema<v.PicklistSchema<["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "key_drift", "merge_tag_request"], undefined>, undefined>;
207
+ readonly runEvents: v.ArraySchema<v.PicklistSchema<["run.started", "run.completed", "run.failed"], undefined>, undefined>;
208
+ readonly alertEvents: v.ArraySchema<v.PicklistSchema<["platform_health.firing", "platform_health.resolved"], undefined>, undefined>;
209
+ readonly enabled: v.BooleanSchema<undefined>;
210
+ readonly hasSecret: v.BooleanSchema<undefined>;
211
+ readonly updatedAt: v.NumberSchema<undefined>;
212
+ }, undefined>;
213
+ };
214
+ };
215
+ /** Remove the endpoint (deliveries stop). Idempotent: 204 whether or not one was registered. */
216
+ export declare const deletePublicNotificationWebhookContract: {
217
+ readonly method: "delete";
218
+ readonly pathResolver: () => string;
219
+ readonly responsesByStatusCode: {
220
+ readonly '4xx': v.ObjectSchema<{
221
+ readonly error: v.ObjectSchema<{
222
+ readonly code: v.StringSchema<undefined>;
223
+ readonly message: v.StringSchema<undefined>;
224
+ readonly details: v.OptionalSchema<v.UnknownSchema, undefined>;
225
+ readonly issues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
226
+ readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
227
+ readonly message: v.StringSchema<undefined>;
228
+ }, undefined>, undefined>, undefined>;
229
+ }, undefined>;
230
+ }, undefined>;
231
+ readonly '5xx': v.ObjectSchema<{
232
+ readonly error: v.ObjectSchema<{
233
+ readonly code: v.StringSchema<undefined>;
234
+ readonly message: v.StringSchema<undefined>;
235
+ readonly details: v.OptionalSchema<v.UnknownSchema, undefined>;
236
+ readonly issues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
237
+ readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
238
+ readonly message: v.StringSchema<undefined>;
239
+ }, undefined>, undefined>, undefined>;
240
+ }, undefined>;
241
+ }, undefined>;
242
+ readonly 204: typeof ContractNoBody;
243
+ };
244
+ };
117
245
  //# sourceMappingURL=notification-webhooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"notification-webhooks.d.ts","sourceRoot":"","sources":["../../src/routes/notification-webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAqB,MAAM,yBAAyB,CAAA;AAC3E,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAc5B,8FAA8F;AAC9F,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOzC,CAAA;AAEF,yFAAyF;AACzF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKzC,CAAA;AAEF,wDAAwD;AACxD,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAI5C,CAAA"}
1
+ {"version":3,"file":"notification-webhooks.d.ts","sourceRoot":"","sources":["../../src/routes/notification-webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAqB,MAAM,yBAAyB,CAAA;AAC3E,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AA0B5B,8FAA8F;AAC9F,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOzC,CAAA;AAEF,yFAAyF;AACzF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKzC,CAAA;AAEF,wDAAwD;AACxD,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAI5C,CAAA;AAIF;;;;GAIG;AACH,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAI/C,CAAA;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAK/C,CAAA;AAEF,gGAAgG;AAChG,eAAO,MAAM,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAIlD,CAAA"}
@@ -1,13 +1,24 @@
1
1
  import { ContractNoBody, defineApiContract } from '@toad-contracts/valibot';
2
2
  import * as v from 'valibot';
3
- import { notificationWebhookSchema, putNotificationWebhookSchema, } from '../notification-webhooks.js';
3
+ import { notificationWebhookSchema, publicNotificationWebhookSchema, putNotificationWebhookSchema, } from '../notification-webhooks.js';
4
4
  import { errorResponses } from './_shared.js';
5
- // Management routes for a workspace's OUTBOUND notification webhook session-authed and mounted
6
- // under `/workspaces/:workspaceId` (so paths are relative), like the tracker/Slack settings. The
7
- // endpoint they configure is consumed by `WebhookNotificationChannel`, not by these routes.
5
+ // Management routes for a workspace's OUTBOUND notification webhook, on TWO surfaces:
8
6
  //
9
- // These are writes to an integration's configuration, so they sit behind the
10
- // `integrations.manage` workspace permission like every other admin controller.
7
+ // 1. Session-authed, mounted under `/workspaces/:workspaceId` (so paths are relative), like the
8
+ // tracker/Slack settings. These are writes to an integration's configuration, so they sit
9
+ // behind the `integrations.manage` workspace permission like every other admin controller.
10
+ // 2. `/api/v1/notification-webhook`, on absolute paths, authenticated in-controller by an
11
+ // `admin`-scope public-API key. Same three verbs against the same service.
12
+ //
13
+ // The endpoint they configure is consumed by `WebhookNotificationChannel` and the run-lifecycle /
14
+ // platform-alert sinks beside it, not by these routes.
15
+ //
16
+ // The second surface exists because the FIRST one made the push channel unreachable to exactly
17
+ // the caller it was built for. A deployment whose operator is headless has no browser session, so
18
+ // the receiver that run-lifecycle push exists to feed could only be registered by a human clicking
19
+ // through an app the feature deliberately does not need. Both surfaces are thin delegates over
20
+ // `NotificationWebhookService` (same URL guard, same write-only secret, same
21
+ // one-row-per-workspace rule), so neither can admit an endpoint the other would reject.
11
22
  /** The workspace's registered webhook, or null when none is set. Never returns the secret. */
12
23
  export const getNotificationWebhookContract = defineApiContract({
13
24
  method: 'get',
@@ -30,4 +41,36 @@ export const deleteNotificationWebhookContract = defineApiContract({
30
41
  pathResolver: () => '/notification-webhook',
31
42
  responsesByStatusCode: { 204: ContractNoBody, ...errorResponses },
32
43
  });
44
+ // ---- the external `/api/v1` surface (absolute paths, key-authenticated) ----
45
+ /**
46
+ * Read the workspace's registered endpoint. `{ webhook: null }` when none is registered: a real
47
+ * answer rather than a 404, so a caller's startup self-check ("am I already wired up?") reads one
48
+ * response shape instead of branching on a status the surface also uses for a bad path.
49
+ */
50
+ export const getPublicNotificationWebhookContract = defineApiContract({
51
+ method: 'get',
52
+ pathResolver: () => '/api/v1/notification-webhook',
53
+ responsesByStatusCode: { 200: publicNotificationWebhookSchema, ...errorResponses },
54
+ });
55
+ /**
56
+ * Register or update the endpoint. Returns the stored projection directly (not the `webhook`
57
+ * wrapper the read uses): a successful write always has an endpoint to describe, so wrapping it
58
+ * would hand every client a null to check that cannot occur.
59
+ *
60
+ * `secret` is write-only on this surface exactly as it is on the session one: supplied here,
61
+ * never returned by the read. An `admin` key can therefore ROTATE the signing secret but can
62
+ * never exfiltrate the one already stored.
63
+ */
64
+ export const putPublicNotificationWebhookContract = defineApiContract({
65
+ method: 'put',
66
+ pathResolver: () => '/api/v1/notification-webhook',
67
+ requestBodySchema: putNotificationWebhookSchema,
68
+ responsesByStatusCode: { 200: notificationWebhookSchema, ...errorResponses },
69
+ });
70
+ /** Remove the endpoint (deliveries stop). Idempotent: 204 whether or not one was registered. */
71
+ export const deletePublicNotificationWebhookContract = defineApiContract({
72
+ method: 'delete',
73
+ pathResolver: () => '/api/v1/notification-webhook',
74
+ responsesByStatusCode: { 204: ContractNoBody, ...errorResponses },
75
+ });
33
76
  //# sourceMappingURL=notification-webhooks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"notification-webhooks.js","sourceRoot":"","sources":["../../src/routes/notification-webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3E,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EACL,yBAAyB,EACzB,4BAA4B,GAC7B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,iGAAiG;AACjG,iGAAiG;AACjG,4FAA4F;AAC5F,EAAE;AACF,6EAA6E;AAC7E,gFAAgF;AAEhF,8FAA8F;AAC9F,MAAM,CAAC,MAAM,8BAA8B,GAAG,iBAAiB,CAAC;IAC9D,MAAM,EAAE,KAAK;IACb,YAAY,EAAE,GAAG,EAAE,CAAC,uBAAuB;IAC3C,qBAAqB,EAAE;QACrB,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QAC1C,GAAG,cAAc;KAClB;CACF,CAAC,CAAA;AAEF,yFAAyF;AACzF,MAAM,CAAC,MAAM,8BAA8B,GAAG,iBAAiB,CAAC;IAC9D,MAAM,EAAE,KAAK;IACb,YAAY,EAAE,GAAG,EAAE,CAAC,uBAAuB;IAC3C,iBAAiB,EAAE,4BAA4B;IAC/C,qBAAqB,EAAE,EAAE,GAAG,EAAE,yBAAyB,EAAE,GAAG,cAAc,EAAE;CAC7E,CAAC,CAAA;AAEF,wDAAwD;AACxD,MAAM,CAAC,MAAM,iCAAiC,GAAG,iBAAiB,CAAC;IACjE,MAAM,EAAE,QAAQ;IAChB,YAAY,EAAE,GAAG,EAAE,CAAC,uBAAuB;IAC3C,qBAAqB,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE;CAClE,CAAC,CAAA"}
1
+ {"version":3,"file":"notification-webhooks.js","sourceRoot":"","sources":["../../src/routes/notification-webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3E,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EACL,yBAAyB,EACzB,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,sFAAsF;AACtF,EAAE;AACF,iGAAiG;AACjG,8FAA8F;AAC9F,+FAA+F;AAC/F,2FAA2F;AAC3F,+EAA+E;AAC/E,EAAE;AACF,kGAAkG;AAClG,uDAAuD;AACvD,EAAE;AACF,+FAA+F;AAC/F,kGAAkG;AAClG,mGAAmG;AACnG,+FAA+F;AAC/F,6EAA6E;AAC7E,wFAAwF;AAExF,8FAA8F;AAC9F,MAAM,CAAC,MAAM,8BAA8B,GAAG,iBAAiB,CAAC;IAC9D,MAAM,EAAE,KAAK;IACb,YAAY,EAAE,GAAG,EAAE,CAAC,uBAAuB;IAC3C,qBAAqB,EAAE;QACrB,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QAC1C,GAAG,cAAc;KAClB;CACF,CAAC,CAAA;AAEF,yFAAyF;AACzF,MAAM,CAAC,MAAM,8BAA8B,GAAG,iBAAiB,CAAC;IAC9D,MAAM,EAAE,KAAK;IACb,YAAY,EAAE,GAAG,EAAE,CAAC,uBAAuB;IAC3C,iBAAiB,EAAE,4BAA4B;IAC/C,qBAAqB,EAAE,EAAE,GAAG,EAAE,yBAAyB,EAAE,GAAG,cAAc,EAAE;CAC7E,CAAC,CAAA;AAEF,wDAAwD;AACxD,MAAM,CAAC,MAAM,iCAAiC,GAAG,iBAAiB,CAAC;IACjE,MAAM,EAAE,QAAQ;IAChB,YAAY,EAAE,GAAG,EAAE,CAAC,uBAAuB;IAC3C,qBAAqB,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE;CAClE,CAAC,CAAA;AAEF,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG,iBAAiB,CAAC;IACpE,MAAM,EAAE,KAAK;IACb,YAAY,EAAE,GAAG,EAAE,CAAC,8BAA8B;IAClD,qBAAqB,EAAE,EAAE,GAAG,EAAE,+BAA+B,EAAE,GAAG,cAAc,EAAE;CACnF,CAAC,CAAA;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG,iBAAiB,CAAC;IACpE,MAAM,EAAE,KAAK;IACb,YAAY,EAAE,GAAG,EAAE,CAAC,8BAA8B;IAClD,iBAAiB,EAAE,4BAA4B;IAC/C,qBAAqB,EAAE,EAAE,GAAG,EAAE,yBAAyB,EAAE,GAAG,cAAc,EAAE;CAC7E,CAAC,CAAA;AAEF,gGAAgG;AAChG,MAAM,CAAC,MAAM,uCAAuC,GAAG,iBAAiB,CAAC;IACvE,MAAM,EAAE,QAAQ;IAChB,YAAY,EAAE,GAAG,EAAE,CAAC,8BAA8B;IAClD,qBAAqB,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE;CAClE,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/contracts",
3
- "version": "0.233.0",
3
+ "version": "0.234.0",
4
4
  "description": "Valibot wire contract shared between the Agent Architecture Board frontend and backend.",
5
5
  "repository": {
6
6
  "type": "git",