@intentius/chant-lexicon-fountain 0.76.0 → 0.78.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.
Files changed (56) hide show
  1. package/README.md +6 -5
  2. package/dist/coverage.d.ts +6 -5
  3. package/dist/coverage.d.ts.map +1 -1
  4. package/dist/generated/index.d.ts.map +1 -1
  5. package/dist/integrity.json +10 -9
  6. package/dist/lint/audit-catalog.d.ts.map +1 -1
  7. package/dist/lint/post-synth/ftn023-acp-runtime-command.d.ts +3 -2
  8. package/dist/lint/post-synth/ftn023-acp-runtime-command.d.ts.map +1 -1
  9. package/dist/lint/post-synth/ftn024-setup-timeout-range.d.ts +3 -0
  10. package/dist/lint/post-synth/ftn024-setup-timeout-range.d.ts.map +1 -0
  11. package/dist/lint/post-synth/index.d.ts.map +1 -1
  12. package/dist/lsp/hover.d.ts.map +1 -1
  13. package/dist/manifest.json +2 -2
  14. package/dist/meta.json +14 -2
  15. package/dist/okf/index.md +2 -1
  16. package/dist/okf/rules/FTN023.md +2 -2
  17. package/dist/okf/rules/FTN024.md +15 -0
  18. package/dist/okf/types/Agent.md +7 -5
  19. package/dist/okf/types/Environment.md +3 -0
  20. package/dist/okf/types/Vault.md +1 -0
  21. package/dist/rules/ftn016-runtime-model-valid.ts +5 -5
  22. package/dist/rules/ftn023-acp-runtime-command.ts +4 -3
  23. package/dist/rules/ftn024-setup-timeout-range.ts +48 -0
  24. package/dist/skills/chant-fountain-ops.md +6 -5
  25. package/dist/skills/chant-fountain-secrets.md +2 -2
  26. package/dist/skills/chant-fountain.md +2 -2
  27. package/dist/spec/fetch.d.ts +18 -3
  28. package/dist/spec/fetch.d.ts.map +1 -1
  29. package/dist/spec/parse.d.ts +5 -3
  30. package/dist/spec/parse.d.ts.map +1 -1
  31. package/dist/types/index.d.ts +14 -6
  32. package/package.json +2 -2
  33. package/src/codegen/docs.ts +2 -2
  34. package/src/composites/composites.test.ts +19 -0
  35. package/src/coverage.test.ts +8 -0
  36. package/src/coverage.ts +24 -8
  37. package/src/generated/index.d.ts +14 -6
  38. package/src/generated/index.ts +2 -2
  39. package/src/generated/lexicon-fountain.json +14 -2
  40. package/src/lint/audit-catalog.ts +11 -3
  41. package/src/lint/post-synth/ftn016-runtime-model-valid.ts +5 -5
  42. package/src/lint/post-synth/ftn023-acp-runtime-command.ts +4 -3
  43. package/src/lint/post-synth/ftn024-setup-timeout-range.ts +48 -0
  44. package/src/lint/post-synth/index.ts +2 -0
  45. package/src/lint/post-synth/post-synth.test.ts +24 -0
  46. package/src/lsp/hover.test.ts +9 -2
  47. package/src/lsp/hover.ts +6 -4
  48. package/src/plugin.test.ts +1 -1
  49. package/src/serializer.test.ts +2 -2
  50. package/src/skills/chant-fountain-ops.md +6 -5
  51. package/src/skills/chant-fountain-secrets.md +2 -2
  52. package/src/skills/chant-fountain.md +2 -2
  53. package/src/spec/fetch.ts +46 -6
  54. package/src/spec/fountain-openapi.snapshot.json +12221 -4739
  55. package/src/spec/parse.ts +84 -41
  56. package/src/spec/spec.test.ts +163 -0
package/src/spec/fetch.ts CHANGED
@@ -16,7 +16,10 @@
16
16
  * The committed snapshot is now only the offline path. It is not a silent
17
17
  * substitute for the pin: both routes log which one was taken and at what
18
18
  * version, because a fallback nobody can see is how you end up debugging types
