@every-app/sdk 0.3.0-rc.13 → 0.3.0-rc.14

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.
@@ -8,17 +8,20 @@
8
8
  * (`providers`) and a capability (`capabilities`) are the Gateway's: their
9
9
  * keys and clients live on the Gateway Worker, set once for every app
10
10
  * with `everyapp secret set <NAME>`. The app's own secrets (`secrets`)
11
- * live on its Worker, set from its directory. Each declaration carries a
12
- * need: required (the default; the app doesn't open until it is set),
13
- * optional (the app opens, and the feature says what is missing where it
14
- * is used), or a member of a named any-of group (the app opens once any
15
- * member is set; only for an app that picks among the set members at run
16
- * time). Each may say `why` it is needed and where it comes from
17
- * (`docs`, an https URL); for providers and capabilities the registries
18
- * here supply a default. An app's plain settings (`settings`: a host, a
19
- * project id, a region) are held like its secrets, on its Worker, but are
20
- * values rather than keys: each says what it takes (a URL, a number, one
21
- * of a list) and may give a default.
11
+ * live on its Worker, set from its directory. Everything the manifest
12
+ * lists at its top level is required: the app doesn't open until it is
13
+ * set. The rest is grouped into features (`features`): each a named set of
14
+ * secrets, settings and the Gateway capabilities and providers it needs,
15
+ * with numbered setup steps. A required feature's values are required; an
16
+ * optional feature is all or nothing, never blocking: off while none of
17
+ * its own values is set, incomplete while some are, ready once all are.
18
+ * Each declaration may say `why` it is needed, where it comes from
19
+ * (`docs`, an https URL) and, for an app's own value, `how` to get it;
20
+ * for providers and capabilities the registries here supply a default. An
21
+ * app's plain settings (`settings`: a host, a project id, a region) are
22
+ * held like its secrets, on its Worker, but are values rather than keys:
23
+ * each says what it takes (a URL, a number, one of a list) and may give a
24
+ * default.
22
25
  *
23
26
  * Everything in this module is pure and tenant-neutral: a manifest ships
24
27
  * in a release, and what is set is asked of the caller (`isSet`), which
@@ -29,17 +32,6 @@ import { CATALOG, capabilitySettings, } from "./capabilities.js";
29
32
  import { aiDefaultSetupHint, aiRequiredSettings, resolveAiDefault, } from "./aiDefault.js";
30
33
  import { isInstallOwnedGatewaySetting, isSettableGatewaySetting, } from "./gatewaySettings.js";
31
34
  import { hasRemoteMcpBlock, remoteMcpBlockProblem } from "./remoteMcp.js";
