@basaltkit/ai 1.0.1 → 1.1.1

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.
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Runtime schemas for the AI layer's public data contracts. `@basaltkit/ai` is a
3
+ * dev-only package, so taking a `zod` dependency here is acceptable — these
4
+ * schemas exist so out-of-process consumers (notably the forthcoming dev-only
5
+ * `@basaltkit/ai-mcp` bridge) can (a) validate tool inputs/outputs and (b) derive
6
+ * JSON Schema to advertise as MCP `inputSchema`/`outputSchema`.
7
+ *
8
+ * The schemas mirror the exported TypeScript interfaces exactly. `parsePlan` and
9
+ * `parseReview` route their already-coerced output through them (validate *after*
10
+ * tolerant coercion — the model's raw text is never fed to `.parse()` directly).
11
+ */
12
+ import { z } from 'zod';
13
+ /** Bump when the serialized shape of a plan changes incompatibly. */
14
+ export const PLAN_SCHEMA_VERSION = 1;
15
+ /** Bump when the serialized shape of a make result changes incompatibly. */
16
+ export const MAKE_SCHEMA_VERSION = 1;
17
+ // --- Provider-agnostic scalars ---------------------------------------------
18
+ const DatabaseSchema = z.enum(['postgresql', 'mysql', 'sqlite']).nullable();
19
+ // --- ProjectContext (context/project.ts) -----------------------------------
20
+ export const DetectedStackSchema = z.object({
21
+ http: z.enum(['fastify']).nullable(),
22
+ orm: z.enum(['prisma']).nullable(),
23
+ database: DatabaseSchema,
24
+ tenancy: z.boolean(),
25
+ auth: z.boolean(),
26
+ rbac: z.boolean(),
27
+ subscriptions: z.boolean(),
28
+ payments: z.boolean(),
29
+ storage: z.boolean(),
30
+ queue: z.boolean(),
31
+ search: z.boolean(),
32
+ audit: z.boolean(),
33
+ events: z.boolean(),
34
+ scheduler: z.boolean(),
35
+ logger: z.boolean(),
36
+ ai: z.boolean(),
37
+ });
38
+ export const PrismaModelSchema = z.object({
39
+ name: z.string(),
40
+ fields: z.array(z.string()),
41
+ tenantScoped: z.boolean(),
42
+ });
43
+ export const PrismaInfoSchema = z.object({
44
+ provider: DatabaseSchema,
45
+ models: z.array(PrismaModelSchema),
46
+ });
47
+ export const AppFileInfoSchema = z.object({
48
+ path: z.string(),
49
+ plugins: z.array(z.string()),
50
+ fastifyLoggerConfigured: z.boolean(),
51
+ memorySources: z.array(z.string()),
52
+ pluginCalls: z.array(z.string()),
53
+ });
54
+ export const ServerFileInfoSchema = z.object({
55
+ path: z.string(),
56
+ connectsAtBoot: z.boolean(),
57
+ startsServer: z.boolean(),
58
+ });
59
+ export const EnvFileInfoSchema = z.object({
60
+ path: z.string(),
61
+ appSecretDefault: z.string().nullable(),
62
+ redisUrlDefault: z.string().nullable(),
63
+ });
64
+ export const ProjectContextSchema = z.object({
65
+ root: z.string(),
66
+ installed: z.array(z.string()),
67
+ stack: DetectedStackSchema,
68
+ prisma: PrismaInfoSchema.nullable(),
69
+ app: AppFileInfoSchema.nullable(),
70
+ server: ServerFileInfoSchema.nullable(),
71
+ env: EnvFileInfoSchema.nullable(),
72
+ });
73
+ // --- Diagnostics + AnalysisReport (doctor/types.ts, analyze/run.ts) --------
74
+ export const SeveritySchema = z.enum(['error', 'warning', 'info']);
75
+ export const DiagnosticCategorySchema = z.enum([
76
+ 'security',
77
+ 'database',
78
+ 'observability',
79
+ 'tenancy',
80
+ 'performance',
81
+ 'durability',
82
+ 'config',
83
+ ]);
84
+ export const DiagnosticSchema = z.object({
85
+ id: z.string(),
86
+ title: z.string(),
87
+ severity: SeveritySchema,
88
+ category: DiagnosticCategorySchema,
89
+ detected: z.string(),
90
+ recommended: z.string(),
91
+ reason: z.string(),
92
+ fix: z.string().optional(),
93
+ docs: z.string().optional(),
94
+ });
95
+ export const AnalysisReportSchema = z.object({
96
+ root: z.string(),
97
+ capabilities: z.array(z.string()),
98
+ installed: z.array(z.string()),
99
+ database: z.string().nullable(),
100
+ models: z.array(z.string()),
101
+ tenantScopedModels: z.array(z.string()),
102
+ unscopedModels: z.array(z.string()),
103
+ diagnostics: z.array(DiagnosticSchema),
104
+ });
105
+ // --- ArchitecturePlan (plan/types.ts) --------------------------------------
106
+ export const PlanFieldSchema = z.object({
107
+ name: z.string(),
108
+ type: z.string(),
109
+ enum: z.array(z.string()).optional(),
110
+ });
111
+ export const PlanRelationSchema = z.object({
112
+ name: z.string(),
113
+ model: z.string(),
114
+ });
115
+ export const PlanEntitySchema = z.object({
116
+ name: z.string(),
117
+ fields: z.array(PlanFieldSchema),
118
+ tenantScoped: z.boolean(),
119
+ relations: z.array(PlanRelationSchema).optional(),
120
+ });
121
+ export const PlanStepKindSchema = z.enum([
122
+ 'generator',
123
+ 'schema',
124
+ 'migration',
125
+ 'service',
126
+ 'routes',
127
+ 'permissions',
128
+ 'audit',
129
+ 'test',
130
+ 'docs',
131
+ 'other',
132
+ ]);
133
+ export const PlanStepSchema = z.object({
134
+ order: z.number(),
135
+ title: z.string(),
136
+ kind: PlanStepKindSchema,
137
+ detail: z.string(),
138
+ command: z.string().optional(),
139
+ files: z.array(z.string()).optional(),
140
+ });
141
+ export const ArchitecturePlanSchema = z.object({
142
+ schemaVersion: z.number().int().default(PLAN_SCHEMA_VERSION),
143
+ request: z.string(),
144
+ summary: z.string(),
145
+ entities: z.array(PlanEntitySchema),
146
+ steps: z.array(PlanStepSchema),
147
+ permissions: z.array(z.string()),
148
+ auditEvents: z.array(z.string()),
149
+ tenantScoped: z.boolean(),
150
+ warnings: z.array(z.string()),
151
+ });
152
+ // --- MakeResult (make/types.ts) --------------------------------------------
153
+ export const GeneratedFileSchema = z.object({
154
+ path: z.string(),
155
+ content: z.string(),
156
+ });
157
+ export const SchemaMergeSchema = z.object({
158
+ path: z.string(),
159
+ found: z.boolean(),
160
+ merged: z.array(z.string()),
161
+ skipped: z.array(z.string()),
162
+ written: z.boolean(),
163
+ });
164
+ export const MigrationSchema = z.object({
165
+ ok: z.boolean(),
166
+ output: z.string(),
167
+ });
168
+ export const ResourceBuildSchema = z.object({
169
+ name: z.string(),
170
+ prisma: z.boolean(),
171
+ softDelete: z.boolean(),
172
+ files: z.array(GeneratedFileSchema),
173
+ augmented: z.boolean(),
174
+ guarded: z.boolean(),
175
+ audited: z.boolean(),
176
+ written: z.array(z.string()),
177
+ registered: z.boolean(),
178
+ note: z.string().optional(),
179
+ });
180
+ export const ReviewStatusSchema = z.enum(['pass', 'warn', 'fail']);
181
+ export const ReviewItemSchema = z.object({
182
+ label: z.string(),
183
+ status: ReviewStatusSchema,
184
+ detail: z.string(),
185
+ });
186
+ export const ReviewResultSchema = z.object({
187
+ items: z.array(ReviewItemSchema),
188
+ ok: z.boolean(),
189
+ });
190
+ export const FilePreviewSchema = z.object({
191
+ path: z.string(),
192
+ action: z.enum(['create', 'overwrite']),
193
+ diff: z.string(),
194
+ });
195
+ export const MakePreviewSchema = z.object({
196
+ perFile: z.array(FilePreviewSchema),
197
+ clashes: z.array(z.string()),
198
+ });
199
+ export const MakeResultSchema = z.object({
200
+ schemaVersion: z.number().int().default(MAKE_SCHEMA_VERSION),
201
+ request: z.string(),
202
+ dryRun: z.boolean(),
203
+ resources: z.array(ResourceBuildSchema),
204
+ schema: SchemaMergeSchema.optional(),
205
+ migration: MigrationSchema.optional(),
206
+ followUps: z.array(z.string()),
207
+ review: ReviewResultSchema,
208
+ preview: MakePreviewSchema.optional(),
209
+ });
210
+ // --- AgentReview (review/types.ts) -----------------------------------------
211
+ export const ReviewIssueSchema = z.object({
212
+ dimension: z.string(),
213
+ severity: z.enum(['error', 'warning']),
214
+ message: z.string(),
215
+ });
216
+ export const AgentReviewSchema = z.object({
217
+ approved: z.boolean(),
218
+ summary: z.string(),
219
+ issues: z.array(ReviewIssueSchema),
220
+ });
221
+ // --- JSON Schema derivation -------------------------------------------------
222
+ /**
223
+ * Convert one of the exported zod schemas to JSON Schema (Draft 2020-12), for an
224
+ * out-of-process consumer to advertise as an MCP tool `inputSchema`/`outputSchema`.
225
+ */
226
+ export function toJsonSchema(schema) {
227
+ return z.toJSONSchema(schema);
228
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Framework-free provider-backed workflow surface: the AI provider factory and
3
+ * the plan/review workflow steps — WITHOUT the `basalt ai` CLI wiring, which
4
+ * imports `@basaltkit/cli` (→ `@basaltkit/core`). Sibling to `@basaltkit/ai/analysis`.
5
+ *
6
+ * It exists so out-of-process, dev-only consumers — notably `@basaltkit/ai-mcp` —
7
+ * can build a provider and run plan/review without pulling `@basaltkit/core` or
8
+ * `@basaltkit/http` into their dependency graph. Everything here is also exported
9
+ * from the main barrel; this is a boundary-preserving subset, not a new API.
10
+ */
11
+ export { createProvider, providerEnvFrom, providerEnvFromProcess, type CreateProviderOptions, type ProviderEnv, type ProviderName, } from './provider/factory.js';
12
+ export { type AIMessage, type AIProvider, type FetchLike, type GenerateOptions, } from './provider/types.js';
13
+ export { type OnProgress, type WorkflowProgress, type WorkflowRunOptions } from './generate.js';
14
+ export { createPlan, parsePlan, type CreatePlanOptions } from './plan/plan.js';
15
+ export type { ArchitecturePlan, PlanEntity, PlanField, PlanRelation, PlanStep, PlanStepKind, } from './plan/types.js';
16
+ export { buildReviewContext, parseReview, reviewImplementation, type ReviewOptions, } from './review/review.js';
17
+ export type { AgentReview, ReviewIssue } from './review/types.js';
18
+ export { runMake } from './make/make.js';
19
+ export type { MakeOptions, MakeResult, MakePreview, FilePreview, ResourceBuild, SchemaMerge, Migration, ReviewResult, ReviewItem, ReviewStatus, } from './make/types.js';
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Framework-free provider-backed workflow surface: the AI provider factory and
3
+ * the plan/review workflow steps — WITHOUT the `basalt ai` CLI wiring, which
4
+ * imports `@basaltkit/cli` (→ `@basaltkit/core`). Sibling to `@basaltkit/ai/analysis`.
5
+ *
6
+ * It exists so out-of-process, dev-only consumers — notably `@basaltkit/ai-mcp` —
7
+ * can build a provider and run plan/review without pulling `@basaltkit/core` or
8
+ * `@basaltkit/http` into their dependency graph. Everything here is also exported
9
+ * from the main barrel; this is a boundary-preserving subset, not a new API.
10
+ */
11
+ // Provider factory + the vendor-agnostic surface.
12
+ export { createProvider, providerEnvFrom, providerEnvFromProcess, } from './provider/factory.js';
13
+ export {} from './provider/types.js';
14
+ // Progress + cancellation vocabulary.
15
+ export {} from './generate.js';
16
+ // Planning.
17
+ export { createPlan, parsePlan } from './plan/plan.js';
18
+ // Review — LLM critique of a build result.
19
+ export { buildReviewContext, parseReview, reviewImplementation, } from './review/review.js';
20
+ // Implementation — execute a plan (scaffold + review gate). Safe by default:
21
+ // dry-run detects clashes and attaches diffs; writes never touch the DB unless
22
+ // `migrate` is set. Framework-free via `@basaltkit/generator/resource`.
23
+ export { runMake } from './make/make.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basaltkit/ai",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "AI-native developer experience for Basalt: a provider-agnostic engine plus `basalt ai` CLI that understands the project's stack, analyzes it, and diagnoses issues — following the framework's own conventions, not inventing new ones.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -8,14 +8,27 @@
8
8
  ".": {
9
9
  "types": "./dist/index.d.ts",
10
10
  "import": "./dist/index.js"
11
+ },
12
+ "./schema": {
13
+ "types": "./dist/schema/index.d.ts",
14
+ "import": "./dist/schema/index.js"
15
+ },
16
+ "./analysis": {
17
+ "types": "./dist/analysis.d.ts",
18
+ "import": "./dist/analysis.js"
19
+ },
20
+ "./workflows": {
21
+ "types": "./dist/workflows.d.ts",
22
+ "import": "./dist/workflows.js"
11
23
  }
12
24
  },
13
25
  "files": [
14
26
  "dist"
15
27
  ],
16
28
  "dependencies": {
17
- "@basaltkit/cli": "^1.2.1",
18
- "@basaltkit/generator": "^1.1.2"
29
+ "zod": "^4.0.0",
30
+ "@basaltkit/cli": "^1.2.2",
31
+ "@basaltkit/generator": "^1.2.1"
19
32
  },
20
33
  "devDependencies": {
21
34
  "@types/node": "^26.3.0",