19
- * that came from somewhere you did not expect.
19
+ * that came from somewhere you did not expect. And it is refused outright when
20
+ * its own `info.version` is not the pin (#2389). A bump that changes the
21
+ * constant but not the snapshot would otherwise generate the old surface on
22
+ * any machine without a network and label it with the new version.
20
23
  */
21
24
 
22
25
  import { join, dirname } from "path";
@@ -31,12 +34,17 @@ import { fetchWithCache } from "@intentius/chant/codegen/fetch";
31
34
  * v0.3.0 was the first release to carry the `openapi.json` asset. v0.16.0 is
32
35
  * the first that describes team, schedules, webhooks, sandboxes and the event
33
36
  * stream, which is what the Teammate, Schedule and Webhook kinds are generated
34
- * from. Bumping this changes the generated surface, so it belongs in its own
37
+ * from. v0.21.0 adds `setup_timeout_seconds` to Environment and describes the
38
+ * acp runtime itself (`runtime: "acp"` and `runtime_command` on Agent, with
39
+ * `model` no longer required), which chant had modeled as an extension until
40
+ * then. Bumping this changes the generated surface, so it belongs in its own
35
41
  * commit with the regenerated snapshot beside it.
36
42
  */
37
- export const FOUNTAIN_SPEC_VERSION = "v0.16.0";
43
+ export const FOUNTAIN_SPEC_VERSION = "v0.21.0";
38
44
 
39
- const SCHEMA_URL = `https://github.com/BinaryBourbon/fountain/releases/download/${FOUNTAIN_SPEC_VERSION}/openapi.json`;
45
+ // The repository moved from BinaryBourbon to managoat. The old path still
46
+ // answers with a redirect, but a pin should not depend on one (#2389).
47
+ const SCHEMA_URL = `https://github.com/managoat/fountain/releases/download/${FOUNTAIN_SPEC_VERSION}/openapi.json`;
40
48
 
41
49
  const CACHE_FILE = join(homedir(), ".chant", `fountain-openapi-${FOUNTAIN_SPEC_VERSION}.json`);
42
50
 
@@ -47,7 +55,11 @@ const SNAPSHOT_FILE = join(dirname(fileURLToPath(import.meta.url)), "fountain-op
47
55
  * snapshot when there is no network. Returns a single-entry map — the whole
48
56
  * spec is one document; the parser fans it out into per-kind results.
49
57
  */
50
- export async function fetchSchemas(options?: { force?: boolean }): Promise<Map<string, Buffer>> {
58
+ export async function fetchSchemas(options?: {
59
+ force?: boolean;
60
+ /** The offline fallback's file. Tests point it at a snapshot of another release. */
61
+ snapshotFile?: string;
62
+ }): Promise<Map<string, Buffer>> {
51
63
  let raw: Buffer;
52
64
  try {
53
65
  raw = await fetchWithCache({ url: SCHEMA_URL, cacheFile: CACHE_FILE }, options?.force);
@@ -61,7 +73,35 @@ export async function fetchSchemas(options?: { force?: boolean }): Promise<Map<s
61
73
  `(${err instanceof Error ? err.message.split("\n")[0] : err}). ` +
62
74
  `Refresh it with \`npm run generate -- --force\` on a networked machine.`,
63
75
  );
64
- raw = readFileSync(SNAPSHOT_FILE);
76
+ raw = readSnapshot(options?.snapshotFile ?? SNAPSHOT_FILE);
65
77
  }
66
78
  return new Map([["fountain-openapi.json", raw]]);
67
79
  }
80
+
81
+ /**
82
+ * Read the committed snapshot, refusing it when it describes a release other
83
+ * than the pinned one. The spec's `info.version` carries no leading `v`
84
+ * (`0.21.0`) where the release tag does (`v0.21.0`), so both are compared
85
+ * without it.
86
+ */
87
+ export function readSnapshot(file: string = SNAPSHOT_FILE, pinned: string = FOUNTAIN_SPEC_VERSION): Buffer {
88
+ const raw = readFileSync(file);
89
+ let version: unknown;
90
+ try {
91
+ version = (JSON.parse(raw.toString("utf-8")) as { info?: { version?: unknown } }).info?.version;
92
+ } catch (err) {
93
+ throw new Error(
94
+ `[fountain] spec: the committed snapshot at ${file} is not JSON ` +
95
+ `(${err instanceof Error ? err.message.split("\n")[0] : err}), so the pinned release ${pinned} cannot be read from it.`,
96
+ );
97
+ }
98
+ const bare = (v: string) => v.replace(/^v/, "");
99
+ if (typeof version !== "string" || bare(version) !== bare(pinned)) {
100
+ throw new Error(
101
+ `[fountain] spec: the committed snapshot is fountain ${typeof version === "string" ? version : "(no info.version)"}, ` +
102
+ `but the pin is ${pinned}. Generating from it would label one release's surface with another's version. ` +
103
+ `Refresh the snapshot from the ${pinned} release asset on a networked machine.`,
104
+ );
105
+ }
106
+ return raw;
107
+ }