32
- /** The need an entry declares; required unless it says otherwise. */
33
- export function needOf(entry) {
34
- if (!entry)
35
- return { kind: "required" };
36
- if (typeof entry.anyOf === "string" && entry.anyOf.trim()) {
37
- return { kind: "anyOf", group: entry.anyOf.trim() };
38
- }
39
- if (entry.optional === true)
40
- return { kind: "optional" };
41
- return { kind: "required" };
42
- }
43
35
  function needFields(entry) {
44
36
  if (!entry || typeof entry !== "object")
45
37
  return {};
@@ -47,11 +39,66 @@ function needFields(entry) {
47
39
  return {
48
40
  ...(typeof record["why"] === "string" ? { why: record["why"] } : {}),
49
41
  ...(typeof record["docs"] === "string" ? { docs: record["docs"] } : {}),
50
- ...(typeof record["optional"] === "boolean"
51
- ? { optional: record["optional"] }
52
- : {}),
53
- ...(typeof record["setup"] === "string" ? { setup: record["setup"] } : {}),
54
- ...(typeof record["anyOf"] === "string" ? { anyOf: record["anyOf"] } : {}),
42
+ };
43
+ }
44
+ /** `how`, `generate` and `file` as a stored entry has them. */
45
+ function ownValueFields(entry) {
46
+ if (!entry || typeof entry !== "object")
47
+ return {};
48
+ const record = entry;
49
+ return {
50
+ ...(typeof record["how"] === "string" ? { how: record["how"] } : {}),
51
+ ...(record["generate"] === true ? { generate: true } : {}),
52
+ ...(record["file"] === true ? { file: true } : {}),
53
+ };
54
+ }
55
+ const stringList = (value) => Array.isArray(value)
56
+ ? value.filter((each) => typeof each === "string")
57
+ : [];
58
+ /** The features the manifest declares, in order, each read whatever a stored row holds. */
59
+ export function featureEntries(manifest) {
60
+ const features = manifest.features;
61
+ if (!features || typeof features !== "object")
62
+ return [];
63
+ return Object.entries(features).flatMap(([id, raw]) => {
64
+ if (!raw || typeof raw !== "object")
65
+ return [];
66
+ const record = raw;
67
+ return [
68
+ {
69
+ id,
70
+ name: typeof record["name"] === "string" && record["name"].trim()
71
+ ? record["name"]
72
+ : id,
73
+ required: record["required"] === true,
74
+ ...(typeof record["why"] === "string" ? { why: record["why"] } : {}),
75
+ steps: stringList(record["steps"]),
76
+ capabilities: stringList(record["capabilities"]),
77
+ providers: stringList(record["providers"]),
78
+ },
79
+ ];
80
+ });
81
+ }
82
+ /** One feature's raw `secrets` or `settings` list, with the feature id. */
83
+ function featureLists(manifest, key) {
84
+ const features = manifest.features;
85
+ if (!features || typeof features !== "object")
86
+ return [];
87
+ return Object.entries(features).flatMap(([feature, raw]) => {
88
+ const list = raw && typeof raw === "object"
89
+ ? raw[key]
90
+ : undefined;
91
+ return Array.isArray(list) ? [{ feature, list }] : [];
92
+ });
93
+ }
94
+ /** The need of a capability or provider: optional when an optional feature lists it, else required. */
95
+ function gatewayNeedOf(features, kind, id) {
96
+ const owner = features.find((feature) => feature[kind].includes(id));
97
+ if (!owner)
98
+ return { need: { kind: "required" } };
99
+ return {
100
+ need: { kind: owner.required ? "required" : "optional" },
101
+ feature: owner.id,
55
102
  };
56
103
  }
57
104
  /** The providers the manifest lists, each as an entry whatever form it took. */
@@ -69,50 +116,68 @@ export function providerEntries(manifest) {
69
116
  export function providerIds(manifest) {
70
117
  return providerEntries(manifest).map((entry) => entry.id);
71
118
  }
72
- /** The app's own secrets the manifest lists, each as an entry whatever form it took. */
73
- export function secretEntries(manifest) {
74
- return (manifest.secrets ?? []).flatMap((entry) => {
75
- if (typeof entry === "string")
76
- return [{ name: entry }];
77
- if (entry && typeof entry === "object" && typeof entry.name === "string") {
78
- return [{ name: entry.name, ...needFields(entry) }];
119
+ function secretEntryOf(entry, feature) {
120
+ const tag = feature === undefined ? {} : { feature };
121
+ if (typeof entry === "string")
122
+ return [{ name: entry, ...tag }];
123
+ if (entry && typeof entry === "object") {
124
+ const name = entry.name;
125
+ if (typeof name === "string") {
126
+ return [{ name, ...needFields(entry), ...ownValueFields(entry), ...tag }];
79
127
  }
80
- return [];
81
- });
128
+ }
129
+ return [];
130
+ }
131
+ /**
132
+ * The app's own secrets the manifest lists, each as an entry whatever form
133
+ * it took: the top-level ones, then each feature's (tagged with it).
134
+ */
135
+ export function secretEntries(manifest) {
136
+ return [
137
+ ...(manifest.secrets ?? []).flatMap((entry) => secretEntryOf(entry)),
138
+ ...featureLists(manifest, "secrets").flatMap(({ feature, list }) => list.flatMap((entry) => secretEntryOf(entry, feature))),
139
+ ];
82
140
  }
83
141
  /** The names of the app's own secrets, in order. */
84
142
  export function secretNames(manifest) {
85
143
  return secretEntries(manifest).map((entry) => entry.name);
86
144
  }
87
- /** The app's plain settings the manifest lists, each as an entry. */
145
+ function settingEntryOf(entry, feature) {
146
+ if (!entry || typeof entry !== "object")
147
+ return [];
148
+ const record = entry;
149
+ if (typeof record["name"] !== "string")
150
+ return [];
151
+ const type = record["type"];
152
+ const values = record["values"];
153
+ return [
154
+ {
155
+ name: record["name"],
156
+ ...needFields(entry),
157
+ ...(typeof record["how"] === "string" ? { how: record["how"] } : {}),
158
+ ...(type === "url" ||
159
+ type === "number" ||
160
+ type === "boolean" ||
161
+ type === "text"
162
+ ? { type }
163
+ : {}),
164
+ ...(Array.isArray(values) &&
165
+ values.every((value) => typeof value === "string")
166
+ ? { values: values }
167
+ : {}),
168
+ ...(typeof record["default"] === "string"
169
+ ? { default: record["default"] }
170
+ : {}),
171
+ ...(feature === undefined ? {} : { feature }),
172
+ },
173
+ ];
174
+ }
175
+ /** The app's plain settings the manifest lists, each as an entry: the top-level ones, then each feature's. */
88
176
  export function settingEntries(manifest) {
89
- return (manifest.settings ?? []).flatMap((entry) => {
90
- if (!entry || typeof entry !== "object" || typeof entry.name !== "string") {
91
- return [];
92
- }
93
- const record = entry;
94
- const type = record["type"];
95
- const values = record["values"];
96
- return [
97
- {
98
- name: entry.name,
99
- ...needFields(entry),
100
- ...(type === "url" ||
101
- type === "number" ||
102
- type === "boolean" ||
103
- type === "text"
104
- ? { type }
105
- : {}),
106
- ...(Array.isArray(values) &&
107
- values.every((value) => typeof value === "string")
108
- ? { values: values }
109
- : {}),
110
- ...(typeof record["default"] === "string"
111
- ? { default: record["default"] }
112
- : {}),
113
- },
114
- ];
115
- });
177
+ return [
178
+ ...(manifest.settings ?? []).flatMap((entry) => settingEntryOf(entry)),
179
+ ...featureLists(manifest, "settings").flatMap(({ feature, list }) => list.flatMap((entry) => settingEntryOf(entry, feature))),
180
+ ];
116
181
  }
117
182
  /** The names of the app's plain settings, in order. */
118
183
  export function settingNames(manifest) {
@@ -256,19 +321,59 @@ function providerHint(capability, names) {
256
321
  ];
257
322
  return lines.length > 0 ? { hint: lines.join(" ") } : {};
258
323
  }
259
- function withNeed(setting, entry, defaults = {}) {
324
+ function withNeed(setting, entry, need, defaults = {}) {
260
325
  const docs = entry?.docs ?? defaults.docs;
261
- // The registry's guide for a Gateway setting; the manifest's for the app's own secret.
262
- const setup = setting.holder === "gateway" ? defaults.setup : entry?.setup;
263
326
  return {
264
327
  ...setting,
265
- need: needOf(entry),
328
+ need: need.need,
329
+ ...(need.feature === undefined ? {} : { feature: need.feature }),
266
330
  ...(entry?.why ? { why: entry.why } : {}),
267
331
  ...(docs ? { docs } : {}),
268
- ...(setup ? { setup } : {}),
332
+ ...(defaults.setup ? { setup: defaults.setup } : {}),
269
333
  ...(defaults.hint ? { hint: defaults.hint } : {}),
270
334
  };
271
335
  }
336
+ /**
337
+ * A stored manifest from before features (deployed before 0.3.0-rc.14) marks a
338
+ * value `optional: true`. The strict schema refuses that key now, but a stored
339
+ * row keeps it until the app is redeployed, so it still reads as optional:
340
+ * updating the Gateway never puts a working app into Needs setup.
341
+ */
342
+ function storedOptional(need, raw) {
343
+ if (need.feature !== undefined || need.need.kind === "optional")
344
+ return need;
345
+ const optional = raw !== null &&
346
+ typeof raw === "object" &&
347
+ raw["optional"] === true;
348
+ return optional ? { need: { kind: "optional" } } : need;
349
+ }
350
+ /** The raw entry named `name` in a stored list (`secrets`, `settings`, `providers`). */
351
+ function rawEntry(list, name, key) {
352
+ if (!Array.isArray(list))
353
+ return undefined;
354
+ return list.find((entry) => entry !== null &&
355
+ typeof entry === "object" &&
356
+ entry[key] === name);
357
+ }
358
+ /** An app's own value's need: its feature's (required, or optional), or required at the top level. */
359
+ function ownNeedOf(features, feature) {
360
+ if (feature === undefined)
361
+ return { need: { kind: "required" } };
362
+ const owner = features.find((each) => each.id === feature);
363
+ return {
364
+ need: { kind: owner?.required ? "required" : "optional" },
365
+ feature,
366
+ };
367
+ }
368
+ /** `how`, `generate` and `file` onto an app's own setting, when its entry says them. */
369
+ function withOwnValue(setting, entry) {
370
+ return {
371
+ ...setting,
372
+ ...(entry.how ? { how: entry.how } : {}),
373
+ ...(entry.generate ? { generate: true } : {}),
374
+ ...(entry.file ? { file: true } : {}),
375
+ };
376
+ }
272
377
  /**
273
378
  * Every setting the manifest declares, in manifest order: its AI
274
379
  * providers, its capabilities, then the app's own secrets. A provider or capability the
@@ -279,6 +384,7 @@ function withNeed(setting, entry, defaults = {}) {
279
384
  */
280
385
  export function appSettings(manifest, lookup = CATALOG, options = {}) {
281
386
  const settings = [];
387
+ const features = featureEntries(manifest);
282
388
  const chat = manifest.ai?.chat;
283
389
  if (chat === true || (chat && typeof chat === "object")) {
284
390
  // The default resolves on what is set: with nothing set, the first of
@@ -302,24 +408,25 @@ export function appSettings(manifest, lookup = CATALOG, options = {}) {
302
408
  alternatives: resolution.candidates
303
409
  .map((candidate) => settable(candidate.settings))
304
410
  .filter((names) => names.length > 0),
305
- }, chat === true ? undefined : chat, {
411
+ }, chat === true ? undefined : needFields(chat), storedOptional({ need: { kind: "required" } }, chat), {
306
412
  ...(provider?.mode === "ai" ? { docs: provider.docs } : {}),
307
413
  setup: "setup/ai.md",
308
414
  hint: aiDefaultSetupHint(resolution),
309
415
  }));
310
416
  }
311
- // The default's settings: an optional pin that needs only those is the
312
- // same row (one key, set once), so it isn't listed twice. A required
313
- // pin stays: it needs that provider's key even while another provider
314
- // serves the default.
417
+ // The default's settings: an optional pin (a provider an optional
418
+ // feature lists) that needs only those is the same row (one key, set
419
+ // once), so it isn't listed twice. A required pin stays: it needs that
420
+ // provider's key even while another provider serves the default.
315
421
  const defaultNames = settings.find((setting) => setting.kind === "ai-default")?.names;
316
422
  for (const entry of providerEntries(manifest)) {
317
423
  const capability = lookup.get(entry.id);
318
424
  if (capability?.mode !== "ai")
319
425
  continue;
320
426
  const names = providerNames(capability);
427
+ const need = storedOptional(gatewayNeedOf(features, "providers", entry.id), rawEntry(manifest.providers, entry.id, "id"));
321
428
  if (defaultNames &&
322
- needOf(entry).kind === "optional" &&
429
+ need.need.kind === "optional" &&
323
430
  names.length > 0 &&
324
431
  names.every((name) => defaultNames.includes(name))) {
325
432
  continue;
@@ -331,7 +438,7 @@ export function appSettings(manifest, lookup = CATALOG, options = {}) {
331
438
  holder: "gateway",
332
439
  names,
333
440
  alsoReads: [],
334
- }, entry, {
441
+ }, entry, need, {
335
442
  docs: capability.docs,
336
443
  setup: capability.setup,
337
444
  ...providerHint(capability, names),
@@ -350,7 +457,7 @@ export function appSettings(manifest, lookup = CATALOG, options = {}) {
350
457
  holder: "gateway",
351
458
  names,
352
459
  alsoReads,
353
- }, needFields(entry), {
460
+ }, needFields(entry), storedOptional(gatewayNeedOf(features, "capabilities", id), entry), {
354
461
  docs: capabilityDocs(capability),
355
462
  setup: capability.setup,
356
463
  ...providerHint(capability, names),
@@ -376,27 +483,30 @@ export function appSettings(manifest, lookup = CATALOG, options = {}) {
376
483
  });
377
484
  }
378
485
  for (const entry of secretEntries(manifest)) {
379
- settings.push(withNeed({
486
+ settings.push(withOwnValue(withNeed({
380
487
  kind: "secret",
381
488
  id: entry.name,
382
489
  label: entry.name,
383
490
  holder: "app",
384
491
  names: [entry.name],
385
492
  alsoReads: [],
386
- }, entry));
493
+ }, entry, storedOptional(ownNeedOf(features, entry.feature), rawEntry(manifest.secrets, entry.name, "name"))), entry));
387
494
  }
388
495
  for (const entry of settingEntries(manifest)) {
389
- // A setting with a default is never unset for long: the deploy writes it.
390
- const need = entry.default !== undefined ? { ...entry, optional: true } : entry;
496
+ const own = storedOptional(ownNeedOf(features, entry.feature), rawEntry(manifest.settings, entry.name, "name"));
391
497
  settings.push({
392
- ...withNeed({
498
+ ...withOwnValue(withNeed({
393
499
  kind: "setting",
394
500
  id: entry.name,
395
501
  label: entry.name,
396
502
  holder: "app",
397
503
  names: [entry.name],
398
504
  alsoReads: [],
399
- }, need),
505
+ }, entry,
506
+ // A setting with a default is never unset for long: the deploy writes it.
507
+ entry.default !== undefined
508
+ ? { ...own, need: { kind: "optional" } }
509
+ : own), entry),
400
510
  value: settingValueRule(entry),
401
511
  });
402
512
  }
@@ -433,12 +543,24 @@ function settingIsSet(setting, isSet) {
433
543
  }
434
544
  return unknown ? null : false;
435
545
  }
546
+ /**
547
+ * A feature's state from its settings (see {@link FeatureState}). Whether
548
+ * it is started is read from its own values that have no default (a
549
+ * default is written by the deploy, so it says nothing), or, for a
550
+ * feature of Gateway settings alone, from those.
551
+ */
552
+ function featureState(settings) {
553
+ if (settings.every((setting) => setting.set !== false))
554
+ return "ready";
555
+ const own = settings.filter((setting) => setting.holder === "app" && setting.value?.default === undefined);
556
+ const started = (own.length > 0 ? own : settings).some((setting) => setting.set === true);
557
+ return started ? "incomplete" : "off";
558
+ }
436
559
  /**
437
560
  * Every setting against what is set. `isSet` answers per holder and name:
438
561
  * true, false, or null when it can't tell (the registry never recorded
439
- * the app Worker's secret names), which never blocks. An any-of group is
440
- * met once any member is set; while none is and none is unknown, every
441
- * member blocks.
562
+ * the app Worker's secret names), which never blocks. A required setting
563
+ * that is unset blocks; an optional one (an optional feature's) never does.
442
564
  */
443
565
  export function evaluateAppSettings(settings, isSet, options = {}) {
444
566
  const evaluated = settings.map((setting) => {
@@ -449,47 +571,30 @@ export function evaluateAppSettings(settings, isSet, options = {}) {
449
571
  blocking: false,
450
572
  };
451
573
  });
452
- const groups = [];
453
- for (const setting of evaluated) {
454
- if (setting.need.kind !== "anyOf")
455
- continue;
456
- const group = setting.need.group;
457
- let found = groups.find((each) => each.group === group);
458
- if (!found) {
459
- found = { group, members: [], met: false };
460
- groups.push(found);
461
- }
462
- found.members.push(setting);
463
- }
464
- for (const group of groups) {
465
- group.met = group.members.some((member) => member.set === true);
466
- const unknown = group.members.some((member) => member.set === null);
467
- if (!group.met && !unknown) {
468
- for (const member of group.members)
469
- member.blocking = true;
470
- }
471
- }
472
574
  for (const setting of evaluated) {
473
575
  if (setting.need.kind === "required" && setting.set === false) {
474
576
  setting.blocking = true;
475
577
  }
476
578
  }
477
579
  const unmet = evaluated.filter((setting) => setting.blocking);
478
- return { ready: unmet.length === 0, settings: evaluated, groups, unmet };
580
+ const features = (options.features ?? []).map((feature) => {
581
+ const own = evaluated.filter((setting) => setting.feature === feature.id);
582
+ return { ...feature, settings: own, state: featureState(own) };
583
+ });
584
+ return { ready: unmet.length === 0, settings: evaluated, unmet, features };
479
585
  }
480
586
  /**
481
587
  * What to run for an app that needs setup: `everyapp configure <app>`,
482
588
  * which reads the app's manifest (from the registry, so it runs from
483
- * anywhere), prompts for each unmet setting (one member of an any-of group
484
- * is enough: it asks which) and sets them where they are held. Null when
589
+ * anywhere), prompts for each unmet setting, feature by feature, and sets
590
+ * them where they are held. Null when
485
591
  * the app is ready. `cli` is how the operator runs everyapp (`pnpm
486
592
  * everyapp` from a checkout). Scripts that set one name at a time use
487
593
  * `everyapp secret set NAME [--app <id>]` instead.
488
594
  *
489
595
  * A provider app (`provider`: the gateway's own, with no Worker and no
490
596
  * directory; `everyapp mcp on <id>`, an MCP app) has nothing to configure: its
491
- * command is the `secret set` of its Gateway key (the first member of an
492
- * unmet any-of group), as `mcp list` says it.
597
+ * command is the `secret set` of its Gateway key, as `mcp list` says it.
493
598
  */
494
599
  export function setupCommand(report, { cli, appId, provider = false, }) {
495
600
  if (report.unmet.length === 0)
@@ -506,15 +611,8 @@ export function setupCommand(report, { cli, appId, provider = false, }) {
506
611
  if (!names.includes(name))
507
612
  names.push(name);
508
613
  };
509
- for (const setting of report.unmet) {
510
- if (setting.need.kind === "required")
511
- add(setting);
512
- }
513
- for (const group of report.groups) {
514
- const first = group.members.find((member) => member.blocking);
515
- if (first)
516
- add(first);
517
- }
614
+ for (const setting of report.unmet)
615
+ add(setting);
518
616
  return { command: `${cli} secret set ${names.join(" ")}` };
519
617
  }
520
618
  export function appSetupOf(report, options) {
@@ -523,10 +621,9 @@ export function appSetupOf(report, options) {
523
621
  ready: report.ready,
524
622
  settings: report.settings.map(strip),
525
623
  unmet: report.unmet.map(strip),
526
- groups: report.groups.map((group) => ({
527
- group: group.group,
528
- met: group.met,
529
- members: group.members.map((member) => member.id),
624
+ features: report.features.map((feature) => ({
625
+ ...feature,
626
+ settings: feature.settings.map((setting) => setting.id),
530
627
  })),
531
628
  command: options.withCommand === false ? null : setupCommand(report, options),
532
629
  };
@@ -540,3 +637,18 @@ export function apiKeyCapabilityOf(id, lookup = CATALOG) {
540
637
  const capability = lookup.get(id);
541
638
  return capability?.mode === "api_key" ? capability : undefined;
542
639
  }
640
+ /**
641
+ * A fresh value for a secret the manifest marks `generate: true`: 32
642
+ * bytes from the platform's cryptographic random source, base64url
643
+ * without padding (43 characters).
644
+ */
645
+ export function generatedSecret() {
646
+ const bytes = crypto.getRandomValues(new Uint8Array(32));
647
+ let binary = "";
648
+ for (const byte of bytes)
649
+ binary += String.fromCharCode(byte);
650
+ return btoa(binary)
651
+ .replace(/\+/g, "-")
652
+ .replace(/\//g, "_")
653
+ .replace(/=+$/, "");
654
+ }
@@ -20,16 +20,16 @@
20
20
  * The Worker reads the manifest back as `env.EVERYAPP_MANIFEST`, which
21
21
  * `everyAppWorker()` sets and `cf workers types` types from the file.
22
22
  */
23
- /** Why a setting is needed and whether the app opens without it (the settings model). */
23
+ /**
24
+ * Why a setting is needed (the settings model). Everything listed at the
25
+ * top level is required; what the app works without goes in an optional
26
+ * feature (`features`).
27
+ */
24
28
  export interface EveryAppSettingNeed {
25
29
  /** Why the app needs it, for whoever sets it. At most 200 characters. */
26
30
  readonly why?: string;
27
31
  /** An https page that says where the key or client comes from. */
28
32
  readonly docs?: string;
29
- /** The app opens without it; the feature using it says what is missing. */
30
- readonly optional?: boolean;
31
- /** The group of which one member is enough ("AI model"). */
32
- readonly anyOf?: string;
33
33
  }
34
34
  /** A route reachable without a signed-in member. */
35
35
  export interface EveryAppPublicRoute {
@@ -142,12 +142,16 @@ export interface EveryAppOAuthCapabilityEntry extends EveryAppSettingNeed {
142
142
  * differs per install (a PostHog host, a region), set with `everyapp
143
143
  * configure <app>` and read from `env`.
144
144
  */
145
- export interface EveryAppSettingEntry {
146
- readonly name: string;
145
+ export interface EveryAppSettingEntry extends EveryAppFeatureSettingEntry {
147
146
  /** Why the app needs it: what whoever installs the app reads. */
148
147
  readonly why: string;
149
148
  readonly docs?: string;
150
- readonly optional?: boolean;
149
+ }
150
+ /** A plain setting in a feature: the feature says why. */
151
+ export interface EveryAppFeatureSettingEntry {
152
+ readonly name: string;
153
+ /** Where the value is and what it needs, for whoever sets it (200 characters at most; `{appUrl}`, `{gatewayUrl}` are filled in). */
154
+ readonly how?: string;
151
155
  /** What it takes; text when not given. */
152
156
  readonly type?: "text" | "url" | "number" | "boolean";
153
157
  /** The values a text setting may take. */
@@ -155,11 +159,39 @@ export interface EveryAppSettingEntry {
155
159
  /** What the app reads while nobody has set it; the deploy writes it. */
156
160
  readonly default?: string;
157
161
  }
158
- /** One of the app's own secrets, with its need. */
159
- export interface EveryAppSecretEntry extends EveryAppSettingNeed {
162
+ /** One of the app's own secrets in a feature: the feature says why. */
163
+ export interface EveryAppFeatureSecretEntry {
164
+ readonly name: string;
165
+ /** Where the value is and what permission it needs (200 characters at most; `{appUrl}`, `{gatewayUrl}` are filled in). */
166
+ readonly how?: string;
167
+ /** `everyapp configure` makes it (32 random bytes, base64url) when unset; shown once when `how` says where to paste it. */
168
+ readonly generate?: boolean;
169
+ /** The value is a file's contents (a .pem): the prompt takes the file's path. */
170
+ readonly file?: boolean;
171
+ }
172
+ /** One of the app's own secrets. */
173
+ export interface EveryAppSecretEntry extends EveryAppSettingNeed, EveryAppFeatureSecretEntry {
174
+ }
175
+ /**
176
+ * One feature: a named group of secrets, settings and Gateway capabilities
177
+ * with numbered setup steps. A required one keeps the app closed until it
178
+ * is set; an optional one (the default) is all or nothing.
179
+ */
180
+ export interface EveryAppFeature {
181
+ /** What people read: "GitHub". */
160
182
  readonly name: string;
161
- /** Its setup guide, a path in the app (`"docs/setup/main-secret.md"`). */
162
- readonly setup?: string;
183
+ /** Default false: the app opens without it. */
184
+ readonly required?: boolean;
185
+ /** What it gives the app, in one sentence (200 characters at most). */
186
+ readonly why: string;
187
+ /** Short Markdown lines, numbered when shown; links as plain URLs or `[text](url)`; `{appUrl}`, `{gatewayUrl}` are filled in. */
188
+ readonly steps?: readonly string[];
189
+ readonly settings?: readonly EveryAppFeatureSettingEntry[];
190
+ readonly secrets?: readonly (string | EveryAppFeatureSecretEntry)[];
191
+ /** Capabilities it needs, by id; each declared under `capabilities` too. */
192
+ readonly capabilities?: readonly string[];
193
+ /** AI providers it needs, by id; each declared under `providers` too. */
194
+ readonly providers?: readonly string[];
163
195
  }
164
196
  /** `everyapp.config.ts`. */
165
197
  export interface EveryAppManifest {
@@ -204,6 +236,10 @@ export interface EveryAppManifest {
204
236
  readonly secrets?: readonly (string | EveryAppSecretEntry)[];
205
237
  /** The app's plain settings: per-install values that aren't secrets. */
206
238
  readonly settings?: readonly EveryAppSettingEntry[];
239
+ /** Features by id (a lowercase slug): what the app needs set, grouped, with setup steps. */
240
+ readonly features?: {
241
+ readonly [id: string]: EveryAppFeature;
242
+ };
207
243
  readonly ai?: {
208
244
  /** Model ids the app may request; any other is `model_not_allowed`. */
209
245
  readonly models?: readonly string[];
@@ -218,7 +254,7 @@ export interface EveryAppManifest {
218
254
  };
219
255
  /** Who can open the app once registered; `"admins"` by default. */
220
256
  readonly access?: "everyone" | "admins";
221
- /** Shell command that builds the app; `cf build` by default. */
257
+ /** Shell command that builds the app; `cf build` by default (`--mode production` without Vite). */
222
258
  readonly build?: string;
223
259
  /** Shell command `everyapp dev` starts; it must listen on PORT. */
224
260
  readonly dev?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}