veryfront 0.1.533 → 0.1.534

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 (99) hide show
  1. package/esm/cli/commands/extension/init-command.d.ts +1 -1
  2. package/esm/cli/commands/extension/init-command.d.ts.map +1 -1
  3. package/esm/cli/commands/extension/init-command.js +14 -4
  4. package/esm/deno.js +1 -1
  5. package/esm/extensions/ext-auth-jwt/src/index.d.ts.map +1 -1
  6. package/esm/extensions/ext-auth-jwt/src/index.js +0 -1
  7. package/esm/extensions/ext-bundler-esbuild/src/index.js +4 -4
  8. package/esm/extensions/ext-content-mdx/src/index.d.ts.map +1 -1
  9. package/esm/extensions/ext-content-mdx/src/index.js +4 -1
  10. package/esm/extensions/ext-css-tailwind/src/index.d.ts.map +1 -1
  11. package/esm/extensions/ext-css-tailwind/src/index.js +3 -1
  12. package/esm/extensions/ext-db-sqlite/src/index.d.ts.map +1 -1
  13. package/esm/extensions/ext-db-sqlite/src/index.js +3 -1
  14. package/esm/extensions/ext-document-kreuzberg/src/index.d.ts.map +1 -1
  15. package/esm/extensions/ext-document-kreuzberg/src/index.js +3 -1
  16. package/esm/extensions/ext-llm-anthropic/src/index.d.ts.map +1 -1
  17. package/esm/extensions/ext-llm-anthropic/src/index.js +4 -1
  18. package/esm/extensions/ext-llm-google/src/index.d.ts.map +1 -1
  19. package/esm/extensions/ext-llm-google/src/index.js +4 -1
  20. package/esm/extensions/ext-llm-openai/src/index.d.ts.map +1 -1
  21. package/esm/extensions/ext-llm-openai/src/index.js +4 -1
  22. package/esm/extensions/ext-observability-opentelemetry/src/index.d.ts.map +1 -1
  23. package/esm/extensions/ext-observability-opentelemetry/src/index.js +3 -2
  24. package/esm/extensions/ext-parser-babel/src/index.d.ts.map +1 -1
  25. package/esm/extensions/ext-parser-babel/src/index.js +4 -1
  26. package/esm/extensions/ext-sandbox-shell-tools/src/index.d.ts.map +1 -1
  27. package/esm/extensions/ext-sandbox-shell-tools/src/index.js +4 -1
  28. package/esm/extensions/ext-schema-zod/src/index.d.ts.map +1 -1
  29. package/esm/extensions/ext-schema-zod/src/index.js +4 -1
  30. package/esm/src/agent/testing/durable-run-canaries/environment.d.ts +11 -0
  31. package/esm/src/agent/testing/durable-run-canaries/environment.d.ts.map +1 -0
  32. package/esm/src/agent/testing/durable-run-canaries/environment.js +13 -0
  33. package/esm/src/agent/testing/durable-run-canaries/index.d.ts +2 -0
  34. package/esm/src/agent/testing/durable-run-canaries/index.d.ts.map +1 -1
  35. package/esm/src/agent/testing/durable-run-canaries/index.js +2 -0
  36. package/esm/src/agent/testing/durable-run-canaries/validation.d.ts +7 -0
  37. package/esm/src/agent/testing/durable-run-canaries/validation.d.ts.map +1 -0
  38. package/esm/src/agent/testing/durable-run-canaries/validation.js +66 -0
  39. package/esm/src/agent/testing/index.d.ts +2 -2
  40. package/esm/src/agent/testing/index.d.ts.map +1 -1
  41. package/esm/src/agent/testing/index.js +2 -2
  42. package/esm/src/agent/testing/live-evals/environment.d.ts +12 -0
  43. package/esm/src/agent/testing/live-evals/environment.d.ts.map +1 -0
  44. package/esm/src/agent/testing/live-evals/environment.js +18 -0
  45. package/esm/src/agent/testing/live-evals/index.d.ts +2 -0
  46. package/esm/src/agent/testing/live-evals/index.d.ts.map +1 -1
  47. package/esm/src/agent/testing/live-evals/index.js +2 -0
  48. package/esm/src/agent/testing/live-evals/preflight.d.ts +9 -0
  49. package/esm/src/agent/testing/live-evals/preflight.d.ts.map +1 -0
  50. package/esm/src/agent/testing/live-evals/preflight.js +25 -0
  51. package/esm/src/extensions/builtin-extensions.d.ts.map +1 -1
  52. package/esm/src/extensions/builtin-extensions.js +4 -1
  53. package/esm/src/extensions/capabilities.d.ts +1 -1
  54. package/esm/src/extensions/capabilities.d.ts.map +1 -1
  55. package/esm/src/extensions/capabilities.js +1 -4
  56. package/esm/src/extensions/discovery.d.ts +2 -1
  57. package/esm/src/extensions/discovery.d.ts.map +1 -1
  58. package/esm/src/extensions/discovery.js +24 -1
  59. package/esm/src/extensions/index.d.ts +1 -1
  60. package/esm/src/extensions/index.d.ts.map +1 -1
  61. package/esm/src/extensions/loader.d.ts.map +1 -1
  62. package/esm/src/extensions/loader.js +26 -11
  63. package/esm/src/extensions/types.d.ts +8 -0
  64. package/esm/src/extensions/types.d.ts.map +1 -1
  65. package/esm/src/extensions/validation.d.ts.map +1 -1
  66. package/esm/src/extensions/validation.js +32 -8
  67. package/esm/src/utils/version-constant.d.ts +1 -1
  68. package/esm/src/utils/version-constant.js +1 -1
  69. package/package.json +1 -1
  70. package/src/cli/commands/extension/init-command.ts +14 -4
  71. package/src/deno.js +1 -1
  72. package/src/extensions/ext-auth-jwt/src/index.ts +0 -1
  73. package/src/extensions/ext-bundler-esbuild/src/index.ts +4 -4
  74. package/src/extensions/ext-content-mdx/src/index.ts +4 -1
  75. package/src/extensions/ext-css-tailwind/src/index.ts +3 -1
  76. package/src/extensions/ext-db-sqlite/src/index.ts +3 -1
  77. package/src/extensions/ext-document-kreuzberg/src/index.ts +3 -1
  78. package/src/extensions/ext-llm-anthropic/src/index.ts +4 -1
  79. package/src/extensions/ext-llm-google/src/index.ts +4 -1
  80. package/src/extensions/ext-llm-openai/src/index.ts +4 -1
  81. package/src/extensions/ext-observability-opentelemetry/src/index.ts +3 -2
  82. package/src/extensions/ext-parser-babel/src/index.ts +4 -1
  83. package/src/extensions/ext-sandbox-shell-tools/src/index.ts +4 -1
  84. package/src/extensions/ext-schema-zod/src/index.ts +4 -1
  85. package/src/src/agent/testing/durable-run-canaries/environment.ts +27 -0
  86. package/src/src/agent/testing/durable-run-canaries/index.ts +13 -0
  87. package/src/src/agent/testing/durable-run-canaries/validation.ts +87 -0
  88. package/src/src/agent/testing/index.ts +14 -0
  89. package/src/src/agent/testing/live-evals/environment.ts +31 -0
  90. package/src/src/agent/testing/live-evals/index.ts +10 -0
  91. package/src/src/agent/testing/live-evals/preflight.ts +42 -0
  92. package/src/src/extensions/builtin-extensions.ts +4 -1
  93. package/src/src/extensions/capabilities.ts +1 -5
  94. package/src/src/extensions/discovery.ts +27 -2
  95. package/src/src/extensions/index.ts +1 -0
  96. package/src/src/extensions/loader.ts +29 -11
  97. package/src/src/extensions/types.ts +10 -0
  98. package/src/src/extensions/validation.ts +47 -7
  99. package/src/src/utils/version-constant.ts +1 -1
