veryfront 0.1.282 → 0.1.284

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 (114) hide show
  1. package/esm/deno.d.ts +0 -8
  2. package/esm/deno.js +8 -11
  3. package/esm/src/agent/agent-service.d.ts +28 -6
  4. package/esm/src/agent/agent-service.d.ts.map +1 -1
  5. package/esm/src/agent/agent-service.js +23 -1
  6. package/esm/src/agent/index.d.ts +1 -1
  7. package/esm/src/agent/index.d.ts.map +1 -1
  8. package/esm/src/agent/runtime/index.d.ts.map +1 -1
  9. package/esm/src/agent/runtime/index.js +23 -0
  10. package/esm/src/agent/runtime/tool-helpers.d.ts +1 -0
  11. package/esm/src/agent/runtime/tool-helpers.d.ts.map +1 -1
  12. package/esm/src/agent/runtime/tool-helpers.js +21 -0
  13. package/esm/src/embedding/resolve.d.ts.map +1 -1
  14. package/esm/src/embedding/resolve.js +15 -2
  15. package/esm/src/embedding/veryfront-cloud/provider.d.ts.map +1 -1
  16. package/esm/src/embedding/veryfront-cloud/provider.js +2 -7
  17. package/esm/src/extensions/contracts.js +3 -1
  18. package/esm/src/extensions/interfaces/ai-provider.d.ts +50 -0
  19. package/esm/src/extensions/interfaces/ai-provider.d.ts.map +1 -0
  20. package/esm/src/extensions/interfaces/ai-provider.js +13 -0
  21. package/esm/src/extensions/interfaces/code-parser.d.ts +11 -0
  22. package/esm/src/extensions/interfaces/code-parser.d.ts.map +1 -1
  23. package/esm/src/extensions/interfaces/css-processor.d.ts +41 -22
  24. package/esm/src/extensions/interfaces/css-processor.d.ts.map +1 -1
  25. package/esm/src/extensions/interfaces/css-processor.js +10 -1
  26. package/esm/src/extensions/interfaces/index.d.ts +5 -4
  27. package/esm/src/extensions/interfaces/index.d.ts.map +1 -1
  28. package/esm/src/extensions/interfaces/index.js +1 -0
  29. package/esm/src/extensions/interfaces/schema-validator.d.ts +84 -5
  30. package/esm/src/extensions/interfaces/schema-validator.d.ts.map +1 -1
  31. package/esm/src/extensions/interfaces/schema-validator.js +5 -0
  32. package/esm/src/extensions/loader.d.ts +7 -0
  33. package/esm/src/extensions/loader.d.ts.map +1 -1
  34. package/esm/src/extensions/loader.js +12 -0
  35. package/esm/src/extensions/orchestrate.d.ts +2 -0
  36. package/esm/src/extensions/orchestrate.d.ts.map +1 -1
  37. package/esm/src/extensions/orchestrate.js +3 -0
  38. package/esm/src/extensions/recommendations.d.ts.map +1 -1
  39. package/esm/src/extensions/recommendations.js +4 -1
  40. package/esm/src/extensions/registries/ai-provider-registry.d.ts +11 -0
  41. package/esm/src/extensions/registries/ai-provider-registry.d.ts.map +1 -0
  42. package/esm/src/extensions/registries/ai-provider-registry.js +40 -0
  43. package/esm/src/html/styles-builder/plugin-loader.d.ts.map +1 -1
  44. package/esm/src/html/styles-builder/plugin-loader.js +4 -16
  45. package/esm/src/html/styles-builder/tailwind-compiler-cache.d.ts +8 -2
  46. package/esm/src/html/styles-builder/tailwind-compiler-cache.d.ts.map +1 -1
  47. package/esm/src/html/styles-builder/tailwind-compiler-cache.js +20 -3
  48. package/esm/src/internal-agents/run-stream.d.ts.map +1 -1
  49. package/esm/src/internal-agents/run-stream.js +22 -0
  50. package/esm/src/provider/model-registry.d.ts.map +1 -1
  51. package/esm/src/provider/model-registry.js +33 -6
  52. package/esm/src/provider/runtime-loader/provider-embedding-responses.d.ts +1 -0
  53. package/esm/src/provider/runtime-loader/provider-embedding-responses.d.ts.map +1 -1
  54. package/esm/src/provider/runtime-loader/provider-embedding-responses.js +1 -1
  55. package/esm/src/provider/runtime-loader/provider-http.d.ts +9 -0
  56. package/esm/src/provider/runtime-loader/provider-http.d.ts.map +1 -1
  57. package/esm/src/provider/runtime-loader/provider-http.js +2 -2
  58. package/esm/src/provider/runtime-loader.d.ts +120 -9
  59. package/esm/src/provider/runtime-loader.d.ts.map +1 -1
  60. package/esm/src/provider/runtime-loader.js +13 -943
  61. package/esm/src/provider/veryfront-cloud/provider.d.ts.map +1 -1
  62. package/esm/src/provider/veryfront-cloud/provider.js +30 -15
  63. package/esm/src/schemas/define.d.ts +31 -0
  64. package/esm/src/schemas/define.d.ts.map +1 -0
  65. package/esm/src/schemas/define.js +42 -0
  66. package/esm/src/schemas/index.d.ts +7 -2
  67. package/esm/src/schemas/index.d.ts.map +1 -1
  68. package/esm/src/schemas/index.js +10 -2
  69. package/esm/src/schemas/zod-adapter.d.ts +25 -0
  70. package/esm/src/schemas/zod-adapter.d.ts.map +1 -0
  71. package/esm/src/schemas/zod-adapter.js +120 -0
  72. package/esm/src/server/bootstrap.d.ts.map +1 -1
  73. package/esm/src/server/bootstrap.js +5 -0
  74. package/esm/src/transforms/plugins/babel-node-positions.d.ts +6 -7
  75. package/esm/src/transforms/plugins/babel-node-positions.d.ts.map +1 -1
  76. package/esm/src/transforms/plugins/babel-node-positions.js +10 -123
  77. package/esm/src/utils/version-constant.d.ts +1 -1
  78. package/esm/src/utils/version-constant.js +1 -1
  79. package/package.json +1 -6
  80. package/src/deno.js +8 -11
  81. package/src/src/agent/agent-service.ts +91 -7
  82. package/src/src/agent/index.ts +4 -0
  83. package/src/src/agent/runtime/index.ts +32 -1
  84. package/src/src/agent/runtime/tool-helpers.ts +32 -0
  85. package/src/src/embedding/resolve.ts +18 -7
  86. package/src/src/embedding/veryfront-cloud/provider.ts +4 -10
  87. package/src/src/extensions/contracts.ts +3 -3
  88. package/src/src/extensions/interfaces/ai-provider.ts +54 -0
  89. package/src/src/extensions/interfaces/code-parser.ts +12 -0
  90. package/src/src/extensions/interfaces/css-processor.ts +43 -22
  91. package/src/src/extensions/interfaces/index.ts +15 -11
  92. package/src/src/extensions/interfaces/schema-validator.ts +112 -5
  93. package/src/src/extensions/loader.ts +14 -0
  94. package/src/src/extensions/orchestrate.ts +5 -0
  95. package/src/src/extensions/recommendations.ts +4 -1
  96. package/src/src/extensions/registries/ai-provider-registry.ts +53 -0
  97. package/src/src/html/styles-builder/plugin-loader.ts +4 -16
  98. package/src/src/html/styles-builder/tailwind-compiler-cache.ts +27 -6
  99. package/src/src/internal-agents/run-stream.ts +34 -0
  100. package/src/src/provider/model-registry.ts +34 -15
  101. package/src/src/provider/runtime-loader/provider-embedding-responses.ts +1 -1
  102. package/src/src/provider/runtime-loader/provider-http.ts +2 -2
  103. package/src/src/provider/runtime-loader.ts +41 -1189
  104. package/src/src/provider/veryfront-cloud/provider.ts +35 -19
  105. package/src/src/schemas/define.ts +48 -0
  106. package/src/src/schemas/index.ts +13 -2
  107. package/src/src/schemas/zod-adapter.ts +180 -0
  108. package/src/src/server/bootstrap.ts +5 -0
  109. package/src/src/transforms/plugins/babel-node-positions.ts +11 -173
  110. package/src/src/utils/version-constant.ts +1 -1
  111. package/esm/src/extensions/interfaces/ai-model-provider.d.ts +0 -94
  112. package/esm/src/extensions/interfaces/ai-model-provider.d.ts.map +0 -1
  113. package/esm/src/extensions/interfaces/ai-model-provider.js +0 -8
  114. package/src/src/extensions/interfaces/ai-model-provider.ts +0 -100
