@lssm/bundle.contractspec-workspace 0.0.0-canary-20251217060834 → 0.0.0-canary-20251217072406
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/_virtual/rolldown_runtime.js +22 -1
- package/dist/adapters/ai.js +82 -1
- package/dist/adapters/factory.js +36 -1
- package/dist/adapters/fs.js +118 -1
- package/dist/adapters/git.js +54 -1
- package/dist/adapters/index.js +7 -1
- package/dist/adapters/logger.js +80 -1
- package/dist/adapters/watcher.js +69 -1
- package/dist/adapters/workspace.js +190 -2
- package/dist/ai/agents/claude-code-agent.js +146 -9
- package/dist/ai/agents/cursor-agent.js +286 -17
- package/dist/ai/agents/index.js +5 -1
- package/dist/ai/agents/openai-codex-agent.js +140 -8
- package/dist/ai/agents/orchestrator.js +142 -1
- package/dist/ai/agents/simple-agent.js +80 -4
- package/dist/ai/client.js +162 -1
- package/dist/ai/index.js +27 -1
- package/dist/ai/prompts/code-generation.js +55 -13
- package/dist/ai/prompts/index.js +12 -1
- package/dist/ai/prompts/spec-creation.js +61 -20
- package/dist/ai/providers.js +40 -1
- package/dist/formatters/index.js +18 -1
- package/dist/formatters/json.js +71 -1
- package/dist/formatters/sarif.js +163 -1
- package/dist/formatters/text.js +208 -2
- package/dist/index.d.ts +0 -3
- package/dist/index.js +81 -1
- package/dist/libs/ai-providers/dist/factory.js +154 -0
- package/dist/libs/ai-providers/dist/index.js +4 -0
- package/dist/libs/ai-providers/dist/legacy.js +72 -0
- package/dist/libs/ai-providers/dist/models.js +287 -0
- package/dist/libs/ai-providers/dist/validation.js +1 -0
- package/dist/libs/contracts/dist/capabilities/openbanking.js +88 -0
- package/dist/libs/contracts/dist/client/index.js +5 -0
- package/dist/libs/contracts/dist/client/react/feature-render.js +2 -0
- package/dist/libs/contracts/dist/client/react/form-render.js +4 -0
- package/dist/libs/contracts/dist/client/react/index.js +4 -0
- package/dist/libs/contracts/dist/contract-registry/index.js +1 -0
- package/dist/libs/contracts/dist/contract-registry/schemas.js +60 -0
- package/dist/libs/contracts/dist/docs/PUBLISHING.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/accessibility_wcag_compliance_specs.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/index.js +29 -0
- package/dist/libs/contracts/dist/docs/presentations.js +71 -0
- package/dist/libs/contracts/dist/docs/registry.js +44 -0
- package/dist/libs/contracts/dist/docs/tech/PHASE_1_QUICKSTART.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/PHASE_3_AUTO_EVOLUTION.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/PHASE_4_PERSONALIZATION_ENGINE.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/PHASE_5_ZERO_TOUCH_OPERATIONS.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/auth/better-auth-nextjs.docblock.js +80 -0
- package/dist/libs/contracts/dist/docs/tech/contracts/openapi-export.docblock.js +57 -0
- package/dist/libs/contracts/dist/docs/tech/lifecycle-stage-system.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/llm/llm-integration.docblock.js +357 -0
- package/dist/libs/contracts/dist/docs/tech/mcp-endpoints.docblock.js +37 -0
- package/dist/libs/contracts/dist/docs/tech/presentation-runtime.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/schema/README.docblock.js +20 -0
- package/dist/libs/contracts/dist/docs/tech/studio/learning-events.docblock.js +48 -0
- package/dist/libs/contracts/dist/docs/tech/studio/learning-journeys.docblock.js +79 -0
- package/dist/libs/contracts/dist/docs/tech/studio/platform-admin-panel.docblock.js +84 -0
- package/dist/libs/contracts/dist/docs/tech/studio/project-access-teams.docblock.js +45 -0
- package/dist/libs/contracts/dist/docs/tech/studio/project-routing.docblock.js +67 -0
- package/dist/libs/contracts/dist/docs/tech/studio/sandbox-unlogged.docblock.js +40 -0
- package/dist/libs/contracts/dist/docs/tech/studio/team-invitations.docblock.js +69 -0
- package/dist/libs/contracts/dist/docs/tech/studio/workspace-ops.docblock.js +47 -0
- package/dist/libs/contracts/dist/docs/tech/studio/workspaces.docblock.js +62 -0
- package/dist/libs/contracts/dist/docs/tech/telemetry-ingest.docblock.js +155 -0
- package/dist/libs/contracts/dist/docs/tech/templates/runtime.docblock.js +20 -0
- package/dist/libs/contracts/dist/docs/tech/vscode-extension.docblock.js +101 -0
- package/dist/libs/contracts/dist/docs/tech/workflows/overview.docblock.js +20 -0
- package/dist/libs/contracts/dist/events.js +8 -0
- package/dist/libs/contracts/dist/experiments/evaluator.js +1 -0
- package/dist/libs/contracts/dist/index.js +72 -0
- package/dist/libs/contracts/dist/install.js +2 -0
- package/dist/libs/contracts/dist/integrations/contracts.js +377 -0
- package/dist/libs/contracts/dist/integrations/index.js +18 -0
- package/dist/libs/contracts/dist/integrations/openbanking/contracts/accounts.js +228 -0
- package/dist/libs/contracts/dist/integrations/openbanking/contracts/balances.js +159 -0
- package/dist/libs/contracts/dist/integrations/openbanking/contracts/index.js +3 -0
- package/dist/libs/contracts/dist/integrations/openbanking/contracts/transactions.js +210 -0
- package/dist/libs/contracts/dist/integrations/openbanking/models.js +242 -0
- package/dist/libs/contracts/dist/integrations/openbanking/telemetry.js +13 -0
- package/dist/libs/contracts/dist/integrations/providers/elevenlabs.js +52 -0
- package/dist/libs/contracts/dist/integrations/providers/gcs-storage.js +75 -0
- package/dist/libs/contracts/dist/integrations/providers/gmail.js +87 -0
- package/dist/libs/contracts/dist/integrations/providers/google-calendar.js +66 -0
- package/dist/libs/contracts/dist/integrations/providers/index.js +11 -0
- package/dist/libs/contracts/dist/integrations/providers/mistral.js +68 -0
- package/dist/libs/contracts/dist/integrations/providers/postmark.js +68 -0
- package/dist/libs/contracts/dist/integrations/providers/powens.js +116 -0
- package/dist/libs/contracts/dist/integrations/providers/qdrant.js +73 -0
- package/dist/libs/contracts/dist/integrations/providers/registry.js +10 -0
- package/dist/libs/contracts/dist/integrations/providers/stripe.js +83 -0
- package/dist/libs/contracts/dist/integrations/providers/twilio-sms.js +61 -0
- package/dist/libs/contracts/dist/jsonschema.js +24 -0
- package/dist/libs/contracts/dist/knowledge/contracts.js +306 -0
- package/dist/libs/contracts/dist/knowledge/index.js +7 -0
- package/dist/libs/contracts/dist/knowledge/spaces/email-threads.js +34 -0
- package/dist/libs/contracts/dist/knowledge/spaces/financial-docs.js +34 -0
- package/dist/libs/contracts/dist/knowledge/spaces/financial-overview.js +38 -0
- package/dist/libs/contracts/dist/knowledge/spaces/index.js +6 -0
- package/dist/libs/contracts/dist/knowledge/spaces/product-canon.js +34 -0
- package/dist/libs/contracts/dist/knowledge/spaces/support-faq.js +37 -0
- package/dist/libs/contracts/dist/knowledge/spaces/uploaded-docs.js +34 -0
- package/dist/libs/contracts/dist/llm/exporters.js +352 -0
- package/dist/libs/contracts/dist/llm/index.js +2 -0
- package/dist/libs/contracts/dist/llm/prompts.js +211 -0
- package/dist/libs/contracts/dist/onboarding-base.js +196 -0
- package/dist/libs/contracts/dist/openapi.js +75 -0
- package/dist/libs/contracts/dist/ownership.js +21 -0
- package/dist/libs/contracts/dist/presentations.js +1 -0
- package/dist/libs/contracts/dist/presentations.v2.js +11 -0
- package/dist/libs/contracts/dist/prompt.js +1 -0
- package/dist/libs/contracts/dist/promptRegistry.js +1 -0
- package/dist/libs/contracts/dist/regenerator/index.js +2 -0
- package/dist/libs/contracts/dist/regenerator/service.js +92 -0
- package/dist/libs/contracts/dist/regenerator/utils.js +51 -0
- package/dist/libs/contracts/dist/registry.js +208 -0
- package/dist/libs/contracts/dist/resources.js +1 -0
- package/dist/libs/contracts/dist/schema/dist/EnumType.js +2 -0
- package/dist/libs/contracts/dist/schema/dist/FieldType.js +49 -0
- package/dist/libs/contracts/dist/schema/dist/ScalarTypeEnum.js +236 -0
- package/dist/libs/contracts/dist/schema/dist/SchemaModel.js +34 -0
- package/dist/libs/contracts/dist/schema/dist/entity/defineEntity.js +1 -0
- package/dist/libs/contracts/dist/schema/dist/entity/index.js +2 -0
- package/dist/libs/contracts/dist/schema/dist/entity/types.js +1 -0
- package/dist/libs/contracts/dist/schema/dist/index.js +6 -0
- package/dist/libs/contracts/dist/server/graphql-pothos.js +6 -0
- package/dist/libs/contracts/dist/server/index.js +8 -0
- package/dist/libs/contracts/dist/server/mcp/createMcpServer.js +4 -0
- package/dist/libs/contracts/dist/server/mcp/registerPresentations.js +2 -0
- package/dist/libs/contracts/dist/server/mcp/registerPrompts.js +1 -0
- package/dist/libs/contracts/dist/server/mcp/registerResources.js +2 -0
- package/dist/libs/contracts/dist/server/mcp/registerTools.js +1 -0
- package/dist/libs/contracts/dist/server/provider-mcp.js +1 -0
- package/dist/libs/contracts/dist/server/rest-elysia.js +1 -0
- package/dist/libs/contracts/dist/server/rest-express.js +1 -0
- package/dist/libs/contracts/dist/server/rest-generic.js +1 -0
- package/dist/libs/contracts/dist/server/rest-next-app.js +1 -0
- package/dist/libs/contracts/dist/server/rest-next-pages.js +1 -0
- package/dist/libs/contracts/dist/spec.js +35 -0
- package/dist/libs/contracts/dist/telemetry/index.js +1 -0
- package/dist/libs/contracts/dist/telemetry/tracker.js +1 -0
- package/dist/libs/contracts/dist/tests/index.js +1 -0
- package/dist/libs/contracts/dist/tests/runner.js +150 -0
- package/dist/libs/contracts/dist/workflow/index.js +1 -0
- package/dist/libs/contracts/dist/workflow/runner.js +1 -0
- package/dist/libs/contracts-transformers/dist/common/utils.js +47 -0
- package/dist/libs/contracts-transformers/dist/openapi/exporter.js +1 -0
- package/dist/libs/contracts-transformers/dist/openapi/importer.js +255 -0
- package/dist/libs/contracts-transformers/dist/openapi/index.js +4 -0
- package/dist/libs/contracts-transformers/dist/openapi/parser.js +231 -0
- package/dist/libs/contracts-transformers/dist/openapi/schema-converter.js +201 -0
- package/dist/modules/contractspec-workspace/dist/ai/code-generation.js +137 -0
- package/dist/modules/contractspec-workspace/dist/ai/spec-creation.js +101 -0
- package/dist/modules/contractspec-workspace/dist/analysis/deps/graph.js +84 -0
- package/dist/modules/contractspec-workspace/dist/analysis/deps/parse-imports.js +30 -0
- package/dist/modules/contractspec-workspace/dist/analysis/diff/semantic.js +96 -0
- package/dist/modules/contractspec-workspace/dist/analysis/feature-scan.js +151 -0
- package/dist/modules/contractspec-workspace/dist/analysis/spec-scan.js +344 -0
- package/dist/modules/contractspec-workspace/dist/analysis/validate/spec-structure.js +122 -0
- package/dist/modules/contractspec-workspace/dist/templates/app-config.js +105 -0
- package/dist/modules/contractspec-workspace/dist/templates/data-view.js +68 -0
- package/dist/modules/contractspec-workspace/dist/templates/event.js +38 -0
- package/dist/modules/contractspec-workspace/dist/templates/experiment.js +87 -0
- package/dist/modules/contractspec-workspace/dist/templates/handler.js +95 -0
- package/dist/modules/contractspec-workspace/dist/templates/integration-utils.js +104 -0
- package/dist/modules/contractspec-workspace/dist/templates/integration.js +62 -0
- package/dist/modules/contractspec-workspace/dist/templates/knowledge.js +68 -0
- package/dist/modules/contractspec-workspace/dist/templates/migration.js +60 -0
- package/dist/modules/contractspec-workspace/dist/templates/operation.js +100 -0
- package/dist/modules/contractspec-workspace/dist/templates/presentation.js +78 -0
- package/dist/modules/contractspec-workspace/dist/templates/telemetry.js +89 -0
- package/dist/modules/contractspec-workspace/dist/templates/utils.js +38 -0
- package/dist/modules/contractspec-workspace/dist/templates/workflow-runner.js +48 -0
- package/dist/modules/contractspec-workspace/dist/templates/workflow.js +67 -0
- package/dist/modules/contractspec-workspace/dist/types/generation-types.js +20 -0
- package/dist/services/agent-guide/adapters/claude-code.js +144 -3
- package/dist/services/agent-guide/adapters/cursor-cli.js +135 -3
- package/dist/services/agent-guide/adapters/generic-mcp.js +159 -3
- package/dist/services/agent-guide/adapters/index.js +30 -1
- package/dist/services/agent-guide/agent-guide-service.js +148 -1
- package/dist/services/agent-guide/index.js +5 -1
- package/dist/services/build.js +140 -1
- package/dist/services/ci-check/ci-check-service.js +393 -1
- package/dist/services/ci-check/index.js +2 -1
- package/dist/services/ci-check/types.js +28 -1
- package/dist/services/clean.js +71 -1
- package/dist/services/config.js +76 -1
- package/dist/services/deps.js +62 -1
- package/dist/services/diff.js +33 -1
- package/dist/services/doctor/checks/ai.js +118 -2
- package/dist/services/doctor/checks/cli.js +146 -1
- package/dist/services/doctor/checks/config.js +170 -1
- package/dist/services/doctor/checks/deps.js +180 -1
- package/dist/services/doctor/checks/index.js +6 -1
- package/dist/services/doctor/checks/mcp.js +144 -1
- package/dist/services/doctor/checks/workspace.js +243 -1
- package/dist/services/doctor/doctor-service.js +115 -2
- package/dist/services/doctor/index.js +2 -1
- package/dist/services/doctor/types.js +26 -1
- package/dist/services/implementation/discovery.js +143 -2
- package/dist/services/implementation/index.js +2 -1
- package/dist/services/implementation/resolver.js +223 -1
- package/dist/services/index.js +53 -1
- package/dist/services/integrity-diagram.js +274 -6
- package/dist/services/integrity.js +272 -1
- package/dist/services/list.js +35 -1
- package/dist/services/openapi/export-service.js +51 -2
- package/dist/services/openapi/import-service.js +75 -1
- package/dist/services/openapi/index.js +4 -1
- package/dist/services/openapi/sync-service.js +121 -1
- package/dist/services/openapi/validate-service.js +130 -1
- package/dist/services/regenerator.js +23 -1
- package/dist/services/registry.js +73 -1
- package/dist/services/setup/config-generators.js +113 -26
- package/dist/services/setup/file-merger.js +60 -2
- package/dist/services/setup/index.js +4 -1
- package/dist/services/setup/setup-service.js +95 -1
- package/dist/services/setup/targets/agents-md.js +46 -1
- package/dist/services/setup/targets/cli-config.js +59 -1
- package/dist/services/setup/targets/cursor-rules.js +47 -1
- package/dist/services/setup/targets/mcp-claude.js +59 -1
- package/dist/services/setup/targets/mcp-cursor.js +58 -1
- package/dist/services/setup/targets/vscode-settings.js +62 -1
- package/dist/services/setup/types.js +26 -1
- package/dist/services/sync.js +62 -1
- package/dist/services/test.js +30 -1
- package/dist/services/validate-implementation.js +69 -1
- package/dist/services/validate.js +47 -1
- package/dist/services/verification-cache/adapters/filesystem.js +121 -1
- package/dist/services/verification-cache/adapters/in-memory.js +45 -1
- package/dist/services/verification-cache/adapters/index.js +3 -1
- package/dist/services/verification-cache/adapters/workspace-state.js +90 -1
- package/dist/services/verification-cache/cache-service.js +255 -1
- package/dist/services/verification-cache/index.js +6 -1
- package/dist/services/verification-cache/types.js +15 -1
- package/dist/services/verify/ai-verifier.js +336 -9
- package/dist/services/verify/behavior-verifier.js +185 -1
- package/dist/services/verify/index.js +4 -1
- package/dist/services/verify/structure-verifier.js +195 -2
- package/dist/services/verify/verify-service.js +203 -3
- package/dist/services/watch.js +31 -1
- package/dist/services/workspace-info.js +102 -2
- package/dist/templates/app-config.template.js +101 -28
- package/dist/templates/data-view.template.js +42 -27
- package/dist/templates/event.template.js +29 -14
- package/dist/templates/experiment.template.js +77 -51
- package/dist/templates/handler.template.js +53 -17
- package/dist/templates/index.js +36 -1
- package/dist/templates/integration.template.js +134 -50
- package/dist/templates/knowledge.template.js +62 -21
- package/dist/templates/migration.template.js +50 -26
- package/dist/templates/operation.template.js +44 -28
- package/dist/templates/presentation.template.js +46 -20
- package/dist/templates/telemetry.template.js +74 -53
- package/dist/templates/workflow-runner.template.js +12 -6
- package/dist/templates/workflow.template.js +51 -24
- package/package.json +13 -9
- package/dist/adapters/index.d.ts +0 -7
- package/dist/ports/index.d.ts +0 -5
- package/dist/services/agent-guide/index.d.ts +0 -6
- package/dist/services/ci-check/index.d.ts +0 -2
- package/dist/services/doctor/index.d.ts +0 -2
- package/dist/services/implementation/index.d.ts +0 -3
- package/dist/services/index.d.ts +0 -56
- package/dist/services/openapi/index.d.ts +0 -5
- package/dist/services/verification-cache/adapters/index.d.ts +0 -3
- package/dist/services/verification-cache/index.d.ts +0 -6
- package/dist/services/verify/index.d.ts +0 -5
|
@@ -1,2 +1,60 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/services/setup/file-merger.ts
|
|
2
|
+
/**
|
|
3
|
+
* File merger utilities.
|
|
4
|
+
*
|
|
5
|
+
* Deep-merges JSON files without losing user settings.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Deep merge two objects, preserving existing user values.
|
|
9
|
+
* New keys are added, but existing keys are NOT overwritten.
|
|
10
|
+
*/
|
|
11
|
+
function deepMergePreserve(existing, defaults) {
|
|
12
|
+
const result = { ...existing };
|
|
13
|
+
for (const key of Object.keys(defaults)) {
|
|
14
|
+
const existingValue = existing[key];
|
|
15
|
+
const defaultValue = defaults[key];
|
|
16
|
+
if (existingValue === void 0) result[key] = defaultValue;
|
|
17
|
+
else if (isPlainObject(existingValue) && isPlainObject(defaultValue)) result[key] = deepMergePreserve(existingValue, defaultValue);
|
|
18
|
+
}
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Deep merge two objects, with new values taking precedence.
|
|
23
|
+
* Used when we want to update existing configs.
|
|
24
|
+
*/
|
|
25
|
+
function deepMergeOverwrite(existing, updates) {
|
|
26
|
+
const result = { ...existing };
|
|
27
|
+
for (const key of Object.keys(updates)) {
|
|
28
|
+
const existingValue = existing[key];
|
|
29
|
+
const updateValue = updates[key];
|
|
30
|
+
if (updateValue === void 0) continue;
|
|
31
|
+
if (isPlainObject(existingValue) && isPlainObject(updateValue)) result[key] = deepMergeOverwrite(existingValue, updateValue);
|
|
32
|
+
else result[key] = updateValue;
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check if a value is a plain object (not array, null, or other).
|
|
38
|
+
*/
|
|
39
|
+
function isPlainObject(value) {
|
|
40
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Parse JSON safely, returning null on failure.
|
|
44
|
+
*/
|
|
45
|
+
function safeParseJson(content) {
|
|
46
|
+
try {
|
|
47
|
+
return JSON.parse(content);
|
|
48
|
+
} catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Format JSON with consistent indentation.
|
|
54
|
+
*/
|
|
55
|
+
function formatJson(obj) {
|
|
56
|
+
return JSON.stringify(obj, null, 2) + "\n";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
export { deepMergeOverwrite, deepMergePreserve, formatJson, safeParseJson };
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ALL_SETUP_TARGETS, SETUP_TARGET_LABELS } from "./types.js";
|
|
2
|
+
import { generateAgentsMd, generateClaudeMcpConfig, generateContractsrcConfig, generateCursorMcpConfig, generateCursorRules, generateVscodeSettings, getClaudeDesktopConfigPath } from "./config-generators.js";
|
|
3
|
+
import { deepMergeOverwrite, deepMergePreserve, formatJson, safeParseJson } from "./file-merger.js";
|
|
4
|
+
import { runSetup } from "./setup-service.js";
|
|
@@ -1 +1,95 @@
|
|
|
1
|
-
import{findPackageRoot
|
|
1
|
+
import { findPackageRoot, findWorkspaceRoot, getPackageName, isMonorepo } from "../../adapters/workspace.js";
|
|
2
|
+
import { ALL_SETUP_TARGETS, SETUP_TARGET_LABELS } from "./types.js";
|
|
3
|
+
import { setupCliConfig } from "./targets/cli-config.js";
|
|
4
|
+
import { setupVscodeSettings } from "./targets/vscode-settings.js";
|
|
5
|
+
import { setupMcpCursor } from "./targets/mcp-cursor.js";
|
|
6
|
+
import { setupMcpClaude } from "./targets/mcp-claude.js";
|
|
7
|
+
import { setupCursorRules } from "./targets/cursor-rules.js";
|
|
8
|
+
import { setupAgentsMd } from "./targets/agents-md.js";
|
|
9
|
+
|
|
10
|
+
//#region src/services/setup/setup-service.ts
|
|
11
|
+
/**
|
|
12
|
+
* Default prompt callbacks that always accept defaults.
|
|
13
|
+
*/
|
|
14
|
+
const defaultPrompts = {
|
|
15
|
+
confirm: async () => true,
|
|
16
|
+
multiSelect: async (_msg, options) => options.filter((o) => o.selected !== false).map((o) => o.value),
|
|
17
|
+
input: async (_msg, defaultValue) => defaultValue ?? ""
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Run the ContractSpec setup.
|
|
21
|
+
*/
|
|
22
|
+
async function runSetup(fs, options, prompts = defaultPrompts) {
|
|
23
|
+
const results = [];
|
|
24
|
+
const targets = options.targets.length > 0 ? options.targets : ALL_SETUP_TARGETS;
|
|
25
|
+
const workspaceRoot = options.workspaceRoot;
|
|
26
|
+
const detectedWorkspaceRoot = findWorkspaceRoot(workspaceRoot);
|
|
27
|
+
const packageRoot = options.packageRoot ?? findPackageRoot(workspaceRoot);
|
|
28
|
+
const monorepo = options.isMonorepo ?? isMonorepo(detectedWorkspaceRoot);
|
|
29
|
+
const packageName = options.packageName ?? (monorepo ? getPackageName(packageRoot) : void 0);
|
|
30
|
+
let scope = options.scope ?? "workspace";
|
|
31
|
+
const isDifferentRoots = packageRoot !== detectedWorkspaceRoot;
|
|
32
|
+
if (monorepo && options.interactive && isDifferentRoots) scope = (await prompts.multiSelect(`Monorepo detected. Configure at which level?`, [{
|
|
33
|
+
value: "package",
|
|
34
|
+
label: `Package level (${packageName ?? packageRoot})`,
|
|
35
|
+
selected: true
|
|
36
|
+
}, {
|
|
37
|
+
value: "workspace",
|
|
38
|
+
label: `Workspace level (${detectedWorkspaceRoot})`
|
|
39
|
+
}]))[0] ?? "package";
|
|
40
|
+
let selectedTargets = targets;
|
|
41
|
+
if (options.interactive) selectedTargets = await prompts.multiSelect("Select components to configure:", ALL_SETUP_TARGETS.map((t) => ({
|
|
42
|
+
value: t,
|
|
43
|
+
label: SETUP_TARGET_LABELS[t],
|
|
44
|
+
selected: targets.includes(t)
|
|
45
|
+
})));
|
|
46
|
+
let projectName = options.projectName;
|
|
47
|
+
if (options.interactive && !projectName) {
|
|
48
|
+
const defaultName = scope === "package" && packageName ? packageName : workspaceRoot.split("/").pop() ?? "my-project";
|
|
49
|
+
projectName = await prompts.input("Project name:", defaultName);
|
|
50
|
+
}
|
|
51
|
+
const setupOptions = {
|
|
52
|
+
...options,
|
|
53
|
+
workspaceRoot: detectedWorkspaceRoot,
|
|
54
|
+
packageRoot,
|
|
55
|
+
isMonorepo: monorepo,
|
|
56
|
+
scope,
|
|
57
|
+
packageName,
|
|
58
|
+
projectName,
|
|
59
|
+
targets: selectedTargets
|
|
60
|
+
};
|
|
61
|
+
for (const target of selectedTargets) {
|
|
62
|
+
const result = await setupTarget(fs, target, setupOptions, prompts);
|
|
63
|
+
results.push(result);
|
|
64
|
+
}
|
|
65
|
+
const succeeded = results.filter((r) => r.action !== "error").length;
|
|
66
|
+
const failed = results.filter((r) => r.action === "error").length;
|
|
67
|
+
const scopeInfo = monorepo ? ` (${scope} level)` : "";
|
|
68
|
+
return {
|
|
69
|
+
success: failed === 0,
|
|
70
|
+
files: results,
|
|
71
|
+
summary: `Setup complete${scopeInfo}: ${succeeded} configured, ${failed} failed.`
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Setup a single target.
|
|
76
|
+
*/
|
|
77
|
+
async function setupTarget(fs, target, options, prompts) {
|
|
78
|
+
switch (target) {
|
|
79
|
+
case "cli-config": return setupCliConfig(fs, options, prompts);
|
|
80
|
+
case "vscode-settings": return setupVscodeSettings(fs, options, prompts);
|
|
81
|
+
case "mcp-cursor": return setupMcpCursor(fs, options, prompts);
|
|
82
|
+
case "mcp-claude": return setupMcpClaude(fs, options, prompts);
|
|
83
|
+
case "cursor-rules": return setupCursorRules(fs, options, prompts);
|
|
84
|
+
case "agents-md": return setupAgentsMd(fs, options, prompts);
|
|
85
|
+
default: return {
|
|
86
|
+
target,
|
|
87
|
+
filePath: "",
|
|
88
|
+
action: "error",
|
|
89
|
+
message: `Unknown target: ${target}`
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
//#endregion
|
|
95
|
+
export { runSetup };
|
|
@@ -1 +1,46 @@
|
|
|
1
|
-
import{generateAgentsMd
|
|
1
|
+
import { generateAgentsMd } from "../config-generators.js";
|
|
2
|
+
|
|
3
|
+
//#region src/services/setup/targets/agents-md.ts
|
|
4
|
+
/**
|
|
5
|
+
* Setup AGENTS.md
|
|
6
|
+
*
|
|
7
|
+
* In monorepo with package scope, creates AGENTS.md at package root.
|
|
8
|
+
*/
|
|
9
|
+
async function setupAgentsMd(fs, options, prompts) {
|
|
10
|
+
const targetRoot = options.isMonorepo && options.scope === "package" ? options.packageRoot ?? options.workspaceRoot : options.workspaceRoot;
|
|
11
|
+
const filePath = fs.join(targetRoot, "AGENTS.md");
|
|
12
|
+
try {
|
|
13
|
+
const exists = await fs.exists(filePath);
|
|
14
|
+
const content = generateAgentsMd(options);
|
|
15
|
+
if (exists) if (options.interactive) {
|
|
16
|
+
if (!await prompts.confirm(`${filePath} exists. Overwrite?`)) return {
|
|
17
|
+
target: "agents-md",
|
|
18
|
+
filePath,
|
|
19
|
+
action: "skipped",
|
|
20
|
+
message: "User kept existing AGENTS.md"
|
|
21
|
+
};
|
|
22
|
+
} else return {
|
|
23
|
+
target: "agents-md",
|
|
24
|
+
filePath,
|
|
25
|
+
action: "skipped",
|
|
26
|
+
message: "File already exists"
|
|
27
|
+
};
|
|
28
|
+
await fs.writeFile(filePath, content);
|
|
29
|
+
return {
|
|
30
|
+
target: "agents-md",
|
|
31
|
+
filePath,
|
|
32
|
+
action: exists ? "merged" : "created",
|
|
33
|
+
message: exists ? "Updated AGENTS.md" : "Created AGENTS.md"
|
|
34
|
+
};
|
|
35
|
+
} catch (error) {
|
|
36
|
+
return {
|
|
37
|
+
target: "agents-md",
|
|
38
|
+
filePath,
|
|
39
|
+
action: "error",
|
|
40
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//#endregion
|
|
46
|
+
export { setupAgentsMd };
|
|
@@ -1 +1,59 @@
|
|
|
1
|
-
import{generateContractsrcConfig
|
|
1
|
+
import { generateContractsrcConfig } from "../config-generators.js";
|
|
2
|
+
import { deepMergePreserve, formatJson, safeParseJson } from "../file-merger.js";
|
|
3
|
+
|
|
4
|
+
//#region src/services/setup/targets/cli-config.ts
|
|
5
|
+
/**
|
|
6
|
+
* Setup .contractsrc.json
|
|
7
|
+
*
|
|
8
|
+
* In monorepo with package scope, creates config at package root.
|
|
9
|
+
*/
|
|
10
|
+
async function setupCliConfig(fs, options, prompts) {
|
|
11
|
+
const targetRoot = options.isMonorepo && options.scope === "package" ? options.packageRoot ?? options.workspaceRoot : options.workspaceRoot;
|
|
12
|
+
const filePath = fs.join(targetRoot, ".contractsrc.json");
|
|
13
|
+
try {
|
|
14
|
+
const exists = await fs.exists(filePath);
|
|
15
|
+
const defaults = generateContractsrcConfig(options);
|
|
16
|
+
if (exists) {
|
|
17
|
+
const existing = safeParseJson(await fs.readFile(filePath));
|
|
18
|
+
if (!existing) return {
|
|
19
|
+
target: "cli-config",
|
|
20
|
+
filePath,
|
|
21
|
+
action: "error",
|
|
22
|
+
message: "Existing file is not valid JSON"
|
|
23
|
+
};
|
|
24
|
+
if (options.interactive) {
|
|
25
|
+
if (!await prompts.confirm(`${filePath} exists. Merge ContractSpec defaults?`)) return {
|
|
26
|
+
target: "cli-config",
|
|
27
|
+
filePath,
|
|
28
|
+
action: "skipped",
|
|
29
|
+
message: "User skipped merge"
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const merged = deepMergePreserve(existing, defaults);
|
|
33
|
+
await fs.writeFile(filePath, formatJson(merged));
|
|
34
|
+
return {
|
|
35
|
+
target: "cli-config",
|
|
36
|
+
filePath,
|
|
37
|
+
action: "merged",
|
|
38
|
+
message: "Merged with existing configuration"
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
await fs.writeFile(filePath, formatJson(defaults));
|
|
42
|
+
return {
|
|
43
|
+
target: "cli-config",
|
|
44
|
+
filePath,
|
|
45
|
+
action: "created",
|
|
46
|
+
message: "Created CLI configuration"
|
|
47
|
+
};
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return {
|
|
50
|
+
target: "cli-config",
|
|
51
|
+
filePath,
|
|
52
|
+
action: "error",
|
|
53
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
export { setupCliConfig };
|
|
@@ -1 +1,47 @@
|
|
|
1
|
-
import{generateCursorRules
|
|
1
|
+
import { generateCursorRules } from "../config-generators.js";
|
|
2
|
+
|
|
3
|
+
//#region src/services/setup/targets/cursor-rules.ts
|
|
4
|
+
/**
|
|
5
|
+
* Setup .cursor/rules/contractspec.mdc
|
|
6
|
+
*/
|
|
7
|
+
async function setupCursorRules(fs, options, prompts) {
|
|
8
|
+
const rulesDir = fs.join(options.workspaceRoot, ".cursor", "rules");
|
|
9
|
+
const filePath = fs.join(rulesDir, "contractspec.mdc");
|
|
10
|
+
try {
|
|
11
|
+
const cursorDir = fs.join(options.workspaceRoot, ".cursor");
|
|
12
|
+
if (!await fs.exists(cursorDir)) await fs.mkdir(cursorDir);
|
|
13
|
+
if (!await fs.exists(rulesDir)) await fs.mkdir(rulesDir);
|
|
14
|
+
const exists = await fs.exists(filePath);
|
|
15
|
+
const content = generateCursorRules(options);
|
|
16
|
+
if (exists) if (options.interactive) {
|
|
17
|
+
if (!await prompts.confirm(`${filePath} exists. Overwrite with latest rules?`)) return {
|
|
18
|
+
target: "cursor-rules",
|
|
19
|
+
filePath,
|
|
20
|
+
action: "skipped",
|
|
21
|
+
message: "User kept existing rules"
|
|
22
|
+
};
|
|
23
|
+
} else return {
|
|
24
|
+
target: "cursor-rules",
|
|
25
|
+
filePath,
|
|
26
|
+
action: "skipped",
|
|
27
|
+
message: "File already exists"
|
|
28
|
+
};
|
|
29
|
+
await fs.writeFile(filePath, content);
|
|
30
|
+
return {
|
|
31
|
+
target: "cursor-rules",
|
|
32
|
+
filePath,
|
|
33
|
+
action: exists ? "merged" : "created",
|
|
34
|
+
message: exists ? "Updated Cursor rules" : "Created Cursor rules"
|
|
35
|
+
};
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return {
|
|
38
|
+
target: "cursor-rules",
|
|
39
|
+
filePath,
|
|
40
|
+
action: "error",
|
|
41
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//#endregion
|
|
47
|
+
export { setupCursorRules };
|
|
@@ -1 +1,59 @@
|
|
|
1
|
-
import{generateClaudeMcpConfig
|
|
1
|
+
import { generateClaudeMcpConfig, getClaudeDesktopConfigPath } from "../config-generators.js";
|
|
2
|
+
import { deepMergePreserve, formatJson, safeParseJson } from "../file-merger.js";
|
|
3
|
+
|
|
4
|
+
//#region src/services/setup/targets/mcp-claude.ts
|
|
5
|
+
/**
|
|
6
|
+
* Setup Claude Desktop MCP config.
|
|
7
|
+
* This modifies the user's global Claude config, so we're extra careful.
|
|
8
|
+
*/
|
|
9
|
+
async function setupMcpClaude(fs, options, prompts) {
|
|
10
|
+
const filePath = getClaudeDesktopConfigPath();
|
|
11
|
+
try {
|
|
12
|
+
const exists = await fs.exists(filePath);
|
|
13
|
+
const defaults = generateClaudeMcpConfig();
|
|
14
|
+
if (options.interactive) {
|
|
15
|
+
if (!await prompts.confirm(`Configure Claude Desktop at ${filePath}?`)) return {
|
|
16
|
+
target: "mcp-claude",
|
|
17
|
+
filePath,
|
|
18
|
+
action: "skipped",
|
|
19
|
+
message: "User skipped Claude Desktop configuration"
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if (exists) {
|
|
23
|
+
const existing = safeParseJson(await fs.readFile(filePath));
|
|
24
|
+
if (!existing) return {
|
|
25
|
+
target: "mcp-claude",
|
|
26
|
+
filePath,
|
|
27
|
+
action: "error",
|
|
28
|
+
message: "Existing file is not valid JSON"
|
|
29
|
+
};
|
|
30
|
+
const merged = deepMergePreserve(existing, defaults);
|
|
31
|
+
await fs.writeFile(filePath, formatJson(merged));
|
|
32
|
+
return {
|
|
33
|
+
target: "mcp-claude",
|
|
34
|
+
filePath,
|
|
35
|
+
action: "merged",
|
|
36
|
+
message: "Added ContractSpec to Claude Desktop"
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const parentDir = filePath.substring(0, filePath.lastIndexOf("/"));
|
|
40
|
+
if (!await fs.exists(parentDir)) await fs.mkdir(parentDir);
|
|
41
|
+
await fs.writeFile(filePath, formatJson(defaults));
|
|
42
|
+
return {
|
|
43
|
+
target: "mcp-claude",
|
|
44
|
+
filePath,
|
|
45
|
+
action: "created",
|
|
46
|
+
message: "Created Claude Desktop configuration"
|
|
47
|
+
};
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return {
|
|
50
|
+
target: "mcp-claude",
|
|
51
|
+
filePath,
|
|
52
|
+
action: "error",
|
|
53
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
export { setupMcpClaude };
|
|
@@ -1 +1,58 @@
|
|
|
1
|
-
import{generateCursorMcpConfig
|
|
1
|
+
import { generateCursorMcpConfig } from "../config-generators.js";
|
|
2
|
+
import { deepMergePreserve, formatJson, safeParseJson } from "../file-merger.js";
|
|
3
|
+
|
|
4
|
+
//#region src/services/setup/targets/mcp-cursor.ts
|
|
5
|
+
/**
|
|
6
|
+
* Setup .cursor/mcp.json
|
|
7
|
+
*/
|
|
8
|
+
async function setupMcpCursor(fs, options, prompts) {
|
|
9
|
+
const dirPath = fs.join(options.workspaceRoot, ".cursor");
|
|
10
|
+
const filePath = fs.join(dirPath, "mcp.json");
|
|
11
|
+
try {
|
|
12
|
+
if (!await fs.exists(dirPath)) await fs.mkdir(dirPath);
|
|
13
|
+
const exists = await fs.exists(filePath);
|
|
14
|
+
const defaults = generateCursorMcpConfig();
|
|
15
|
+
if (exists) {
|
|
16
|
+
const existing = safeParseJson(await fs.readFile(filePath));
|
|
17
|
+
if (!existing) return {
|
|
18
|
+
target: "mcp-cursor",
|
|
19
|
+
filePath,
|
|
20
|
+
action: "error",
|
|
21
|
+
message: "Existing file is not valid JSON"
|
|
22
|
+
};
|
|
23
|
+
if (options.interactive) {
|
|
24
|
+
if (!await prompts.confirm(`${filePath} exists. Add ContractSpec MCP server?`)) return {
|
|
25
|
+
target: "mcp-cursor",
|
|
26
|
+
filePath,
|
|
27
|
+
action: "skipped",
|
|
28
|
+
message: "User skipped merge"
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const merged = deepMergePreserve(existing, defaults);
|
|
32
|
+
await fs.writeFile(filePath, formatJson(merged));
|
|
33
|
+
return {
|
|
34
|
+
target: "mcp-cursor",
|
|
35
|
+
filePath,
|
|
36
|
+
action: "merged",
|
|
37
|
+
message: "Added ContractSpec MCP server"
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
await fs.writeFile(filePath, formatJson(defaults));
|
|
41
|
+
return {
|
|
42
|
+
target: "mcp-cursor",
|
|
43
|
+
filePath,
|
|
44
|
+
action: "created",
|
|
45
|
+
message: "Created Cursor MCP configuration"
|
|
46
|
+
};
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return {
|
|
49
|
+
target: "mcp-cursor",
|
|
50
|
+
filePath,
|
|
51
|
+
action: "error",
|
|
52
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
58
|
+
export { setupMcpCursor };
|
|
@@ -1 +1,62 @@
|
|
|
1
|
-
import{generateVscodeSettings
|
|
1
|
+
import { generateVscodeSettings } from "../config-generators.js";
|
|
2
|
+
import { deepMergePreserve, formatJson, safeParseJson } from "../file-merger.js";
|
|
3
|
+
|
|
4
|
+
//#region src/services/setup/targets/vscode-settings.ts
|
|
5
|
+
/**
|
|
6
|
+
* Setup .vscode/settings.json
|
|
7
|
+
*
|
|
8
|
+
* VS Code settings are typically at workspace root, but in monorepo
|
|
9
|
+
* with package scope, can be at package root.
|
|
10
|
+
*/
|
|
11
|
+
async function setupVscodeSettings(fs, options, prompts) {
|
|
12
|
+
const targetRoot = options.isMonorepo && options.scope === "package" ? options.packageRoot ?? options.workspaceRoot : options.workspaceRoot;
|
|
13
|
+
const dirPath = fs.join(targetRoot, ".vscode");
|
|
14
|
+
const filePath = fs.join(dirPath, "settings.json");
|
|
15
|
+
try {
|
|
16
|
+
if (!await fs.exists(dirPath)) await fs.mkdir(dirPath);
|
|
17
|
+
const exists = await fs.exists(filePath);
|
|
18
|
+
const defaults = generateVscodeSettings();
|
|
19
|
+
if (exists) {
|
|
20
|
+
const existing = safeParseJson(await fs.readFile(filePath));
|
|
21
|
+
if (!existing) return {
|
|
22
|
+
target: "vscode-settings",
|
|
23
|
+
filePath,
|
|
24
|
+
action: "error",
|
|
25
|
+
message: "Existing file is not valid JSON"
|
|
26
|
+
};
|
|
27
|
+
if (options.interactive) {
|
|
28
|
+
if (!await prompts.confirm(`${filePath} exists. Add ContractSpec settings?`)) return {
|
|
29
|
+
target: "vscode-settings",
|
|
30
|
+
filePath,
|
|
31
|
+
action: "skipped",
|
|
32
|
+
message: "User skipped merge"
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const merged = deepMergePreserve(existing, defaults);
|
|
36
|
+
await fs.writeFile(filePath, formatJson(merged));
|
|
37
|
+
return {
|
|
38
|
+
target: "vscode-settings",
|
|
39
|
+
filePath,
|
|
40
|
+
action: "merged",
|
|
41
|
+
message: "Added ContractSpec settings"
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
await fs.writeFile(filePath, formatJson(defaults));
|
|
45
|
+
return {
|
|
46
|
+
target: "vscode-settings",
|
|
47
|
+
filePath,
|
|
48
|
+
action: "created",
|
|
49
|
+
message: "Created VS Code settings"
|
|
50
|
+
};
|
|
51
|
+
} catch (error) {
|
|
52
|
+
return {
|
|
53
|
+
target: "vscode-settings",
|
|
54
|
+
filePath,
|
|
55
|
+
action: "error",
|
|
56
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//#endregion
|
|
62
|
+
export { setupVscodeSettings };
|
|
@@ -1 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/services/setup/types.ts
|
|
2
|
+
/**
|
|
3
|
+
* All available setup targets.
|
|
4
|
+
*/
|
|
5
|
+
const ALL_SETUP_TARGETS = [
|
|
6
|
+
"cli-config",
|
|
7
|
+
"vscode-settings",
|
|
8
|
+
"mcp-cursor",
|
|
9
|
+
"mcp-claude",
|
|
10
|
+
"cursor-rules",
|
|
11
|
+
"agents-md"
|
|
12
|
+
];
|
|
13
|
+
/**
|
|
14
|
+
* Human-readable labels for setup targets.
|
|
15
|
+
*/
|
|
16
|
+
const SETUP_TARGET_LABELS = {
|
|
17
|
+
"cli-config": "CLI Configuration (.contractsrc.json)",
|
|
18
|
+
"vscode-settings": "VS Code Settings (.vscode/settings.json)",
|
|
19
|
+
"mcp-cursor": "MCP for Cursor (.cursor/mcp.json)",
|
|
20
|
+
"mcp-claude": "MCP for Claude Desktop",
|
|
21
|
+
"cursor-rules": "Cursor AI Rules (.cursor/rules/)",
|
|
22
|
+
"agents-md": "Project AI Guide (AGENTS.md)"
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { ALL_SETUP_TARGETS, SETUP_TARGET_LABELS };
|
package/dist/services/sync.js
CHANGED
|
@@ -1 +1,62 @@
|
|
|
1
|
-
import{validateSpec
|
|
1
|
+
import { validateSpec } from "./validate.js";
|
|
2
|
+
import { buildSpec } from "./build.js";
|
|
3
|
+
|
|
4
|
+
//#region src/services/sync.ts
|
|
5
|
+
async function syncSpecs(adapters, config, options = {}, overrides) {
|
|
6
|
+
const { fs, logger } = adapters;
|
|
7
|
+
const specs = await fs.glob({ pattern: options.pattern });
|
|
8
|
+
const outputDirs = options.outputDirs?.length ? options.outputDirs : [void 0];
|
|
9
|
+
const runs = [];
|
|
10
|
+
const validateFn = overrides?.validate ?? ((specPath) => validateSpec(specPath, {
|
|
11
|
+
fs,
|
|
12
|
+
logger
|
|
13
|
+
}));
|
|
14
|
+
const buildFn = overrides?.build ?? ((specPath, outputDir) => buildSpec(specPath, {
|
|
15
|
+
fs,
|
|
16
|
+
logger
|
|
17
|
+
}, outputDir ? {
|
|
18
|
+
...config,
|
|
19
|
+
outputDir
|
|
20
|
+
} : config, {
|
|
21
|
+
...options.buildOptions ?? {},
|
|
22
|
+
outputDir
|
|
23
|
+
}));
|
|
24
|
+
for (const specPath of specs) for (const outputDir of outputDirs) {
|
|
25
|
+
const run = {
|
|
26
|
+
specPath,
|
|
27
|
+
outputDir
|
|
28
|
+
};
|
|
29
|
+
if (options.validate) try {
|
|
30
|
+
run.validation = await validateFn(specPath);
|
|
31
|
+
} catch (error) {
|
|
32
|
+
run.error = {
|
|
33
|
+
phase: "validate",
|
|
34
|
+
message: error instanceof Error ? error.message : String(error)
|
|
35
|
+
};
|
|
36
|
+
runs.push(run);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (!options.dryRun) try {
|
|
40
|
+
run.build = await buildFn(specPath, outputDir);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
run.error = {
|
|
43
|
+
phase: "build",
|
|
44
|
+
message: error instanceof Error ? error.message : String(error)
|
|
45
|
+
};
|
|
46
|
+
runs.push(run);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
else logger.info("[dry-run] syncSpecs skipped build", {
|
|
50
|
+
specPath,
|
|
51
|
+
outputDir
|
|
52
|
+
});
|
|
53
|
+
runs.push(run);
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
specs,
|
|
57
|
+
runs
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//#endregion
|
|
62
|
+
export { syncSpecs };
|
package/dist/services/test.js
CHANGED
|
@@ -1 +1,30 @@
|
|
|
1
|
-
import{TestRunner
|
|
1
|
+
import { TestRunner } from "../libs/contracts/dist/tests/runner.js";
|
|
2
|
+
import "../libs/contracts/dist/tests/index.js";
|
|
3
|
+
|
|
4
|
+
//#region src/services/test.ts
|
|
5
|
+
/**
|
|
6
|
+
* Test service.
|
|
7
|
+
*
|
|
8
|
+
* Pure runner wrapper that executes TestSpec scenarios against a SpecRegistry.
|
|
9
|
+
* Loading/compiling spec modules (TS/ESM) is intentionally left to the caller.
|
|
10
|
+
*/
|
|
11
|
+
async function runTests(specs, registry) {
|
|
12
|
+
const runner = new TestRunner({ registry });
|
|
13
|
+
const results = [];
|
|
14
|
+
let passed = 0;
|
|
15
|
+
let failed = 0;
|
|
16
|
+
for (const spec of specs) {
|
|
17
|
+
const result = await runner.run(spec);
|
|
18
|
+
results.push(result);
|
|
19
|
+
passed += result.passed;
|
|
20
|
+
failed += result.failed;
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
results,
|
|
24
|
+
passed,
|
|
25
|
+
failed
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
30
|
+
export { runTests };
|