@contractspec/bundle.workspace 3.2.0 → 3.3.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 +337 -207
- package/dist/node/index.js +337 -207
- package/package.json +11 -11
package/dist/node/index.js
CHANGED
|
@@ -9,8 +9,218 @@ var __export = (target, all) => {
|
|
|
9
9
|
set: (newValue) => all[name] = () => newValue
|
|
10
10
|
});
|
|
11
11
|
};
|
|
12
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
12
13
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
13
14
|
|
|
15
|
+
// src/services/config.ts
|
|
16
|
+
import {
|
|
17
|
+
ContractsrcSchema,
|
|
18
|
+
DEFAULT_CONTRACTSRC as DEFAULT_CONTRACTSRC2
|
|
19
|
+
} from "@contractspec/lib.contracts-spec/workspace-config";
|
|
20
|
+
async function loadWorkspaceConfig(fs5, cwd) {
|
|
21
|
+
const configPath = fs5.join(cwd ?? ".", ".contractsrc.json");
|
|
22
|
+
const exists = await fs5.exists(configPath);
|
|
23
|
+
if (!exists) {
|
|
24
|
+
return DEFAULT_CONTRACTSRC2;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const content = await fs5.readFile(configPath);
|
|
28
|
+
const parsed = JSON.parse(content);
|
|
29
|
+
const resolved = ContractsrcSchema.safeParse(parsed);
|
|
30
|
+
return {
|
|
31
|
+
...DEFAULT_CONTRACTSRC2,
|
|
32
|
+
...resolved.data,
|
|
33
|
+
conventions: {
|
|
34
|
+
...DEFAULT_CONTRACTSRC2.conventions,
|
|
35
|
+
...resolved.data?.conventions || {}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
} catch {
|
|
39
|
+
return DEFAULT_CONTRACTSRC2;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function getApiKey(provider) {
|
|
43
|
+
switch (provider) {
|
|
44
|
+
case "claude":
|
|
45
|
+
return process.env["ANTHROPIC_API_KEY"];
|
|
46
|
+
case "openai":
|
|
47
|
+
return process.env["OPENAI_API_KEY"];
|
|
48
|
+
case "custom":
|
|
49
|
+
return process.env["CONTRACTSPEC_LLM_API_KEY"];
|
|
50
|
+
case "ollama":
|
|
51
|
+
return;
|
|
52
|
+
default:
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
var init_config = () => {};
|
|
57
|
+
|
|
58
|
+
// src/services/create/ai-generator.ts
|
|
59
|
+
var exports_ai_generator = {};
|
|
60
|
+
__export(exports_ai_generator, {
|
|
61
|
+
AIGenerator: () => AIGenerator
|
|
62
|
+
});
|
|
63
|
+
import { generateObject as generateObject2, generateText as generateText6, streamText as streamText2 } from "ai";
|
|
64
|
+
import * as z2 from "zod";
|
|
65
|
+
import {
|
|
66
|
+
createProvider
|
|
67
|
+
} from "@contractspec/lib.ai-providers";
|
|
68
|
+
import {
|
|
69
|
+
buildComponentPrompt as buildComponentPrompt2,
|
|
70
|
+
buildEventSpecPrompt,
|
|
71
|
+
buildFormPrompt as buildFormPrompt2,
|
|
72
|
+
buildHandlerPrompt as buildHandlerPrompt2,
|
|
73
|
+
buildOperationSpecPrompt,
|
|
74
|
+
buildPresentationSpecPrompt,
|
|
75
|
+
buildTestPrompt as buildTestPrompt2,
|
|
76
|
+
getCodeGenSystemPrompt as getCodeGenSystemPrompt2,
|
|
77
|
+
getSystemPrompt
|
|
78
|
+
} from "@contractspec/module.workspace";
|
|
79
|
+
|
|
80
|
+
class AIGenerator {
|
|
81
|
+
config;
|
|
82
|
+
constructor(config) {
|
|
83
|
+
this.config = config;
|
|
84
|
+
}
|
|
85
|
+
getModel() {
|
|
86
|
+
const providerName = this.config.aiProvider;
|
|
87
|
+
const apiKey = this.config.customApiKey || getApiKey(this.config.aiProvider);
|
|
88
|
+
const providerConfig = {
|
|
89
|
+
provider: providerName === "custom" ? "openai" : providerName,
|
|
90
|
+
model: this.config.aiModel,
|
|
91
|
+
apiKey,
|
|
92
|
+
baseUrl: this.config.customEndpoint || undefined
|
|
93
|
+
};
|
|
94
|
+
const provider = createProvider(providerConfig);
|
|
95
|
+
return provider.getModel();
|
|
96
|
+
}
|
|
97
|
+
async generateOperationSpec(description, kind) {
|
|
98
|
+
const model = this.getModel();
|
|
99
|
+
const schema = z2.object({
|
|
100
|
+
name: z2.string().describe('Dot notation name like "domain.operation"'),
|
|
101
|
+
version: z2.number().int().positive().default(1),
|
|
102
|
+
description: z2.string().describe("Clear, concise summary"),
|
|
103
|
+
goal: z2.string().describe("Business purpose"),
|
|
104
|
+
context: z2.string().describe("Background and constraints"),
|
|
105
|
+
stability: z2.enum(["experimental", "beta", "stable", "deprecated"]).default("beta"),
|
|
106
|
+
owners: z2.array(z2.string()).describe("Team/person owners with @ prefix"),
|
|
107
|
+
tags: z2.array(z2.string()).describe("Categorization tags"),
|
|
108
|
+
auth: z2.enum(["anonymous", "user", "admin"]).describe("Required auth level"),
|
|
109
|
+
inputShape: z2.string().describe("Description of input structure"),
|
|
110
|
+
outputShape: z2.string().describe("Description of output structure"),
|
|
111
|
+
flags: z2.array(z2.string()).describe("Feature flags").default([]),
|
|
112
|
+
possibleEvents: z2.array(z2.string()).describe("Events this may emit").default([]),
|
|
113
|
+
analytics: z2.array(z2.string()).describe("Analytics events to track").default([])
|
|
114
|
+
});
|
|
115
|
+
const prompt = buildOperationSpecPrompt(description, kind);
|
|
116
|
+
const result = await generateObject2({
|
|
117
|
+
model,
|
|
118
|
+
schema,
|
|
119
|
+
prompt,
|
|
120
|
+
system: getSystemPrompt()
|
|
121
|
+
});
|
|
122
|
+
return result.object;
|
|
123
|
+
}
|
|
124
|
+
async generateEventSpec(description) {
|
|
125
|
+
const model = this.getModel();
|
|
126
|
+
const schema = z2.object({
|
|
127
|
+
name: z2.string().describe('Dot notation name like "domain.event_name"'),
|
|
128
|
+
version: z2.number().int().positive().default(1),
|
|
129
|
+
description: z2.string().describe("When this event is emitted"),
|
|
130
|
+
stability: z2.enum(["experimental", "beta", "stable", "deprecated"]).default("beta"),
|
|
131
|
+
owners: z2.array(z2.string()).default([]),
|
|
132
|
+
tags: z2.array(z2.string()).default([]),
|
|
133
|
+
payloadShape: z2.string().describe("Description of event payload"),
|
|
134
|
+
piiFields: z2.array(z2.string()).describe("PII field paths").default([])
|
|
135
|
+
});
|
|
136
|
+
const prompt = buildEventSpecPrompt(description);
|
|
137
|
+
const result = await generateObject2({
|
|
138
|
+
model,
|
|
139
|
+
schema,
|
|
140
|
+
prompt,
|
|
141
|
+
system: getSystemPrompt()
|
|
142
|
+
});
|
|
143
|
+
return result.object;
|
|
144
|
+
}
|
|
145
|
+
async generatePresentationSpec(description, kind) {
|
|
146
|
+
const model = this.getModel();
|
|
147
|
+
const schema = z2.object({
|
|
148
|
+
name: z2.string(),
|
|
149
|
+
version: z2.number().int().positive().default(1),
|
|
150
|
+
description: z2.string(),
|
|
151
|
+
stability: z2.enum(["experimental", "beta", "stable", "deprecated"]).default("beta"),
|
|
152
|
+
owners: z2.array(z2.string()).default([]),
|
|
153
|
+
tags: z2.array(z2.string()).default([]),
|
|
154
|
+
componentKey: z2.string().optional(),
|
|
155
|
+
propsShape: z2.string().optional(),
|
|
156
|
+
content: z2.string().optional(),
|
|
157
|
+
mimeType: z2.string().optional(),
|
|
158
|
+
dataShape: z2.string().optional()
|
|
159
|
+
});
|
|
160
|
+
const prompt = buildPresentationSpecPrompt(description, kind);
|
|
161
|
+
const result = await generateObject2({
|
|
162
|
+
model,
|
|
163
|
+
schema,
|
|
164
|
+
prompt,
|
|
165
|
+
system: getSystemPrompt()
|
|
166
|
+
});
|
|
167
|
+
return result.object;
|
|
168
|
+
}
|
|
169
|
+
async generateHandler(specCode) {
|
|
170
|
+
const model = this.getModel();
|
|
171
|
+
const result = await generateText6({
|
|
172
|
+
model,
|
|
173
|
+
prompt: buildHandlerPrompt2(specCode),
|
|
174
|
+
system: getCodeGenSystemPrompt2()
|
|
175
|
+
});
|
|
176
|
+
return result.text;
|
|
177
|
+
}
|
|
178
|
+
async generateComponent(specCode) {
|
|
179
|
+
const model = this.getModel();
|
|
180
|
+
const result = await generateText6({
|
|
181
|
+
model,
|
|
182
|
+
prompt: buildComponentPrompt2(specCode),
|
|
183
|
+
system: getCodeGenSystemPrompt2()
|
|
184
|
+
});
|
|
185
|
+
return result.text;
|
|
186
|
+
}
|
|
187
|
+
async generateForm(specCode) {
|
|
188
|
+
const model = this.getModel();
|
|
189
|
+
const result = await generateText6({
|
|
190
|
+
model,
|
|
191
|
+
prompt: buildFormPrompt2(specCode),
|
|
192
|
+
system: getCodeGenSystemPrompt2()
|
|
193
|
+
});
|
|
194
|
+
return result.text;
|
|
195
|
+
}
|
|
196
|
+
async generateTests(specCode, implementationCode, testType) {
|
|
197
|
+
const model = this.getModel();
|
|
198
|
+
const result = await generateText6({
|
|
199
|
+
model,
|
|
200
|
+
prompt: buildTestPrompt2(specCode, implementationCode, testType),
|
|
201
|
+
system: getCodeGenSystemPrompt2()
|
|
202
|
+
});
|
|
203
|
+
return result.text;
|
|
204
|
+
}
|
|
205
|
+
async streamCodeGeneration(prompt, onChunk) {
|
|
206
|
+
const model = this.getModel();
|
|
207
|
+
const result = await streamText2({
|
|
208
|
+
model,
|
|
209
|
+
prompt,
|
|
210
|
+
system: getCodeGenSystemPrompt2()
|
|
211
|
+
});
|
|
212
|
+
let fullText = "";
|
|
213
|
+
for await (const chunk of result.textStream) {
|
|
214
|
+
fullText += chunk;
|
|
215
|
+
onChunk(chunk);
|
|
216
|
+
}
|
|
217
|
+
return fullText;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
var init_ai_generator = __esm(() => {
|
|
221
|
+
init_config();
|
|
222
|
+
});
|
|
223
|
+
|
|
14
224
|
// src/index.ts
|
|
15
225
|
import * as module from "@contractspec/module.workspace";
|
|
16
226
|
// src/adapters/fs.node.ts
|
|
@@ -2900,47 +3110,10 @@ function getGraphStats(graph) {
|
|
|
2900
3110
|
unused: unused.length
|
|
2901
3111
|
};
|
|
2902
3112
|
}
|
|
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
|
-
}
|
|
3113
|
+
|
|
3114
|
+
// src/services/index.ts
|
|
3115
|
+
init_config();
|
|
3116
|
+
|
|
2944
3117
|
// src/services/build.ts
|
|
2945
3118
|
import {
|
|
2946
3119
|
generateComponentTemplate,
|
|
@@ -7473,6 +7646,7 @@ async function runDoctorChecks(adapters, options) {
|
|
|
7473
7646
|
return issues;
|
|
7474
7647
|
}
|
|
7475
7648
|
// src/services/ci-check/checks/handlers.ts
|
|
7649
|
+
init_config();
|
|
7476
7650
|
async function runHandlerChecks(adapters, specFiles) {
|
|
7477
7651
|
const { fs: fs5 } = adapters;
|
|
7478
7652
|
const issues = [];
|
|
@@ -7506,6 +7680,7 @@ async function runHandlerChecks(adapters, specFiles) {
|
|
|
7506
7680
|
return issues;
|
|
7507
7681
|
}
|
|
7508
7682
|
// src/services/ci-check/checks/tests.ts
|
|
7683
|
+
init_config();
|
|
7509
7684
|
async function runTestChecks(adapters, specFiles) {
|
|
7510
7685
|
const { fs: fs5 } = adapters;
|
|
7511
7686
|
const issues = [];
|
|
@@ -7834,6 +8009,9 @@ async function runCoverageChecks(adapters, specFiles, options) {
|
|
|
7834
8009
|
}
|
|
7835
8010
|
return issues;
|
|
7836
8011
|
}
|
|
8012
|
+
// src/services/ci-check/checks/implementation.ts
|
|
8013
|
+
init_config();
|
|
8014
|
+
|
|
7837
8015
|
// src/services/implementation/resolver/index.ts
|
|
7838
8016
|
import { createHash } from "crypto";
|
|
7839
8017
|
|
|
@@ -8392,6 +8570,9 @@ async function runLayerChecks2(adapters, _options) {
|
|
|
8392
8570
|
}
|
|
8393
8571
|
return issues;
|
|
8394
8572
|
}
|
|
8573
|
+
// src/services/ci-check/checks/drift.ts
|
|
8574
|
+
init_config();
|
|
8575
|
+
|
|
8395
8576
|
// src/services/drift.ts
|
|
8396
8577
|
import path4 from "path";
|
|
8397
8578
|
import { mkdtemp, rm as rm3 } from "node:fs/promises";
|
|
@@ -9709,163 +9890,8 @@ function exportSpecForLLM(spec, format, agent = "generic-mcp") {
|
|
|
9709
9890
|
return specToMarkdown(spec, "full");
|
|
9710
9891
|
}
|
|
9711
9892
|
}
|
|
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
|
-
}
|
|
9893
|
+
// src/services/create/index.ts
|
|
9894
|
+
init_ai_generator();
|
|
9869
9895
|
|
|
9870
9896
|
// src/services/create/templates.ts
|
|
9871
9897
|
var exports_templates2 = {};
|
|
@@ -11171,6 +11197,8 @@ ${formatRefs(params.experiments) || " // Add experiments here"}
|
|
|
11171
11197
|
`;
|
|
11172
11198
|
}
|
|
11173
11199
|
// src/services/create/index.ts
|
|
11200
|
+
init_ai_generator();
|
|
11201
|
+
|
|
11174
11202
|
class SpecCreatorService {
|
|
11175
11203
|
ai;
|
|
11176
11204
|
templates = exports_templates2;
|
|
@@ -13109,6 +13137,7 @@ import {
|
|
|
13109
13137
|
} from "@contractspec/lib.contracts-spec";
|
|
13110
13138
|
|
|
13111
13139
|
// src/services/versioning/changelog-formatter.ts
|
|
13140
|
+
import { dirname as dirname10, basename as basename5 } from "node:path";
|
|
13112
13141
|
function formatKeepAChangelog(entries) {
|
|
13113
13142
|
const lines = [
|
|
13114
13143
|
"# Changelog",
|
|
@@ -13231,9 +13260,55 @@ function formatChangelogJson(analysis, baseline) {
|
|
|
13231
13260
|
}
|
|
13232
13261
|
]
|
|
13233
13262
|
})),
|
|
13234
|
-
libraries:
|
|
13263
|
+
libraries: groupSpecsByLibrary(specsNeedingBump, isoDate)
|
|
13235
13264
|
};
|
|
13236
13265
|
}
|
|
13266
|
+
function extractLibraryPath(specPath) {
|
|
13267
|
+
const parts = specPath.split("/");
|
|
13268
|
+
const packagesIdx = parts.lastIndexOf("packages");
|
|
13269
|
+
if (packagesIdx >= 0 && packagesIdx + 2 < parts.length) {
|
|
13270
|
+
return parts.slice(0, packagesIdx + 3).join("/");
|
|
13271
|
+
}
|
|
13272
|
+
return dirname10(specPath);
|
|
13273
|
+
}
|
|
13274
|
+
var BUMP_RANK = { major: 3, minor: 2, patch: 1 };
|
|
13275
|
+
function groupSpecsByLibrary(specs, isoDate) {
|
|
13276
|
+
const groups = new Map;
|
|
13277
|
+
for (const spec of specs) {
|
|
13278
|
+
const libPath = extractLibraryPath(spec.specPath);
|
|
13279
|
+
const existing = groups.get(libPath);
|
|
13280
|
+
if (existing) {
|
|
13281
|
+
existing.push(spec);
|
|
13282
|
+
} else {
|
|
13283
|
+
groups.set(libPath, [spec]);
|
|
13284
|
+
}
|
|
13285
|
+
}
|
|
13286
|
+
return Array.from(groups.entries()).flatMap(([libPath, libSpecs]) => {
|
|
13287
|
+
const first = libSpecs[0];
|
|
13288
|
+
if (!first)
|
|
13289
|
+
return [];
|
|
13290
|
+
const highestBump = libSpecs.reduce((max, s) => {
|
|
13291
|
+
const rank = BUMP_RANK[s.bumpType] ?? 0;
|
|
13292
|
+
return rank > (BUMP_RANK[max.bumpType] ?? 0) ? s : max;
|
|
13293
|
+
}, first);
|
|
13294
|
+
return [
|
|
13295
|
+
{
|
|
13296
|
+
name: basename5(libPath),
|
|
13297
|
+
path: libPath,
|
|
13298
|
+
version: highestBump.suggestedVersion,
|
|
13299
|
+
entries: [
|
|
13300
|
+
{
|
|
13301
|
+
version: highestBump.suggestedVersion,
|
|
13302
|
+
date: isoDate,
|
|
13303
|
+
bumpType: highestBump.bumpType,
|
|
13304
|
+
changes: libSpecs.flatMap((s) => s.changes),
|
|
13305
|
+
breakingChanges: libSpecs.flatMap((s) => s.changes).filter((c) => c.type === "breaking")
|
|
13306
|
+
}
|
|
13307
|
+
]
|
|
13308
|
+
}
|
|
13309
|
+
];
|
|
13310
|
+
});
|
|
13311
|
+
}
|
|
13237
13312
|
function compareVersionsDescending(a, b) {
|
|
13238
13313
|
const parseVer = (v) => {
|
|
13239
13314
|
const parts = v.split(".").map((p) => parseInt(p, 10) || 0);
|
|
@@ -14838,11 +14913,50 @@ async function implementAiStrategy(issue, options, adapters2) {
|
|
|
14838
14913
|
};
|
|
14839
14914
|
}
|
|
14840
14915
|
}
|
|
14841
|
-
async function enrichWithAI(ctx,
|
|
14916
|
+
async function enrichWithAI(ctx, options, logger3) {
|
|
14842
14917
|
logger3.info("Generating AI content for spec", {
|
|
14843
14918
|
key: ctx.key,
|
|
14844
14919
|
type: ctx.specType
|
|
14845
14920
|
});
|
|
14921
|
+
if (options.aiConfig) {
|
|
14922
|
+
try {
|
|
14923
|
+
const { AIGenerator: AIGenerator2 } = await Promise.resolve().then(() => (init_ai_generator(), exports_ai_generator));
|
|
14924
|
+
const config = buildResolvedConfig(options);
|
|
14925
|
+
const generator = new AIGenerator2(config);
|
|
14926
|
+
const kind = ctx.specType === "operation" ? "command" : ctx.specType;
|
|
14927
|
+
const description = `${capitalize2(ctx.specType)} for ${ctx.key}`;
|
|
14928
|
+
if (ctx.specType === "operation") {
|
|
14929
|
+
const result = await generator.generateOperationSpec(description, kind);
|
|
14930
|
+
return {
|
|
14931
|
+
...ctx,
|
|
14932
|
+
description: result.description,
|
|
14933
|
+
enrichment: {
|
|
14934
|
+
goal: result.goal,
|
|
14935
|
+
context: result.context,
|
|
14936
|
+
owners: result.owners,
|
|
14937
|
+
tags: result.tags
|
|
14938
|
+
}
|
|
14939
|
+
};
|
|
14940
|
+
}
|
|
14941
|
+
if (ctx.specType === "event") {
|
|
14942
|
+
const result = await generator.generateEventSpec(description);
|
|
14943
|
+
return {
|
|
14944
|
+
...ctx,
|
|
14945
|
+
description: result.description,
|
|
14946
|
+
enrichment: {
|
|
14947
|
+
goal: `Emit ${ctx.key} event`,
|
|
14948
|
+
context: result.description,
|
|
14949
|
+
owners: ["@team"],
|
|
14950
|
+
tags: result.tags
|
|
14951
|
+
}
|
|
14952
|
+
};
|
|
14953
|
+
}
|
|
14954
|
+
} catch (aiError) {
|
|
14955
|
+
logger3.warn("AIGenerator call failed, falling back to heuristics", {
|
|
14956
|
+
error: aiError instanceof Error ? aiError.message : String(aiError)
|
|
14957
|
+
});
|
|
14958
|
+
}
|
|
14959
|
+
}
|
|
14846
14960
|
const enrichment = inferEnrichmentFromKey(ctx.key, ctx.specType);
|
|
14847
14961
|
return {
|
|
14848
14962
|
...ctx,
|
|
@@ -14855,6 +14969,21 @@ async function enrichWithAI(ctx, _options, logger3) {
|
|
|
14855
14969
|
}
|
|
14856
14970
|
};
|
|
14857
14971
|
}
|
|
14972
|
+
function buildResolvedConfig(options) {
|
|
14973
|
+
const ai3 = options.aiConfig;
|
|
14974
|
+
const providerMap = {
|
|
14975
|
+
claude: "anthropic",
|
|
14976
|
+
openai: "openai",
|
|
14977
|
+
ollama: "ollama",
|
|
14978
|
+
custom: "custom"
|
|
14979
|
+
};
|
|
14980
|
+
return {
|
|
14981
|
+
aiProvider: providerMap[ai3?.provider ?? "openai"] ?? "openai",
|
|
14982
|
+
aiModel: ai3?.model ?? "gpt-4-turbo",
|
|
14983
|
+
customApiKey: ai3?.apiKey ?? "",
|
|
14984
|
+
customEndpoint: ai3?.endpoint ?? ""
|
|
14985
|
+
};
|
|
14986
|
+
}
|
|
14858
14987
|
function inferEnrichmentFromKey(key, specType) {
|
|
14859
14988
|
const parts = key.split(".");
|
|
14860
14989
|
const domain = parts[0] || "unknown";
|
|
@@ -15376,6 +15505,7 @@ async function analyzeGap(adapters2, cwd) {
|
|
|
15376
15505
|
};
|
|
15377
15506
|
}
|
|
15378
15507
|
// src/services/extract.ts
|
|
15508
|
+
init_config();
|
|
15379
15509
|
async function extractContracts(adapters2, options, cwd) {
|
|
15380
15510
|
const { fs: fs5, logger: logger3 } = adapters2;
|
|
15381
15511
|
const { source, outputDir } = options;
|
|
@@ -15766,7 +15896,7 @@ async function getWorkflow(id, cwd) {
|
|
|
15766
15896
|
// src/services/vibe/context.ts
|
|
15767
15897
|
import { mkdir as mkdir4, readFile as readFile7, writeFile as writeFile3, copyFile } from "node:fs/promises";
|
|
15768
15898
|
import { existsSync as existsSync6 } from "node:fs";
|
|
15769
|
-
import { join as join11, dirname as
|
|
15899
|
+
import { join as join11, dirname as dirname11 } from "node:path";
|
|
15770
15900
|
import { glob } from "glob";
|
|
15771
15901
|
var DEFAULT_IGNORES2 = [
|
|
15772
15902
|
"**/node_modules/**",
|
|
@@ -15817,7 +15947,7 @@ async function exportContext(cwd) {
|
|
|
15817
15947
|
for (const file of uniqueFiles) {
|
|
15818
15948
|
const absSource = join11(root, file);
|
|
15819
15949
|
const absDest = join11(contextFilesDir, file);
|
|
15820
|
-
await mkdir4(
|
|
15950
|
+
await mkdir4(dirname11(absDest), { recursive: true });
|
|
15821
15951
|
await copyFile(absSource, absDest);
|
|
15822
15952
|
exportedFiles.push({ path: file, size: 0 });
|
|
15823
15953
|
}
|
|
@@ -15909,7 +16039,7 @@ import {
|
|
|
15909
16039
|
generateRegistry,
|
|
15910
16040
|
generateSchemas
|
|
15911
16041
|
} from "@contractspec/lib.source-extractors/codegen";
|
|
15912
|
-
import { dirname as
|
|
16042
|
+
import { dirname as dirname12, join as join13 } from "path";
|
|
15913
16043
|
async function importFromSourceService(config, options, adapters2, cwd) {
|
|
15914
16044
|
const { fs: fs5, logger: logger3 } = adapters2;
|
|
15915
16045
|
const rootPath = cwd ?? process.cwd();
|
|
@@ -15972,7 +16102,7 @@ async function importFromSourceService(config, options, adapters2, cwd) {
|
|
|
15972
16102
|
if (!options.dryRun) {
|
|
15973
16103
|
for (const file of allFiles) {
|
|
15974
16104
|
const fullPath = join13(outputDir, file.path);
|
|
15975
|
-
const dir =
|
|
16105
|
+
const dir = dirname12(fullPath);
|
|
15976
16106
|
if (!await fs5.exists(dir)) {
|
|
15977
16107
|
await fs5.mkdir(dir);
|
|
15978
16108
|
}
|
|
@@ -16697,7 +16827,7 @@ function sarifToJson(sarif) {
|
|
|
16697
16827
|
}
|
|
16698
16828
|
// src/formatters/json.ts
|
|
16699
16829
|
function formatAsJson(result, options = {}) {
|
|
16700
|
-
const { pretty = true } = options;
|
|
16830
|
+
const { pretty = true, driftResult } = options;
|
|
16701
16831
|
const checks = result.issues.map((issue) => ({
|
|
16702
16832
|
name: issue.ruleId,
|
|
16703
16833
|
status: issue.severity === "error" ? "fail" : issue.severity === "warning" ? "warn" : "pass",
|
|
@@ -16713,8 +16843,8 @@ function formatAsJson(result, options = {}) {
|
|
|
16713
16843
|
schemaVersion: "1.0",
|
|
16714
16844
|
checks,
|
|
16715
16845
|
drift: {
|
|
16716
|
-
status: "none",
|
|
16717
|
-
files: []
|
|
16846
|
+
status: driftResult?.hasDrift ? "detected" : "none",
|
|
16847
|
+
files: driftResult?.files ?? []
|
|
16718
16848
|
},
|
|
16719
16849
|
summary: {
|
|
16720
16850
|
pass: 0,
|