@@ -1,9 +1,8 @@
1
1
  import { createError, toError } from "../../errors/veryfront-error.js";
2
- import {
3
- createAnthropicModelRuntime,
4
- createGoogleModelRuntime,
5
- createOpenAIModelRuntime,
6
- } from "../runtime-loader.js";
2
+ import { createGoogleModelRuntime } from "../runtime-loader.js";
3
+ import { tryResolve } from "../../extensions/contracts.js";
4
+ import type { AIProviderRegistry } from "../../extensions/interfaces/index.js";
5
+ import { AIProviderRegistryName } from "../../extensions/interfaces/index.js";
7
6
  import type { ModelRuntime } from "../types.js";
8
7
  import {
9
8
  createVeryfrontCloudFetch,
@@ -19,13 +18,22 @@ export function createVeryfrontCloudModel(modelId: string): ModelRuntime {
19
18
  const fetch = createVeryfrontCloudFetch(apiToken, projectSlug);
20
19
 
21
20
  switch (provider) {
22
- case "anthropic":
23
- return createAnthropicModelRuntime({
24
- authToken: apiToken,
25
- baseURL,
26
- name: "veryfront-cloud",
27
- fetch,
28
- }, upstreamModelId);
21
+ case "anthropic": {
22
+ const registry = tryResolve<AIProviderRegistry>(AIProviderRegistryName);
23
+ const anthropic = registry?.get("anthropic");
24
+ if (anthropic) {
25
+ return anthropic.createModel(upstreamModelId, {
26
+ credential: apiToken,
27
+ authToken: apiToken,
28
+ baseURL,
29
+ name: "veryfront-cloud",
30
+ fetch,
31
+ });
32
+ }
33
+ throw new Error(
34
+ "Anthropic provider not installed. Add @veryfront/ext-anthropic to use anthropic/* models via veryfront-cloud.",
35
+ );
36
+ }
29
37
 
30
38
  case "google":
31
39
  return createGoogleModelRuntime({
@@ -36,13 +44,21 @@ export function createVeryfrontCloudModel(modelId: string): ModelRuntime {
36
44
  }, upstreamModelId);
37
45
 
38
46
  case "openai":
39
- case "moonshotai":
40
- return createOpenAIModelRuntime({
41
- apiKey: apiToken,
42
- baseURL,
43
- name: "veryfront-cloud",
44
- fetch,
45
- }, upstreamModelId);
47
+ case "moonshotai": {
48
+ const registry = tryResolve<AIProviderRegistry>(AIProviderRegistryName);
49
+ const openai = registry?.get("openai");
50
+ if (openai) {
51
+ return openai.createModel(upstreamModelId, {
52
+ credential: apiToken,
53
+ baseURL,
54
+ name: "veryfront-cloud",
55
+ fetch,
56
+ });
57
+ }
58
+ throw new Error(
59
+ "OpenAI provider not installed. Add @veryfront/ext-openai to use openai/moonshotai models via veryfront-cloud.",
60
+ );
61
+ }
46
62
 
47
63
  default: {
48
64
  const _exhaustive: never = provider;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Lazy schema factory.
3
+ *
4
+ * `defineSchema(factory)` returns a memoized getter that resolves the
5
+ * `SchemaValidator` extension contract on first call and materializes the
6
+ * schema via the provided factory. This indirection lets core modules declare
7
+ * schemas without importing zod directly — a real validator (typically
8
+ * `@veryfront/ext-zod`) must be registered in the contract registry before
9
+ * the schema is first accessed.
10
+ *
11
+ * @module schemas/define
12
+ */
13
+
14
+ import { tryResolve } from "../extensions/contracts.js";
15
+ import type {
16
+ Schema,
17
+ SchemaFactory,
18
+ SchemaValidator,
19
+ } from "../extensions/interfaces/index.js";
20
+
21
+ /**
22
+ * Wrap a schema factory so that it is built lazily on first call.
23
+ *
24
+ * @param factory - Receives a `SchemaValidator` and returns a `Schema<T>`.
25
+ * @returns A zero-arg getter that caches and returns the built schema.
26
+ * @throws Error when no `SchemaValidator` contract is registered.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * const getUserSchema = defineSchema((v) =>
31
+ * v.object({ id: v.string().uuid(), name: v.string().min(1) })
32
+ * );
33
+ *
34
+ * const user = getUserSchema().parse(input);
35
+ * ```
36
+ */
37
+ export function defineSchema<T>(factory: SchemaFactory<T>): () => Schema<T> {
38
+ let cached: Schema<T> | undefined;
39
+ return () => {
40
+ if (cached) return cached;
41
+ const v = tryResolve<SchemaValidator>("SchemaValidator");
42
+ if (!v) {
43
+ throw new Error("SchemaValidator contract unresolved — install ext-zod");
44
+ }
45
+ cached = factory(v);
46
+ return cached;
47
+ };
48
+ }
@@ -1,10 +1,21 @@
1
1
  /**
2
- * Reusable Zod validation schemas — common types (email, slug, URL, UUID,
3
- * pagination) and primitives (file paths, hex colors, semver, timestamps).
2
+ * Reusable validation schemas — common types (email, slug, URL, UUID,
3
+ * pagination) and primitives (file paths, hex colors, semver, timestamps),
4
+ * plus the `defineSchema` lazy-factory helper.
5
+ *
6
+ * Importing this module also registers the default zod-backed
7
+ * `SchemaValidator` adapter so that `defineSchema(...)` works out of the box.
4
8
  *
5
9
  * @module schemas
6
10
  */
7
11
 
12
+ import { registerZodAdapter } from "./zod-adapter.js";
13
+
14
+ // Register the default SchemaValidator implementation once at module load.
15
+ registerZodAdapter();
16
+
17
+ export { defineSchema } from "./define.js";
18
+
8
19
  export {
9
20
  CommonSchemas,
10
21
  type DateRange,
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Zod-backed `SchemaValidator` adapter.
3
+ *
4
+ * This is the default (core-provided) implementation of the
5
+ * `SchemaValidator` contract. It thinly wraps zod so that core modules can
6
+ * declare schemas through the extension-neutral DSL while still getting zod's
7
+ * runtime behavior.
8
+ *
9
+ * The entire zod surface used by the contract is confined to this file; when
10
+ * `@veryfront/ext-zod` takes over in Phase B this file will be deleted and
11
+ * the `"zod"` import map entry removed.
12
+ *
13
+ * @module schemas/zod-adapter
14
+ */
15
+
16
+ import { z } from "zod";
17
+ import { register } from "../extensions/contracts.js";
18
+ import type {
19
+ InferShape,
20
+ Schema,
21
+ SchemaValidator,
22
+ SchemaValidatorCoerce,
23
+ ValidationIssue,
24
+ ValidationResult,
25
+ } from "../extensions/interfaces/index.js";
26
+
27
+ // deno-lint-ignore no-explicit-any -- zod's chainable APIs return parametric types
28
+ type AnyZodSchema = z.ZodType<any, any, any>;
29
+
30
+ /** Unwrap our opaque Schema<T> back to the underlying zod schema. */
31
+ function toZod<T>(schema: Schema<T>): AnyZodSchema {
32
+ return (schema as unknown as { __zod: AnyZodSchema }).__zod;
33
+ }
34
+
35
+ /** Wrap a zod schema as an opaque Schema<T> with chainables routed through zod. */
36
+ function wrap<T>(zs: AnyZodSchema): Schema<T> {
37
+ // The wrapper fakes the full Schema<T> surface; unsupported chainables on
38
+ // unsuitable kinds (e.g. calling `.email()` on a number) throw at runtime
39
+ // just like zod would.
40
+ // deno-lint-ignore no-explicit-any -- safe within this adapter
41
+ const anyZs = zs as any;
42
+ const s: Schema<T> = {
43
+ _output: undefined as unknown as T,
44
+ optional: () => wrap<T | undefined>(zs.optional()),
45
+ nullable: () => wrap<T | null>(zs.nullable()),
46
+ nullish: () => wrap<T | null | undefined>(zs.nullish()),
47
+ default: (value: T | (() => T)) => wrap<T>(anyZs.default(value)),
48
+ describe: (description: string) => wrap<T>(zs.describe(description)),
49
+ refine: (
50
+ check: (value: T) => boolean,
51
+ message?: string | { message?: string },
52
+ ) => wrap<T>(zs.refine(check as (v: unknown) => boolean, message as never)),
53
+ transform: <U>(fn: (value: T) => U) => wrap<U>(zs.transform(fn as never)),
54
+ strict: () => wrap<T>(anyZs.strict()),
55
+ passthrough: () => wrap<T>(anyZs.passthrough()),
56
+ partial: () => wrap<Partial<T>>(anyZs.partial()),
57
+ extend: <U extends Record<string, Schema<unknown>>>(shape: U) => {
58
+ const zodShape = toZodShape(shape);
59
+ return wrap<T & { [K in keyof U]: U[K] extends Schema<infer V> ? V : never }>(
60
+ anyZs.extend(zodShape),
61
+ );
62
+ },
63
+ merge: <U>(other: Schema<U>) => wrap<T & U>(anyZs.merge(toZod(other))),
64
+ min: (value: number, message?: string) => wrap<T>(anyZs.min(value, message)),
65
+ max: (value: number, message?: string) => wrap<T>(anyZs.max(value, message)),
66
+ int: (message?: string) => wrap<T>(anyZs.int(message)),
67
+ positive: (message?: string) => wrap<T>(anyZs.positive(message)),
68
+ nonnegative: (message?: string) => wrap<T>(anyZs.nonnegative(message)),
69
+ regex: (pattern: RegExp, message?: string) => wrap<T>(anyZs.regex(pattern, message)),
70
+ email: (message?: string) => wrap<T>(anyZs.email(message)),
71
+ url: (message?: string) => wrap<T>(anyZs.url(message)),
72
+ uuid: (message?: string) => wrap<T>(anyZs.uuid(message)),
73
+ datetime: (message?: string) => wrap<T>(anyZs.datetime(message)),
74
+ parse: (data: unknown): T => zs.parse(data) as T,
75
+ safeParse: (data: unknown): ValidationResult<T> => {
76
+ const res = zs.safeParse(data);
77
+ if (res.success) return { success: true, data: res.data as T };
78
+ const issues: ValidationIssue[] = res.error.issues.map((issue) => ({
79
+ path: issue.path as (string | number)[],
80
+ message: issue.message,
81
+ code: issue.code,
82
+ }));
83
+ return { success: false, issues, error: res.error };
84
+ },
85
+ };
86
+ // Attach the underlying zod schema for adapter round-trips without
87
+ // widening the public Schema<T> surface.
88
+ (s as unknown as { __zod: AnyZodSchema }).__zod = zs;
89
+ return s;
90
+ }
91
+
92
+ function toZodShape(
93
+ shape: Record<string, Schema<unknown>>,
94
+ ): Record<string, AnyZodSchema> {
95
+ const out: Record<string, AnyZodSchema> = {};
96
+ for (const [key, value] of Object.entries(shape)) {
97
+ out[key] = toZod(value);
98
+ }
99
+ return out;
100
+ }
101
+
102
+ const coerce: SchemaValidatorCoerce = {
103
+ string: (): Schema<string> => wrap(z.coerce.string()),
104
+ number: (): Schema<number> => wrap(z.coerce.number()),
105
+ boolean: (): Schema<boolean> => wrap(z.coerce.boolean()),
106
+ date: (): Schema<Date> => wrap(z.coerce.date()),
107
+ };
108
+
109
+ /** The zod-backed `SchemaValidator` singleton registered by `registerZodAdapter`. */
110
+ export const zodAdapter: SchemaValidator = {
111
+ string: (): Schema<string> => wrap(z.string()),
112
+ number: (): Schema<number> => wrap(z.number()),
113
+ boolean: (): Schema<boolean> => wrap(z.boolean()),
114
+ date: (): Schema<Date> => wrap(z.date()),
115
+ null: (): Schema<null> => wrap(z.null()),
116
+ unknown: (): Schema<unknown> => wrap(z.unknown()),
117
+ // deno-lint-ignore no-explicit-any -- contract mirrors zod's `any` constructor
118
+ any: (): Schema<any> => wrap(z.any()),
119
+
120
+ object: <S extends Record<string, Schema<unknown>>>(shape: S): Schema<InferShape<S>> =>
121
+ wrap(z.object(toZodShape(shape))),
122
+
123
+ array: <T>(element: Schema<T>): Schema<T[]> => wrap(z.array(toZod(element))),
124
+
125
+ record: <K extends string | number | symbol, V>(
126
+ keys: Schema<K>,
127
+ values: Schema<V>,
128
+ ): Schema<Record<K, V>> => wrap(z.record(toZod(keys) as unknown as z.ZodString, toZod(values))),
129
+
130
+ union: <T extends readonly [Schema<unknown>, ...Schema<unknown>[]]>(
131
+ schemas: T,
132
+ ): Schema<T[number] extends Schema<infer U> ? U : never> => {
133
+ const zodSchemas = schemas.map((s: Schema<unknown>) => toZod(s)) as unknown as [
134
+ AnyZodSchema,
135
+ AnyZodSchema,
136
+ ...AnyZodSchema[],
137
+ ];
138
+ return wrap(z.union(zodSchemas));
139
+ },
140
+
141
+ discriminatedUnion: <
142
+ K extends string,
143
+ T extends readonly [Schema<unknown>, ...Schema<unknown>[]],
144
+ >(
145
+ discriminator: K,
146
+ schemas: T,
147
+ ): Schema<T[number] extends Schema<infer U> ? U : never> => {
148
+ const zodSchemas = schemas.map((s: Schema<unknown>) => toZod(s)) as unknown as [
149
+ // deno-lint-ignore no-explicit-any -- discriminated-union variants widen here
150
+ z.ZodObject<any>,
151
+ // deno-lint-ignore no-explicit-any -- discriminated-union variants widen here
152
+ z.ZodObject<any>,
153
+ // deno-lint-ignore no-explicit-any -- discriminated-union variants widen here
154
+ ...z.ZodObject<any>[],
155
+ ];
156
+ return wrap(z.discriminatedUnion(discriminator, zodSchemas));
157
+ },
158
+
159
+ literal: <T extends string | number | boolean | null>(value: T): Schema<T> =>
160
+ wrap(z.literal(value as never)),
161
+
162
+ enum: <T extends readonly [string, ...string[]]>(values: T): Schema<T[number]> =>
163
+ wrap(
164
+ (z.enum as unknown as (v: readonly [string, ...string[]]) => AnyZodSchema)(values),
165
+ ),
166
+
167
+ coerce,
168
+
169
+ validate: <T>(schema: Schema<T>, data: unknown): ValidationResult<T> => schema.safeParse(data),
170
+ };
171
+
172
+ /**
173
+ * Register the zod adapter as the default `SchemaValidator` implementation.
174
+ *
175
+ * Called once at core bootstrap (`src/schemas/index.ts` side-effect import).
176
+ * Phase B will delete this function when `@veryfront/ext-zod` takes over.
177
+ */
178
+ export function registerZodAdapter(): void {
179
+ register<SchemaValidator>("SchemaValidator", zodAdapter);
180
+ }
@@ -3,6 +3,8 @@ import type { VeryfrontConfig } from "../config/index.js";
3
3
  import type { InvalidationProjectContext } from "../platform/adapters/fs/veryfront/types.js";
4
4
  import { clearConfigCache, getConfig } from "../config/index.js";
5
5
  import { type ExtensionLoader, orchestrateExtensions, tryResolve } from "../extensions/index.js";
6
+ import { AIProviderRegistryName } from "../extensions/interfaces/index.js";
7
+ import { createAIProviderRegistry } from "../extensions/registries/ai-provider-registry.js";
6
8
  import type { TracingExporter } from "../extensions/interfaces/tracing-exporter.js";
7
9
  import {
8
10
  setGlobalActiveSpanAccessor,
@@ -198,6 +200,7 @@ export async function bootstrap(
198
200
  projectDir,
199
201
  config,
200
202
  logger: bootstrapLog,
203
+ primeContracts: { [AIProviderRegistryName]: createAIProviderRegistry() },
201
204
  });
202
205
  wireTracingShim();
203
206
  return {
@@ -239,6 +242,7 @@ export async function bootstrap(
239
242
  projectDir,
240
243
  config,
241
244
  logger: bootstrapLog,
245
+ primeContracts: { [AIProviderRegistryName]: createAIProviderRegistry() },
242
246
  });
243
247
  wireTracingShim();
244
248
  return {
@@ -302,6 +306,7 @@ export async function bootstrap(
302
306
  projectDir,
303
307
  config,
304
308
  logger: bootstrapLog,
309
+ primeContracts: { [AIProviderRegistryName]: createAIProviderRegistry() },
305
310
  }),
306
311
  fsDispose,
307
312
  );
@@ -1,184 +1,22 @@
1
1
  /**
2
- * Babel Transform for TSX Source Position Injection
2
+ * Shim over the `CodeParser` contract's `injectJsxNodePositions()` method.
3
3
  *
4
- * Injects data-node-* attributes into JSX elements for Studio Navigator integration.
5
- * This mirrors the position tracking done by remarkAddNodeId for MDX files.
4
+ * The actual Babel-based implementation lives in `@veryfront/ext-babel`.
5
+ * Core modules continue to import from this path; the shim resolves the
6
+ * contract at call time. Position injection powers Studio Navigator only —
7
+ * if `ext-babel` is not installed we return the source unchanged rather
8
+ * than fail the SSR path.
6
9
  */
7
10
 
8
- import * as parser from "@babel/parser";
9
- import * as traverseModule from "@babel/traverse";
10
- import * as generateModule from "@babel/generator";
11
- import * as t from "@babel/types";
12
-
13
- // Local type definitions for Babel traverse/generate (they don't bundle types)
14
- interface BabelNodePath<T = t.Node> {
15
- node: T;
16
- parent: t.Node;
17
- parentPath: BabelNodePath | null;
18
- scope: unknown;
19
- type: string;
20
- skip(): void;
21
- stop(): void;
22
- }
23
-
24
- interface BabelGeneratorResult {
25
- code: string;
26
- map?: unknown;
27
- }
28
-
29
- type TraverseFunction = (ast: t.Node, opts: Record<string, unknown>) => void;
30
- type GenerateFunction = (ast: t.Node, opts?: Record<string, unknown>) => BabelGeneratorResult;
31
-
32
- interface ModuleWithDefault<T> {
33
- default: T | { default: T };
34
- }
35
-
36
- function resolveDefaultExport<T>(mod: unknown): T {
37
- const m = mod as ModuleWithDefault<T>;
38
- if (typeof m.default === "function") return m.default as T;
39
-
40
- const nested = m.default as { default?: T } | undefined;
41
- if (typeof nested?.default === "function") return nested.default as T;
42
-
43
- return mod as T;
44
- }
45
-
46
- const traverse: TraverseFunction = resolveDefaultExport<TraverseFunction>(traverseModule);
47
- const generate: GenerateFunction = resolveDefaultExport<GenerateFunction>(generateModule);
48
-
49
- const SKIPPED_ELEMENTS = new Set([
50
- "html",
51
- "head",
52
- "title",
53
- "body",
54
- "link",
55
- "base",
56
- "meta",
57
- "script",
58
- "style",
59
- "noscript",
60
- "template",
61
- "svg",
62
- "path",
63
- "circle",
64
- "ellipse",
65
- "line",
66
- "polygon",
67
- "polyline",
68
- "rect",
69
- "g",
70
- "defs",
71
- "linearGradient",
72
- "radialGradient",
73
- "stop",
74
- "text",
75
- "tspan",
76
- "use",
77
- "filter",
78
- ]);
11
+ import { tryResolve } from "../../extensions/contracts.js";
12
+ import type { CodeParser } from "../../extensions/interfaces/index.js";
79
13
 
80
14
  interface TransformOptions {
81
15
  filePath: string;
82
16
  }
83
17
 
84
- function getElementName(openingElement: t.JSXOpeningElement): string {
85
- const { name } = openingElement;
86
-
87
- if (t.isJSXIdentifier(name)) return name.name;
88
-
89
- if (!t.isJSXMemberExpression(name)) return "DynamicComponent";
90
-
91
- const parts: string[] = [];
92
- let current: t.JSXMemberExpression | t.JSXIdentifier = name;
93
-
94
- while (t.isJSXMemberExpression(current)) {
95
- if (t.isJSXIdentifier(current.property)) parts.unshift(current.property.name);
96
- current = current.object;
97
- }
98
-
99
- if (t.isJSXIdentifier(current)) parts.unshift(current.name);
100
-
101
- return parts.length ? parts.join(".") : "MemberExpression";
102
- }
103
-
104
- function isFragment(openingElement: t.JSXOpeningElement): boolean {
105
- const { name } = openingElement;
106
-
107
- if (t.isJSXMemberExpression(name)) {
108
- return (
109
- t.isJSXIdentifier(name.object) &&
110
- name.object.name === "React" &&
111
- t.isJSXIdentifier(name.property) &&
112
- name.property.name === "Fragment"
113
- );
114
- }
115
-
116
- return t.isJSXIdentifier(name) && name.name === "Fragment";
117
- }
118
-
119
- function hasPositionAttribute(attributes: (t.JSXAttribute | t.JSXSpreadAttribute)[]): boolean {
120
- return attributes.some((attr) => {
121
- if (!t.isJSXAttribute(attr) || !t.isJSXIdentifier(attr.name)) return false;
122
- return attr.name.name === "data-node-line" || attr.name.name === "data-vf-id";
123
- });
124
- }
125
-
126
- /**
127
- * Transform TSX source to inject position data attributes into JSX elements.
128
- * This enables Studio Navigator to map rendered elements back to source positions.
129
- */
130
18
  export function injectNodePositions(source: string, options: TransformOptions): string {
131
- if (!source.trim()) return source;
132
- if (!options.filePath) return source;
133
-
134
- try {
135
- const ast = parser.parse(source, {
136
- sourceType: "module",
137
- plugins: ["typescript", "jsx"],
138
- });
139
-
140
- let nodeCounter = 0;
141
-
142
- traverse(ast as t.Node, {
143
- JSXElement: {
144
- enter(path: BabelNodePath<t.JSXElement>) {
145
- const openingElement = path.node.openingElement;
146
- const elementName = getElementName(openingElement);
147
-
148
- if (SKIPPED_ELEMENTS.has(elementName.toLowerCase())) return;
149
- if (isFragment(openingElement)) return;
150
- if (hasPositionAttribute(openingElement.attributes)) return;
151
-
152
- const loc = openingElement.loc;
153
- if (!loc) return;
154
-
155
- const nodeId = `node-${nodeCounter++}`;
156
- openingElement.attributes.push(
157
- t.jsxAttribute(t.jsxIdentifier("data-node-id"), t.stringLiteral(nodeId)),
158
- t.jsxAttribute(
159
- t.jsxIdentifier("data-node-file"),
160
- t.stringLiteral(options.filePath),
161
- ),
162
- t.jsxAttribute(t.jsxIdentifier("data-node-name"), t.stringLiteral(elementName)),
163
- t.jsxAttribute(
164
- t.jsxIdentifier("data-node-line"),
165
- t.stringLiteral(String(loc.start.line)),
166
- ),
167
- t.jsxAttribute(
168
- t.jsxIdentifier("data-node-column"),
169
- t.stringLiteral(String(loc.start.column)),
170
- ),
171
- );
172
- },
173
- },
174
- });
175
-
176
- return generate(ast as t.Node, {
177
- retainLines: true,
178
- compact: false,
179
- }).code;
180
- } catch (_) {
181
- /* expected: source may not be parseable TSX/JSX */
182
- return source;
183
- }
19
+ const parser = tryResolve<CodeParser>("CodeParser");
20
+ if (!parser) return source;
21
+ return parser.injectJsxNodePositions(source, options);
184
22
  }
@@ -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.282";
3
+ export const VERSION = "0.1.284";
@@ -1,94 +0,0 @@
1
- /**
2
- * Contract interface for AI/LLM model providers.
3
- *
4
- * Default implementation: `@veryfront/ext-openai`
5
- *
6
- * @module extensions/interfaces/ai-model-provider
7
- */
8
- /** A single part of a multi-modal message (text or image). */
9
- export interface ContentPart {
10
- /** Part type. */
11
- type: "text" | "image";
12
- /** Text content (when `type` is `"text"`). */
13
- text?: string;
14
- /** Image URL or base64 data (when `type` is `"image"`). */
15
- imageUrl?: string;
16
- }
17
- /** A chat message in a conversation. */
18
- export interface ChatMessage {
19
- /** Message role. */
20
- role: "system" | "user" | "assistant" | "tool";
21
- /** Simple text content. */
22
- content?: string;
23
- /** Multi-modal content parts (used instead of `content`). */
24
- parts?: ContentPart[];
25
- /** Tool call ID this message responds to (for `tool` role). */
26
- toolCallId?: string;
27
- }
28
- /** Definition of a tool the model may invoke. */
29
- export interface ToolDefinition {
30
- /** Tool name. */
31
- name: string;
32
- /** Human-readable description of what the tool does. */
33
- description: string;
34
- /** JSON Schema describing the tool's parameters. */
35
- parameters: Record<string, unknown>;
36
- }
37
- /** Options passed to {@link AIModelProvider.complete} and {@link AIModelProvider.stream}. */
38
- export interface CompletionOptions {
39
- /** Model identifier (e.g. `"gpt-4o"`, `"claude-sonnet-4-20250514"`). */
40
- model: string;
41
- /** Conversation messages. */
42
- messages: ChatMessage[];
43
- /** Sampling temperature. */
44
- temperature?: number;
45
- /** Maximum tokens to generate. */
46
- maxTokens?: number;
47
- /** Available tools for function calling. */
48
- tools?: ToolDefinition[];
49
- /** Additional provider-specific options. */
50
- [key: string]: unknown;
51
- }
52
- /** Result returned from {@link AIModelProvider.complete}. */
53
- export interface CompletionResult {
54
- /** Generated text content. */
55
- content: string;
56
- /** Tool calls requested by the model, if any. */
57
- toolCalls?: Array<{
58
- id: string;
59
- name: string;
60
- arguments: string;
61
- }>;
62
- /** Token usage statistics. */
63
- usage?: {
64
- promptTokens: number;
65
- completionTokens: number;
66
- totalTokens: number;
67
- };
68
- }
69
- /** A chunk emitted during streaming completion. */
70
- export interface StreamChunk {
71
- /** Incremental text delta. */
72
- content?: string;
73
- /** Incremental tool call delta. */
74
- toolCallDelta?: {
75
- id?: string;
76
- name?: string;
77
- arguments?: string;
78
- };
79
- /** Whether this is the final chunk. */
80
- done: boolean;
81
- }
82
- /**
83
- * AIModelProvider contract interface.
84
- *
85
- * Implementations provide chat completion and streaming capabilities
86
- * against large language models.
87
- */
88
- export interface AIModelProvider {
89
- /** Generate a complete response for the given conversation. */
90
- complete(options: CompletionOptions): Promise<CompletionResult>;
91
- /** Stream a response token-by-token. */
92
- stream(options: CompletionOptions): AsyncIterable<StreamChunk>;
93
- }
94
- //# sourceMappingURL=ai-model-provider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai-model-provider.d.ts","sourceRoot":"","sources":["../../../../src/src/extensions/interfaces/ai-model-provider.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,iBAAiB;IACjB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wCAAwC;AACxC,MAAM,WAAW,WAAW;IAC1B,oBAAoB;IACpB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,6FAA6F;AAC7F,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,4CAA4C;IAC5C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,8BAA8B;IAC9B,KAAK,CAAC,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,aAAa,CAAC,EAAE;QACd,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,uCAAuC;IACvC,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAChE,wCAAwC;IACxC,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;CAChE"}
@@ -1,8 +0,0 @@
1
- /**
2
- * Contract interface for AI/LLM model providers.
3
- *
4
- * Default implementation: `@veryfront/ext-openai`
5
- *
6
- * @module extensions/interfaces/ai-model-provider
7
- */
8
- export {};