@contractspec/bundle.workspace 3.2.0 → 3.4.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.
- package/dist/formatters/json.d.ts +3 -0
- package/dist/index.js +342 -208
- package/dist/node/index.js +342 -208
- package/package.json +11 -11
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* for parsing in CI/CD scripts and integrations.
|
|
6
6
|
*/
|
|
7
7
|
import type { CICheckResult } from '../services/ci-check/types';
|
|
8
|
+
import type { DriftResult } from '../services/drift';
|
|
8
9
|
/**
|
|
9
10
|
* Base interface for all standardized JSON outputs.
|
|
10
11
|
*/
|
|
@@ -18,6 +19,8 @@ export interface BaseJsonOutput {
|
|
|
18
19
|
export interface JsonFormatOptions {
|
|
19
20
|
/** Pretty print with indentation. */
|
|
20
21
|
pretty?: boolean;
|
|
22
|
+
/** Drift detection result to include in the output. */
|
|
23
|
+
driftResult?: DriftResult;
|
|
21
24
|
}
|
|
22
25
|
/**
|
|
23
26
|
* CI JSON output structure (v1.0).
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,230 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
3
7
|
var __export = (target, all) => {
|
|
4
8
|
for (var name in all)
|
|
5
9
|
__defProp(target, name, {
|
|
6
10
|
get: all[name],
|
|
7
11
|
enumerable: true,
|
|
8
12
|
configurable: true,
|
|
9
|
-
set: (
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
10
14
|
});
|
|
11
15
|
};
|
|
16
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
12
17
|
var __require = import.meta.require;
|
|
13
18
|
|
|
19
|
+
// src/services/config.ts
|
|
20
|
+
import {
|
|
21
|
+
ContractsrcSchema,
|
|
22
|
+
DEFAULT_CONTRACTSRC as DEFAULT_CONTRACTSRC2
|
|
23
|
+
} from "@contractspec/lib.contracts-spec/workspace-config";
|
|
24
|
+
async function loadWorkspaceConfig(fs5, cwd) {
|
|
25
|
+
const configPath = fs5.join(cwd ?? ".", ".contractsrc.json");
|
|
26
|
+
const exists = await fs5.exists(configPath);
|
|
27
|
+
if (!exists) {
|
|
28
|
+
return DEFAULT_CONTRACTSRC2;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const content = await fs5.readFile(configPath);
|
|
32
|
+
const parsed = JSON.parse(content);
|
|
33
|
+
const resolved = ContractsrcSchema.safeParse(parsed);
|
|
34
|
+
return {
|
|
35
|
+
...DEFAULT_CONTRACTSRC2,
|
|
36
|
+
...resolved.data,
|
|
37
|
+
conventions: {
|
|
38
|
+
...DEFAULT_CONTRACTSRC2.conventions,
|
|
39
|
+
...resolved.data?.conventions || {}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
} catch {
|
|
43
|
+
return DEFAULT_CONTRACTSRC2;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function getApiKey(provider) {
|
|
47
|
+
switch (provider) {
|
|
48
|
+
case "claude":
|
|
49
|
+
return process.env["ANTHROPIC_API_KEY"];
|
|
50
|
+
case "openai":
|
|
51
|
+
return process.env["OPENAI_API_KEY"];
|
|
52
|
+
case "custom":
|
|
53
|
+
return process.env["CONTRACTSPEC_LLM_API_KEY"];
|
|
54
|
+
case "ollama":
|
|
55
|
+
return;
|
|
56
|
+
default:
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
var init_config = () => {};
|
|
61
|
+
|
|
62
|
+
// src/services/create/ai-generator.ts
|
|
63
|
+
var exports_ai_generator = {};
|
|
64
|
+
__export(exports_ai_generator, {
|
|
65
|
+
AIGenerator: () => AIGenerator
|
|
66
|
+
});
|
|
67
|
+
import { generateObject as generateObject2, generateText as generateText6, streamText as streamText2 } from "ai";
|
|
68
|
+
import * as z2 from "zod";
|
|
69
|
+
import {
|
|
70
|
+
createProvider
|
|
71
|
+
} from "@contractspec/lib.ai-providers";
|
|
72
|
+
import {
|
|
73
|
+
buildComponentPrompt as buildComponentPrompt2,
|
|
74
|
+
buildEventSpecPrompt,
|
|
75
|
+
buildFormPrompt as buildFormPrompt2,
|
|
76
|
+
buildHandlerPrompt as buildHandlerPrompt2,
|
|
77
|
+
buildOperationSpecPrompt,
|
|
78
|
+
buildPresentationSpecPrompt,
|
|
79
|
+
buildTestPrompt as buildTestPrompt2,
|
|
80
|
+
getCodeGenSystemPrompt as getCodeGenSystemPrompt2,
|
|
81
|
+
getSystemPrompt
|
|
82
|
+
} from "@contractspec/module.workspace";
|
|
83
|
+
|
|
84
|
+
class AIGenerator {
|
|
85
|
+
config;
|
|
86
|
+
constructor(config) {
|
|
87
|
+
this.config = config;
|
|
88
|
+
}
|
|
89
|
+
getModel() {
|
|
90
|
+
const providerName = this.config.aiProvider;
|
|
91
|
+
const apiKey = this.config.customApiKey || getApiKey(this.config.aiProvider);
|
|
92
|
+
const providerConfig = {
|
|
93
|
+
provider: providerName === "custom" ? "openai" : providerName,
|
|
94
|
+
model: this.config.aiModel,
|
|
95
|
+
apiKey,
|
|
96
|
+
baseUrl: this.config.customEndpoint || undefined
|
|
97
|
+
};
|
|
98
|
+
const provider = createProvider(providerConfig);
|
|
99
|
+
return provider.getModel();
|
|
100
|
+
}
|
|
101
|
+
async generateOperationSpec(description, kind) {
|
|
102
|
+
const model = this.getModel();
|
|
103
|
+
const schema = z2.object({
|
|
104
|
+
name: z2.string().describe('Dot notation name like "domain.operation"'),
|
|
105
|
+
version: z2.number().int().positive().default(1),
|
|
106
|
+
description: z2.string().describe("Clear, concise summary"),
|
|
107
|
+
goal: z2.string().describe("Business purpose"),
|
|
108
|
+
context: z2.string().describe("Background and constraints"),
|
|
109
|
+
stability: z2.enum(["experimental", "beta", "stable", "deprecated"]).default("beta"),
|
|
110
|
+
owners: z2.array(z2.string()).describe("Team/person owners with @ prefix"),
|
|
111
|
+
tags: z2.array(z2.string()).describe("Categorization tags"),
|
|
112
|
+
auth: z2.enum(["anonymous", "user", "admin"]).describe("Required auth level"),
|
|
113
|
+
inputShape: z2.string().describe("Description of input structure"),
|
|
114
|
+
outputShape: z2.string().describe("Description of output structure"),
|
|
115
|
+
flags: z2.array(z2.string()).describe("Feature flags").default([]),
|
|
116
|
+
possibleEvents: z2.array(z2.string()).describe("Events this may emit").default([]),
|
|
117
|
+
analytics: z2.array(z2.string()).describe("Analytics events to track").default([])
|
|
118
|
+
});
|
|
119
|
+
const prompt = buildOperationSpecPrompt(description, kind);
|
|
120
|
+
const result = await generateObject2({
|
|
121
|
+
model,
|
|
122
|
+
schema,
|
|
123
|
+
prompt,
|
|
124
|
+
system: getSystemPrompt()
|
|
125
|
+
});
|
|
126
|
+
return result.object;
|
|
127
|
+
}
|
|
128
|
+
async generateEventSpec(description) {
|
|
129
|
+
const model = this.getModel();
|
|
130
|
+
const schema = z2.object({
|
|
131
|
+
name: z2.string().describe('Dot notation name like "domain.event_name"'),
|
|
132
|
+
version: z2.number().int().positive().default(1),
|
|
133
|
+
description: z2.string().describe("When this event is emitted"),
|
|
134
|
+
stability: z2.enum(["experimental", "beta", "stable", "deprecated"]).default("beta"),
|
|
135
|
+
owners: z2.array(z2.string()).default([]),
|
|
136
|
+
tags: z2.array(z2.string()).default([]),
|
|
137
|
+
payloadShape: z2.string().describe("Description of event payload"),
|
|
138
|
+
piiFields: z2.array(z2.string()).describe("PII field paths").default([])
|
|
139
|
+
});
|
|
140
|
+
const prompt = buildEventSpecPrompt(description);
|
|
141
|
+
const result = await generateObject2({
|
|
142
|
+
model,
|
|
143
|
+
schema,
|
|
144
|
+
prompt,
|
|
145
|
+
system: getSystemPrompt()
|
|
146
|
+
});
|
|
147
|
+
return result.object;
|
|
148
|
+
}
|
|
149
|
+
async generatePresentationSpec(description, kind) {
|
|
150
|
+
const model = this.getModel();
|
|
151
|
+
const schema = z2.object({
|
|
152
|
+
name: z2.string(),
|
|
153
|
+
version: z2.number().int().positive().default(1),
|
|
154
|
+
description: z2.string(),
|
|
155
|
+
stability: z2.enum(["experimental", "beta", "stable", "deprecated"]).default("beta"),
|
|
156
|
+
owners: z2.array(z2.string()).default([]),
|
|
157
|
+
tags: z2.array(z2.string()).default([]),
|
|
158
|
+
componentKey: z2.string().optional(),
|
|
159
|
+
propsShape: z2.string().optional(),
|
|
160
|
+
content: z2.string().optional(),
|
|
161
|
+
mimeType: z2.string().optional(),
|
|
162
|
+
dataShape: z2.string().optional()
|
|
163
|
+
});
|
|
164
|
+
const prompt = buildPresentationSpecPrompt(description, kind);
|
|
165
|
+
const result = await generateObject2({
|
|
166
|
+
model,
|
|
167
|
+
schema,
|
|
168
|
+
prompt,
|
|
169
|
+
system: getSystemPrompt()
|
|
170
|
+
});
|
|
171
|
+
return result.object;
|
|
172
|
+
}
|
|
173
|
+
async generateHandler(specCode) {
|
|
174
|
+
const model = this.getModel();
|
|
175
|
+
const result = await generateText6({
|
|
176
|
+
model,
|
|
177
|
+
prompt: buildHandlerPrompt2(specCode),
|
|
178
|
+
system: getCodeGenSystemPrompt2()
|
|
179
|
+
});
|
|
180
|
+
return result.text;
|
|
181
|
+
}
|
|
182
|
+
async generateComponent(specCode) {
|
|
183
|
+
const model = this.getModel();
|
|
184
|
+
const result = await generateText6({
|
|
185
|
+
model,
|
|
186
|
+
prompt: buildComponentPrompt2(specCode),
|
|
187
|
+
system: getCodeGenSystemPrompt2()
|
|
188
|
+
});
|
|
189
|
+
return result.text;
|
|
190
|
+
}
|
|
191
|
+
async generateForm(specCode) {
|
|
192
|
+
const model = this.getModel();
|
|
193
|
+
const result = await generateText6({
|
|
194
|
+
model,
|
|
195
|
+
prompt: buildFormPrompt2(specCode),
|
|
196
|
+
system: getCodeGenSystemPrompt2()
|
|
197
|
+
});
|
|
198
|
+
return result.text;
|
|
199
|
+
}
|
|
200
|
+
async generateTests(specCode, implementationCode, testType) {
|
|
201
|
+
const model = this.getModel();
|
|
202
|
+
const result = await generateText6({
|
|
203
|
+
model,
|
|
204
|
+
prompt: buildTestPrompt2(specCode, implementationCode, testType),
|
|
205
|
+
system: getCodeGenSystemPrompt2()
|
|
206
|
+
});
|
|
207
|
+
return result.text;
|
|
208
|
+
}
|
|
209
|
+
async streamCodeGeneration(prompt, onChunk) {
|
|
210
|
+
const model = this.getModel();
|
|
211
|
+
const result = await streamText2({
|
|
212
|
+
model,
|
|
213
|
+
prompt,
|
|
214
|
+
system: getCodeGenSystemPrompt2()
|
|
215
|
+
});
|
|
216
|
+
let fullText = "";
|
|
217
|
+
for await (const chunk of result.textStream) {
|
|
218
|
+
fullText += chunk;
|
|
219
|
+
onChunk(chunk);
|
|
220
|
+
}
|
|
221
|
+
return fullText;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
var init_ai_generator = __esm(() => {
|
|
225
|
+
init_config();
|
|
226
|
+
});
|
|
227
|
+
|
|
14
228
|
// src/index.ts
|
|
15
229
|
import * as module from "@contractspec/module.workspace";
|
|
16
230
|
// src/adapters/fs.node.ts
|
|
@@ -2900,47 +3114,10 @@ function getGraphStats(graph) {
|
|
|
2900
3114
|
unused: unused.length
|
|
2901
3115
|
};
|
|
2902
3116
|
}
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
} from "@contractspec/lib.contracts-spec/workspace-config";
|
|
2908
|
-
async function loadWorkspaceConfig(fs5, cwd) {
|
|
2909
|
-
const configPath = fs5.join(cwd ?? ".", ".contractsrc.json");
|
|
2910
|
-
const exists = await fs5.exists(configPath);
|
|
2911
|
-
if (!exists) {
|
|
2912
|
-
return DEFAULT_CONTRACTSRC2;
|
|
2913
|
-
}
|
|
2914
|
-
try {
|
|
2915
|
-
const content = await fs5.readFile(configPath);
|
|
2916
|
-
const parsed = JSON.parse(content);
|
|
2917
|
-
const resolved = ContractsrcSchema.safeParse(parsed);
|
|
2918
|
-
return {
|
|
2919
|
-
...DEFAULT_CONTRACTSRC2,
|
|
2920
|
-
...resolved.data,
|
|
2921
|
-
conventions: {
|
|
2922
|
-
...DEFAULT_CONTRACTSRC2.conventions,
|
|
2923
|
-
...resolved.data?.conventions || {}
|
|
2924
|
-
}
|
|
2925
|
-
};
|
|
2926
|
-
} catch {
|
|
2927
|
-
return DEFAULT_CONTRACTSRC2;
|
|
2928
|
-
}
|
|
2929
|
-
}
|
|
2930
|
-
function getApiKey(provider) {
|
|
2931
|
-
switch (provider) {
|
|
2932
|
-
case "claude":
|
|
2933
|
-
return process.env["ANTHROPIC_API_KEY"];
|
|
2934
|
-
case "openai":
|
|
2935
|
-
return process.env["OPENAI_API_KEY"];
|
|
2936
|
-
case "custom":
|
|
2937
|
-
return process.env["CONTRACTSPEC_LLM_API_KEY"];
|
|
2938
|
-
case "ollama":
|
|
2939
|
-
return;
|
|
2940
|
-
default:
|
|
2941
|
-
return;
|
|
2942
|
-
}
|
|
2943
|
-
}
|
|
3117
|
+
|
|
3118
|
+
// src/services/index.ts
|
|
3119
|
+
init_config();
|
|
3120
|
+
|
|
2944
3121
|
// src/services/build.ts
|
|
2945
3122
|
import {
|
|
2946
3123
|
generateComponentTemplate,
|
|
@@ -7473,6 +7650,7 @@ async function runDoctorChecks(adapters, options) {
|
|
|
7473
7650
|
return issues;
|
|
7474
7651
|
}
|
|
7475
7652
|
// src/services/ci-check/checks/handlers.ts
|
|
7653
|
+
init_config();
|
|
7476
7654
|
async function runHandlerChecks(adapters, specFiles) {
|
|
7477
7655
|
const { fs: fs5 } = adapters;
|
|
7478
7656
|
const issues = [];
|
|
@@ -7506,6 +7684,7 @@ async function runHandlerChecks(adapters, specFiles) {
|
|
|
7506
7684
|
return issues;
|
|
7507
7685
|
}
|
|
7508
7686
|
// src/services/ci-check/checks/tests.ts
|
|
7687
|
+
init_config();
|
|
7509
7688
|
async function runTestChecks(adapters, specFiles) {
|
|
7510
7689
|
const { fs: fs5 } = adapters;
|
|
7511
7690
|
const issues = [];
|
|
@@ -7834,6 +8013,9 @@ async function runCoverageChecks(adapters, specFiles, options) {
|
|
|
7834
8013
|
}
|
|
7835
8014
|
return issues;
|
|
7836
8015
|
}
|
|
8016
|
+
// src/services/ci-check/checks/implementation.ts
|
|
8017
|
+
init_config();
|
|
8018
|
+
|
|
7837
8019
|
// src/services/implementation/resolver/index.ts
|
|
7838
8020
|
import { createHash } from "crypto";
|
|
7839
8021
|
|
|
@@ -8392,6 +8574,9 @@ async function runLayerChecks2(adapters, _options) {
|
|
|
8392
8574
|
}
|
|
8393
8575
|
return issues;
|
|
8394
8576
|
}
|
|
8577
|
+
// src/services/ci-check/checks/drift.ts
|
|
8578
|
+
init_config();
|
|
8579
|
+
|
|
8395
8580
|
// src/services/drift.ts
|
|
8396
8581
|
import path4 from "path";
|
|
8397
8582
|
import { mkdtemp, rm as rm3 } from "fs/promises";
|
|
@@ -9709,163 +9894,8 @@ function exportSpecForLLM(spec, format, agent = "generic-mcp") {
|
|
|
9709
9894
|
return specToMarkdown(spec, "full");
|
|
9710
9895
|
}
|
|
9711
9896
|
}
|
|
9712
|
-
// src/services/create/
|
|
9713
|
-
|
|
9714
|
-
import * as z2 from "zod";
|
|
9715
|
-
import {
|
|
9716
|
-
createProvider
|
|
9717
|
-
} from "@contractspec/lib.ai-providers";
|
|
9718
|
-
import {
|
|
9719
|
-
buildComponentPrompt as buildComponentPrompt2,
|
|
9720
|
-
buildEventSpecPrompt,
|
|
9721
|
-
buildFormPrompt as buildFormPrompt2,
|
|
9722
|
-
buildHandlerPrompt as buildHandlerPrompt2,
|
|
9723
|
-
buildOperationSpecPrompt,
|
|
9724
|
-
buildPresentationSpecPrompt,
|
|
9725
|
-
buildTestPrompt as buildTestPrompt2,
|
|
9726
|
-
getCodeGenSystemPrompt as getCodeGenSystemPrompt2,
|
|
9727
|
-
getSystemPrompt
|
|
9728
|
-
} from "@contractspec/module.workspace";
|
|
9729
|
-
class AIGenerator {
|
|
9730
|
-
config;
|
|
9731
|
-
constructor(config) {
|
|
9732
|
-
this.config = config;
|
|
9733
|
-
}
|
|
9734
|
-
getModel() {
|
|
9735
|
-
const providerName = this.config.aiProvider;
|
|
9736
|
-
const apiKey = this.config.customApiKey || getApiKey(this.config.aiProvider);
|
|
9737
|
-
const providerConfig = {
|
|
9738
|
-
provider: providerName === "custom" ? "openai" : providerName,
|
|
9739
|
-
model: this.config.aiModel,
|
|
9740
|
-
apiKey,
|
|
9741
|
-
baseUrl: this.config.customEndpoint || undefined
|
|
9742
|
-
};
|
|
9743
|
-
const provider = createProvider(providerConfig);
|
|
9744
|
-
return provider.getModel();
|
|
9745
|
-
}
|
|
9746
|
-
async generateOperationSpec(description, kind) {
|
|
9747
|
-
const model = this.getModel();
|
|
9748
|
-
const schema = z2.object({
|
|
9749
|
-
name: z2.string().describe('Dot notation name like "domain.operation"'),
|
|
9750
|
-
version: z2.number().int().positive().default(1),
|
|
9751
|
-
description: z2.string().describe("Clear, concise summary"),
|
|
9752
|
-
goal: z2.string().describe("Business purpose"),
|
|
9753
|
-
context: z2.string().describe("Background and constraints"),
|
|
9754
|
-
stability: z2.enum(["experimental", "beta", "stable", "deprecated"]).default("beta"),
|
|
9755
|
-
owners: z2.array(z2.string()).describe("Team/person owners with @ prefix"),
|
|
9756
|
-
tags: z2.array(z2.string()).describe("Categorization tags"),
|
|
9757
|
-
auth: z2.enum(["anonymous", "user", "admin"]).describe("Required auth level"),
|
|
9758
|
-
inputShape: z2.string().describe("Description of input structure"),
|
|
9759
|
-
outputShape: z2.string().describe("Description of output structure"),
|
|
9760
|
-
flags: z2.array(z2.string()).describe("Feature flags").default([]),
|
|
9761
|
-
possibleEvents: z2.array(z2.string()).describe("Events this may emit").default([]),
|
|
9762
|
-
analytics: z2.array(z2.string()).describe("Analytics events to track").default([])
|
|
9763
|
-
});
|
|
9764
|
-
const prompt = buildOperationSpecPrompt(description, kind);
|
|
9765
|
-
const result = await generateObject2({
|
|
9766
|
-
model,
|
|
9767
|
-
schema,
|
|
9768
|
-
prompt,
|
|
9769
|
-
system: getSystemPrompt()
|
|
9770
|
-
});
|
|
9771
|
-
return result.object;
|
|
9772
|
-
}
|
|
9773
|
-
async generateEventSpec(description) {
|
|
9774
|
-
const model = this.getModel();
|
|
9775
|
-
const schema = z2.object({
|
|
9776
|
-
name: z2.string().describe('Dot notation name like "domain.event_name"'),
|
|
9777
|
-
version: z2.number().int().positive().default(1),
|
|
9778
|
-
description: z2.string().describe("When this event is emitted"),
|
|
9779
|
-
stability: z2.enum(["experimental", "beta", "stable", "deprecated"]).default("beta"),
|
|
9780
|
-
owners: z2.array(z2.string()).default([]),
|
|
9781
|
-
tags: z2.array(z2.string()).default([]),
|
|
9782
|
-
payloadShape: z2.string().describe("Description of event payload"),
|
|
9783
|
-
piiFields: z2.array(z2.string()).describe("PII field paths").default([])
|
|
9784
|
-
});
|
|
9785
|
-
const prompt = buildEventSpecPrompt(description);
|
|
9786
|
-
const result = await generateObject2({
|
|
9787
|
-
model,
|
|
9788
|
-
schema,
|
|
9789
|
-
prompt,
|
|
9790
|
-
system: getSystemPrompt()
|
|
9791
|
-
});
|
|
9792
|
-
return result.object;
|
|
9793
|
-
}
|
|
9794
|
-
async generatePresentationSpec(description, kind) {
|
|
9795
|
-
const model = this.getModel();
|
|
9796
|
-
const schema = z2.object({
|
|
9797
|
-
name: z2.string(),
|
|
9798
|
-
version: z2.number().int().positive().default(1),
|
|
9799
|
-
description: z2.string(),
|
|
9800
|
-
stability: z2.enum(["experimental", "beta", "stable", "deprecated"]).default("beta"),
|
|
9801
|
-
owners: z2.array(z2.string()).default([]),
|
|
9802
|
-
tags: z2.array(z2.string()).default([]),
|
|
9803
|
-
componentKey: z2.string().optional(),
|
|
9804
|
-
propsShape: z2.string().optional(),
|
|
9805
|
-
content: z2.string().optional(),
|
|
9806
|
-
mimeType: z2.string().optional(),
|
|
9807
|
-
dataShape: z2.string().optional()
|
|
9808
|
-
});
|
|
9809
|
-
const prompt = buildPresentationSpecPrompt(description, kind);
|
|
9810
|
-
const result = await generateObject2({
|
|
9811
|
-
model,
|
|
9812
|
-
schema,
|
|
9813
|
-
prompt,
|
|
9814
|
-
system: getSystemPrompt()
|
|
9815
|
-
});
|
|
9816
|
-
return result.object;
|
|
9817
|
-
}
|
|
9818
|
-
async generateHandler(specCode) {
|
|
9819
|
-
const model = this.getModel();
|
|
9820
|
-
const result = await generateText6({
|
|
9821
|
-
model,
|
|
9822
|
-
prompt: buildHandlerPrompt2(specCode),
|
|
9823
|
-
system: getCodeGenSystemPrompt2()
|
|
9824
|
-
});
|
|
9825
|
-
return result.text;
|
|
9826
|
-
}
|
|
9827
|
-
async generateComponent(specCode) {
|
|
9828
|
-
const model = this.getModel();
|
|
9829
|
-
const result = await generateText6({
|
|
9830
|
-
model,
|
|
9831
|
-
prompt: buildComponentPrompt2(specCode),
|
|
9832
|
-
system: getCodeGenSystemPrompt2()
|
|
9833
|
-
});
|
|
9834
|
-
return result.text;
|
|
9835
|
-
}
|
|
9836
|
-
async generateForm(specCode) {
|
|
9837
|
-
const model = this.getModel();
|
|
9838
|
-
const result = await generateText6({
|
|
9839
|
-
model,
|
|
9840
|
-
prompt: buildFormPrompt2(specCode),
|
|
9841
|
-
system: getCodeGenSystemPrompt2()
|
|
9842
|
-
});
|
|
9843
|
-
return result.text;
|
|
9844
|
-
}
|
|
9845
|
-
async generateTests(specCode, implementationCode, testType) {
|
|
9846
|
-
const model = this.getModel();
|
|
9847
|
-
const result = await generateText6({
|
|
9848
|
-
model,
|
|
9849
|
-
prompt: buildTestPrompt2(specCode, implementationCode, testType),
|
|
9850
|
-
system: getCodeGenSystemPrompt2()
|
|
9851
|
-
});
|
|
9852
|
-
return result.text;
|
|
9853
|
-
}
|
|
9854
|
-
async streamCodeGeneration(prompt, onChunk) {
|
|
9855
|
-
const model = this.getModel();
|
|
9856
|
-
const result = await streamText2({
|
|
9857
|
-
model,
|
|
9858
|
-
prompt,
|
|
9859
|
-
system: getCodeGenSystemPrompt2()
|
|
9860
|
-
});
|
|
9861
|
-
let fullText = "";
|
|
9862
|
-
for await (const chunk of result.textStream) {
|
|
9863
|
-
fullText += chunk;
|
|
9864
|
-
onChunk(chunk);
|
|
9865
|
-
}
|
|
9866
|
-
return fullText;
|
|
9867
|
-
}
|
|
9868
|
-
}
|
|
9897
|
+
// src/services/create/index.ts
|
|
9898
|
+
init_ai_generator();
|
|
9869
9899
|
|
|
9870
9900
|
// src/services/create/templates.ts
|
|
9871
9901
|
var exports_templates2 = {};
|
|
@@ -11171,6 +11201,8 @@ ${formatRefs(params.experiments) || " // Add experiments here"}
|
|
|
11171
11201
|
`;
|
|
11172
11202
|
}
|
|
11173
11203
|
// src/services/create/index.ts
|
|
11204
|
+
init_ai_generator();
|
|
11205
|
+
|
|
11174
11206
|
class SpecCreatorService {
|
|
11175
11207
|
ai;
|
|
11176
11208
|
templates = exports_templates2;
|
|
@@ -13109,6 +13141,7 @@ import {
|
|
|
13109
13141
|
} from "@contractspec/lib.contracts-spec";
|
|
13110
13142
|
|
|
13111
13143
|
// src/services/versioning/changelog-formatter.ts
|
|
13144
|
+
import { dirname as dirname10, basename as basename5 } from "path";
|
|
13112
13145
|
function formatKeepAChangelog(entries) {
|
|
13113
13146
|
const lines = [
|
|
13114
13147
|
"# Changelog",
|
|
@@ -13231,9 +13264,55 @@ function formatChangelogJson(analysis, baseline) {
|
|
|
13231
13264
|
}
|
|
13232
13265
|
]
|
|
13233
13266
|
})),
|
|
13234
|
-
libraries:
|
|
13267
|
+
libraries: groupSpecsByLibrary(specsNeedingBump, isoDate)
|
|
13235
13268
|
};
|
|
13236
13269
|
}
|
|
13270
|
+
function extractLibraryPath(specPath) {
|
|
13271
|
+
const parts = specPath.split("/");
|
|
13272
|
+
const packagesIdx = parts.lastIndexOf("packages");
|
|
13273
|
+
if (packagesIdx >= 0 && packagesIdx + 2 < parts.length) {
|
|
13274
|
+
return parts.slice(0, packagesIdx + 3).join("/");
|
|
13275
|
+
}
|
|
13276
|
+
return dirname10(specPath);
|
|
13277
|
+
}
|
|
13278
|
+
var BUMP_RANK = { major: 3, minor: 2, patch: 1 };
|
|
13279
|
+
function groupSpecsByLibrary(specs, isoDate) {
|
|
13280
|
+
const groups = new Map;
|
|
13281
|
+
for (const spec of specs) {
|
|
13282
|
+
const libPath = extractLibraryPath(spec.specPath);
|
|
13283
|
+
const existing = groups.get(libPath);
|
|
13284
|
+
if (existing) {
|
|
13285
|
+
existing.push(spec);
|
|
13286
|
+
} else {
|
|
13287
|
+
groups.set(libPath, [spec]);
|
|
13288
|
+
}
|
|
13289
|
+
}
|
|
13290
|
+
return Array.from(groups.entries()).flatMap(([libPath, libSpecs]) => {
|
|
13291
|
+
const first = libSpecs[0];
|
|
13292
|
+
if (!first)
|
|
13293
|
+
return [];
|
|
13294
|
+
const highestBump = libSpecs.reduce((max, s) => {
|
|
13295
|
+
const rank = BUMP_RANK[s.bumpType] ?? 0;
|
|
13296
|
+
return rank > (BUMP_RANK[max.bumpType] ?? 0) ? s : max;
|
|
13297
|
+
}, first);
|
|
13298
|
+
return [
|
|
13299
|
+
{
|
|
13300
|
+
name: basename5(libPath),
|
|
13301
|
+
path: libPath,
|
|
13302
|
+
version: highestBump.suggestedVersion,
|
|
13303
|
+
entries: [
|
|
13304
|
+
{
|
|
13305
|
+
version: highestBump.suggestedVersion,
|
|
13306
|
+
date: isoDate,
|
|
13307
|
+
bumpType: highestBump.bumpType,
|
|
13308
|
+
changes: libSpecs.flatMap((s) => s.changes),
|
|
13309
|
+
breakingChanges: libSpecs.flatMap((s) => s.changes).filter((c) => c.type === "breaking")
|
|
13310
|
+
}
|
|
13311
|
+
]
|
|
13312
|
+
}
|
|
13313
|
+
];
|
|
13314
|
+
});
|
|
13315
|
+
}
|
|
13237
13316
|
function compareVersionsDescending(a, b) {
|
|
13238
13317
|
const parseVer = (v) => {
|
|
13239
13318
|
const parts = v.split(".").map((p) => parseInt(p, 10) || 0);
|
|
@@ -14838,11 +14917,50 @@ async function implementAiStrategy(issue, options, adapters2) {
|
|
|
14838
14917
|
};
|
|
14839
14918
|
}
|
|
14840
14919
|
}
|
|
14841
|
-
async function enrichWithAI(ctx,
|
|
14920
|
+
async function enrichWithAI(ctx, options, logger3) {
|
|
14842
14921
|
logger3.info("Generating AI content for spec", {
|
|
14843
14922
|
key: ctx.key,
|
|
14844
14923
|
type: ctx.specType
|
|
14845
14924
|
});
|
|
14925
|
+
if (options.aiConfig) {
|
|
14926
|
+
try {
|
|
14927
|
+
const { AIGenerator: AIGenerator2 } = await Promise.resolve().then(() => (init_ai_generator(), exports_ai_generator));
|
|
14928
|
+
const config = buildResolvedConfig(options);
|
|
14929
|
+
const generator = new AIGenerator2(config);
|
|
14930
|
+
const kind = ctx.specType === "operation" ? "command" : ctx.specType;
|
|
14931
|
+
const description = `${capitalize2(ctx.specType)} for ${ctx.key}`;
|
|
14932
|
+
if (ctx.specType === "operation") {
|
|
14933
|
+
const result = await generator.generateOperationSpec(description, kind);
|
|
14934
|
+
return {
|
|
14935
|
+
...ctx,
|
|
14936
|
+
description: result.description,
|
|
14937
|
+
enrichment: {
|
|
14938
|
+
goal: result.goal,
|
|
14939
|
+
context: result.context,
|
|
14940
|
+
owners: result.owners,
|
|
14941
|
+
tags: result.tags
|
|
14942
|
+
}
|
|
14943
|
+
};
|
|
14944
|
+
}
|
|
14945
|
+
if (ctx.specType === "event") {
|
|
14946
|
+
const result = await generator.generateEventSpec(description);
|
|
14947
|
+
return {
|
|
14948
|
+
...ctx,
|
|
14949
|
+
description: result.description,
|
|
14950
|
+
enrichment: {
|
|
14951
|
+
goal: `Emit ${ctx.key} event`,
|
|
14952
|
+
context: result.description,
|
|
14953
|
+
owners: ["@team"],
|
|
14954
|
+
tags: result.tags
|
|
14955
|
+
}
|
|
14956
|
+
};
|
|
14957
|
+
}
|
|
14958
|
+
} catch (aiError) {
|
|
14959
|
+
logger3.warn("AIGenerator call failed, falling back to heuristics", {
|
|
14960
|
+
error: aiError instanceof Error ? aiError.message : String(aiError)
|
|
14961
|
+
});
|
|
14962
|
+
}
|
|
14963
|
+
}
|
|
14846
14964
|
const enrichment = inferEnrichmentFromKey(ctx.key, ctx.specType);
|
|
14847
14965
|
return {
|
|
14848
14966
|
...ctx,
|
|
@@ -14855,6 +14973,21 @@ async function enrichWithAI(ctx, _options, logger3) {
|
|
|
14855
14973
|
}
|
|
14856
14974
|
};
|
|
14857
14975
|
}
|
|
14976
|
+
function buildResolvedConfig(options) {
|
|
14977
|
+
const ai3 = options.aiConfig;
|
|
14978
|
+
const providerMap = {
|
|
14979
|
+
claude: "anthropic",
|
|
14980
|
+
openai: "openai",
|
|
14981
|
+
ollama: "ollama",
|
|
14982
|
+
custom: "custom"
|
|
14983
|
+
};
|
|
14984
|
+
return {
|
|
14985
|
+
aiProvider: providerMap[ai3?.provider ?? "openai"] ?? "openai",
|
|
14986
|
+
aiModel: ai3?.model ?? "gpt-4-turbo",
|
|
14987
|
+
customApiKey: ai3?.apiKey ?? "",
|
|
14988
|
+
customEndpoint: ai3?.endpoint ?? ""
|
|
14989
|
+
};
|
|
14990
|
+
}
|
|
14858
14991
|
function inferEnrichmentFromKey(key, specType) {
|
|
14859
14992
|
const parts = key.split(".");
|
|
14860
14993
|
const domain = parts[0] || "unknown";
|
|
@@ -15376,6 +15509,7 @@ async function analyzeGap(adapters2, cwd) {
|
|
|
15376
15509
|
};
|
|
15377
15510
|
}
|
|
15378
15511
|
// src/services/extract.ts
|
|
15512
|
+
init_config();
|
|
15379
15513
|
async function extractContracts(adapters2, options, cwd) {
|
|
15380
15514
|
const { fs: fs5, logger: logger3 } = adapters2;
|
|
15381
15515
|
const { source, outputDir } = options;
|
|
@@ -15766,7 +15900,7 @@ async function getWorkflow(id, cwd) {
|
|
|
15766
15900
|
// src/services/vibe/context.ts
|
|
15767
15901
|
import { mkdir as mkdir4, readFile as readFile7, writeFile as writeFile3, copyFile } from "fs/promises";
|
|
15768
15902
|
import { existsSync as existsSync6 } from "fs";
|
|
15769
|
-
import { join as join11, dirname as
|
|
15903
|
+
import { join as join11, dirname as dirname11 } from "path";
|
|
15770
15904
|
import { glob } from "glob";
|
|
15771
15905
|
var DEFAULT_IGNORES2 = [
|
|
15772
15906
|
"**/node_modules/**",
|
|
@@ -15817,7 +15951,7 @@ async function exportContext(cwd) {
|
|
|
15817
15951
|
for (const file of uniqueFiles) {
|
|
15818
15952
|
const absSource = join11(root, file);
|
|
15819
15953
|
const absDest = join11(contextFilesDir, file);
|
|
15820
|
-
await mkdir4(
|
|
15954
|
+
await mkdir4(dirname11(absDest), { recursive: true });
|
|
15821
15955
|
await copyFile(absSource, absDest);
|
|
15822
15956
|
exportedFiles.push({ path: file, size: 0 });
|
|
15823
15957
|
}
|
|
@@ -15909,7 +16043,7 @@ import {
|
|
|
15909
16043
|
generateRegistry,
|
|
15910
16044
|
generateSchemas
|
|
15911
16045
|
} from "@contractspec/lib.source-extractors/codegen";
|
|
15912
|
-
import { dirname as
|
|
16046
|
+
import { dirname as dirname12, join as join13 } from "path";
|
|
15913
16047
|
async function importFromSourceService(config, options, adapters2, cwd) {
|
|
15914
16048
|
const { fs: fs5, logger: logger3 } = adapters2;
|
|
15915
16049
|
const rootPath = cwd ?? process.cwd();
|
|
@@ -15972,7 +16106,7 @@ async function importFromSourceService(config, options, adapters2, cwd) {
|
|
|
15972
16106
|
if (!options.dryRun) {
|
|
15973
16107
|
for (const file of allFiles) {
|
|
15974
16108
|
const fullPath = join13(outputDir, file.path);
|
|
15975
|
-
const dir =
|
|
16109
|
+
const dir = dirname12(fullPath);
|
|
15976
16110
|
if (!await fs5.exists(dir)) {
|
|
15977
16111
|
await fs5.mkdir(dir);
|
|
15978
16112
|
}
|
|
@@ -16697,7 +16831,7 @@ function sarifToJson(sarif) {
|
|
|
16697
16831
|
}
|
|
16698
16832
|
// src/formatters/json.ts
|
|
16699
16833
|
function formatAsJson(result, options = {}) {
|
|
16700
|
-
const { pretty = true } = options;
|
|
16834
|
+
const { pretty = true, driftResult } = options;
|
|
16701
16835
|
const checks = result.issues.map((issue) => ({
|
|
16702
16836
|
name: issue.ruleId,
|
|
16703
16837
|
status: issue.severity === "error" ? "fail" : issue.severity === "warning" ? "warn" : "pass",
|
|
@@ -16713,8 +16847,8 @@ function formatAsJson(result, options = {}) {
|
|
|
16713
16847
|
schemaVersion: "1.0",
|
|
16714
16848
|
checks,
|
|
16715
16849
|
drift: {
|
|
16716
|
-
status: "none",
|
|
16717
|
-
files: []
|
|
16850
|
+
status: driftResult?.hasDrift ? "detected" : "none",
|
|
16851
|
+
files: driftResult?.files ?? []
|
|
16718
16852
|
},
|
|
16719
16853
|
summary: {
|
|
16720
16854
|
pass: 0,
|