@@ -0,0 +1,25 @@
1
+ import { parseAgentServiceConfig } from "../../service/config.js";
2
+ export function evaluateRuntimeConfidenceEnv(env = {}, resolvedApiUrl = parseAgentServiceConfig(env).VERYFRONT_API_URL) {
3
+ const messages = [`Resolved VERYFRONT_API_URL: ${resolvedApiUrl}`];
4
+ let hasBlockers = false;
5
+ if (typeof env.VERYFRONT_TOKEN !== "string" || env.VERYFRONT_TOKEN.length === 0) {
6
+ hasBlockers = true;
7
+ messages.push("BLOCKER: VERYFRONT_TOKEN is missing");
8
+ }
9
+ if (typeof env.AG_UI_EVAL_PROJECT_ID !== "string" || env.AG_UI_EVAL_PROJECT_ID.length === 0) {
10
+ hasBlockers = true;
11
+ messages.push("BLOCKER: AG_UI_EVAL_PROJECT_ID is missing");
12
+ }
13
+ if (!hasBlockers) {
14
+ messages.push("Runtime-confidence preflight: PASS");
15
+ return { ok: true, resolvedApiUrl, messages };
16
+ }
17
+ messages.push("Runtime-confidence preflight: FAIL");
18
+ return { ok: false, resolvedApiUrl, messages };
19
+ }
20
+ export function printRuntimeConfidencePreflight(result, output = console) {
21
+ for (const message of result.messages) {
22
+ const writer = result.ok ? output.log : output.error;
23
+ writer(message);
24
+ }
25
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"builtin-extensions.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/builtin-extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,KAAK,EAAe,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AA0DvE,wBAAgB,yBAAyB,IAAI,mBAAmB,CAM/D;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAInD;AAiCD,wBAAgB,uBAAuB,IAAI,iBAAiB,EAAE,CAoD7D"}
1
+ {"version":3,"file":"builtin-extensions.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/builtin-extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,KAAK,EAAe,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AA0DvE,wBAAgB,yBAAyB,IAAI,mBAAmB,CAM/D;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAInD;AAoCD,wBAAgB,uBAAuB,IAAI,iBAAiB,EAAE,CAoD7D"}
@@ -65,7 +65,10 @@ function createBuiltinLLMProviderExtension(definition) {
65
65
  extension: {
66
66
  name: definition.extensionName,
67
67
  version: "0.1.0",
68
- capabilities: [{ type: "contract", name: `LLMProvider:${provider.id}` }],
68
+ contracts: {
69
+ requires: [LLMProviderRegistryName],
70
+ },
71
+ capabilities: [],
69
72
  setup(ctx) {
70
73
  const registry = ctx.require(LLMProviderRegistryName);
71
74
  didRegister = registerBuiltinLLMProvider(registry, provider);
@@ -10,7 +10,7 @@ import type { Capability, ExtensionLogger } from "./types.js";
10
10
  export declare function formatCapabilities(capabilities: Capability[]): string[];
11
11
  /**
12
12
  * Map capabilities to Deno CLI permission flags.
13
- * Skips non-system capabilities (e.g., "contract").
13
+ * Skips capabilities without a Deno permission mapping.
14
14
  */
15
15
  export declare function mapToDenoPermissions(capabilities: Capability[]): string[];
16
16
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/capabilities.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE9D;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,CAevE;AA2BD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,CAyBzE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,UAAU,EAAE,EAC1B,MAAM,EAAE,eAAe,GACtB,IAAI,CAKN"}
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/capabilities.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE9D;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,CAWvE;AA2BD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,CAyBzE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,UAAU,EAAE,EAC1B,MAAM,EAAE,eAAe,GACtB,IAAI,CAKN"}
@@ -8,9 +8,6 @@
8
8
  */
9
9
  export function formatCapabilities(capabilities) {
10
10
  return capabilities.map((cap) => {
11
- if (cap.type === "contract") {
12
- return `contract: ${cap.name}`;
13
- }
14
11
  const { type, ...rest } = cap;
15
12
  const extras = Object.keys(rest);
16
13
  if (extras.length === 0)
@@ -41,7 +38,7 @@ const DENO_PERMISSION_MAP = {
41
38
  };
42
39
  /**
43
40
  * Map capabilities to Deno CLI permission flags.
44
- * Skips non-system capabilities (e.g., "contract").
41
+ * Skips capabilities without a Deno permission mapping.
45
42
  */
46
43
  export function mapToDenoPermissions(capabilities) {
47
44
  const seen = new Set();
@@ -1,4 +1,4 @@
1
- import type { Capability, ResolvedExtension } from "./types.js";
1
+ import type { Capability, PackageContractMetadata, ResolvedExtension } from "./types.js";
2
2
  /**
3
3
  * Metadata extracted from a package.json that declares itself
4
4
  * as a veryfront extension.
@@ -6,6 +6,7 @@ import type { Capability, ResolvedExtension } from "./types.js";
6
6
  export interface PackageMetadata {
7
7
  isExtension: true;
8
8
  capabilities: Capability[];
9
+ contracts?: PackageContractMetadata;
9
10
  }
10
11
  /**
11
12
  * Parse veryfront extension metadata from a package.json-like object.
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/discovery.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEhE;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,IAAI,CAAC;IAClB,YAAY,EAAE,UAAU,EAAE,CAAC;CAC5B;AAUD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,eAAe,GAAG,SAAS,CAmB7B;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,iBAAiB,EAAE,EAC3B,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,OAAO,EAAE,iBAAiB,EAAE,EAC5B,KAAK,EAAE,iBAAiB,EAAE,EAC1B,iBAAiB,CAAC,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAA;CAAE,CAAC,EAC3D,OAAO,CAAC,EAAE,iBAAiB,EAAE,GAC5B,iBAAiB,EAAE,CA2BrB;AA6BD;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAA;CAAE,CAAC,CAAC,CA4BpE;AAqBD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBnB;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,EAAE,CAAC,CAKnB"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/discovery.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEzF;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,IAAI,CAAC;IAClB,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,uBAAuB,CAAC;CACrC;AA+BD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,eAAe,GAAG,SAAS,CAsB7B;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,iBAAiB,EAAE,EAC3B,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,OAAO,EAAE,iBAAiB,EAAE,EAC5B,KAAK,EAAE,iBAAiB,EAAE,EAC1B,iBAAiB,CAAC,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAA;CAAE,CAAC,EAC3D,OAAO,CAAC,EAAE,iBAAiB,EAAE,GAC5B,iBAAiB,EAAE,CA2BrB;AA6BD;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAA;CAAE,CAAC,CAAC,CA4BpE;AAqBD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBnB;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,EAAE,CAAC,CAKnB"}
@@ -15,6 +15,26 @@ function isCapability(value) {
15
15
  const cap = value;
16
16
  return typeof cap.type === "string" && cap.type.length > 0;
17
17
  }
18
+ function parseStringList(value) {
19
+ if (!Array.isArray(value))
20
+ return undefined;
21
+ const entries = value.filter((entry) => typeof entry === "string" && entry.length > 0);
22
+ return entries.length > 0 ? entries : undefined;
23
+ }
24
+ function parseContractMetadata(value) {
25
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
26
+ return undefined;
27
+ }
28
+ const raw = value;
29
+ const contracts = {};
30
+ const provides = parseStringList(raw.provides);
31
+ const requires = parseStringList(raw.requires);
32
+ if (provides)
33
+ contracts.provides = provides;
34
+ if (requires)
35
+ contracts.requires = requires;
36
+ return provides || requires ? contracts : undefined;
37
+ }
18
38
  /**
19
39
  * Parse veryfront extension metadata from a package.json-like object.
20
40
  *
@@ -35,7 +55,10 @@ export function parsePackageMetadata(pkg) {
35
55
  const capabilities = Array.isArray(meta.capabilities)
36
56
  ? meta.capabilities.filter(isCapability)
37
57
  : [];
38
- return { isExtension: true, capabilities };
58
+ const contracts = parseContractMetadata(meta.contracts);
59
+ return contracts
60
+ ? { isExtension: true, capabilities, contracts }
61
+ : { isExtension: true, capabilities };
39
62
  }
40
63
  /**
41
64
  * Merge extensions from all four sources in priority order.
@@ -21,7 +21,7 @@
21
21
  * ```
22
22
  */
23
23
  import "../../_dnt.polyfills.js";
24
- export type { Capability, Extension, ExtensionConfigEntry, ExtensionContext, ExtensionFactory, ExtensionLogger, ExtensionSource, ResolvedExtension, } from "./types.js";
24
+ export type { Capability, Extension, ExtensionConfigEntry, ExtensionContext, ExtensionContractMetadata, ExtensionFactory, ExtensionLogger, ExtensionSource, ResolvedExtension, } from "./types.js";
25
25
  export { resolve, tryResolve } from "./contracts.js";
26
26
  export type { PackageMetadata } from "./discovery.js";
27
27
  export { discoverLocalExtensions, discoverPackageExtensions, discoverProjectExtensions, mergeExtensions, parsePackageMetadata, } from "./discovery.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,yBAAyB,CAAC;AAEjC,YAAY,EACV,UAAU,EACV,SAAS,EACT,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAKpB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGrD,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAGhG,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,4BAA4B,EAC5B,kBAAkB,EAClB,0BAA0B,EAC1B,uBAAuB,EACvB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,yBAAyB,CAAC;AAEjC,YAAY,EACV,UAAU,EACV,SAAS,EACT,oBAAoB,EACpB,gBAAgB,EAChB,yBAAyB,EACzB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAKpB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGrD,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAGhG,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,4BAA4B,EAC5B,kBAAkB,EAClB,0BAA0B,EAC1B,uBAAuB,EACvB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,OAAO,KAAK,EAA+B,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAElG,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,MAAM,CAA+B;IAE7C;;;;OAIG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;gBAI5C,MAAM,EAAE,eAAe;IAInC;;;;OAIG;IACH,cAAc,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,EAAE;IAIpE,OAAO,CAAC,mBAAmB;IA8B3B;;;OAGG;IACH,eAAe,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,EAAE;IA6ErE;;;OAGG;IACG,QAAQ,CACZ,UAAU,EAAE,iBAAiB,EAAE,EAC/B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACrC,OAAO,CAAC,IAAI,CAAC;IAgFhB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAmBnC"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,OAAO,KAAK,EAA+B,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAElG,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,MAAM,CAA+B;IAE7C;;;;OAIG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;gBAI5C,MAAM,EAAE,eAAe;IAInC;;;;OAIG;IACH,cAAc,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,EAAE;IAIpE,OAAO,CAAC,mBAAmB;IA8B3B;;;OAGG;IACH,eAAe,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,EAAE;IAyErE;;;OAGG;IACG,QAAQ,CACZ,UAAU,EAAE,iBAAiB,EAAE,EAC/B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACrC,OAAO,CAAC,IAAI,CAAC;IAuFhB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAmBnC"}
@@ -66,14 +66,10 @@ export class ExtensionLoader {
66
66
  for (const resolved of extensions) {
67
67
  const ext = resolved.extension;
68
68
  extByName.set(ext.name, resolved);
69
- if (ext.provides) {
70
- for (const contract of Object.keys(ext.provides)) {
71
- providerOf.set(contract, ext.name);
72
- }
69
+ for (const contract of providedContractNames(ext)) {
70
+ providerOf.set(contract, ext.name);
73
71
  }
74
- const contracts = ext.capabilities
75
- .filter((c) => c.type === "contract")
76
- .map((c) => c.name);
72
+ const contracts = requiredContractNames(ext);
77
73
  if (contracts.length > 0) {
78
74
  consumesContracts.set(ext.name, contracts);
79
75
  }
@@ -138,8 +134,9 @@ export class ExtensionLoader {
138
134
  for (const [name, impl] of Object.entries(this.primed)) {
139
135
  register(name, impl);
140
136
  }
137
+ const loadOrder = this.topologicalSort(this.flattenPresets(extensions));
141
138
  // Check for contract conflicts before loading
142
- const conflicts = detectConflicts(extensions);
139
+ const conflicts = detectConflicts(loadOrder);
143
140
  if (conflicts.length > 0) {
144
141
  const details = conflicts
145
142
  .map((c) => `"${c.contract}" provided by: ${c.providers.map((p) => p.name).join(", ")}`)
@@ -152,8 +149,8 @@ export class ExtensionLoader {
152
149
  // provider later in the iteration order cannot overwrite the winning impl
153
150
  // via register(). Without this, merged inputs (config -> package ->
154
151
  // project -> local-file) silently invert the documented source priority.
155
- const contractWinner = selectContractProviders(extensions);
156
- for (const resolved of extensions) {
152
+ const contractWinner = selectContractProviders(loadOrder);
153
+ for (const resolved of loadOrder) {
157
154
  const ext = resolved.extension;
158
155
  const issues = validateExtension(ext);
159
156
  if (issues.length > 0) {
@@ -173,7 +170,12 @@ export class ExtensionLoader {
173
170
  const ctx = {
174
171
  get: (contract) => tryResolve(contract),
175
172
  require: (contract) => resolveContract(contract),
176
- provide: (contract, impl) => register(contract, impl),
173
+ provide: (contract, impl) => {
174
+ const winner = contractWinner.get(contract);
175
+ if (!winner || winner === resolved) {
176
+ register(contract, impl);
177
+ }
178
+ },
177
179
  config: projectConfig,
178
180
  logger: this.logger,
179
181
  };
@@ -225,3 +227,16 @@ export class ExtensionLoader {
225
227
  reset();
226
228
  }
227
229
  }
230
+ function providedContractNames(ext) {
231
+ const names = new Set();
232
+ for (const contract of Object.keys(ext.provides ?? {})) {
233
+ names.add(contract);
234
+ }
235
+ for (const contract of ext.contracts?.provides ?? []) {
236
+ names.add(contract);
237
+ }
238
+ return [...names];
239
+ }
240
+ function requiredContractNames(ext) {
241
+ return ext.contracts?.requires ?? [];
242
+ }
@@ -11,6 +11,13 @@ export interface Capability {
11
11
  type: string;
12
12
  [key: string]: unknown;
13
13
  }
14
+ export interface ExtensionContractMetadata {
15
+ /** Contracts this extension registers dynamically during setup(). */
16
+ provides?: string[];
17
+ /** Contracts this extension needs before setup() runs. */
18
+ requires?: string[];
19
+ }
20
+ export type PackageContractMetadata = ExtensionContractMetadata;
14
21
  export interface ExtensionContext {
15
22
  get<T>(contract: string): T | undefined;
16
23
  require<T>(contract: string): T;
@@ -28,6 +35,7 @@ export interface Extension {
28
35
  name: string;
29
36
  version: string;
30
37
  capabilities: Capability[];
38
+ contracts?: ExtensionContractMetadata;
31
39
  setup?(ctx: ExtensionContext): Promise<void> | void;
32
40
  teardown?(): Promise<void> | void;
33
41
  provides?: Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;IACxC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,CAAC;IAChC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClD;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,KAAK,CAAC,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACpD,QAAQ,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;CACvB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,SAAS,CAAC;AAE/D,MAAM,MAAM,oBAAoB,GAC5B,SAAS,GACT;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAA;CAAE,CAAC;AAErC,MAAM,MAAM,eAAe,GACvB,QAAQ,GACR,SAAS,GACT,SAAS,GACT,YAAY,GACZ,SAAS,CAAC;AAEd,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACxC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,MAAM,uBAAuB,GAAG,yBAAyB,CAAC;AAEhE,MAAM,WAAW,gBAAgB;IAC/B,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;IACxC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,CAAC;IAChC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClD;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,yBAAyB,CAAC;IACtC,KAAK,CAAC,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACpD,QAAQ,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;CACvB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,SAAS,CAAC;AAE/D,MAAM,MAAM,oBAAoB,GAC5B,SAAS,GACT;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAA;CAAE,CAAC;AAErC,MAAM,MAAM,eAAe,GACvB,QAAQ,GACR,SAAS,GACT,SAAS,GACT,YAAY,GACZ,SAAS,CAAC;AAEd,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAa,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC;CAC7D;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAM3D,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,iBAAiB,EAAE,GAC9B,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAgBhC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAmCxD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,YAAY,EAAE,CA2C/E"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAa,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC;CAC7D;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAM3D,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,iBAAiB,EAAE,GAC9B,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAchC;AA0BD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAwDxD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,YAAY,EAAE,CAwC/E"}
@@ -23,10 +23,7 @@ export const SOURCE_PRIORITY = {
23
23
  export function selectContractProviders(extensions) {
24
24
  const winner = new Map();
25
25
  for (const resolved of extensions) {
26
- const provides = resolved.extension.provides;
27
- if (!provides)
28
- continue;
29
- for (const contract of Object.keys(provides)) {
26
+ for (const contract of providedContractNames(resolved.extension)) {
30
27
  const current = winner.get(contract);
31
28
  if (!current ||
32
29
  SOURCE_PRIORITY[resolved.source] < SOURCE_PRIORITY[current.source]) {
@@ -36,6 +33,25 @@ export function selectContractProviders(extensions) {
36
33
  }
37
34
  return winner;
38
35
  }
36
+ function providedContractNames(extension) {
37
+ return [
38
+ ...Object.keys(extension.provides ?? {}),
39
+ ...(extension.contracts?.provides ?? []),
40
+ ];
41
+ }
42
+ function validateContractList(field, value, issues) {
43
+ if (value === undefined)
44
+ return;
45
+ if (!Array.isArray(value)) {
46
+ issues.push(`${field} must be an array`);
47
+ return;
48
+ }
49
+ for (let i = 0; i < value.length; i++) {
50
+ if (typeof value[i] !== "string" || value[i].length === 0) {
51
+ issues.push(`${field}[${i}] must be a non-empty string`);
52
+ }
53
+ }
54
+ }
39
55
  /**
40
56
  * Validate the shape of an extension object.
41
57
  * Returns an array of issue descriptions (empty array = valid).
@@ -70,6 +86,17 @@ export function validateExtension(ext) {
70
86
  issues.push(`capabilities[${i}].type must be a non-empty string`);
71
87
  }
72
88
  }
89
+ if (candidate.contracts !== undefined) {
90
+ if (typeof candidate.contracts !== "object" ||
91
+ candidate.contracts === null ||
92
+ Array.isArray(candidate.contracts)) {
93
+ issues.push("contracts must be an object");
94
+ }
95
+ else {
96
+ validateContractList("contracts.provides", candidate.contracts.provides, issues);
97
+ validateContractList("contracts.requires", candidate.contracts.requires, issues);
98
+ }
99
+ }
73
100
  return issues;
74
101
  }
75
102
  /**
@@ -81,10 +108,7 @@ export function validateExtension(ext) {
81
108
  export function detectConflicts(extensions) {
82
109
  const contractProviders = new Map();
83
110
  for (const resolved of extensions) {
84
- const provides = resolved.extension.provides;
85
- if (!provides)
86
- continue;
87
- for (const contract of Object.keys(provides)) {
111
+ for (const contract of providedContractNames(resolved.extension)) {
88
112
  let list = contractProviders.get(contract);
89
113
  if (!list) {
90
114
  list = [];
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.1.533";
1
+ export declare const VERSION = "0.1.534";
2
2
  //# sourceMappingURL=version-constant.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
- export const VERSION = "0.1.533";
3
+ export const VERSION = "0.1.534";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.533",
3
+ "version": "0.1.534",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Extension init command scaffold a new extension.
2
+ * Extension init command: scaffold a new extension.
3
3
  *
4
4
  * @module cli/commands/extension/init-command
5
5
  */
@@ -28,7 +28,7 @@ export function validateExtensionName(name: string): string | undefined {
28
28
 
29
29
  /**
30
30
  * Generate the file contents for a new extension scaffold.
31
- * Does not write to disk returns file path/content pairs.
31
+ * Does not write to disk. Returns file path/content pairs.
32
32
  */
33
33
  export function generateExtensionFiles(name: string): GeneratedFile[] {
34
34
  const base = `extensions/${name}`;
@@ -44,6 +44,12 @@ import type { ExtensionFactory } from "veryfront/extensions";
44
44
  const ${camelCase(name)}: ExtensionFactory = () => ({
45
45
  name: "${name}",
46
46
  version: "0.1.0",
47
+ // Use contracts.provides for dynamic ctx.provide() registrations.
48
+ // Use contracts.requires before calling ctx.require().
49
+ contracts: {
50
+ provides: [],
51
+ requires: [],
52
+ },
47
53
  capabilities: [],
48
54
 
49
55
  // Uncomment and modify to provide a contract implementation:
@@ -53,8 +59,8 @@ const ${camelCase(name)}: ExtensionFactory = () => ({
53
59
 
54
60
  // Uncomment for async setup:
55
61
  // async setup(ctx) {
56
- // // ctx.get<T>("ContractName") consume another contract
57
- // // ctx.provide("ContractName", impl) register a contract
62
+ // // ctx.get<T>("ContractName"): consume another contract
63
+ // // ctx.provide("ContractName", impl): register a contract
58
64
  // },
59
65
 
60
66
  // Uncomment for cleanup:
@@ -101,6 +107,10 @@ describe("${name} extension", () => {
101
107
  version: "0.1.0",
102
108
  veryfront: {
103
109
  extension: true,
110
+ contracts: {
111
+ provides: [],
112
+ requires: [],
113
+ },
104
114
  capabilities: [],
105
115
  },
106
116
  },
package/src/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.533",
3
+ "version": "0.1.534",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "workspace": [
@@ -188,7 +188,6 @@ const extJwt: ExtensionFactory = (config?: unknown) => {
188
188
  name: "ext-auth-jwt",
189
189
  version: "0.1.0",
190
190
  capabilities: [
191
- { type: "contract", name: "AuthProvider" },
192
191
  { type: "net:outbound", hosts: ["*"] },
193
192
  ],
194
193
  provides: {
@@ -23,10 +23,10 @@ const extEsbuild: ExtensionFactory = () => {
23
23
  return {
24
24
  name: "ext-bundler-esbuild",
25
25
  version: "0.1.0",
26
- capabilities: [
27
- { type: "contract", name: "Bundler" },
28
- { type: "contract", name: "ModuleLexer" },
29
- ],
26
+ contracts: {
27
+ provides: ["Bundler", "ModuleLexer"],
28
+ },
29
+ capabilities: [],
30
30
  setup(ctx) {
31
31
  if (!ctx.get("Bundler")) {
32
32
  ctx.provide("Bundler", bundler);
@@ -48,7 +48,10 @@ const extMdx: ExtensionFactory = () => {
48
48
  return {
49
49
  name: "ext-content-mdx",
50
50
  version: "0.1.0",
51
- capabilities: [{ type: "contract", name: "ContentProcessor" }],
51
+ contracts: {
52
+ provides: ["ContentProcessor"],
53
+ },
54
+ capabilities: [],
52
55
  setup(ctx) {
53
56
  ctx.provide("ContentProcessor", impl);
54
57
  ctx.logger.info("[ext-content-mdx] ContentProcessor registered");
@@ -59,8 +59,10 @@ const extTailwind: ExtensionFactory = () => {
59
59
  return {
60
60
  name: "ext-css-tailwind",
61
61
  version: "0.1.0",
62
+ contracts: {
63
+ provides: ["CSSProcessor"],
64
+ },
62
65
  capabilities: [
63
- { type: "contract", name: "CSSProcessor" },
64
66
  { type: "net:outbound", hosts: ["esm.sh"] },
65
67
  ],
66
68
  setup(ctx) {
@@ -29,8 +29,10 @@ const extDbSqlite: ExtensionFactory = () => {
29
29
  return {
30
30
  name: "ext-db-sqlite",
31
31
  version: "0.1.0",
32
+ contracts: {
33
+ provides: ["SqliteStore"],
34
+ },
32
35
  capabilities: [
33
- { type: "contract", name: "SqliteStore" },
34
36
  { type: "fs:read" },
35
37
  { type: "fs:write" },
36
38
  ],
@@ -80,8 +80,10 @@ const extDocumentKreuzberg: ExtensionFactory = () => {
80
80
  return {
81
81
  name: "ext-document-kreuzberg",
82
82
  version: "0.1.0",
83
+ contracts: {
84
+ provides: ["DocumentExtractor"],
85
+ },
83
86
  capabilities: [
84
- { type: "contract", name: "DocumentExtractor" },
85
87
  { type: "fs:read" },
86
88
  ],
87
89
 
@@ -16,7 +16,10 @@ const extAnthropic: ExtensionFactory = () => {
16
16
  return {
17
17
  name: "ext-llm-anthropic",
18
18
  version: "0.1.0",
19
- capabilities: [{ type: "contract", name: "LLMProvider:anthropic" }],
19
+ contracts: {
20
+ requires: [LLMProviderRegistryName],
21
+ },
22
+ capabilities: [],
20
23
  setup(ctx) {
21
24
  const registry = ctx.require<LLMProviderRegistry>(LLMProviderRegistryName);
22
25
  registry.register(provider);
@@ -15,7 +15,10 @@ const extGoogle: ExtensionFactory = () => {
15
15
  return {
16
16
  name: "ext-llm-google",
17
17
  version: "0.1.0",
18
- capabilities: [{ type: "contract", name: "LLMProvider:google" }],
18
+ contracts: {
19
+ requires: [LLMProviderRegistryName],
20
+ },
21
+ capabilities: [],
19
22
  setup(ctx) {
20
23
  const registry = ctx.require<LLMProviderRegistry>(LLMProviderRegistryName);
21
24
  registry.register(provider);
@@ -16,7 +16,10 @@ const extOpenAI: ExtensionFactory = () => {
16
16
  return {
17
17
  name: "ext-llm-openai",
18
18
  version: "0.1.0",
19
- capabilities: [{ type: "contract", name: "LLMProvider:openai" }],
19
+ contracts: {
20
+ requires: [LLMProviderRegistryName],
21
+ },
22
+ capabilities: [],
20
23
  setup(ctx) {
21
24
  registry = ctx.require<LLMProviderRegistry>(LLMProviderRegistryName);
22
25
  registry.register(provider);
@@ -259,9 +259,10 @@ const extOpenTelemetry: ExtensionFactory = () => {
259
259
  return {
260
260
  name: "ext-observability-opentelemetry",
261
261
  version: "0.1.0",
262
+ contracts: {
263
+ provides: ["TracingExporter", "NodeTelemetryProvider"],
264
+ },
262
265
  capabilities: [
263
- { type: "contract", name: "TracingExporter" },
264
- { type: "contract", name: "NodeTelemetryProvider" },
265
266
  { type: "net:outbound", hosts: ["*"] },
266
267
  {
267
268
  type: "env:read",
@@ -93,7 +93,10 @@ const extBabel: ExtensionFactory = () => {
93
93
  return {
94
94
  name: "ext-parser-babel",
95
95
  version: "0.1.0",
96
- capabilities: [{ type: "contract", name: "CodeParser" }],
96
+ contracts: {
97
+ provides: ["CodeParser"],
98
+ },
99
+ capabilities: [],
97
100
  setup(ctx) {
98
101
  ctx.provide("CodeParser", impl);
99
102
  ctx.logger.info("[ext-parser-babel] CodeParser registered");
@@ -27,7 +27,10 @@ const provider = createSandboxShellToolsProvider(createBashTool);
27
27
  const extSandboxShellTools: ExtensionFactory = () => ({
28
28
  name: "ext-sandbox-shell-tools",
29
29
  version: "0.1.0",
30
- capabilities: [{ type: "contract", name: SandboxShellToolsProviderName }],
30
+ contracts: {
31
+ provides: [SandboxShellToolsProviderName],
32
+ },
33
+ capabilities: [],
31
34
  setup(ctx) {
32
35
  ctx.provide(SandboxShellToolsProviderName, provider);
33
36
  ctx.logger.info("[ext-sandbox-shell-tools] Sandbox shell tools provider registered");
@@ -21,7 +21,10 @@ const extZod: ExtensionFactory = () => {
21
21
  return {
22
22
  name: "ext-schema-zod",
23
23
  version: "0.1.0",
24
- capabilities: [{ type: "contract", name: "SchemaValidator" }],
24
+ contracts: {
25
+ provides: ["SchemaValidator"],
26
+ },
27
+ capabilities: [],
25
28
  setup(ctx) {
26
29
  ctx.provide("SchemaValidator", impl);
27
30
  ctx.logger.info("[ext-schema-zod] SchemaValidator registered");
@@ -0,0 +1,27 @@
1
+ import { type AgentServiceConfigInput, parseAgentServiceConfig } from "../../service/config.js";
2
+
3
+ export interface DurableRunCanaryEnvironment {
4
+ apiUrl: string;
5
+ authToken: string;
6
+ projectId: string;
7
+ requestTimeoutMs: number;
8
+ keepSuccessfulEvidence: boolean;
9
+ }
10
+
11
+ export const DEFAULT_DURABLE_RUN_CANARY_TIMEOUT_MS = 240_000;
12
+
13
+ export function resolveDurableRunCanaryEnvironment(
14
+ env: AgentServiceConfigInput = {},
15
+ ): DurableRunCanaryEnvironment {
16
+ return {
17
+ apiUrl: typeof env.VERYFRONT_API_URL === "string"
18
+ ? env.VERYFRONT_API_URL
19
+ : parseAgentServiceConfig(env).VERYFRONT_API_URL,
20
+ authToken: typeof env.VERYFRONT_TOKEN === "string" ? env.VERYFRONT_TOKEN : "",
21
+ projectId: typeof env.AG_UI_EVAL_PROJECT_ID === "string" ? env.AG_UI_EVAL_PROJECT_ID : "",
22
+ requestTimeoutMs: Number(
23
+ env.DURABLE_CANARY_TIMEOUT_MS ?? DEFAULT_DURABLE_RUN_CANARY_TIMEOUT_MS,
24
+ ),
25
+ keepSuccessfulEvidence: env.DURABLE_CANARY_KEEP_SUCCESS === "1",
26
+ };
27
+ }