@planu/cli 0.96.4 → 0.97.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/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/commands/install.js +70 -2
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/config/compliance-profiles.json +62 -0
- package/dist/config/license-plans.json +19 -2
- package/dist/config/spec-templates/crud-rest-api/spec.md +35 -0
- package/dist/config/spec-templates/crud-rest-api/template.json +10 -0
- package/dist/config/spec-templates/email-notifications/spec.md +31 -0
- package/dist/config/spec-templates/email-notifications/template.json +10 -0
- package/dist/config/spec-templates/file-upload-s3/spec.md +31 -0
- package/dist/config/spec-templates/file-upload-s3/template.json +11 -0
- package/dist/config/spec-templates/jwt-auth/spec.md +35 -0
- package/dist/config/spec-templates/jwt-auth/template.json +10 -0
- package/dist/config/spec-templates/oauth-social-login/spec.md +31 -0
- package/dist/config/spec-templates/oauth-social-login/template.json +10 -0
- package/dist/config/spec-templates/rate-limiting/spec.md +31 -0
- package/dist/config/spec-templates/rate-limiting/template.json +10 -0
- package/dist/config/spec-templates/stripe-payments/spec.md +32 -0
- package/dist/config/spec-templates/stripe-payments/template.json +10 -0
- package/dist/config/spec-templates/webhook-system/spec.md +36 -0
- package/dist/config/spec-templates/webhook-system/template.json +10 -0
- package/dist/engine/agent-ready-exporter/formatters/devin.d.ts +7 -0
- package/dist/engine/agent-ready-exporter/formatters/devin.d.ts.map +1 -0
- package/dist/engine/agent-ready-exporter/formatters/devin.js +23 -0
- package/dist/engine/agent-ready-exporter/formatters/devin.js.map +1 -0
- package/dist/engine/agent-ready-exporter/formatters/generic.d.ts +7 -0
- package/dist/engine/agent-ready-exporter/formatters/generic.d.ts.map +1 -0
- package/dist/engine/agent-ready-exporter/formatters/generic.js +9 -0
- package/dist/engine/agent-ready-exporter/formatters/generic.js.map +1 -0
- package/dist/engine/agent-ready-exporter/formatters/kiro.d.ts +6 -0
- package/dist/engine/agent-ready-exporter/formatters/kiro.d.ts.map +1 -0
- package/dist/engine/agent-ready-exporter/formatters/kiro.js +34 -0
- package/dist/engine/agent-ready-exporter/formatters/kiro.js.map +1 -0
- package/dist/engine/agent-ready-exporter/formatters/swe-agent.d.ts +6 -0
- package/dist/engine/agent-ready-exporter/formatters/swe-agent.d.ts.map +1 -0
- package/dist/engine/agent-ready-exporter/formatters/swe-agent.js +40 -0
- package/dist/engine/agent-ready-exporter/formatters/swe-agent.js.map +1 -0
- package/dist/engine/agent-ready-exporter.d.ts +11 -0
- package/dist/engine/agent-ready-exporter.d.ts.map +1 -0
- package/dist/engine/agent-ready-exporter.js +86 -0
- package/dist/engine/agent-ready-exporter.js.map +1 -0
- package/dist/engine/compliance-checker.d.ts +19 -0
- package/dist/engine/compliance-checker.d.ts.map +1 -0
- package/dist/engine/compliance-checker.js +145 -0
- package/dist/engine/compliance-checker.js.map +1 -0
- package/dist/engine/generate-tests/generators/property-based-generator.d.ts +12 -0
- package/dist/engine/generate-tests/generators/property-based-generator.d.ts.map +1 -0
- package/dist/engine/generate-tests/generators/property-based-generator.js +159 -0
- package/dist/engine/generate-tests/generators/property-based-generator.js.map +1 -0
- package/dist/engine/jira-exporter.d.ts +39 -0
- package/dist/engine/jira-exporter.d.ts.map +1 -0
- package/dist/engine/jira-exporter.js +190 -0
- package/dist/engine/jira-exporter.js.map +1 -0
- package/dist/engine/linear-exporter.d.ts +32 -0
- package/dist/engine/linear-exporter.d.ts.map +1 -0
- package/dist/engine/linear-exporter.js +184 -0
- package/dist/engine/linear-exporter.js.map +1 -0
- package/dist/engine/planu-config-writer.d.ts +13 -2
- package/dist/engine/planu-config-writer.d.ts.map +1 -1
- package/dist/engine/planu-config-writer.js +32 -1
- package/dist/engine/planu-config-writer.js.map +1 -1
- package/dist/engine/property-test-generator.d.ts +14 -0
- package/dist/engine/property-test-generator.d.ts.map +1 -0
- package/dist/engine/property-test-generator.js +223 -0
- package/dist/engine/property-test-generator.js.map +1 -0
- package/dist/engine/skill-evaluator.d.ts +21 -0
- package/dist/engine/skill-evaluator.d.ts.map +1 -0
- package/dist/engine/skill-evaluator.js +126 -0
- package/dist/engine/skill-evaluator.js.map +1 -0
- package/dist/engine/spec-quality-scorer.d.ts +4 -0
- package/dist/engine/spec-quality-scorer.d.ts.map +1 -0
- package/dist/engine/spec-quality-scorer.js +334 -0
- package/dist/engine/spec-quality-scorer.js.map +1 -0
- package/dist/engine/spec-template-engine.d.ts +26 -0
- package/dist/engine/spec-template-engine.d.ts.map +1 -0
- package/dist/engine/spec-template-engine.js +127 -0
- package/dist/engine/spec-template-engine.js.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/storage/compliance-store.d.ts +11 -0
- package/dist/storage/compliance-store.d.ts.map +1 -0
- package/dist/storage/compliance-store.js +30 -0
- package/dist/storage/compliance-store.js.map +1 -0
- package/dist/storage/jira-store.d.ts +30 -0
- package/dist/storage/jira-store.d.ts.map +1 -0
- package/dist/storage/jira-store.js +84 -0
- package/dist/storage/jira-store.js.map +1 -0
- package/dist/storage/linear-store.d.ts +30 -0
- package/dist/storage/linear-store.d.ts.map +1 -0
- package/dist/storage/linear-store.js +84 -0
- package/dist/storage/linear-store.js.map +1 -0
- package/dist/tools/check-readiness.d.ts.map +1 -1
- package/dist/tools/check-readiness.js +8 -2
- package/dist/tools/check-readiness.js.map +1 -1
- package/dist/tools/compliance-handler.d.ts +6 -0
- package/dist/tools/compliance-handler.d.ts.map +1 -0
- package/dist/tools/compliance-handler.js +99 -0
- package/dist/tools/compliance-handler.js.map +1 -0
- package/dist/tools/eval-skill-handler.d.ts +4 -0
- package/dist/tools/eval-skill-handler.d.ts.map +1 -0
- package/dist/tools/eval-skill-handler.js +26 -0
- package/dist/tools/eval-skill-handler.js.map +1 -0
- package/dist/tools/export-spec.d.ts.map +1 -1
- package/dist/tools/export-spec.js +42 -1
- package/dist/tools/export-spec.js.map +1 -1
- package/dist/tools/generate-tests/generators/property-based-generator.d.ts +11 -0
- package/dist/tools/generate-tests/generators/property-based-generator.d.ts.map +1 -0
- package/dist/tools/generate-tests/generators/property-based-generator.js +27 -0
- package/dist/tools/generate-tests/generators/property-based-generator.js.map +1 -0
- package/dist/tools/generate-tests/spec-dispatcher.d.ts +5 -0
- package/dist/tools/generate-tests/spec-dispatcher.d.ts.map +1 -1
- package/dist/tools/generate-tests/spec-dispatcher.js +18 -1
- package/dist/tools/generate-tests/spec-dispatcher.js.map +1 -1
- package/dist/tools/init-project/config-builder.d.ts +3 -2
- package/dist/tools/init-project/config-builder.d.ts.map +1 -1
- package/dist/tools/init-project/config-builder.js +9 -4
- package/dist/tools/init-project/config-builder.js.map +1 -1
- package/dist/tools/init-project/handler.d.ts.map +1 -1
- package/dist/tools/init-project/handler.js +3 -2
- package/dist/tools/init-project/handler.js.map +1 -1
- package/dist/tools/jira-sync-handler.d.ts +6 -0
- package/dist/tools/jira-sync-handler.d.ts.map +1 -0
- package/dist/tools/jira-sync-handler.js +220 -0
- package/dist/tools/jira-sync-handler.js.map +1 -0
- package/dist/tools/linear-sync-handler.d.ts +6 -0
- package/dist/tools/linear-sync-handler.d.ts.map +1 -0
- package/dist/tools/linear-sync-handler.js +212 -0
- package/dist/tools/linear-sync-handler.js.map +1 -0
- package/dist/tools/register-export-tools.d.ts.map +1 -1
- package/dist/tools/register-export-tools.js +10 -3
- package/dist/tools/register-export-tools.js.map +1 -1
- package/dist/tools/register-spec-314.d.ts +3 -0
- package/dist/tools/register-spec-314.d.ts.map +1 -0
- package/dist/tools/register-spec-314.js +38 -0
- package/dist/tools/register-spec-314.js.map +1 -0
- package/dist/tools/register-spec-316.d.ts +3 -0
- package/dist/tools/register-spec-316.d.ts.map +1 -0
- package/dist/tools/register-spec-316.js +71 -0
- package/dist/tools/register-spec-316.js.map +1 -0
- package/dist/tools/register-spec-317.d.ts +3 -0
- package/dist/tools/register-spec-317.d.ts.map +1 -0
- package/dist/tools/register-spec-317.js +158 -0
- package/dist/tools/register-spec-317.js.map +1 -0
- package/dist/tools/register-spec-319.d.ts +3 -0
- package/dist/tools/register-spec-319.d.ts.map +1 -0
- package/dist/tools/register-spec-319.js +59 -0
- package/dist/tools/register-spec-319.js.map +1 -0
- package/dist/tools/register-spec-320.d.ts +3 -0
- package/dist/tools/register-spec-320.d.ts.map +1 -0
- package/dist/tools/register-spec-320.js +60 -0
- package/dist/tools/register-spec-320.js.map +1 -0
- package/dist/tools/register-spec-tools/core-spec-tools.d.ts.map +1 -1
- package/dist/tools/register-spec-tools/core-spec-tools.js +15 -1
- package/dist/tools/register-spec-tools/core-spec-tools.js.map +1 -1
- package/dist/tools/schemas/index.d.ts +1 -1
- package/dist/tools/schemas/index.d.ts.map +1 -1
- package/dist/tools/schemas/index.js +1 -1
- package/dist/tools/schemas/index.js.map +1 -1
- package/dist/tools/schemas/spec.d.ts +6 -0
- package/dist/tools/schemas/spec.d.ts.map +1 -1
- package/dist/tools/schemas/spec.js +4 -0
- package/dist/tools/schemas/spec.js.map +1 -1
- package/dist/tools/set-work-mode-handler.d.ts +7 -0
- package/dist/tools/set-work-mode-handler.d.ts.map +1 -0
- package/dist/tools/set-work-mode-handler.js +30 -0
- package/dist/tools/set-work-mode-handler.js.map +1 -0
- package/dist/tools/spec-marketplace-handler.d.ts +6 -0
- package/dist/tools/spec-marketplace-handler.d.ts.map +1 -0
- package/dist/tools/spec-marketplace-handler.js +113 -0
- package/dist/tools/spec-marketplace-handler.js.map +1 -0
- package/dist/tools/spec-quality-score-handler.d.ts +7 -0
- package/dist/tools/spec-quality-score-handler.d.ts.map +1 -0
- package/dist/tools/spec-quality-score-handler.js +106 -0
- package/dist/tools/spec-quality-score-handler.js.map +1 -0
- package/dist/tools/status-handler.d.ts.map +1 -1
- package/dist/tools/status-handler.js +12 -3
- package/dist/tools/status-handler.js.map +1 -1
- package/dist/types/agent-ready.d.ts +58 -0
- package/dist/types/agent-ready.d.ts.map +1 -0
- package/dist/types/agent-ready.js +3 -0
- package/dist/types/agent-ready.js.map +1 -0
- package/dist/types/common/primitives.d.ts +2 -0
- package/dist/types/common/primitives.d.ts.map +1 -1
- package/dist/types/compliance.d.ts +44 -0
- package/dist/types/compliance.d.ts.map +1 -0
- package/dist/types/compliance.js +3 -0
- package/dist/types/compliance.js.map +1 -0
- package/dist/types/export.d.ts +5 -1
- package/dist/types/export.d.ts.map +1 -1
- package/dist/types/export.js +1 -1
- package/dist/types/export.js.map +1 -1
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/jira-linear.d.ts +216 -0
- package/dist/types/jira-linear.d.ts.map +1 -0
- package/dist/types/jira-linear.js +3 -0
- package/dist/types/jira-linear.js.map +1 -0
- package/dist/types/project/inputs.d.ts +3 -1
- package/dist/types/project/inputs.d.ts.map +1 -1
- package/dist/types/project/planu-config.d.ts +2 -0
- package/dist/types/project/planu-config.d.ts.map +1 -1
- package/dist/types/property-testing.d.ts +50 -0
- package/dist/types/property-testing.d.ts.map +1 -0
- package/dist/types/property-testing.js +3 -0
- package/dist/types/property-testing.js.map +1 -0
- package/dist/types/skill-eval.d.ts +41 -0
- package/dist/types/skill-eval.d.ts.map +1 -0
- package/dist/types/skill-eval.js +3 -0
- package/dist/types/skill-eval.js.map +1 -0
- package/dist/types/spec-marketplace.d.ts +31 -0
- package/dist/types/spec-marketplace.d.ts.map +1 -0
- package/dist/types/spec-marketplace.js +3 -0
- package/dist/types/spec-marketplace.js.map +1 -0
- package/dist/types/spec-quality.d.ts +36 -0
- package/dist/types/spec-quality.d.ts.map +1 -0
- package/dist/types/spec-quality.js +3 -0
- package/dist/types/spec-quality.js.map +1 -0
- package/package.json +7 -2
- package/src/config/compliance-profiles.json +62 -0
- package/src/config/license-plans.json +19 -2
- package/src/config/spec-templates/crud-rest-api/spec.md +35 -0
- package/src/config/spec-templates/crud-rest-api/template.json +10 -0
- package/src/config/spec-templates/email-notifications/spec.md +31 -0
- package/src/config/spec-templates/email-notifications/template.json +10 -0
- package/src/config/spec-templates/file-upload-s3/spec.md +31 -0
- package/src/config/spec-templates/file-upload-s3/template.json +11 -0
- package/src/config/spec-templates/jwt-auth/spec.md +35 -0
- package/src/config/spec-templates/jwt-auth/template.json +10 -0
- package/src/config/spec-templates/oauth-social-login/spec.md +31 -0
- package/src/config/spec-templates/oauth-social-login/template.json +10 -0
- package/src/config/spec-templates/rate-limiting/spec.md +31 -0
- package/src/config/spec-templates/rate-limiting/template.json +10 -0
- package/src/config/spec-templates/stripe-payments/spec.md +32 -0
- package/src/config/spec-templates/stripe-payments/template.json +10 -0
- package/src/config/spec-templates/webhook-system/spec.md +36 -0
- package/src/config/spec-templates/webhook-system/template.json +10 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { JiraConfig, JiraDelivery, SyncedJiraIssue } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Read the Jira configuration for a project. Returns null if not configured.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getJiraConfig(projectPath: string): Promise<JiraConfig | null>;
|
|
6
|
+
/**
|
|
7
|
+
* Persist the Jira configuration for a project.
|
|
8
|
+
*/
|
|
9
|
+
export declare function saveJiraConfig(projectPath: string, config: JiraConfig): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Remove the Jira configuration for a project.
|
|
12
|
+
*/
|
|
13
|
+
export declare function removeJiraConfig(projectPath: string): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Read the last 20 Jira sync log entries for a project.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getJiraSyncLog(projectPath: string): Promise<JiraDelivery[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Append a sync entry to the log, keeping at most MAX_LOG_ENTRIES entries.
|
|
20
|
+
*/
|
|
21
|
+
export declare function appendJiraSyncEntry(projectPath: string, entry: JiraDelivery): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Read the map of specId → SyncedJiraIssue for a project.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getSyncedJiraIssues(projectPath: string): Promise<Record<string, SyncedJiraIssue>>;
|
|
26
|
+
/**
|
|
27
|
+
* Upsert a single synced Jira issue entry.
|
|
28
|
+
*/
|
|
29
|
+
export declare function upsertSyncedJiraIssue(projectPath: string, issue: SyncedJiraIssue): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=jira-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jira-store.d.ts","sourceRoot":"","sources":["../../src/storage/jira-store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AA6BnF;;GAEG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAEnF;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3F;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE;AAMD;;GAEG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAEjF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAQf;AAMD;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAE1C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,IAAI,CAAC,CAOf"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// storage/jira-store.ts — Jira sync persistence (SPEC-317)
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { hashProjectPath, readJson, writeJson } from './base-store.js';
|
|
4
|
+
import { withFileLock } from './file-mutex.js';
|
|
5
|
+
const MAX_LOG_ENTRIES = 20;
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Path helpers
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
function projectDir(projectPath) {
|
|
10
|
+
const id = hashProjectPath(projectPath);
|
|
11
|
+
return join('data', 'projects', id);
|
|
12
|
+
}
|
|
13
|
+
function configPath(projectPath) {
|
|
14
|
+
return join(projectDir(projectPath), 'jira-config.json');
|
|
15
|
+
}
|
|
16
|
+
function logPath(projectPath) {
|
|
17
|
+
return join(projectDir(projectPath), 'jira-sync-log.json');
|
|
18
|
+
}
|
|
19
|
+
function syncedIssuesPath(projectPath) {
|
|
20
|
+
return join(projectDir(projectPath), 'jira-synced-issues.json');
|
|
21
|
+
}
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Config
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
/**
|
|
26
|
+
* Read the Jira configuration for a project. Returns null if not configured.
|
|
27
|
+
*/
|
|
28
|
+
export async function getJiraConfig(projectPath) {
|
|
29
|
+
return readJson(configPath(projectPath), null);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Persist the Jira configuration for a project.
|
|
33
|
+
*/
|
|
34
|
+
export async function saveJiraConfig(projectPath, config) {
|
|
35
|
+
await writeJson(configPath(projectPath), config);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Remove the Jira configuration for a project.
|
|
39
|
+
*/
|
|
40
|
+
export async function removeJiraConfig(projectPath) {
|
|
41
|
+
await writeJson(configPath(projectPath), null);
|
|
42
|
+
}
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Sync log
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/**
|
|
47
|
+
* Read the last 20 Jira sync log entries for a project.
|
|
48
|
+
*/
|
|
49
|
+
export async function getJiraSyncLog(projectPath) {
|
|
50
|
+
return readJson(logPath(projectPath), []);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Append a sync entry to the log, keeping at most MAX_LOG_ENTRIES entries.
|
|
54
|
+
*/
|
|
55
|
+
export async function appendJiraSyncEntry(projectPath, entry) {
|
|
56
|
+
const filePath = logPath(projectPath);
|
|
57
|
+
await withFileLock(filePath, async () => {
|
|
58
|
+
const entries = await readJson(filePath, []);
|
|
59
|
+
entries.push(entry);
|
|
60
|
+
const trimmed = entries.slice(-MAX_LOG_ENTRIES);
|
|
61
|
+
await writeJson(filePath, trimmed);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Synced issues map (specId → SyncedJiraIssue)
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
/**
|
|
68
|
+
* Read the map of specId → SyncedJiraIssue for a project.
|
|
69
|
+
*/
|
|
70
|
+
export async function getSyncedJiraIssues(projectPath) {
|
|
71
|
+
return readJson(syncedIssuesPath(projectPath), {});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Upsert a single synced Jira issue entry.
|
|
75
|
+
*/
|
|
76
|
+
export async function upsertSyncedJiraIssue(projectPath, issue) {
|
|
77
|
+
const filePath = syncedIssuesPath(projectPath);
|
|
78
|
+
await withFileLock(filePath, async () => {
|
|
79
|
+
const issues = await readJson(filePath, {});
|
|
80
|
+
issues[issue.specId] = issue;
|
|
81
|
+
await writeJson(filePath, issues);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=jira-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jira-store.js","sourceRoot":"","sources":["../../src/storage/jira-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { LinearConfig, LinearDelivery, SyncedLinearIssue } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Read the Linear configuration for a project. Returns null if not configured.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getLinearConfig(projectPath: string): Promise<LinearConfig | null>;
|
|
6
|
+
/**
|
|
7
|
+
* Persist the Linear configuration for a project.
|
|
8
|
+
*/
|
|
9
|
+
export declare function saveLinearConfig(projectPath: string, config: LinearConfig): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Remove the Linear configuration for a project.
|
|
12
|
+
*/
|
|
13
|
+
export declare function removeLinearConfig(projectPath: string): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Read the last 20 Linear sync log entries for a project.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getLinearSyncLog(projectPath: string): Promise<LinearDelivery[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Append a sync entry to the log, keeping at most MAX_LOG_ENTRIES entries.
|
|
20
|
+
*/
|
|
21
|
+
export declare function appendLinearSyncEntry(projectPath: string, entry: LinearDelivery): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Read the map of specId → SyncedLinearIssue for a project.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getSyncedLinearIssues(projectPath: string): Promise<Record<string, SyncedLinearIssue>>;
|
|
26
|
+
/**
|
|
27
|
+
* Upsert a single synced Linear issue entry.
|
|
28
|
+
*/
|
|
29
|
+
export declare function upsertSyncedLinearIssue(projectPath: string, issue: SyncedLinearIssue): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=linear-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-store.d.ts","sourceRoot":"","sources":["../../src/storage/linear-store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AA6BzF;;GAEG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAEvF;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3E;AAMD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAErF;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,IAAI,CAAC,CAQf;AAMD;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAE5C;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,IAAI,CAAC,CAOf"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// storage/linear-store.ts — Linear sync persistence (SPEC-317)
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { hashProjectPath, readJson, writeJson } from './base-store.js';
|
|
4
|
+
import { withFileLock } from './file-mutex.js';
|
|
5
|
+
const MAX_LOG_ENTRIES = 20;
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Path helpers
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
function projectDir(projectPath) {
|
|
10
|
+
const id = hashProjectPath(projectPath);
|
|
11
|
+
return join('data', 'projects', id);
|
|
12
|
+
}
|
|
13
|
+
function configPath(projectPath) {
|
|
14
|
+
return join(projectDir(projectPath), 'linear-config.json');
|
|
15
|
+
}
|
|
16
|
+
function logPath(projectPath) {
|
|
17
|
+
return join(projectDir(projectPath), 'linear-sync-log.json');
|
|
18
|
+
}
|
|
19
|
+
function syncedIssuesPath(projectPath) {
|
|
20
|
+
return join(projectDir(projectPath), 'linear-synced-issues.json');
|
|
21
|
+
}
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Config
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
/**
|
|
26
|
+
* Read the Linear configuration for a project. Returns null if not configured.
|
|
27
|
+
*/
|
|
28
|
+
export async function getLinearConfig(projectPath) {
|
|
29
|
+
return readJson(configPath(projectPath), null);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Persist the Linear configuration for a project.
|
|
33
|
+
*/
|
|
34
|
+
export async function saveLinearConfig(projectPath, config) {
|
|
35
|
+
await writeJson(configPath(projectPath), config);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Remove the Linear configuration for a project.
|
|
39
|
+
*/
|
|
40
|
+
export async function removeLinearConfig(projectPath) {
|
|
41
|
+
await writeJson(configPath(projectPath), null);
|
|
42
|
+
}
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Sync log
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/**
|
|
47
|
+
* Read the last 20 Linear sync log entries for a project.
|
|
48
|
+
*/
|
|
49
|
+
export async function getLinearSyncLog(projectPath) {
|
|
50
|
+
return readJson(logPath(projectPath), []);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Append a sync entry to the log, keeping at most MAX_LOG_ENTRIES entries.
|
|
54
|
+
*/
|
|
55
|
+
export async function appendLinearSyncEntry(projectPath, entry) {
|
|
56
|
+
const filePath = logPath(projectPath);
|
|
57
|
+
await withFileLock(filePath, async () => {
|
|
58
|
+
const entries = await readJson(filePath, []);
|
|
59
|
+
entries.push(entry);
|
|
60
|
+
const trimmed = entries.slice(-MAX_LOG_ENTRIES);
|
|
61
|
+
await writeJson(filePath, trimmed);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Synced issues map (specId → SyncedLinearIssue)
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
/**
|
|
68
|
+
* Read the map of specId → SyncedLinearIssue for a project.
|
|
69
|
+
*/
|
|
70
|
+
export async function getSyncedLinearIssues(projectPath) {
|
|
71
|
+
return readJson(syncedIssuesPath(projectPath), {});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Upsert a single synced Linear issue entry.
|
|
75
|
+
*/
|
|
76
|
+
export async function upsertSyncedLinearIssue(projectPath, issue) {
|
|
77
|
+
const filePath = syncedIssuesPath(projectPath);
|
|
78
|
+
await withFileLock(filePath, async () => {
|
|
79
|
+
const issues = await readJson(filePath, {});
|
|
80
|
+
issues[issue.specId] = issue;
|
|
81
|
+
await writeJson(filePath, issues);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=linear-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-store.js","sourceRoot":"","sources":["../../src/storage/linear-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-readiness.d.ts","sourceRoot":"","sources":["../../src/tools/check-readiness.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"check-readiness.d.ts","sourceRoot":"","sources":["../../src/tools/check-readiness.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAmB,MAAM,mBAAmB,CAAC;AA6F1F,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,mBAAmB,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD,OAAO,CAAC,UAAU,CAAC,CA0CrB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
// tools/check-readiness.ts — Completeness checkpoint tool (SPEC-039)
|
|
1
|
+
// tools/check-readiness.ts — Completeness checkpoint tool (SPEC-039, SPEC-314)
|
|
2
2
|
import { specStore } from '../storage/index.js';
|
|
3
3
|
import { checkSpecReadiness } from '../engine/readiness-checker.js';
|
|
4
|
+
import { scoreSpecQuality } from '../engine/spec-quality-scorer.js';
|
|
4
5
|
import { resolveProjectId } from './resolve-project-id.js';
|
|
5
6
|
// ── Formatting helpers ───────────────────────────────────────────────────────
|
|
6
7
|
function formatScore(score) {
|
|
@@ -99,7 +100,11 @@ export async function handleCheckReadiness(args) {
|
|
|
99
100
|
isError: true,
|
|
100
101
|
};
|
|
101
102
|
}
|
|
102
|
-
const report = await
|
|
103
|
+
const [report, qualityReport] = await Promise.all([
|
|
104
|
+
checkSpecReadiness(spec, mode),
|
|
105
|
+
scoreSpecQuality(spec),
|
|
106
|
+
]);
|
|
107
|
+
const qualityScore = qualityReport.score;
|
|
103
108
|
const formatted = formatReport(report);
|
|
104
109
|
return {
|
|
105
110
|
content: [{ type: 'text', text: formatted }],
|
|
@@ -110,6 +115,7 @@ export async function handleCheckReadiness(args) {
|
|
|
110
115
|
mode: report.mode,
|
|
111
116
|
issues: report.issues,
|
|
112
117
|
recommendations: report.recommendations,
|
|
118
|
+
qualityScore,
|
|
113
119
|
},
|
|
114
120
|
};
|
|
115
121
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-readiness.js","sourceRoot":"","sources":["../../src/tools/check-readiness.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"check-readiness.js","sourceRoot":"","sources":["../../src/tools/check-readiness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ToolResult } from '../types/index.js';
|
|
2
|
+
import type { CheckComplianceInput, ConfigureComplianceInput, ComplianceSpecFramework } from '../types/compliance.js';
|
|
3
|
+
export declare function handleCheckCompliance(input: CheckComplianceInput): Promise<ToolResult>;
|
|
4
|
+
export declare function handleConfigureCompliance(input: ConfigureComplianceInput): Promise<ToolResult>;
|
|
5
|
+
export declare function resolveFrameworks(projectPath: string, title: string, description: string, explicit?: ComplianceSpecFramework[]): Promise<ComplianceSpecFramework[]>;
|
|
6
|
+
//# sourceMappingURL=compliance-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compliance-handler.d.ts","sourceRoot":"","sources":["../../src/tools/compliance-handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,wBAAwB,CAAC;AAahC,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAoErB;AAMD,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,UAAU,CAAC,CAerB;AAMD,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,uBAAuB,EAAE,GACnC,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAUpC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { hashProjectPath } from '../storage/base-store.js';
|
|
2
|
+
import { getSpec } from '../storage/spec-store.js';
|
|
3
|
+
import { getComplianceConfig, saveComplianceConfig } from '../storage/compliance-store.js';
|
|
4
|
+
import { detectComplianceContext, checkCompliance, } from '../engine/compliance-checker.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// check_compliance
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
export async function handleCheckCompliance(input) {
|
|
9
|
+
const projectId = hashProjectPath(input.projectPath);
|
|
10
|
+
const spec = await getSpec(projectId, input.specId);
|
|
11
|
+
if (spec === null) {
|
|
12
|
+
return {
|
|
13
|
+
content: [
|
|
14
|
+
{
|
|
15
|
+
type: 'text',
|
|
16
|
+
text: `Spec ${input.specId} not found. Check the ID and try again.`,
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
isError: true,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
// Resolve frameworks: use provided ones, or auto-detect, or fall back to project config
|
|
23
|
+
let frameworks = input.frameworks ?? [];
|
|
24
|
+
if (frameworks.length === 0) {
|
|
25
|
+
const detected = detectComplianceContext(spec.title, '');
|
|
26
|
+
if (detected.length > 0) {
|
|
27
|
+
frameworks = detected;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
const config = await getComplianceConfig(input.projectPath);
|
|
31
|
+
frameworks = config?.frameworks ?? [];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (frameworks.length === 0) {
|
|
35
|
+
return {
|
|
36
|
+
content: [
|
|
37
|
+
{
|
|
38
|
+
type: 'text',
|
|
39
|
+
text: 'No compliance frameworks detected or configured. ' +
|
|
40
|
+
'Provide `frameworks` in the request or run `configure_compliance` first.',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const report = await checkCompliance(spec, frameworks);
|
|
46
|
+
const lines = [
|
|
47
|
+
`## Compliance Report — ${spec.id}: ${spec.title}`,
|
|
48
|
+
'',
|
|
49
|
+
`**Frameworks checked:** ${report.frameworks.join(', ')}`,
|
|
50
|
+
`**Coverage:** ${String(report.coveragePercent)}%`,
|
|
51
|
+
`**Total gaps:** ${String(report.gaps.length)}`,
|
|
52
|
+
'',
|
|
53
|
+
];
|
|
54
|
+
if (report.gaps.length === 0) {
|
|
55
|
+
lines.push('All required compliance criteria are present. No action needed.');
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
lines.push('### Gaps Found', '');
|
|
59
|
+
for (const gap of report.gaps) {
|
|
60
|
+
const icon = gap.status === 'partial' ? '~' : '✗';
|
|
61
|
+
lines.push(`- [${gap.framework.toUpperCase()}] ${icon} ${gap.criterion}`);
|
|
62
|
+
}
|
|
63
|
+
lines.push('');
|
|
64
|
+
lines.push(`Run \`inject_criteria\` or update the spec's acceptance criteria to address these gaps.`);
|
|
65
|
+
}
|
|
66
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
67
|
+
}
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
// configure_compliance
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
export async function handleConfigureCompliance(input) {
|
|
72
|
+
await saveComplianceConfig(input.projectPath, {
|
|
73
|
+
frameworks: input.frameworks,
|
|
74
|
+
updatedAt: new Date().toISOString(),
|
|
75
|
+
});
|
|
76
|
+
const lines = [
|
|
77
|
+
'Compliance configuration saved.',
|
|
78
|
+
'',
|
|
79
|
+
`**Active frameworks:** ${input.frameworks.join(', ')}`,
|
|
80
|
+
'',
|
|
81
|
+
'Run `check_compliance` on any spec to detect compliance gaps.',
|
|
82
|
+
];
|
|
83
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
84
|
+
}
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// Internal — resolve frameworks for a project path (used in auto-detection)
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
export async function resolveFrameworks(projectPath, title, description, explicit) {
|
|
89
|
+
if (explicit !== undefined && explicit.length > 0) {
|
|
90
|
+
return explicit;
|
|
91
|
+
}
|
|
92
|
+
const detected = detectComplianceContext(title, description);
|
|
93
|
+
if (detected.length > 0) {
|
|
94
|
+
return detected;
|
|
95
|
+
}
|
|
96
|
+
const config = await getComplianceConfig(projectPath);
|
|
97
|
+
return config?.frameworks ?? [];
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=compliance-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compliance-handler.js","sourceRoot":"","sources":["../../src/tools/compliance-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ToolResult, EvalSkillInput, EvalRuleInput } from '../types/index.js';
|
|
2
|
+
export declare function handleEvalSkill(input: EvalSkillInput): Promise<ToolResult>;
|
|
3
|
+
export declare function handleEvalRule(input: EvalRuleInput): Promise<ToolResult>;
|
|
4
|
+
//# sourceMappingURL=eval-skill-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval-skill-handler.d.ts","sourceRoot":"","sources":["../../src/tools/eval-skill-handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAanF,wBAAsB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAWhF;AAMD,wBAAsB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAW9E"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// tools/eval-skill-handler.ts — MCP tool handlers for eval_skill and eval_rule (SPEC-316)
|
|
2
|
+
import { evaluateSkill, evaluateRule, resolveSkillPath, resolveRulePath, } from '../engine/skill-evaluator.js';
|
|
3
|
+
import { jsonResult, errText } from './response-helpers.js';
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// eval_skill
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
export async function handleEvalSkill(input) {
|
|
8
|
+
if (input.testScenarios.length === 0) {
|
|
9
|
+
return errText('No test scenarios provided. Provide at least one scenario with input, expectedOutput, and criteria.');
|
|
10
|
+
}
|
|
11
|
+
const skillPath = resolveSkillPath(input.projectPath, input.skillName);
|
|
12
|
+
const result = await evaluateSkill(skillPath, input.testScenarios);
|
|
13
|
+
return jsonResult(result);
|
|
14
|
+
}
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// eval_rule
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
export async function handleEvalRule(input) {
|
|
19
|
+
if (input.testScenarios.length === 0) {
|
|
20
|
+
return errText('No test scenarios provided. Provide at least one scenario with input, expectedOutput, and criteria.');
|
|
21
|
+
}
|
|
22
|
+
const rulePath = resolveRulePath(input.projectPath, input.ruleName);
|
|
23
|
+
const result = await evaluateRule(rulePath, input.testScenarios);
|
|
24
|
+
return jsonResult(result);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=eval-skill-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval-skill-handler.js","sourceRoot":"","sources":["../../src/tools/eval-skill-handler.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAG1F,OAAO,EACL,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAChB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAE5D,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAqB;IACzD,IAAI,KAAK,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,OAAO,CACZ,qGAAqG,CACtG,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAEnE,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAoB;IACvD,IAAI,KAAK,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,OAAO,CACZ,qGAAqG,CACtG,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAEjE,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export-spec.d.ts","sourceRoot":"","sources":["../../src/tools/export-spec.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"export-spec.d.ts","sourceRoot":"","sources":["../../src/tools/export-spec.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAqDrE,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CA0InF"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
// tools/export-spec.ts — MCP tool handler for export_spec (SPEC-097)
|
|
1
|
+
// tools/export-spec.ts — MCP tool handler for export_spec (SPEC-097, SPEC-318)
|
|
2
2
|
import { readFile, mkdir, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { join, resolve, relative } from 'node:path';
|
|
4
4
|
import { specStore, knowledgeStore } from '../storage/index.js';
|
|
5
5
|
import { hashProjectPath } from '../storage/base-store.js';
|
|
6
6
|
import { exportToSpecKit } from '../engine/spec-kit-exporter.js';
|
|
7
7
|
import { stripFrontmatter } from '../engine/frontmatter-parser.js';
|
|
8
|
+
import { specToAgentReady, serializeAgentReady } from '../engine/agent-ready-exporter.js';
|
|
8
9
|
async function readFileContent(filePath) {
|
|
9
10
|
try {
|
|
10
11
|
const raw = await readFile(filePath, 'utf-8');
|
|
@@ -56,6 +57,46 @@ export async function handleExportSpec(params) {
|
|
|
56
57
|
isError: true,
|
|
57
58
|
};
|
|
58
59
|
}
|
|
60
|
+
// Agent-ready format — no disk reads needed, derives from structured spec metadata
|
|
61
|
+
if (params.format === 'agent-ready') {
|
|
62
|
+
const target = params.agentTarget ?? 'generic';
|
|
63
|
+
const agentSpec = specToAgentReady(spec, target);
|
|
64
|
+
const content = serializeAgentReady(agentSpec, target);
|
|
65
|
+
let filePath;
|
|
66
|
+
if (params.outputDir) {
|
|
67
|
+
const resolvedOutput = resolve(params.outputDir);
|
|
68
|
+
const resolvedProject = resolve(params.projectPath);
|
|
69
|
+
const rel = relative(resolvedProject, resolvedOutput);
|
|
70
|
+
if (rel.startsWith('..') || rel.startsWith('/')) {
|
|
71
|
+
return {
|
|
72
|
+
content: [
|
|
73
|
+
{
|
|
74
|
+
type: 'text',
|
|
75
|
+
text: `Invalid outputDir: path escapes the project directory. Resolved to "${resolvedOutput}".`,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
isError: true,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
await mkdir(resolvedOutput, { recursive: true });
|
|
82
|
+
filePath = join(resolvedOutput, `${params.specId.toLowerCase()}-agent-ready.json`);
|
|
83
|
+
await writeFile(filePath, content, 'utf-8');
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
content: [
|
|
87
|
+
{
|
|
88
|
+
type: 'text',
|
|
89
|
+
text: JSON.stringify({
|
|
90
|
+
message: `Exported ${params.specId} to agent-ready format (${target})`,
|
|
91
|
+
format: 'agent-ready',
|
|
92
|
+
agentTarget: target,
|
|
93
|
+
filePath,
|
|
94
|
+
content,
|
|
95
|
+
}, null, 2),
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
59
100
|
// Read spec content from disk
|
|
60
101
|
const specContent = await readFileContent(spec.specPath);
|
|
61
102
|
if (!specContent) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export-spec.js","sourceRoot":"","sources":["../../src/tools/export-spec.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"export-spec.js","sourceRoot":"","sources":["../../src/tools/export-spec.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGpD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAE1F,KAAK,UAAU,eAAe,CAAC,QAAgB;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,KAAa;IAC3B,OAAO,KAAK;SACT,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,eAAe,CAAC,WAAmB;IAC1C,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,UAAU,GAAG,IAAI,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,UAAU,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxE,kEAAkE;YAClE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC1F,UAAU,GAAG,KAAK,CAAC;gBACnB,SAAS;YACX,CAAC;QACH,CAAC;QACD,IAAI,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACzC,WAAW,GAAG,CAAC,WAAW,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,IAAI,UAAU,IAAI,WAAW,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YAC7C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAuB;IAC5D,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAEtD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/D,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,CAAC,MAAM,cAAc,EAAE,CAAC;YACvE,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,mFAAmF;IACnF,IAAI,MAAM,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;QACpC,MAAM,MAAM,GAAiB,MAAM,CAAC,WAAuC,IAAI,SAAS,CAAC;QACzF,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAEvD,IAAI,QAA4B,CAAC;QACjC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACjD,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;YACtD,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChD,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,uEAAuE,cAAc,IAAI;yBAChG;qBACF;oBACD,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACjD,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;YACnF,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,OAAO,EAAE,YAAY,MAAM,CAAC,MAAM,2BAA2B,MAAM,GAAG;wBACtE,MAAM,EAAE,aAAa;wBACrB,WAAW,EAAE,MAAM;wBACnB,QAAQ;wBACR,OAAO;qBACR,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAED,8BAA8B;IAC9B,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,6BAA6B,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;YACjF,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,kCAAkC;IAClC,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa;QACzC,CAAC,CAAC,MAAM,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC;QAC3C,CAAC,CAAC,SAAS,CAAC;IAEd,6BAA6B;IAC7B,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IACrE,MAAM,eAAe,GAAG,YAAY;QAClC,CAAC,CAAC,YAAY,CAAC,UAAU;aACpB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,QAAQ,OAAO,CAAC,CAAC,YAAY,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC;aACrE,IAAI,CAAC,IAAI,CAAC;QACf,CAAC,CAAC,SAAS,CAAC;IAEd,sCAAsC;IACtC,MAAM,QAAQ,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAE9C,2BAA2B;IAC3B,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,WAAW,EAAE;QAChD,gBAAgB;QAChB,YAAY,EAAE,eAAe;QAC7B,QAAQ,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;KACrD,CAAC,CAAC;IAEH,4BAA4B;IAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAEzF,MAAM,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;IACtD,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAChD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,uEAAuE,cAAc,IAAI;iBAChG;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAEhD,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;QAC7C,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;QAC7C,SAAS,CAAC,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;KAChD,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,OAAO,EAAE,YAAY,MAAM,CAAC,MAAM,qBAAqB;oBACvD,MAAM,EAAE,UAAU;oBAClB,SAAS;oBACT,KAAK,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,WAAW,CAAC;iBAC7C,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Spec, ProjectKnowledge, TestFile } from '../../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build a TestFile for property-based tests of the given spec.
|
|
4
|
+
* The file content is generated by the engine layer.
|
|
5
|
+
*
|
|
6
|
+
* @param criteria - Acceptance criteria strings from spec.md (optional).
|
|
7
|
+
* When provided, the generator will extract property-based tests from them.
|
|
8
|
+
* When omitted, a placeholder file is generated with instructions.
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildPropertyBasedTestFile(spec: Spec, knowledge: ProjectKnowledge, testDir: string, autoGenerate: boolean, criteria?: string[]): TestFile;
|
|
11
|
+
//# sourceMappingURL=property-based-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"property-based-generator.d.ts","sourceRoot":"","sources":["../../../../src/tools/generate-tests/generators/property-based-generator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGhF;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,gBAAgB,EAC3B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,OAAO,EACrB,QAAQ,GAAE,MAAM,EAAO,GACtB,QAAQ,CAgBV"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// tools/generate-tests/generators/property-based-generator.ts — SPEC-315
|
|
2
|
+
// Adapter: bridges spec-dispatcher with the engine property-based generator.
|
|
3
|
+
import { generatePropertyBasedTests } from '../../../engine/generate-tests/generators/property-based-generator.js';
|
|
4
|
+
/**
|
|
5
|
+
* Build a TestFile for property-based tests of the given spec.
|
|
6
|
+
* The file content is generated by the engine layer.
|
|
7
|
+
*
|
|
8
|
+
* @param criteria - Acceptance criteria strings from spec.md (optional).
|
|
9
|
+
* When provided, the generator will extract property-based tests from them.
|
|
10
|
+
* When omitted, a placeholder file is generated with instructions.
|
|
11
|
+
*/
|
|
12
|
+
export function buildPropertyBasedTestFile(spec, knowledge, testDir, autoGenerate, criteria = []) {
|
|
13
|
+
const slug = spec.id.toLowerCase().replace(/[^a-z0-9]/g, '-');
|
|
14
|
+
const ext = knowledge.language === 'python' ? 'py' : 'ts';
|
|
15
|
+
const framework = knowledge.language === 'python'
|
|
16
|
+
? 'hypothesis'
|
|
17
|
+
: knowledge.language === 'java' || knowledge.language === 'kotlin'
|
|
18
|
+
? 'jqwik'
|
|
19
|
+
: 'fast-check';
|
|
20
|
+
return {
|
|
21
|
+
path: `${testDir}/property/${slug}.property.${ext}`,
|
|
22
|
+
framework,
|
|
23
|
+
content: generatePropertyBasedTests(spec, knowledge, criteria),
|
|
24
|
+
ready: autoGenerate,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=property-based-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"property-based-generator.js","sourceRoot":"","sources":["../../../../src/tools/generate-tests/generators/property-based-generator.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,6EAA6E;AAG7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,uEAAuE,CAAC;AAEnH;;;;;;;GAOG;AACH,MAAM,UAAU,0BAA0B,CACxC,IAAU,EACV,SAA2B,EAC3B,OAAe,EACf,YAAqB,EACrB,WAAqB,EAAE;IAEvB,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,MAAM,SAAS,GACb,SAAS,CAAC,QAAQ,KAAK,QAAQ;QAC7B,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,SAAS,CAAC,QAAQ,KAAK,MAAM,IAAI,SAAS,CAAC,QAAQ,KAAK,QAAQ;YAChE,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,YAAY,CAAC;IAErB,OAAO;QACL,IAAI,EAAE,GAAG,OAAO,aAAa,IAAI,aAAa,GAAG,EAAE;QACnD,SAAS;QACT,OAAO,EAAE,0BAA0B,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC;QAC9D,KAAK,EAAE,YAAY;KACpB,CAAC;AACJ,CAAC"}
|
|
@@ -3,6 +3,9 @@ import type { Spec, ProjectKnowledge, TestDefinition, TestFile } from '../../typ
|
|
|
3
3
|
* Runs all spec-specific test generation dispatchers.
|
|
4
4
|
* Mutates unitTests, integrationTests, testFiles in-place.
|
|
5
5
|
* Returns { isApiSpec } for use in output formatting.
|
|
6
|
+
*
|
|
7
|
+
* When strategy='property-based', skips domain dispatchers and generates
|
|
8
|
+
* property tests derived from acceptance criteria invariants.
|
|
6
9
|
*/
|
|
7
10
|
export declare function runSpecializedGenerators(args: {
|
|
8
11
|
spec: Spec;
|
|
@@ -12,6 +15,8 @@ export declare function runSpecializedGenerators(args: {
|
|
|
12
15
|
slug: string;
|
|
13
16
|
autoGenerate: boolean;
|
|
14
17
|
testExt: string;
|
|
18
|
+
/** Optional generation strategy. 'property-based' triggers invariant extraction. */
|
|
19
|
+
strategy?: string;
|
|
15
20
|
}, unitTests: TestDefinition[], integrationTests: TestDefinition[], testFiles: TestFile[]): {
|
|
16
21
|
isApiSpec: boolean;
|
|
17
22
|
};
|