primitive-admin 1.1.0-alpha.64 → 1.1.0-alpha.65
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/assets/skill/skills/primitive-platform/SKILL.md +68 -6
- package/dist/bin/primitive.js +2 -0
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/config.js +11 -4
- package/dist/src/commands/config.js.map +1 -1
- package/dist/src/commands/cron-triggers.js +25 -28
- package/dist/src/commands/cron-triggers.js.map +1 -1
- package/dist/src/commands/feature-flags.d.ts +14 -0
- package/dist/src/commands/feature-flags.js +116 -0
- package/dist/src/commands/feature-flags.js.map +1 -0
- package/dist/src/commands/integrations.js +55 -2
- package/dist/src/commands/integrations.js.map +1 -1
- package/dist/src/commands/prompts.js +58 -3
- package/dist/src/commands/prompts.js.map +1 -1
- package/dist/src/commands/rule-sets.d.ts +1 -1
- package/dist/src/commands/rule-sets.js +1 -0
- package/dist/src/commands/rule-sets.js.map +1 -1
- package/dist/src/commands/sync.d.ts +69 -12
- package/dist/src/commands/sync.js +497 -114
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/users.js +92 -1
- package/dist/src/commands/users.js.map +1 -1
- package/dist/src/commands/webhooks.js +59 -2
- package/dist/src/commands/webhooks.js.map +1 -1
- package/dist/src/commands/workflows.js +18 -19
- package/dist/src/commands/workflows.js.map +1 -1
- package/dist/src/lib/api-client.d.ts +51 -4
- package/dist/src/lib/api-client.js +71 -7
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/config-object-descriptor.js +6 -14
- package/dist/src/lib/config-object-descriptor.js.map +1 -1
- package/dist/src/lib/config-surface.d.ts +2 -1
- package/dist/src/lib/config-surface.js +5 -1
- package/dist/src/lib/config-surface.js.map +1 -1
- package/dist/src/lib/generated-config-surfaces.d.ts +33 -0
- package/dist/src/lib/generated-config-surfaces.js +240 -55
- package/dist/src/lib/generated-config-surfaces.js.map +1 -1
- package/dist/src/lib/log-inspection.d.ts +2 -2
- package/dist/src/lib/log-inspection.js +3 -3
- package/dist/src/lib/log-inspection.js.map +1 -1
- package/dist/src/lib/object-status-filter.d.ts +22 -0
- package/dist/src/lib/object-status-filter.js +45 -0
- package/dist/src/lib/object-status-filter.js.map +1 -0
- package/dist/src/lib/swift-codegen/generator.js +2 -4
- package/dist/src/lib/swift-codegen/generator.js.map +1 -1
- package/dist/src/lib/sync-resource-types.js +13 -2
- package/dist/src/lib/sync-resource-types.js.map +1 -1
- package/dist/src/lib/workflow-defaults.d.ts +1 -2
- package/dist/src/lib/workflow-defaults.js +3 -3
- package/dist/src/lib/workflow-defaults.js.map +1 -1
- package/dist/src/lib/workflow-payload.js +0 -6
- package/dist/src/lib/workflow-payload.js.map +1 -1
- package/dist/src/types/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -494,6 +494,12 @@ export declare function requestSchemaKeys(table: ConfigTable, mode: "create" | "
|
|
|
494
494
|
* is no place to write one.
|
|
495
495
|
*/
|
|
496
496
|
export declare function configRequestSchema(table: ConfigTable, mode: "create" | "update"): ConfigRequestSchema;
|
|
497
|
+
/**
|
|
498
|
+
* The retired-key guidance for a generated schema, keyed by body key — or
|
|
499
|
+
* `undefined` when the schema's object has none. Consumed by the app API's
|
|
500
|
+
* request validator (`src/app-api/request-validation.ts`).
|
|
501
|
+
*/
|
|
502
|
+
export declare function retiredRequestKeys(schema: object | undefined): Readonly<Record<string, string>> | undefined;
|
|
497
503
|
/**
|
|
498
504
|
* One schema for an endpoint whose body spans MORE than one table.
|
|
499
505
|
*
|
|
@@ -512,6 +518,33 @@ export declare function mergeRequestSchemas(...schemas: readonly ConfigRequestSc
|
|
|
512
518
|
export declare function unknownRequestKeys(body: unknown, table: ConfigTable, mode: "create" | "update"): string[];
|
|
513
519
|
/** The 400 message naming the unknown key(s), shared by both APIs. */
|
|
514
520
|
export declare function unknownRequestKeysMessage(keys: readonly string[]): string;
|
|
521
|
+
/**
|
|
522
|
+
* Keys deliberately RETIRED from a configuration object's write surface.
|
|
523
|
+
*
|
|
524
|
+
* A retired key is not an unknown key. The generic hint for an unrecognized
|
|
525
|
+
* TOML key — "check the spelling, or upgrade the CLI" — is exactly backwards
|
|
526
|
+
* for one this CLI removed on purpose, and the generic 400 for an unaccepted
|
|
527
|
+
* request key says only that the key is not allowed, not where the value moved
|
|
528
|
+
* to. Both surfaces need the same sentence, and neither should invent it.
|
|
529
|
+
*
|
|
530
|
+
* So the guidance lives here, next to the definitions, with one entry per
|
|
531
|
+
* retired key: the TOML wording for `config push` (which can tell the author to
|
|
532
|
+
* delete a line) and the request wording for the API handlers (which cannot).
|
|
533
|
+
*
|
|
534
|
+
* Keyed by the table's TOML path prefix (`workflow`, `cronTrigger`, …), because
|
|
535
|
+
* that is the identifier both consumers already have in hand.
|
|
536
|
+
*
|
|
537
|
+
* Pure: no models, no tenant context, no `env` (see `types.ts` §Purity).
|
|
538
|
+
*/
|
|
539
|
+
export interface RetiredConfigKey {
|
|
540
|
+
/** What `config push` says about a file that still carries the key. */
|
|
541
|
+
toml: string;
|
|
542
|
+
/** What a create/update handler says about a body that still sends it. */
|
|
543
|
+
request: string;
|
|
544
|
+
}
|
|
545
|
+
export declare const RETIRED_CONFIG_KEYS: Record<string, Record<string, RetiredConfigKey>>;
|
|
546
|
+
/** The retired-key entry for `key` under `prefix`, or null when it is simply unknown. */
|
|
547
|
+
export declare function retiredConfigKey(prefix: string, key: string): RetiredConfigKey | null;
|
|
515
548
|
export declare const WORKFLOW_SURFACE: ConfigObjectSurface;
|
|
516
549
|
export declare const PROMPT_SURFACE: ConfigObjectSurface;
|
|
517
550
|
export declare const INTEGRATION_SURFACE: ConfigObjectSurface;
|
|
@@ -508,7 +508,55 @@ export function configRequestSchema(table, mode) {
|
|
|
508
508
|
for (const key of requestSchemaKeys(table, mode)) {
|
|
509
509
|
properties[key] = {};
|
|
510
510
|
}
|
|
511
|
-
|
|
511
|
+
const schema = {
|
|
512
|
+
type: "object",
|
|
513
|
+
properties,
|
|
514
|
+
additionalProperties: false,
|
|
515
|
+
};
|
|
516
|
+
rememberRetiredKeys(schema, RETIRED_CONFIG_KEYS[table.tomlPath[0]]);
|
|
517
|
+
return schema;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Retired-key guidance carried BESIDE a generated schema, not inside it
|
|
521
|
+
* (issue #2803, second opinion).
|
|
522
|
+
*
|
|
523
|
+
* A route that opts into runtime validation is validated before its handler
|
|
524
|
+
* runs, so a handler's targeted "`status` is server-owned, use
|
|
525
|
+
* `<noun> enable|disable`" refusal never fired for the app-API webhook and cron
|
|
526
|
+
* routes: `additionalProperties: false` answered first, with the generic
|
|
527
|
+
* "Request body validation failed". The guidance has to reach the validator.
|
|
528
|
+
*
|
|
529
|
+
* It travels in a side table rather than as a schema keyword because the schema
|
|
530
|
+
* object IS the OpenAPI `meta.request` and is held to a fail-closed keyword
|
|
531
|
+
* allowlist (`RUNTIME_SUPPORTED_SCHEMA_KEYWORDS`) — an invented keyword would
|
|
532
|
+
* be published in the spec and would fail that guard. Keying on the schema's
|
|
533
|
+
* identity also means the guidance cannot drift: it is attached by the same
|
|
534
|
+
* call that builds the key set, so a route cannot opt into one without the
|
|
535
|
+
* other.
|
|
536
|
+
*/
|
|
537
|
+
const retiredKeyGuidance = new WeakMap();
|
|
538
|
+
function rememberRetiredKeys(schema, retired) {
|
|
539
|
+
if (!retired)
|
|
540
|
+
return;
|
|
541
|
+
const entries = {};
|
|
542
|
+
for (const [key, entry] of Object.entries(retired)) {
|
|
543
|
+
// A key the schema ACCEPTS is not retired on this surface, whatever the
|
|
544
|
+
// TOML surface says about it. The accepted key set wins, so the guidance
|
|
545
|
+
// can never shadow a live field.
|
|
546
|
+
if (key in schema.properties)
|
|
547
|
+
continue;
|
|
548
|
+
entries[key] = entry.request;
|
|
549
|
+
}
|
|
550
|
+
if (Object.keys(entries).length > 0)
|
|
551
|
+
retiredKeyGuidance.set(schema, entries);
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* The retired-key guidance for a generated schema, keyed by body key — or
|
|
555
|
+
* `undefined` when the schema's object has none. Consumed by the app API's
|
|
556
|
+
* request validator (`src/app-api/request-validation.ts`).
|
|
557
|
+
*/
|
|
558
|
+
export function retiredRequestKeys(schema) {
|
|
559
|
+
return schema ? retiredKeyGuidance.get(schema) : undefined;
|
|
512
560
|
}
|
|
513
561
|
/**
|
|
514
562
|
* One schema for an endpoint whose body spans MORE than one table.
|
|
@@ -524,7 +572,22 @@ export function mergeRequestSchemas(...schemas) {
|
|
|
524
572
|
for (const key of Object.keys(schema.properties))
|
|
525
573
|
properties[key] = {};
|
|
526
574
|
}
|
|
527
|
-
|
|
575
|
+
// The union's guidance is the union of its halves'. A key one table retired
|
|
576
|
+
// and another accepts is admitted by the merged key set, so `rememberRetiredKeys`
|
|
577
|
+
// drops it below.
|
|
578
|
+
const retired = {};
|
|
579
|
+
for (const schema of schemas) {
|
|
580
|
+
for (const [key, request] of Object.entries(retiredRequestKeys(schema) ?? {})) {
|
|
581
|
+
retired[key] = { request };
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
const merged = {
|
|
585
|
+
type: "object",
|
|
586
|
+
properties,
|
|
587
|
+
additionalProperties: false,
|
|
588
|
+
};
|
|
589
|
+
rememberRetiredKeys(merged, retired);
|
|
590
|
+
return merged;
|
|
528
591
|
}
|
|
529
592
|
/**
|
|
530
593
|
* The body keys `table` does not accept in `mode` — the 400's subject.
|
|
@@ -546,6 +609,90 @@ export function unknownRequestKeysMessage(keys) {
|
|
|
546
609
|
`${keys.join(", ")}. This endpoint rejects keys it does not accept rather ` +
|
|
547
610
|
"than ignoring them.");
|
|
548
611
|
}
|
|
612
|
+
export const RETIRED_CONFIG_KEYS = {
|
|
613
|
+
// #2645 — pausing moved off `state` onto its own field, so `state` stopped
|
|
614
|
+
// being author-writable rather than becoming a second way to say "paused".
|
|
615
|
+
// Every pre-#2645 pull wrote the line, so existing repos hit this on their
|
|
616
|
+
// first push after upgrading: the failure is deliberate (sponsor decision at
|
|
617
|
+
// the approval gate, 2026-08-15), because the line has to be removed, not
|
|
618
|
+
// silently ignored, or the file keeps claiming a pause state push does not
|
|
619
|
+
// apply.
|
|
620
|
+
cronTrigger: {
|
|
621
|
+
state: {
|
|
622
|
+
toml: "`state` is no longer authored in TOML (#2645), and #2803 replaced it " +
|
|
623
|
+
"with the server-owned `status`. Availability is " +
|
|
624
|
+
"`primitive cron-triggers enable|disable`. Delete the line and push " +
|
|
625
|
+
"again.",
|
|
626
|
+
request: "`state` is server-owned and superseded by `status` (#2645, #2803). " +
|
|
627
|
+
"Use `primitive cron-triggers enable|disable` to change availability.",
|
|
628
|
+
},
|
|
629
|
+
status: {
|
|
630
|
+
toml: "`status` is no longer authored in TOML (#2803). Availability is " +
|
|
631
|
+
"server-owned: use `primitive cron-triggers enable|disable`. " +
|
|
632
|
+
"Delete the line and push again.",
|
|
633
|
+
request: "`status` is server-owned (#2803). Use " +
|
|
634
|
+
"`primitive cron-triggers enable|disable` to change availability.",
|
|
635
|
+
},
|
|
636
|
+
},
|
|
637
|
+
// #2803 — the OBJECT-level availability leaves TOML. The per-version
|
|
638
|
+
// `[[configs]] status` (`active | archived`) is a different question — which
|
|
639
|
+
// named config is retired — and stays authorable.
|
|
640
|
+
prompt: {
|
|
641
|
+
status: {
|
|
642
|
+
toml: "`[prompt].status` is no longer authored in TOML (#2803). " +
|
|
643
|
+
"Availability is server-owned: use `primitive prompts enable|disable`. " +
|
|
644
|
+
"Delete the line and push again — the per-config `[[configs]] status` " +
|
|
645
|
+
"is unaffected.",
|
|
646
|
+
request: "`status` is server-owned (#2803). Use " +
|
|
647
|
+
"`primitive prompts enable|disable` to change availability.",
|
|
648
|
+
},
|
|
649
|
+
},
|
|
650
|
+
integration: {
|
|
651
|
+
status: {
|
|
652
|
+
toml: "`status` is no longer authored in TOML (#2803), and `draft` no longer " +
|
|
653
|
+
"exists. Availability is server-owned: use " +
|
|
654
|
+
"`primitive integrations enable|disable`. Delete the line and push " +
|
|
655
|
+
"again. If this file describes an ARCHIVED integration, delete the " +
|
|
656
|
+
"file instead — pull no longer exports tombstones, and the next " +
|
|
657
|
+
"confirmed `config push --prune` hard-deletes the row.",
|
|
658
|
+
request: "`status` is server-owned (#2803). Use " +
|
|
659
|
+
"`primitive integrations enable|disable` to change availability.",
|
|
660
|
+
},
|
|
661
|
+
},
|
|
662
|
+
// #2803 — availability is one server-owned `status`. As a TOML key it made
|
|
663
|
+
// `config push` a second writer: pushing a file pulled before an operator ran
|
|
664
|
+
// `webhooks disable` put the endpoint back in service as a side effect. The
|
|
665
|
+
// tenant app-API create/update also stored the value UNVALIDATED, so any app
|
|
666
|
+
// admin could write any string into the field the receiver gates on.
|
|
667
|
+
webhook: {
|
|
668
|
+
status: {
|
|
669
|
+
toml: "`status` is no longer authored in TOML (#2803). Availability is " +
|
|
670
|
+
"server-owned: use `primitive webhooks enable|disable`. Delete the " +
|
|
671
|
+
"line and push again. If this file describes an ARCHIVED webhook, " +
|
|
672
|
+
"delete the file instead — pull no longer exports tombstones, and the " +
|
|
673
|
+
"next confirmed `config push --prune` hard-deletes the row, freeing " +
|
|
674
|
+
"its slot and its key.",
|
|
675
|
+
request: "`status` is server-owned (#2803). Use " +
|
|
676
|
+
"`primitive webhooks enable|disable` to change availability.",
|
|
677
|
+
},
|
|
678
|
+
},
|
|
679
|
+
// #2803 — availability is one server-owned `status`. As a TOML key it made
|
|
680
|
+
// `config push` a second writer: pushing a file pulled before an operator ran
|
|
681
|
+
// `workflows disable` put the workflow back in service as a side effect.
|
|
682
|
+
workflow: {
|
|
683
|
+
status: {
|
|
684
|
+
toml: "`status` is no longer authored in TOML (#2803). Availability is " +
|
|
685
|
+
"server-owned: use `primitive workflows enable|disable`. " +
|
|
686
|
+
"Delete the line and push again.",
|
|
687
|
+
request: "`status` is server-owned (#2803). Use " +
|
|
688
|
+
"`primitive workflows enable|disable` to change availability.",
|
|
689
|
+
},
|
|
690
|
+
},
|
|
691
|
+
};
|
|
692
|
+
/** The retired-key entry for `key` under `prefix`, or null when it is simply unknown. */
|
|
693
|
+
export function retiredConfigKey(prefix, key) {
|
|
694
|
+
return RETIRED_CONFIG_KEYS[prefix]?.[key] ?? null;
|
|
695
|
+
}
|
|
549
696
|
// ── src/config-surface/workflow.ts ───────────────────────────────────────
|
|
550
697
|
/**
|
|
551
698
|
* The `workflow` configuration object's definition (issue #2644, phase 1).
|
|
@@ -610,14 +757,6 @@ export const WORKFLOW_SURFACE = {
|
|
|
610
757
|
writableOn: BOTH,
|
|
611
758
|
validation: handler("normalizeWorkflowDescription"),
|
|
612
759
|
},
|
|
613
|
-
{
|
|
614
|
-
field: "status",
|
|
615
|
-
tomlKey: "status",
|
|
616
|
-
type: "string",
|
|
617
|
-
emit: "always",
|
|
618
|
-
writableOn: BOTH,
|
|
619
|
-
validation: handler("normalizeWorkflowStatus"),
|
|
620
|
-
},
|
|
621
760
|
{
|
|
622
761
|
field: "accessRule",
|
|
623
762
|
tomlKey: "accessRule",
|
|
@@ -705,6 +844,20 @@ export const WORKFLOW_SURFACE = {
|
|
|
705
844
|
kind: "server-owned",
|
|
706
845
|
note: "ULID assigned on create; never author-authored.",
|
|
707
846
|
},
|
|
847
|
+
// #2803 — `status` is the ONE availability control and it is
|
|
848
|
+
// server-owned. It used to be a `[workflow]` key, which made `config
|
|
849
|
+
// push` a second writer: pushing a file pulled before an operator ran
|
|
850
|
+
// `workflows disable` put the workflow back in service as a side
|
|
851
|
+
// effect. `server-owned` keeps it out of both the TOML surface and the
|
|
852
|
+
// create/update request schemas, so the only writers are
|
|
853
|
+
// `workflows enable|disable` and create (which assigns `active`).
|
|
854
|
+
status: {
|
|
855
|
+
kind: "server-owned",
|
|
856
|
+
note: "Availability (#2803). Written only by `workflows enable|disable` " +
|
|
857
|
+
"and by create, which always assigns `active`. Never authored in " +
|
|
858
|
+
"TOML: `config pull` does not emit it and a file that still " +
|
|
859
|
+
"carries the key fails push (RETIRED_TOML_KEYS).",
|
|
860
|
+
},
|
|
708
861
|
// #2645 criterion 9 — the operational toggle. Configuration is
|
|
709
862
|
// authored in TOML and applied with `config push`, so anything this
|
|
710
863
|
// table exposes has the repo as its single writer. Taking a workflow
|
|
@@ -909,14 +1062,6 @@ export const PROMPT_SURFACE = {
|
|
|
909
1062
|
writableOn: BOTH,
|
|
910
1063
|
validation: "passthrough",
|
|
911
1064
|
},
|
|
912
|
-
{
|
|
913
|
-
field: "status",
|
|
914
|
-
tomlKey: "status",
|
|
915
|
-
type: "string",
|
|
916
|
-
emit: "always",
|
|
917
|
-
writableOn: BOTH,
|
|
918
|
-
validation: handledBy(PROMPT_HANDLER, "AdminAPI"),
|
|
919
|
-
},
|
|
920
1065
|
// JSON Schema objects. Stored as JSON strings, returned parsed; TOML
|
|
921
1066
|
// may present them as an inline table or a JSON string.
|
|
922
1067
|
{
|
|
@@ -957,6 +1102,17 @@ export const PROMPT_SURFACE = {
|
|
|
957
1102
|
kind: "server-owned",
|
|
958
1103
|
note: "ULID assigned on create; never author-authored.",
|
|
959
1104
|
},
|
|
1105
|
+
// #2803 — the OBJECT-level availability, server-owned. Distinct from
|
|
1106
|
+
// the per-version `[[configs]] status` below, which stays a TOML key:
|
|
1107
|
+
// that says which named config is retired, this says whether the
|
|
1108
|
+
// prompt is in service at all.
|
|
1109
|
+
status: {
|
|
1110
|
+
kind: "server-owned",
|
|
1111
|
+
note: "Availability (#2803): active | inactive. Written only by " +
|
|
1112
|
+
"`prompts enable|disable` and by create, which always assigns " +
|
|
1113
|
+
"`active`. Never authored in TOML; the per-version " +
|
|
1114
|
+
"`[[configs]] status` is unaffected.",
|
|
1115
|
+
},
|
|
960
1116
|
appId: {
|
|
961
1117
|
kind: "server-owned",
|
|
962
1118
|
note: "Tenant scope, taken from the route; never on the wire.",
|
|
@@ -1260,15 +1416,6 @@ export const INTEGRATION_SURFACE = {
|
|
|
1260
1416
|
writableOn: BOTH,
|
|
1261
1417
|
validation: "passthrough",
|
|
1262
1418
|
},
|
|
1263
|
-
{
|
|
1264
|
-
field: "status",
|
|
1265
|
-
tomlKey: "status",
|
|
1266
|
-
type: "string",
|
|
1267
|
-
emit: "always",
|
|
1268
|
-
writableOn: BOTH,
|
|
1269
|
-
// draft | active | archived, rejected with a 400 naming the set.
|
|
1270
|
-
validation: handledBy(INTEGRATION_HANDLER, "AdminAPI"),
|
|
1271
|
-
},
|
|
1272
1419
|
{
|
|
1273
1420
|
field: "timeoutMs",
|
|
1274
1421
|
tomlKey: "timeoutMs",
|
|
@@ -1304,6 +1451,15 @@ export const INTEGRATION_SURFACE = {
|
|
|
1304
1451
|
kind: "server-owned",
|
|
1305
1452
|
note: "ULID assigned on create; never author-authored.",
|
|
1306
1453
|
},
|
|
1454
|
+
// #2803 — availability, server-owned. `draft` is gone from the model;
|
|
1455
|
+
// a stored one reads `inactive` through the canonical normalizer.
|
|
1456
|
+
status: {
|
|
1457
|
+
kind: "server-owned",
|
|
1458
|
+
note: "Availability (#2803): active | inactive | archived. Written only " +
|
|
1459
|
+
"by `integrations enable|disable`, by the delete flow's tombstone, " +
|
|
1460
|
+
"and by create, which always assigns `active`. Never authored in " +
|
|
1461
|
+
"TOML: pull does not emit it and pull skips archived rows.",
|
|
1462
|
+
},
|
|
1307
1463
|
appId: {
|
|
1308
1464
|
kind: "server-owned",
|
|
1309
1465
|
note: "Tenant scope, taken from the route; never on the wire.",
|
|
@@ -1422,15 +1578,6 @@ export const WEBHOOK_SURFACE = {
|
|
|
1422
1578
|
writableOn: BOTH,
|
|
1423
1579
|
validation: "passthrough",
|
|
1424
1580
|
},
|
|
1425
|
-
{
|
|
1426
|
-
field: "status",
|
|
1427
|
-
tomlKey: "status",
|
|
1428
|
-
type: "string",
|
|
1429
|
-
emit: "always",
|
|
1430
|
-
writableOn: BOTH,
|
|
1431
|
-
// active | paused; `archived` is reserved for soft-delete.
|
|
1432
|
-
validation: handledBy(WEBHOOK_HANDLER, "AdminAPI"),
|
|
1433
|
-
},
|
|
1434
1581
|
{
|
|
1435
1582
|
field: "workflowKey",
|
|
1436
1583
|
tomlKey: "workflowKey",
|
|
@@ -1507,6 +1654,19 @@ export const WEBHOOK_SURFACE = {
|
|
|
1507
1654
|
kind: "server-owned",
|
|
1508
1655
|
note: "ULID assigned on create; never author-authored.",
|
|
1509
1656
|
},
|
|
1657
|
+
// #2803 — availability is server-owned. As a `[webhook]` key it made
|
|
1658
|
+
// `config push` a second writer: a file pulled before an operator
|
|
1659
|
+
// paused the webhook put the endpoint back in service on the next
|
|
1660
|
+
// push. `server-owned` keeps it out of the TOML surface AND out of the
|
|
1661
|
+
// create/update request schemas, closing the tenant app-API path that
|
|
1662
|
+
// stored `body.status` unvalidated.
|
|
1663
|
+
status: {
|
|
1664
|
+
kind: "server-owned",
|
|
1665
|
+
note: "Availability (#2803): active | inactive | archived. Written only " +
|
|
1666
|
+
"by `webhooks enable|disable` and by the delete flow's tombstone. " +
|
|
1667
|
+
"Never authored in TOML: pull does not emit it, pull skips " +
|
|
1668
|
+
"archived rows entirely, and a file carrying the key fails push.",
|
|
1669
|
+
},
|
|
1510
1670
|
appId: {
|
|
1511
1671
|
kind: "server-owned",
|
|
1512
1672
|
note: "Tenant scope, taken from the route; never on the wire.",
|
|
@@ -1712,29 +1872,37 @@ export const CRON_TRIGGER_SURFACE = {
|
|
|
1712
1872
|
},
|
|
1713
1873
|
],
|
|
1714
1874
|
notExposed: {
|
|
1715
|
-
// #
|
|
1716
|
-
// `
|
|
1717
|
-
//
|
|
1718
|
-
//
|
|
1719
|
-
//
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1875
|
+
// #2803 — the ONE availability control, server-owned. Written only by
|
|
1876
|
+
// `cron-triggers enable|disable`, the delete flow (the `archived`
|
|
1877
|
+
// tombstone) and the alarm's error-pause path. `server-owned` keeps it
|
|
1878
|
+
// out of both the TOML surface and the create/update request schemas,
|
|
1879
|
+
// so no configuration write can change availability as a side effect.
|
|
1880
|
+
status: {
|
|
1881
|
+
kind: "server-owned",
|
|
1882
|
+
note: "Availability (#2803): active | inactive | archived. Written only " +
|
|
1883
|
+
"by `cron-triggers enable|disable`, the delete flow and the " +
|
|
1884
|
+
"error-pause path. Never authored in TOML: pull does not emit it " +
|
|
1885
|
+
"and a file that still carries the key fails push.",
|
|
1886
|
+
},
|
|
1887
|
+
// #2645 criterion 9 moved pausing off `state`; #2803 retired the field
|
|
1888
|
+
// entirely. It mixed lifecycle (`archived`, `error_paused`) with
|
|
1889
|
+
// availability (`paused`), which is what made two writers possible in
|
|
1890
|
+
// the first place. `server-owned` now, not `structural` with an
|
|
1891
|
+
// update-only mode: the console's carve-out is gone with it, so the
|
|
1892
|
+
// generic update rejects a supplied `state` exactly as create always
|
|
1893
|
+
// did.
|
|
1725
1894
|
state: {
|
|
1726
|
-
kind: "
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
"
|
|
1730
|
-
"
|
|
1731
|
-
"`operationallyDisabled` instead (#2645). Not authored in TOML.",
|
|
1895
|
+
kind: "server-owned",
|
|
1896
|
+
note: "DEPRECATED (#2803), superseded by `status`. Read only by " +
|
|
1897
|
+
"`canonicalCronStatus()`; normalized back to `active` by " +
|
|
1898
|
+
"`cron-triggers enable`. Never authored in TOML and never accepted " +
|
|
1899
|
+
"on the wire.",
|
|
1732
1900
|
},
|
|
1733
1901
|
operationallyDisabled: {
|
|
1734
1902
|
kind: "server-owned",
|
|
1735
|
-
note: "
|
|
1736
|
-
"
|
|
1737
|
-
"Never authored in TOML and never accepted on the config " +
|
|
1903
|
+
note: "DEPRECATED (#2803), superseded by `status`. The #2645 operational " +
|
|
1904
|
+
"toggle, cleared by `cron-triggers enable|disable` as rows are " +
|
|
1905
|
+
"touched. Never authored in TOML and never accepted on the config " +
|
|
1738
1906
|
"create/update wire.",
|
|
1739
1907
|
},
|
|
1740
1908
|
triggerId: {
|
|
@@ -3031,6 +3199,21 @@ export const APP_SETTINGS_SURFACE = {
|
|
|
3031
3199
|
writableOn: UPDATE_ONLY,
|
|
3032
3200
|
validation: "passthrough",
|
|
3033
3201
|
},
|
|
3202
|
+
{
|
|
3203
|
+
field: "directLlmEnabled",
|
|
3204
|
+
tomlKey: "directLlmEnabled",
|
|
3205
|
+
type: "boolean",
|
|
3206
|
+
// Always emitted: an app that has not opted the deprecated direct
|
|
3207
|
+
// LLM/Gemini proxy in must see `directLlmEnabled = false` in its
|
|
3208
|
+
// pulled `app.toml`, not a key it has to already know about (#2687).
|
|
3209
|
+
emit: "always",
|
|
3210
|
+
writableOn: UPDATE_ONLY,
|
|
3211
|
+
// STRICT, not `!!`: the value arms a credit-spending surface read
|
|
3212
|
+
// with `=== true`, so `"false"` must be a 400 rather than a stored
|
|
3213
|
+
// `true`. The generated request schema stays keys-only (#1976), so
|
|
3214
|
+
// the check is `parseDirectLlmEnabledWrite` in the handler.
|
|
3215
|
+
validation: handledBy(SETTINGS_HANDLER, "SettingsController"),
|
|
3216
|
+
},
|
|
3034
3217
|
{
|
|
3035
3218
|
field: "allowedDomains",
|
|
3036
3219
|
tomlKey: "allowedDomains",
|
|
@@ -3407,6 +3590,7 @@ export const GENERATED_CONFIG_MODEL_FIELDS = {
|
|
|
3407
3590
|
"magicLinkEnabled",
|
|
3408
3591
|
"otpEnabled",
|
|
3409
3592
|
"baseUrl",
|
|
3593
|
+
"directLlmEnabled",
|
|
3410
3594
|
"memberInvitationsEnabled",
|
|
3411
3595
|
"memberInvitationLimit",
|
|
3412
3596
|
"createdAt",
|
|
@@ -3554,6 +3738,7 @@ export const GENERATED_CONFIG_MODEL_FIELDS = {
|
|
|
3554
3738
|
"overlapPolicy",
|
|
3555
3739
|
"rootInput",
|
|
3556
3740
|
"inputMapping",
|
|
3741
|
+
"status",
|
|
3557
3742
|
"state",
|
|
3558
3743
|
"operationallyDisabled",
|
|
3559
3744
|
"lastError",
|