@contractspec/bundle.workspace 1.45.3 → 1.45.5

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.
Files changed (54) hide show
  1. package/dist/adapters/fs.d.ts +2 -1
  2. package/dist/adapters/fs.d.ts.map +1 -1
  3. package/dist/adapters/fs.js +1 -1
  4. package/dist/adapters/fs.js.map +1 -1
  5. package/dist/adapters/git.js +29 -0
  6. package/dist/adapters/git.js.map +1 -1
  7. package/dist/adapters/index.d.ts +1 -1
  8. package/dist/adapters/index.js +1 -1
  9. package/dist/index.d.ts +10 -7
  10. package/dist/index.js +4 -2
  11. package/dist/ports/git.d.ts +14 -1
  12. package/dist/ports/git.d.ts.map +1 -1
  13. package/dist/ports/index.d.ts +1 -1
  14. package/dist/services/doctor/checks/config.js +132 -0
  15. package/dist/services/doctor/checks/config.js.map +1 -1
  16. package/dist/services/hooks/hooks-service.d.ts +24 -0
  17. package/dist/services/hooks/hooks-service.d.ts.map +1 -0
  18. package/dist/services/hooks/hooks-service.js +126 -0
  19. package/dist/services/hooks/hooks-service.js.map +1 -0
  20. package/dist/services/hooks/index.d.ts +10 -0
  21. package/dist/services/hooks/index.d.ts.map +1 -0
  22. package/dist/services/hooks/index.js +12 -0
  23. package/dist/services/hooks/index.js.map +1 -0
  24. package/dist/services/hooks/types.d.ts +56 -0
  25. package/dist/services/hooks/types.d.ts.map +1 -0
  26. package/dist/services/index.d.ts +4 -1
  27. package/dist/services/index.js +2 -0
  28. package/dist/services/setup/config-generators.d.ts.map +1 -1
  29. package/dist/services/setup/config-generators.js +14 -0
  30. package/dist/services/setup/config-generators.js.map +1 -1
  31. package/dist/services/upgrade/index.d.ts +10 -0
  32. package/dist/services/upgrade/index.d.ts.map +1 -0
  33. package/dist/services/upgrade/index.js +15 -0
  34. package/dist/services/upgrade/index.js.map +1 -0
  35. package/dist/services/upgrade/types.d.ts +78 -0
  36. package/dist/services/upgrade/types.d.ts.map +1 -0
  37. package/dist/services/upgrade/upgrade-service.d.ts +38 -0
  38. package/dist/services/upgrade/upgrade-service.d.ts.map +1 -0
  39. package/dist/services/upgrade/upgrade-service.js +201 -0
  40. package/dist/services/upgrade/upgrade-service.js.map +1 -0
  41. package/dist/services/versioning/conventional-commits.d.ts +95 -0
  42. package/dist/services/versioning/conventional-commits.d.ts.map +1 -0
  43. package/dist/services/versioning/conventional-commits.js +184 -0
  44. package/dist/services/versioning/conventional-commits.js.map +1 -0
  45. package/dist/services/versioning/index.d.ts +4 -3
  46. package/dist/services/versioning/index.js +13 -2
  47. package/dist/services/versioning/index.js.map +1 -1
  48. package/dist/services/versioning/types.d.ts +9 -7
  49. package/dist/services/versioning/types.d.ts.map +1 -1
  50. package/dist/services/versioning/versioning-service.d.ts +43 -1
  51. package/dist/services/versioning/versioning-service.d.ts.map +1 -1
  52. package/dist/services/versioning/versioning-service.js +144 -2
  53. package/dist/services/versioning/versioning-service.js.map +1 -1
  54. package/package.json +7 -7
@@ -2,10 +2,11 @@ import { FsAdapter } from "../ports/fs.js";
2
2
 
3
3
  //#region src/adapters/fs.d.ts
4
4
 
5
+ declare const DEFAULT_SPEC_PATTERNS: string[];
5
6
  /**
6
7
  * Create a Node.js filesystem adapter.
7
8
  */
8
9
  declare function createNodeFsAdapter(cwd?: string): FsAdapter;
9
10
  //#endregion
10
- export { createNodeFsAdapter };
11
+ export { DEFAULT_SPEC_PATTERNS, createNodeFsAdapter };
11
12
  //# sourceMappingURL=fs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fs.d.ts","names":[],"sources":["../../src/adapters/fs.ts"],"sourcesContent":[],"mappings":";;;;;;;iBA2EgB,mBAAA,gBAAmC"}
1
+ {"version":3,"file":"fs.d.ts","names":[],"sources":["../../src/adapters/fs.ts"],"sourcesContent":[],"mappings":";;;;AA2EgB,cApDH,qBAoDsC,EAAA,MAAS,EAAA;;;;iBAA5C,mBAAA,gBAAmC"}
@@ -127,5 +127,5 @@ function createNodeFsAdapter(cwd) {
127
127
  }
128
128
 
129
129
  //#endregion
130
- export { createNodeFsAdapter };
130
+ export { DEFAULT_SPEC_PATTERNS, createNodeFsAdapter };
131
131
  //# sourceMappingURL=fs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fs.js","names":["fsStat","all: string[]","globFn"],"sources":["../../src/adapters/fs.ts"],"sourcesContent":["/**\n * Node.js filesystem adapter implementation.\n */\n\nimport {\n access,\n mkdir,\n readFile,\n rm,\n stat as fsStat,\n writeFile,\n} from 'node:fs/promises';\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n relative,\n resolve,\n} from 'node:path';\nimport { glob as globFn } from 'glob';\nimport type { DiscoverOptions, FileStat, FsAdapter } from '../ports/fs';\n\nconst DEFAULT_SPEC_PATTERNS = [\n // Standard dot-prefixed naming convention\n '**/*.operation.ts',\n '**/*.operations.ts',\n '**/*.event.ts',\n '**/*.presentation.ts',\n '**/*.feature.ts',\n '**/*.capability.ts',\n '**/*.workflow.ts',\n '**/*.data-view.ts',\n '**/*.form.ts',\n '**/*.migration.ts',\n '**/*.telemetry.ts',\n '**/*.experiment.ts',\n '**/*.app-config.ts',\n '**/*.integration.ts',\n '**/*.knowledge.ts',\n '**/*.policy.ts',\n '**/*.test-spec.ts',\n // Directory-based patterns (contracts/ and operations/ directories)\n '**/contracts/*.ts',\n '**/contracts/index.ts',\n '**/operations/*.ts',\n '**/operations/index.ts',\n // Standalone file patterns (events.ts, presentations.ts)\n '**/operations.ts',\n '**/events.ts',\n '**/presentations.ts',\n // Directory index patterns (/events/index.ts, /presentations/index.ts)\n '**/events/index.ts',\n '**/presentations/index.ts',\n];\n\nconst DEFAULT_IGNORES = [\n '**/node_modules/**',\n '**/dist/**',\n '**/.turbo/**',\n '**/.next/**',\n '**/build/**',\n '**/coverage/**',\n '**/*.d.ts',\n // Code generators and transformers (not actual specs)\n '**/importer/**',\n '**/exporter/**',\n // Documentation blocks (treated separately)\n '**/docs/**/*.docblock.ts',\n '**/docs/presentations.ts',\n];\n\n/**\n * Create a Node.js filesystem adapter.\n */\nexport function createNodeFsAdapter(cwd?: string): FsAdapter {\n const baseCwd = cwd ?? process.cwd();\n\n return {\n async exists(path: string): Promise<boolean> {\n try {\n await access(resolvePath(path));\n return true;\n } catch {\n return false;\n }\n },\n\n async readFile(path: string): Promise<string> {\n return readFile(resolvePath(path), 'utf-8');\n },\n\n async writeFile(path: string, content: string): Promise<void> {\n const fullPath = resolvePath(path);\n const dir = dirname(fullPath);\n await mkdir(dir, { recursive: true });\n await writeFile(fullPath, content, 'utf-8');\n },\n\n async remove(path: string): Promise<void> {\n await rm(resolvePath(path), { recursive: true, force: true });\n },\n\n async stat(path: string): Promise<FileStat> {\n const stats = await fsStat(resolvePath(path));\n return {\n size: stats.size,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n mtime: stats.mtime,\n };\n },\n\n async mkdir(path: string): Promise<void> {\n await mkdir(resolvePath(path), { recursive: true });\n },\n\n async glob(options: DiscoverOptions): Promise<string[]> {\n const patterns =\n options.patterns ??\n (options.pattern ? [options.pattern] : DEFAULT_SPEC_PATTERNS);\n const ignore = options.ignore ?? DEFAULT_IGNORES;\n // Use provided cwd or fall back to adapter's baseCwd\n const globCwd = options.cwd ?? baseCwd;\n // Default to absolute paths for safer file operations\n const absolute = options.absolute ?? true;\n\n const all: string[] = [];\n for (const pattern of patterns) {\n const matches = await globFn(pattern, {\n cwd: globCwd,\n ignore,\n absolute,\n });\n all.push(...matches);\n }\n\n return Array.from(new Set(all)).sort((a, b) => a.localeCompare(b));\n },\n\n resolve(...paths: string[]): string {\n const [first, ...rest] = paths;\n if (!first) return baseCwd;\n return resolve(baseCwd, first, ...rest);\n },\n\n dirname(path: string): string {\n return dirname(path);\n },\n\n basename(path: string): string {\n return basename(path);\n },\n\n join(...paths: string[]): string {\n return join(...paths);\n },\n\n relative(from: string, to: string): string {\n return relative(from, to);\n },\n };\n\n function resolvePath(path: string): string {\n return isAbsolute(path) ? path : resolve(baseCwd, path);\n }\n}\n"],"mappings":";;;;;;;;AAuBA,MAAM,wBAAwB;CAE5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CAEA;CACA;CACA;CAEA;CACA;CACD;AAED,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CAEA;CACA;CACD;;;;AAKD,SAAgB,oBAAoB,KAAyB;CAC3D,MAAM,UAAU,OAAO,QAAQ,KAAK;AAEpC,QAAO;EACL,MAAM,OAAO,MAAgC;AAC3C,OAAI;AACF,UAAM,OAAO,YAAY,KAAK,CAAC;AAC/B,WAAO;WACD;AACN,WAAO;;;EAIX,MAAM,SAAS,MAA+B;AAC5C,UAAO,SAAS,YAAY,KAAK,EAAE,QAAQ;;EAG7C,MAAM,UAAU,MAAc,SAAgC;GAC5D,MAAM,WAAW,YAAY,KAAK;AAElC,SAAM,MADM,QAAQ,SAAS,EACZ,EAAE,WAAW,MAAM,CAAC;AACrC,SAAM,UAAU,UAAU,SAAS,QAAQ;;EAG7C,MAAM,OAAO,MAA6B;AACxC,SAAM,GAAG,YAAY,KAAK,EAAE;IAAE,WAAW;IAAM,OAAO;IAAM,CAAC;;EAG/D,MAAM,KAAK,MAAiC;GAC1C,MAAM,QAAQ,MAAMA,KAAO,YAAY,KAAK,CAAC;AAC7C,UAAO;IACL,MAAM,MAAM;IACZ,QAAQ,MAAM,QAAQ;IACtB,aAAa,MAAM,aAAa;IAChC,OAAO,MAAM;IACd;;EAGH,MAAM,MAAM,MAA6B;AACvC,SAAM,MAAM,YAAY,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;;EAGrD,MAAM,KAAK,SAA6C;GACtD,MAAM,WACJ,QAAQ,aACP,QAAQ,UAAU,CAAC,QAAQ,QAAQ,GAAG;GACzC,MAAM,SAAS,QAAQ,UAAU;GAEjC,MAAM,UAAU,QAAQ,OAAO;GAE/B,MAAM,WAAW,QAAQ,YAAY;GAErC,MAAMC,MAAgB,EAAE;AACxB,QAAK,MAAM,WAAW,UAAU;IAC9B,MAAM,UAAU,MAAMC,KAAO,SAAS;KACpC,KAAK;KACL;KACA;KACD,CAAC;AACF,QAAI,KAAK,GAAG,QAAQ;;AAGtB,UAAO,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,CAAC;;EAGpE,QAAQ,GAAG,OAAyB;GAClC,MAAM,CAAC,OAAO,GAAG,QAAQ;AACzB,OAAI,CAAC,MAAO,QAAO;AACnB,UAAO,QAAQ,SAAS,OAAO,GAAG,KAAK;;EAGzC,QAAQ,MAAsB;AAC5B,UAAO,QAAQ,KAAK;;EAGtB,SAAS,MAAsB;AAC7B,UAAO,SAAS,KAAK;;EAGvB,KAAK,GAAG,OAAyB;AAC/B,UAAO,KAAK,GAAG,MAAM;;EAGvB,SAAS,MAAc,IAAoB;AACzC,UAAO,SAAS,MAAM,GAAG;;EAE5B;CAED,SAAS,YAAY,MAAsB;AACzC,SAAO,WAAW,KAAK,GAAG,OAAO,QAAQ,SAAS,KAAK"}
1
+ {"version":3,"file":"fs.js","names":["fsStat","all: string[]","globFn"],"sources":["../../src/adapters/fs.ts"],"sourcesContent":["/**\n * Node.js filesystem adapter implementation.\n */\n\nimport {\n access,\n mkdir,\n readFile,\n rm,\n stat as fsStat,\n writeFile,\n} from 'node:fs/promises';\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n relative,\n resolve,\n} from 'node:path';\nimport { glob as globFn } from 'glob';\nimport type { DiscoverOptions, FileStat, FsAdapter } from '../ports/fs';\n\nexport const DEFAULT_SPEC_PATTERNS = [\n // Standard dot-prefixed naming convention\n '**/*.operation.ts',\n '**/*.operations.ts',\n '**/*.event.ts',\n '**/*.presentation.ts',\n '**/*.feature.ts',\n '**/*.capability.ts',\n '**/*.workflow.ts',\n '**/*.data-view.ts',\n '**/*.form.ts',\n '**/*.migration.ts',\n '**/*.telemetry.ts',\n '**/*.experiment.ts',\n '**/*.app-config.ts',\n '**/*.integration.ts',\n '**/*.knowledge.ts',\n '**/*.policy.ts',\n '**/*.test-spec.ts',\n // Directory-based patterns (contracts/ and operations/ directories)\n '**/contracts/*.ts',\n '**/contracts/index.ts',\n '**/operations/*.ts',\n '**/operations/index.ts',\n // Standalone file patterns (events.ts, presentations.ts)\n '**/operations.ts',\n '**/events.ts',\n '**/presentations.ts',\n // Directory index patterns (/events/index.ts, /presentations/index.ts)\n '**/events/index.ts',\n '**/presentations/index.ts',\n];\n\nconst DEFAULT_IGNORES = [\n '**/node_modules/**',\n '**/dist/**',\n '**/.turbo/**',\n '**/.next/**',\n '**/build/**',\n '**/coverage/**',\n '**/*.d.ts',\n // Code generators and transformers (not actual specs)\n '**/importer/**',\n '**/exporter/**',\n // Documentation blocks (treated separately)\n '**/docs/**/*.docblock.ts',\n '**/docs/presentations.ts',\n];\n\n/**\n * Create a Node.js filesystem adapter.\n */\nexport function createNodeFsAdapter(cwd?: string): FsAdapter {\n const baseCwd = cwd ?? process.cwd();\n\n return {\n async exists(path: string): Promise<boolean> {\n try {\n await access(resolvePath(path));\n return true;\n } catch {\n return false;\n }\n },\n\n async readFile(path: string): Promise<string> {\n return readFile(resolvePath(path), 'utf-8');\n },\n\n async writeFile(path: string, content: string): Promise<void> {\n const fullPath = resolvePath(path);\n const dir = dirname(fullPath);\n await mkdir(dir, { recursive: true });\n await writeFile(fullPath, content, 'utf-8');\n },\n\n async remove(path: string): Promise<void> {\n await rm(resolvePath(path), { recursive: true, force: true });\n },\n\n async stat(path: string): Promise<FileStat> {\n const stats = await fsStat(resolvePath(path));\n return {\n size: stats.size,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n mtime: stats.mtime,\n };\n },\n\n async mkdir(path: string): Promise<void> {\n await mkdir(resolvePath(path), { recursive: true });\n },\n\n async glob(options: DiscoverOptions): Promise<string[]> {\n const patterns =\n options.patterns ??\n (options.pattern ? [options.pattern] : DEFAULT_SPEC_PATTERNS);\n const ignore = options.ignore ?? DEFAULT_IGNORES;\n // Use provided cwd or fall back to adapter's baseCwd\n const globCwd = options.cwd ?? baseCwd;\n // Default to absolute paths for safer file operations\n const absolute = options.absolute ?? true;\n\n const all: string[] = [];\n for (const pattern of patterns) {\n const matches = await globFn(pattern, {\n cwd: globCwd,\n ignore,\n absolute,\n });\n all.push(...matches);\n }\n\n return Array.from(new Set(all)).sort((a, b) => a.localeCompare(b));\n },\n\n resolve(...paths: string[]): string {\n const [first, ...rest] = paths;\n if (!first) return baseCwd;\n return resolve(baseCwd, first, ...rest);\n },\n\n dirname(path: string): string {\n return dirname(path);\n },\n\n basename(path: string): string {\n return basename(path);\n },\n\n join(...paths: string[]): string {\n return join(...paths);\n },\n\n relative(from: string, to: string): string {\n return relative(from, to);\n },\n };\n\n function resolvePath(path: string): string {\n return isAbsolute(path) ? path : resolve(baseCwd, path);\n }\n}\n"],"mappings":";;;;;;;;AAuBA,MAAa,wBAAwB;CAEnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CAEA;CACA;CACA;CAEA;CACA;CACD;AAED,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CAEA;CACA;CACD;;;;AAKD,SAAgB,oBAAoB,KAAyB;CAC3D,MAAM,UAAU,OAAO,QAAQ,KAAK;AAEpC,QAAO;EACL,MAAM,OAAO,MAAgC;AAC3C,OAAI;AACF,UAAM,OAAO,YAAY,KAAK,CAAC;AAC/B,WAAO;WACD;AACN,WAAO;;;EAIX,MAAM,SAAS,MAA+B;AAC5C,UAAO,SAAS,YAAY,KAAK,EAAE,QAAQ;;EAG7C,MAAM,UAAU,MAAc,SAAgC;GAC5D,MAAM,WAAW,YAAY,KAAK;AAElC,SAAM,MADM,QAAQ,SAAS,EACZ,EAAE,WAAW,MAAM,CAAC;AACrC,SAAM,UAAU,UAAU,SAAS,QAAQ;;EAG7C,MAAM,OAAO,MAA6B;AACxC,SAAM,GAAG,YAAY,KAAK,EAAE;IAAE,WAAW;IAAM,OAAO;IAAM,CAAC;;EAG/D,MAAM,KAAK,MAAiC;GAC1C,MAAM,QAAQ,MAAMA,KAAO,YAAY,KAAK,CAAC;AAC7C,UAAO;IACL,MAAM,MAAM;IACZ,QAAQ,MAAM,QAAQ;IACtB,aAAa,MAAM,aAAa;IAChC,OAAO,MAAM;IACd;;EAGH,MAAM,MAAM,MAA6B;AACvC,SAAM,MAAM,YAAY,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;;EAGrD,MAAM,KAAK,SAA6C;GACtD,MAAM,WACJ,QAAQ,aACP,QAAQ,UAAU,CAAC,QAAQ,QAAQ,GAAG;GACzC,MAAM,SAAS,QAAQ,UAAU;GAEjC,MAAM,UAAU,QAAQ,OAAO;GAE/B,MAAM,WAAW,QAAQ,YAAY;GAErC,MAAMC,MAAgB,EAAE;AACxB,QAAK,MAAM,WAAW,UAAU;IAC9B,MAAM,UAAU,MAAMC,KAAO,SAAS;KACpC,KAAK;KACL;KACA;KACD,CAAC;AACF,QAAI,KAAK,GAAG,QAAQ;;AAGtB,UAAO,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,cAAc,EAAE,CAAC;;EAGpE,QAAQ,GAAG,OAAyB;GAClC,MAAM,CAAC,OAAO,GAAG,QAAQ;AACzB,OAAI,CAAC,MAAO,QAAO;AACnB,UAAO,QAAQ,SAAS,OAAO,GAAG,KAAK;;EAGzC,QAAQ,MAAsB;AAC5B,UAAO,QAAQ,KAAK;;EAGtB,SAAS,MAAsB;AAC7B,UAAO,SAAS,KAAK;;EAGvB,KAAK,GAAG,OAAyB;AAC/B,UAAO,KAAK,GAAG,MAAM;;EAGvB,SAAS,MAAc,IAAoB;AACzC,UAAO,SAAS,MAAM,GAAG;;EAE5B;CAED,SAAS,YAAY,MAAsB;AACzC,SAAO,WAAW,KAAK,GAAG,OAAO,QAAQ,SAAS,KAAK"}
@@ -46,6 +46,35 @@ function createNodeGitAdapter(cwd) {
46
46
  } catch {
47
47
  return false;
48
48
  }
49
+ },
50
+ async log(baseline) {
51
+ const ref = baseline ?? "HEAD~10";
52
+ const format = "--format=%H|||%s|||%an|||%aI";
53
+ try {
54
+ const output = execSync(`git log ${ref}..HEAD ${format}`, {
55
+ cwd: baseCwd,
56
+ encoding: "utf-8",
57
+ stdio: [
58
+ "ignore",
59
+ "pipe",
60
+ "pipe"
61
+ ]
62
+ });
63
+ const entries = [];
64
+ for (const line of output.trim().split("\n")) {
65
+ if (!line) continue;
66
+ const [hash, message, author, date] = line.split("|||");
67
+ if (hash && message) entries.push({
68
+ hash,
69
+ message,
70
+ author,
71
+ date
72
+ });
73
+ }
74
+ return entries;
75
+ } catch {
76
+ return [];
77
+ }
49
78
  }
50
79
  };
51
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"git.js","names":["flags: string[]"],"sources":["../../src/adapters/git.ts"],"sourcesContent":["/**\n * Node.js git adapter implementation.\n */\n\nimport { execSync } from 'node:child_process';\nimport { access } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport type { GitAdapter, GitCleanOptions } from '../ports/git';\n\n/**\n * Create a Node.js git adapter.\n */\nexport function createNodeGitAdapter(cwd?: string): GitAdapter {\n const baseCwd = cwd ?? process.cwd();\n\n return {\n async showFile(ref: string, filePath: string): Promise<string> {\n try {\n return execSync(`git show ${ref}:${filePath}`, {\n cwd: baseCwd,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n } catch (error) {\n throw new Error(\n `Could not load ${filePath} at ref ${ref}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n async clean(options?: GitCleanOptions): Promise<void> {\n const flags: string[] = [];\n if (options?.force) flags.push('-f');\n if (options?.directories) flags.push('-d');\n if (options?.ignored) flags.push('-x');\n if (options?.dryRun) flags.push('--dry-run');\n\n execSync(`git clean ${flags.join(' ')}`, {\n cwd: baseCwd,\n stdio: 'inherit',\n });\n },\n\n async isGitRepo(path?: string): Promise<boolean> {\n const targetPath = path ? resolve(baseCwd, path) : baseCwd;\n try {\n await access(resolve(targetPath, '.git'));\n return true;\n } catch {\n return false;\n }\n },\n };\n}\n"],"mappings":";;;;;;;;;;;AAYA,SAAgB,qBAAqB,KAA0B;CAC7D,MAAM,UAAU,OAAO,QAAQ,KAAK;AAEpC,QAAO;EACL,MAAM,SAAS,KAAa,UAAmC;AAC7D,OAAI;AACF,WAAO,SAAS,YAAY,IAAI,GAAG,YAAY;KAC7C,KAAK;KACL,UAAU;KACV,OAAO;MAAC;MAAU;MAAQ;MAAO;KAClC,CAAC;YACK,OAAO;AACd,UAAM,IAAI,MACR,kBAAkB,SAAS,UAAU,IAAI,IACvC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GAEzD;;;EAIL,MAAM,MAAM,SAA0C;GACpD,MAAMA,QAAkB,EAAE;AAC1B,OAAI,SAAS,MAAO,OAAM,KAAK,KAAK;AACpC,OAAI,SAAS,YAAa,OAAM,KAAK,KAAK;AAC1C,OAAI,SAAS,QAAS,OAAM,KAAK,KAAK;AACtC,OAAI,SAAS,OAAQ,OAAM,KAAK,YAAY;AAE5C,YAAS,aAAa,MAAM,KAAK,IAAI,IAAI;IACvC,KAAK;IACL,OAAO;IACR,CAAC;;EAGJ,MAAM,UAAU,MAAiC;GAC/C,MAAM,aAAa,OAAO,QAAQ,SAAS,KAAK,GAAG;AACnD,OAAI;AACF,UAAM,OAAO,QAAQ,YAAY,OAAO,CAAC;AACzC,WAAO;WACD;AACN,WAAO;;;EAGZ"}
1
+ {"version":3,"file":"git.js","names":["flags: string[]","entries: GitLogEntry[]"],"sources":["../../src/adapters/git.ts"],"sourcesContent":["/**\n * Node.js git adapter implementation.\n */\n\nimport { execSync } from 'node:child_process';\nimport { access } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport type { GitAdapter, GitCleanOptions, GitLogEntry } from '../ports/git';\n\n/**\n * Create a Node.js git adapter.\n */\nexport function createNodeGitAdapter(cwd?: string): GitAdapter {\n const baseCwd = cwd ?? process.cwd();\n\n return {\n async showFile(ref: string, filePath: string): Promise<string> {\n try {\n return execSync(`git show ${ref}:${filePath}`, {\n cwd: baseCwd,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n } catch (error) {\n throw new Error(\n `Could not load ${filePath} at ref ${ref}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n async clean(options?: GitCleanOptions): Promise<void> {\n const flags: string[] = [];\n if (options?.force) flags.push('-f');\n if (options?.directories) flags.push('-d');\n if (options?.ignored) flags.push('-x');\n if (options?.dryRun) flags.push('--dry-run');\n\n execSync(`git clean ${flags.join(' ')}`, {\n cwd: baseCwd,\n stdio: 'inherit',\n });\n },\n\n async isGitRepo(path?: string): Promise<boolean> {\n const targetPath = path ? resolve(baseCwd, path) : baseCwd;\n try {\n await access(resolve(targetPath, '.git'));\n return true;\n } catch {\n return false;\n }\n },\n\n async log(baseline?: string): Promise<GitLogEntry[]> {\n const ref = baseline ?? 'HEAD~10';\n const format = '--format=%H|||%s|||%an|||%aI';\n\n try {\n const output = execSync(`git log ${ref}..HEAD ${format}`, {\n cwd: baseCwd,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n const entries: GitLogEntry[] = [];\n\n for (const line of output.trim().split('\\n')) {\n if (!line) continue;\n const [hash, message, author, date] = line.split('|||');\n if (hash && message) {\n entries.push({ hash, message, author, date });\n }\n }\n\n return entries;\n } catch {\n // Return empty if git log fails (e.g., not enough commits)\n return [];\n }\n },\n };\n}\n"],"mappings":";;;;;;;;;;;AAYA,SAAgB,qBAAqB,KAA0B;CAC7D,MAAM,UAAU,OAAO,QAAQ,KAAK;AAEpC,QAAO;EACL,MAAM,SAAS,KAAa,UAAmC;AAC7D,OAAI;AACF,WAAO,SAAS,YAAY,IAAI,GAAG,YAAY;KAC7C,KAAK;KACL,UAAU;KACV,OAAO;MAAC;MAAU;MAAQ;MAAO;KAClC,CAAC;YACK,OAAO;AACd,UAAM,IAAI,MACR,kBAAkB,SAAS,UAAU,IAAI,IACvC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GAEzD;;;EAIL,MAAM,MAAM,SAA0C;GACpD,MAAMA,QAAkB,EAAE;AAC1B,OAAI,SAAS,MAAO,OAAM,KAAK,KAAK;AACpC,OAAI,SAAS,YAAa,OAAM,KAAK,KAAK;AAC1C,OAAI,SAAS,QAAS,OAAM,KAAK,KAAK;AACtC,OAAI,SAAS,OAAQ,OAAM,KAAK,YAAY;AAE5C,YAAS,aAAa,MAAM,KAAK,IAAI,IAAI;IACvC,KAAK;IACL,OAAO;IACR,CAAC;;EAGJ,MAAM,UAAU,MAAiC;GAC/C,MAAM,aAAa,OAAO,QAAQ,SAAS,KAAK,GAAG;AACnD,OAAI;AACF,UAAM,OAAO,QAAQ,YAAY,OAAO,CAAC;AACzC,WAAO;WACD;AACN,WAAO;;;EAIX,MAAM,IAAI,UAA2C;GACnD,MAAM,MAAM,YAAY;GACxB,MAAM,SAAS;AAEf,OAAI;IACF,MAAM,SAAS,SAAS,WAAW,IAAI,SAAS,UAAU;KACxD,KAAK;KACL,UAAU;KACV,OAAO;MAAC;MAAU;MAAQ;MAAO;KAClC,CAAC;IAEF,MAAMC,UAAyB,EAAE;AAEjC,SAAK,MAAM,QAAQ,OAAO,MAAM,CAAC,MAAM,KAAK,EAAE;AAC5C,SAAI,CAAC,KAAM;KACX,MAAM,CAAC,MAAM,SAAS,QAAQ,QAAQ,KAAK,MAAM,MAAM;AACvD,SAAI,QAAQ,QACV,SAAQ,KAAK;MAAE;MAAM;MAAS;MAAQ;MAAM,CAAC;;AAIjD,WAAO;WACD;AAEN,WAAO,EAAE;;;EAGd"}
@@ -1,4 +1,4 @@
1
- import { createNodeFsAdapter } from "./fs.js";
1
+ import { DEFAULT_SPEC_PATTERNS, createNodeFsAdapter } from "./fs.js";
2
2
  import { createNodeGitAdapter } from "./git.js";
3
3
  import { createNodeWatcherAdapter } from "./watcher.js";
4
4
  import { createNodeAiAdapter } from "./ai.js";
@@ -1,4 +1,4 @@
1
- import { createNodeFsAdapter } from "./fs.js";
1
+ import { DEFAULT_SPEC_PATTERNS, createNodeFsAdapter } from "./fs.js";
2
2
  import { createNodeGitAdapter } from "./git.js";
3
3
  import { createNodeWatcherAdapter } from "./watcher.js";
4
4
  import { createNodeAiAdapter } from "./ai.js";
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { DiscoverOptions, FileStat, FsAdapter } from "./ports/fs.js";
2
- import { GitAdapter, GitCleanOptions } from "./ports/git.js";
2
+ import { GitAdapter, GitCleanOptions, GitLogEntry } from "./ports/git.js";
3
3
  import { WatchEvent, WatchEventHandler, WatchEventType, WatchOptions, Watcher, WatcherAdapter } from "./ports/watcher.js";
4
4
  import { AiAdapter, AiGenerateOptions, AiGenerateResult, AiGenerateStructuredOptions, AiValidationResult } from "./ports/ai.js";
5
5
  import { LogLevel, LoggerAdapter, ProgressReporter, ProgressUpdate, WorkspaceAdapters } from "./ports/logger.js";
6
6
  import "./ports/index.js";
7
- import { createNodeFsAdapter } from "./adapters/fs.js";
7
+ import { DEFAULT_SPEC_PATTERNS, createNodeFsAdapter } from "./adapters/fs.js";
8
8
  import { createNodeGitAdapter } from "./adapters/git.js";
9
9
  import { createNodeWatcherAdapter } from "./adapters/watcher.js";
10
10
  import { createNodeAiAdapter } from "./adapters/ai.js";
@@ -68,7 +68,7 @@ import { generateIntegrationSpec } from "./templates/integration.template.js";
68
68
  import { generateKnowledgeSpaceSpec } from "./templates/knowledge.template.js";
69
69
  import { generateComponentTemplate, generateHandlerTemplate, generateTestTemplate } from "./templates/handler.template.js";
70
70
  import { generateWorkflowRunnerTemplate } from "./templates/workflow-runner.template.js";
71
- import { index_d_exports as index_d_exports$3 } from "./templates/index.js";
71
+ import { index_d_exports as index_d_exports$4 } from "./templates/index.js";
72
72
  import { SpecCreatorService, createSpecCreator } from "./services/create/index.js";
73
73
  import { AIReviewResult, BehaviorCheck, FieldMapping, FieldMatchType, IntentAlignment, SemanticVerificationResult, StructureCheck, VerifyConfig, VerifyInput, VerifyOptions, VerifyResult } from "./services/verify/types.js";
74
74
  import { VerifyService, createVerifyService, verifyService } from "./services/verify/verify-service.js";
@@ -87,9 +87,12 @@ import { PackageInstallResult, QuickstartDependency, QuickstartMode, QuickstartO
87
87
  import { FULL_DEPENDENCIES, MINIMAL_DEPENDENCIES, getDependencies, getDevDependencies, getProductionDependencies } from "./services/quickstart/dependencies.js";
88
88
  import { formatQuickstartPreview, isContractSpecInstalled, runQuickstart } from "./services/quickstart/quickstart-service.js";
89
89
  import { DocsServiceOptions, DocsServiceResult, generateDocsFromSpecs } from "./services/docs/docs-service.js";
90
- import { index_d_exports as index_d_exports$1 } from "./services/impact/index.js";
90
+ import { index_d_exports as index_d_exports$2 } from "./services/impact/index.js";
91
91
  import { FormatterOptions, formatFiles } from "./services/formatter.js";
92
- import { index_d_exports as index_d_exports$4 } from "./services/versioning/index.js";
92
+ import { SpecVersionAnalysis } from "./services/versioning/types.js";
93
+ import { index_d_exports as index_d_exports$6 } from "./services/versioning/index.js";
94
+ import { index_d_exports as index_d_exports$5 } from "./services/upgrade/index.js";
95
+ import { index_d_exports as index_d_exports$1 } from "./services/hooks/index.js";
93
96
  import "./services/index.js";
94
97
  import { index_d_exports } from "./formatters/index.js";
95
98
  import { AIClient } from "./ai/client.js";
@@ -100,7 +103,7 @@ import { SimpleAgent } from "./ai/agents/simple-agent.js";
100
103
  import { CursorAgent } from "./ai/agents/cursor-agent.js";
101
104
  import { ClaudeCodeAgent } from "./ai/agents/claude-code-agent.js";
102
105
  import { OpenAICodexAgent } from "./ai/agents/openai-codex-agent.js";
103
- import { index_d_exports as index_d_exports$2 } from "./ai/prompts/index.js";
106
+ import { index_d_exports as index_d_exports$3 } from "./ai/prompts/index.js";
104
107
  import "./ai/index.js";
105
108
  import * as module from "@contractspec/module.workspace";
106
- export { AIClient, AIGenerator, AIReviewResult, ALL_CHECK_CATEGORIES, ALL_CI_CHECK_CATEGORIES, ALL_SETUP_TARGETS, AgentAdapter, AgentConfig, AgentGuideConfig, AgentGuideService, type AgentMode, AgentOrchestrator, AgentProvider, AgentResult, AgentTask, AiAdapter, AiGenerateOptions, AiGenerateResult, AiGenerateStructuredOptions, type AiProvider, AiValidationResult, AnalyzeDepsOptions, AnalyzeDepsResult, BehaviorCheck, BlueprintValidationResult, BuildSpecOptions, BuildSpecResult, BuildTarget, BuildTargetResult, CHECK_CATEGORY_LABELS, CICheckCategory, CICheckCategorySummary, CICheckOptions, CICheckResult, CIFormatOptions, CIIssue, CIIssueSeverity, CIOutputFormat, CI_CHECK_CATEGORY_LABELS, CacheEntryMeta, CacheKeyString, CacheLookupResult, CacheMissReason, CacheStats, CacheStorageAdapter, CheckCategory, CheckContext, CheckResult, CheckStatus, ClaudeCodeAdapter, ClaudeCodeAgent, CleanOptions, CleanResult, CompareSpecsOptions, CompareSpecsResult, type Config, CoverageByType, CreateAdaptersOptions, CreateRegeneratorOptions, CursorAgent, CursorCLIAdapter, DEFAULT_CACHE_CONFIG, DiagramOptions, DiagramType, DiscoverOptions, DiscoveryOptions, DocsServiceOptions, DocsServiceResult, DoctorOptions, DoctorPromptCallbacks, DoctorResult, ExtendedWorkspaceInfo, FULL_DEPENDENCIES, FieldMapping, FieldMatchType, FileStat, FileSystemCacheStorage, FixAction, FixResult, FormatOptions, FormatterOptions, FsAdapter, GenericMCPAdapter, GitAdapter, GitCleanOptions, GuideOptions, GuideResult, ImplementationSource, ImplementationStatus, ImplementationValidationResult, ImplementationValidatorOptions, InMemoryCacheStorage, IntegrityAnalysisOptions, IntegrityAnalysisResult, IntegrityIssue, IntentAlignment, KeyValueStore, LayerDiscoveryOptions, LayerDiscoveryResult, LayerInventory, LayerLocation, OpenApiExportOptions as LegacyOpenApiExportOptions, OpenApiExportResult as LegacyOpenApiExportResult, ListSpecsOptions, LogLevel, LoggerAdapter, MINIMAL_DEPENDENCIES, MetaRepoInfo, MonorepoConfig, OpenAICodexAgent, OpenApiExportServiceOptions, OpenApiExportServiceResult, OpenApiImportServiceOptions, OpenApiImportServiceResult, OpenApiSyncServiceOptions, OpenApiSyncServiceResult, OpenApiValidateServiceOptions, OpenApiValidateServiceResult, PackageInstallResult, PackageManager, ProgressReporter, ProgressUpdate, QuickstartDependency, QuickstartMode, QuickstartOptions, QuickstartPromptCallbacks, QuickstartResult, RegistryClient, RegistryClientOptions, RepositoryType, ResolvedImplementation, ResolverOptions, RunTestsResult, SETUP_TARGET_LABELS, SemanticVerificationResult, SetupFileResult, SetupOptions, SetupPromptCallbacks, SetupResult, SetupScope, SetupTarget, SimpleAgent, SpecCreatorService, SpecImplementationResult, SpecInventory, SpecLocation, SpecReferenceMatch, StructureCheck, SubmoduleInfo, SyncBuildFn, SyncSpecsOptions, SyncSpecsResult, SyncSpecsRunResult, SyncValidateFn, TenantValidationContext, TenantValidationResult, TestServiceOptions, TestServiceResult, ValidateImplementationOptions, ValidateImplementationResult, ValidateSpecOptions, ValidateSpecResult, VerificationCacheConfig, VerificationCacheEntry, VerificationCacheKey, VerificationCacheService, VerificationIssue, VerifyConfig, VerifyInput, VerifyOptions, VerifyResult, VerifyService, WatchBuildFn, WatchEvent, WatchEventHandler, WatchEventType, WatchOptions, WatchSpecsOptions, WatchValidateFn, Watcher, WatcherAdapter, WorkspaceAdapters, WorkspaceConfigInfo, WorkspaceInfo, WorkspaceStateCacheStorage, addToRegistry, agentAdapters, agentGuideService, analyzeDeps, analyzeIntegrity, buildSpec, cacheKeyToString, claudeCodeAdapter, cleanArtifacts, compareSpecs, computeContentHash, createAgentGuideService, createConsoleLoggerAdapter, createEmptyLayerInventory, createFileSystemCacheStorage, createInMemoryCacheStorage, createNodeAdapters, createNodeAiAdapter, createNodeFsAdapter, createNodeGitAdapter, createNodeWatcherAdapter, createNoopLoggerAdapter, createQuickAIReview, createRegeneratorService, createSpecCreator, createVerificationCacheService, createVerifyService, createWorkspaceStateCacheStorage, cursorCLIAdapter, deepMergeOverwrite, deepMergePreserve, detectPackageManager, detectRepositoryType, discoverAllImplementations, discoverImplementationsForSpec, discoverLayers, exportGraphAsDot, exportOpenApi, exportSpecForLLM, extractSpecReferences, filterIssuesBySeverity, filterIssuesByType, findAllConfigFiles, findMetaRepoRoot, findPackageRoot, findWorkspaceRoot, formatCheckResult, formatDoctorSummary, formatFiles, formatJson, formatQuickstartPreview, formatVerificationReport, formatWorkspaceInfo, index_d_exports as formatters, generateAgentsMd, generateAppBlueprintSpec, generateClaudeMcpConfig, generateComponentTemplate, generateContractsrcConfig, generateCursorMcpConfig, generateCursorRules, generateCursorRulesFromParsedSpec, generateDataViewSpec, generateDocsFromSpecs, generateEventSpec, generateExperimentSpec, generateFeatureContextMarkdown, generateGuideFromParsedSpec, generateHandlerTemplate, generateIntegrationSpec, generateKnowledgeSpaceSpec, generateMermaidDiagram, generateMigrationSpec, generateOperationSpec, generatePresentationSpec, generateTelemetrySpec, generateTestTemplate, generateVscodeSettings, generateWorkflowRunnerTemplate, generateWorkflowSpec, genericMCPAdapter, getAIProvider, getAgentAdapter, getAllLayerLocations, getAllSpecs, getApiKey, getClaudeDesktopConfigPath, getContractNode, getDependencies, getDevDependencies, getExecCommand, getExtendedWorkspaceInfo, getGraphStats, getImplementationSummary, getInstallCommand, getMetaRepoInfo, getPackageName, getProductionDependencies, getRecommendedModels, getRunCommand, getWorkspaceInfo, getWorkspacePackages, groupSpecsByType, index_d_exports$1 as impact, importFromOpenApiService, inferImplementationType, isContractSpecInstalled, isMonorepo, listAgentTypes, listFromRegistry, listSpecs, loadWorkspaceConfig, mergeMonorepoConfigs, module, parseGitModules, index_d_exports$2 as prompts, resolveAllImplementations, resolveImplementations, resolveRegistryUrl, runCIChecks, runDoctor, runQuickstart, runSetup, runTestSpecs, runTests, safeParseJson, searchRegistry, stringToCacheKey, syncSpecs, syncWithOpenApiService, index_d_exports$3 as templates, validateAgainstOpenApiService, validateBlueprint, validateImplementationFiles, validateImplementationWithAgent, validateProvider, validateSpec, validateSpecs, validateTenantConfig, verifyBehavior, verifyImplementationAgainstParsedSpec, verifySemanticFields, verifyService, verifyStructure, verifyWithAI, verifyWithAIEnhanced, index_d_exports$4 as versioning, watchSpecs };
109
+ export { AIClient, AIGenerator, AIReviewResult, ALL_CHECK_CATEGORIES, ALL_CI_CHECK_CATEGORIES, ALL_SETUP_TARGETS, AgentAdapter, AgentConfig, AgentGuideConfig, AgentGuideService, type AgentMode, AgentOrchestrator, AgentProvider, AgentResult, AgentTask, AiAdapter, AiGenerateOptions, AiGenerateResult, AiGenerateStructuredOptions, type AiProvider, AiValidationResult, AnalyzeDepsOptions, AnalyzeDepsResult, BehaviorCheck, BlueprintValidationResult, BuildSpecOptions, BuildSpecResult, BuildTarget, BuildTargetResult, CHECK_CATEGORY_LABELS, CICheckCategory, CICheckCategorySummary, CICheckOptions, CICheckResult, CIFormatOptions, CIIssue, CIIssueSeverity, CIOutputFormat, CI_CHECK_CATEGORY_LABELS, CacheEntryMeta, CacheKeyString, CacheLookupResult, CacheMissReason, CacheStats, CacheStorageAdapter, CheckCategory, CheckContext, CheckResult, CheckStatus, ClaudeCodeAdapter, ClaudeCodeAgent, CleanOptions, CleanResult, CompareSpecsOptions, CompareSpecsResult, type Config, CoverageByType, CreateAdaptersOptions, CreateRegeneratorOptions, CursorAgent, CursorCLIAdapter, DEFAULT_CACHE_CONFIG, DEFAULT_SPEC_PATTERNS, DiagramOptions, DiagramType, DiscoverOptions, DiscoveryOptions, DocsServiceOptions, DocsServiceResult, DoctorOptions, DoctorPromptCallbacks, DoctorResult, ExtendedWorkspaceInfo, FULL_DEPENDENCIES, FieldMapping, FieldMatchType, FileStat, FileSystemCacheStorage, FixAction, FixResult, FormatOptions, FormatterOptions, FsAdapter, GenericMCPAdapter, GitAdapter, GitCleanOptions, GitLogEntry, GuideOptions, GuideResult, ImplementationSource, ImplementationStatus, ImplementationValidationResult, ImplementationValidatorOptions, InMemoryCacheStorage, IntegrityAnalysisOptions, IntegrityAnalysisResult, IntegrityIssue, IntentAlignment, KeyValueStore, LayerDiscoveryOptions, LayerDiscoveryResult, LayerInventory, LayerLocation, OpenApiExportOptions as LegacyOpenApiExportOptions, OpenApiExportResult as LegacyOpenApiExportResult, ListSpecsOptions, LogLevel, LoggerAdapter, MINIMAL_DEPENDENCIES, MetaRepoInfo, MonorepoConfig, OpenAICodexAgent, OpenApiExportServiceOptions, OpenApiExportServiceResult, OpenApiImportServiceOptions, OpenApiImportServiceResult, OpenApiSyncServiceOptions, OpenApiSyncServiceResult, OpenApiValidateServiceOptions, OpenApiValidateServiceResult, PackageInstallResult, PackageManager, ProgressReporter, ProgressUpdate, QuickstartDependency, QuickstartMode, QuickstartOptions, QuickstartPromptCallbacks, QuickstartResult, RegistryClient, RegistryClientOptions, RepositoryType, ResolvedImplementation, ResolverOptions, RunTestsResult, SETUP_TARGET_LABELS, SemanticVerificationResult, SetupFileResult, SetupOptions, SetupPromptCallbacks, SetupResult, SetupScope, SetupTarget, SimpleAgent, SpecCreatorService, SpecImplementationResult, SpecInventory, SpecLocation, SpecReferenceMatch, SpecVersionAnalysis, StructureCheck, SubmoduleInfo, SyncBuildFn, SyncSpecsOptions, SyncSpecsResult, SyncSpecsRunResult, SyncValidateFn, TenantValidationContext, TenantValidationResult, TestServiceOptions, TestServiceResult, ValidateImplementationOptions, ValidateImplementationResult, ValidateSpecOptions, ValidateSpecResult, VerificationCacheConfig, VerificationCacheEntry, VerificationCacheKey, VerificationCacheService, VerificationIssue, VerifyConfig, VerifyInput, VerifyOptions, VerifyResult, VerifyService, WatchBuildFn, WatchEvent, WatchEventHandler, WatchEventType, WatchOptions, WatchSpecsOptions, WatchValidateFn, Watcher, WatcherAdapter, WorkspaceAdapters, WorkspaceConfigInfo, WorkspaceInfo, WorkspaceStateCacheStorage, addToRegistry, agentAdapters, agentGuideService, analyzeDeps, analyzeIntegrity, buildSpec, cacheKeyToString, claudeCodeAdapter, cleanArtifacts, compareSpecs, computeContentHash, createAgentGuideService, createConsoleLoggerAdapter, createEmptyLayerInventory, createFileSystemCacheStorage, createInMemoryCacheStorage, createNodeAdapters, createNodeAiAdapter, createNodeFsAdapter, createNodeGitAdapter, createNodeWatcherAdapter, createNoopLoggerAdapter, createQuickAIReview, createRegeneratorService, createSpecCreator, createVerificationCacheService, createVerifyService, createWorkspaceStateCacheStorage, cursorCLIAdapter, deepMergeOverwrite, deepMergePreserve, detectPackageManager, detectRepositoryType, discoverAllImplementations, discoverImplementationsForSpec, discoverLayers, exportGraphAsDot, exportOpenApi, exportSpecForLLM, extractSpecReferences, filterIssuesBySeverity, filterIssuesByType, findAllConfigFiles, findMetaRepoRoot, findPackageRoot, findWorkspaceRoot, formatCheckResult, formatDoctorSummary, formatFiles, formatJson, formatQuickstartPreview, formatVerificationReport, formatWorkspaceInfo, index_d_exports as formatters, generateAgentsMd, generateAppBlueprintSpec, generateClaudeMcpConfig, generateComponentTemplate, generateContractsrcConfig, generateCursorMcpConfig, generateCursorRules, generateCursorRulesFromParsedSpec, generateDataViewSpec, generateDocsFromSpecs, generateEventSpec, generateExperimentSpec, generateFeatureContextMarkdown, generateGuideFromParsedSpec, generateHandlerTemplate, generateIntegrationSpec, generateKnowledgeSpaceSpec, generateMermaidDiagram, generateMigrationSpec, generateOperationSpec, generatePresentationSpec, generateTelemetrySpec, generateTestTemplate, generateVscodeSettings, generateWorkflowRunnerTemplate, generateWorkflowSpec, genericMCPAdapter, getAIProvider, getAgentAdapter, getAllLayerLocations, getAllSpecs, getApiKey, getClaudeDesktopConfigPath, getContractNode, getDependencies, getDevDependencies, getExecCommand, getExtendedWorkspaceInfo, getGraphStats, getImplementationSummary, getInstallCommand, getMetaRepoInfo, getPackageName, getProductionDependencies, getRecommendedModels, getRunCommand, getWorkspaceInfo, getWorkspacePackages, groupSpecsByType, index_d_exports$1 as hooks, index_d_exports$2 as impact, importFromOpenApiService, inferImplementationType, isContractSpecInstalled, isMonorepo, listAgentTypes, listFromRegistry, listSpecs, loadWorkspaceConfig, mergeMonorepoConfigs, module, parseGitModules, index_d_exports$3 as prompts, resolveAllImplementations, resolveImplementations, resolveRegistryUrl, runCIChecks, runDoctor, runQuickstart, runSetup, runTestSpecs, runTests, safeParseJson, searchRegistry, stringToCacheKey, syncSpecs, syncWithOpenApiService, index_d_exports$4 as templates, index_d_exports$5 as upgrade, validateAgainstOpenApiService, validateBlueprint, validateImplementationFiles, validateImplementationWithAgent, validateProvider, validateSpec, validateSpecs, validateTenantConfig, verifyBehavior, verifyImplementationAgainstParsedSpec, verifySemanticFields, verifyService, verifyStructure, verifyWithAI, verifyWithAIEnhanced, index_d_exports$6 as versioning, watchSpecs };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createNodeFsAdapter } from "./adapters/fs.js";
1
+ import { DEFAULT_SPEC_PATTERNS, createNodeFsAdapter } from "./adapters/fs.js";
2
2
  import { createNodeGitAdapter } from "./adapters/git.js";
3
3
  import { createNodeWatcherAdapter } from "./adapters/watcher.js";
4
4
  import { createNodeAiAdapter } from "./adapters/ai.js";
@@ -84,6 +84,8 @@ import { generateDocsFromSpecs } from "./services/docs/docs-service.js";
84
84
  import { impact_exports } from "./services/impact/index.js";
85
85
  import { formatFiles } from "./services/formatter.js";
86
86
  import { versioning_exports } from "./services/versioning/index.js";
87
+ import { upgrade_exports } from "./services/upgrade/index.js";
88
+ import { hooks_exports } from "./services/hooks/index.js";
87
89
  import "./services/index.js";
88
90
  import { formatters_exports } from "./formatters/index.js";
89
91
  import { AIClient } from "./ai/client.js";
@@ -91,4 +93,4 @@ import { prompts_exports } from "./ai/prompts/index.js";
91
93
  import "./ai/index.js";
92
94
  import * as module from "@contractspec/module.workspace";
93
95
 
94
- export { AIClient, AIGenerator, ALL_CHECK_CATEGORIES, ALL_CI_CHECK_CATEGORIES, ALL_SETUP_TARGETS, AgentGuideService, AgentOrchestrator, CHECK_CATEGORY_LABELS, CI_CHECK_CATEGORY_LABELS, ClaudeCodeAdapter, ClaudeCodeAgent, CursorAgent, CursorCLIAdapter, DEFAULT_CACHE_CONFIG, FULL_DEPENDENCIES, FileSystemCacheStorage, GenericMCPAdapter, InMemoryCacheStorage, MINIMAL_DEPENDENCIES, OpenAICodexAgent, RegistryClient, SETUP_TARGET_LABELS, SimpleAgent, SpecCreatorService, VerificationCacheService, VerifyService, WorkspaceStateCacheStorage, addToRegistry, agentAdapters, agentGuideService, analyzeDeps, analyzeIntegrity, buildSpec, cacheKeyToString, claudeCodeAdapter, cleanArtifacts, compareSpecs, computeContentHash, createAgentGuideService, createConsoleLoggerAdapter, createEmptyLayerInventory, createFileSystemCacheStorage, createInMemoryCacheStorage, createNodeAdapters, createNodeAiAdapter, createNodeFsAdapter, createNodeGitAdapter, createNodeWatcherAdapter, createNoopLoggerAdapter, createQuickAIReview, createRegeneratorService, createSpecCreator, createVerificationCacheService, createVerifyService, createWorkspaceStateCacheStorage, cursorCLIAdapter, deepMergeOverwrite, deepMergePreserve, detectPackageManager, detectRepositoryType, discoverAllImplementations, discoverImplementationsForSpec, discoverLayers, exportGraphAsDot, exportOpenApi, exportSpecForLLM, extractSpecReferences, filterIssuesBySeverity, filterIssuesByType, findAllConfigFiles, findMetaRepoRoot, findPackageRoot, findWorkspaceRoot, formatCheckResult, formatDoctorSummary, formatFiles, formatJson, formatQuickstartPreview, formatVerificationReport, formatWorkspaceInfo, formatters_exports as formatters, generateAgentsMd, generateAppBlueprintSpec, generateClaudeMcpConfig, generateComponentTemplate, generateContractsrcConfig, generateCursorMcpConfig, generateCursorRules, generateCursorRulesFromParsedSpec, generateDataViewSpec, generateDocsFromSpecs, generateEventSpec, generateExperimentSpec, generateFeatureContextMarkdown, generateGuideFromParsedSpec, generateHandlerTemplate, generateIntegrationSpec, generateKnowledgeSpaceSpec, generateMermaidDiagram, generateMigrationSpec, generateOperationSpec, generatePresentationSpec, generateTelemetrySpec, generateTestTemplate, generateVscodeSettings, generateWorkflowRunnerTemplate, generateWorkflowSpec, genericMCPAdapter, getAIProvider, getAgentAdapter, getAllLayerLocations, getAllSpecs, getApiKey, getClaudeDesktopConfigPath, getContractNode, getDependencies, getDevDependencies, getExecCommand, getExtendedWorkspaceInfo, getGraphStats, getImplementationSummary, getInstallCommand, getMetaRepoInfo, getPackageName, getProductionDependencies, getRecommendedModels, getRunCommand, getWorkspaceInfo, getWorkspacePackages, groupSpecsByType, impact_exports as impact, importFromOpenApiService, inferImplementationType, isContractSpecInstalled, isMonorepo, listAgentTypes, listFromRegistry, listSpecs, loadWorkspaceConfig, mergeMonorepoConfigs, module, parseGitModules, prompts_exports as prompts, resolveAllImplementations, resolveImplementations, resolveRegistryUrl, runCIChecks, runDoctor, runQuickstart, runSetup, runTestSpecs, runTests, safeParseJson, searchRegistry, stringToCacheKey, syncSpecs, syncWithOpenApiService, templates_exports as templates, validateAgainstOpenApiService, validateBlueprint, validateImplementationFiles, validateImplementationWithAgent, validateProvider, validateSpec, validateSpecs, validateTenantConfig, verifyBehavior, verifyImplementationAgainstParsedSpec, verifySemanticFields, verifyService, verifyStructure, verifyWithAI, verifyWithAIEnhanced, versioning_exports as versioning, watchSpecs };
96
+ export { AIClient, AIGenerator, ALL_CHECK_CATEGORIES, ALL_CI_CHECK_CATEGORIES, ALL_SETUP_TARGETS, AgentGuideService, AgentOrchestrator, CHECK_CATEGORY_LABELS, CI_CHECK_CATEGORY_LABELS, ClaudeCodeAdapter, ClaudeCodeAgent, CursorAgent, CursorCLIAdapter, DEFAULT_CACHE_CONFIG, DEFAULT_SPEC_PATTERNS, FULL_DEPENDENCIES, FileSystemCacheStorage, GenericMCPAdapter, InMemoryCacheStorage, MINIMAL_DEPENDENCIES, OpenAICodexAgent, RegistryClient, SETUP_TARGET_LABELS, SimpleAgent, SpecCreatorService, VerificationCacheService, VerifyService, WorkspaceStateCacheStorage, addToRegistry, agentAdapters, agentGuideService, analyzeDeps, analyzeIntegrity, buildSpec, cacheKeyToString, claudeCodeAdapter, cleanArtifacts, compareSpecs, computeContentHash, createAgentGuideService, createConsoleLoggerAdapter, createEmptyLayerInventory, createFileSystemCacheStorage, createInMemoryCacheStorage, createNodeAdapters, createNodeAiAdapter, createNodeFsAdapter, createNodeGitAdapter, createNodeWatcherAdapter, createNoopLoggerAdapter, createQuickAIReview, createRegeneratorService, createSpecCreator, createVerificationCacheService, createVerifyService, createWorkspaceStateCacheStorage, cursorCLIAdapter, deepMergeOverwrite, deepMergePreserve, detectPackageManager, detectRepositoryType, discoverAllImplementations, discoverImplementationsForSpec, discoverLayers, exportGraphAsDot, exportOpenApi, exportSpecForLLM, extractSpecReferences, filterIssuesBySeverity, filterIssuesByType, findAllConfigFiles, findMetaRepoRoot, findPackageRoot, findWorkspaceRoot, formatCheckResult, formatDoctorSummary, formatFiles, formatJson, formatQuickstartPreview, formatVerificationReport, formatWorkspaceInfo, formatters_exports as formatters, generateAgentsMd, generateAppBlueprintSpec, generateClaudeMcpConfig, generateComponentTemplate, generateContractsrcConfig, generateCursorMcpConfig, generateCursorRules, generateCursorRulesFromParsedSpec, generateDataViewSpec, generateDocsFromSpecs, generateEventSpec, generateExperimentSpec, generateFeatureContextMarkdown, generateGuideFromParsedSpec, generateHandlerTemplate, generateIntegrationSpec, generateKnowledgeSpaceSpec, generateMermaidDiagram, generateMigrationSpec, generateOperationSpec, generatePresentationSpec, generateTelemetrySpec, generateTestTemplate, generateVscodeSettings, generateWorkflowRunnerTemplate, generateWorkflowSpec, genericMCPAdapter, getAIProvider, getAgentAdapter, getAllLayerLocations, getAllSpecs, getApiKey, getClaudeDesktopConfigPath, getContractNode, getDependencies, getDevDependencies, getExecCommand, getExtendedWorkspaceInfo, getGraphStats, getImplementationSummary, getInstallCommand, getMetaRepoInfo, getPackageName, getProductionDependencies, getRecommendedModels, getRunCommand, getWorkspaceInfo, getWorkspacePackages, groupSpecsByType, hooks_exports as hooks, impact_exports as impact, importFromOpenApiService, inferImplementationType, isContractSpecInstalled, isMonorepo, listAgentTypes, listFromRegistry, listSpecs, loadWorkspaceConfig, mergeMonorepoConfigs, module, parseGitModules, prompts_exports as prompts, resolveAllImplementations, resolveImplementations, resolveRegistryUrl, runCIChecks, runDoctor, runQuickstart, runSetup, runTestSpecs, runTests, safeParseJson, searchRegistry, stringToCacheKey, syncSpecs, syncWithOpenApiService, templates_exports as templates, upgrade_exports as upgrade, validateAgainstOpenApiService, validateBlueprint, validateImplementationFiles, validateImplementationWithAgent, validateProvider, validateSpec, validateSpecs, validateTenantConfig, verifyBehavior, verifyImplementationAgainstParsedSpec, verifySemanticFields, verifyService, verifyStructure, verifyWithAI, verifyWithAIEnhanced, versioning_exports as versioning, watchSpecs };
@@ -18,6 +18,19 @@ interface GitAdapter {
18
18
  * Check if path is inside a git repository.
19
19
  */
20
20
  isGitRepo(path?: string): Promise<boolean>;
21
+ /**
22
+ * Get commit log since a baseline ref.
23
+ */
24
+ log(baseline?: string): Promise<GitLogEntry[]>;
25
+ }
26
+ /**
27
+ * Entry from git log.
28
+ */
29
+ interface GitLogEntry {
30
+ hash: string;
31
+ message: string;
32
+ author?: string;
33
+ date?: string;
21
34
  }
22
35
  /**
23
36
  * Options for git clean.
@@ -29,5 +42,5 @@ interface GitCleanOptions {
29
42
  ignored?: boolean;
30
43
  }
31
44
  //#endregion
32
- export { GitAdapter, GitCleanOptions };
45
+ export { GitAdapter, GitCleanOptions, GitLogEntry };
33
46
  //# sourceMappingURL=git.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"git.d.ts","names":[],"sources":["../../src/ports/git.ts"],"sourcesContent":[],"mappings":";;AAOA;;;;;AAcmC,UAdlB,UAAA,CAckB;EAMlB;;;2CAhB0B;;;;kBAKzB,kBAAkB;;;;4BAKR;;;;;UAMX,eAAA"}
1
+ {"version":3,"file":"git.d.ts","names":[],"sources":["../../src/ports/git.ts"],"sourcesContent":[],"mappings":";;AAOA;;;;;AAmBkC,UAnBjB,UAAA,CAmBiB;EAAR;;AAM1B;EAUiB,QAAA,CAAA,GAAA,EAAA,MAAe,EAAA,QAAA,EAAA,MAAA,CAAA,EA/BW,OA+BX,CAAA,MAAA,CAAA;;;;kBA1Bd,kBAAkB;;;;4BAKR;;;;0BAKF,QAAQ;;;;;UAMjB,WAAA;;;;;;;;;UAUA,eAAA"}
@@ -1,5 +1,5 @@
1
1
  import { DiscoverOptions, FileStat, FsAdapter } from "./fs.js";
2
- import { GitAdapter, GitCleanOptions } from "./git.js";
2
+ import { GitAdapter, GitCleanOptions, GitLogEntry } from "./git.js";
3
3
  import { WatchEvent, WatchEventHandler, WatchEventType, WatchOptions, Watcher, WatcherAdapter } from "./watcher.js";
4
4
  import { AiAdapter, AiGenerateOptions, AiGenerateResult, AiGenerateStructuredOptions, AiValidationResult } from "./ai.js";
5
5
  import { LogLevel, LoggerAdapter, ProgressReporter, ProgressUpdate, WorkspaceAdapters } from "./logger.js";
@@ -10,6 +10,8 @@ async function runConfigChecks(fs, ctx) {
10
10
  results.push(await checkContractsrcExists(fs, ctx));
11
11
  results.push(await checkContractsrcValid(fs, ctx));
12
12
  results.push(await checkContractsrcFields(fs, ctx));
13
+ results.push(await checkVersioningConfig(fs, ctx));
14
+ results.push(await checkHooksConfig(fs, ctx));
13
15
  return results;
14
16
  }
15
17
  /**
@@ -165,6 +167,136 @@ async function checkContractsrcFields(fs, ctx) {
165
167
  };
166
168
  }
167
169
  }
170
+ /**
171
+ * Check if versioning configuration is present.
172
+ */
173
+ async function checkVersioningConfig(fs, ctx) {
174
+ const configPath = fs.join(ctx.workspaceRoot, ".contractsrc.json");
175
+ if (!await fs.exists(configPath)) return {
176
+ category: "config",
177
+ name: "Versioning Config",
178
+ status: "skip",
179
+ message: "Config file does not exist"
180
+ };
181
+ try {
182
+ const content = await fs.readFile(configPath);
183
+ const config = JSON.parse(content);
184
+ if (config["versioning"]) return {
185
+ category: "config",
186
+ name: "Versioning Config",
187
+ status: "pass",
188
+ message: config["versioning"]["integrateWithChangesets"] === true ? "Versioning configured with Changesets integration" : "Versioning configured"
189
+ };
190
+ return {
191
+ category: "config",
192
+ name: "Versioning Config",
193
+ status: "warn",
194
+ message: "Versioning configuration not found",
195
+ details: "Consider adding versioning config for automated version bumps and changelog generation",
196
+ fix: {
197
+ description: "Add versioning configuration with defaults",
198
+ apply: async () => {
199
+ try {
200
+ config["versioning"] = {
201
+ autoBump: false,
202
+ bumpStrategy: "impact",
203
+ changelogTiers: [
204
+ "spec",
205
+ "library",
206
+ "monorepo"
207
+ ],
208
+ format: "keep-a-changelog",
209
+ commitChanges: false,
210
+ createTags: false,
211
+ integrateWithChangesets: true
212
+ };
213
+ await fs.writeFile(configPath, formatJson(config));
214
+ return {
215
+ success: true,
216
+ message: "Added versioning configuration"
217
+ };
218
+ } catch (err) {
219
+ return {
220
+ success: false,
221
+ message: `Failed: ${err instanceof Error ? err.message : String(err)}`
222
+ };
223
+ }
224
+ }
225
+ }
226
+ };
227
+ } catch {
228
+ return {
229
+ category: "config",
230
+ name: "Versioning Config",
231
+ status: "skip",
232
+ message: "Could not parse config"
233
+ };
234
+ }
235
+ }
236
+ /**
237
+ * Check if hooks configuration is present.
238
+ */
239
+ async function checkHooksConfig(fs, ctx) {
240
+ const configPath = fs.join(ctx.workspaceRoot, ".contractsrc.json");
241
+ if (!await fs.exists(configPath)) return {
242
+ category: "config",
243
+ name: "Hooks Config",
244
+ status: "skip",
245
+ message: "Config file does not exist"
246
+ };
247
+ try {
248
+ const content = await fs.readFile(configPath);
249
+ const config = JSON.parse(content);
250
+ if (config["hooks"]) {
251
+ const hooks = config["hooks"];
252
+ return {
253
+ category: "config",
254
+ name: "Hooks Config",
255
+ status: "pass",
256
+ message: `${Object.keys(hooks).length} git hook(s) configured`
257
+ };
258
+ }
259
+ const huskyPath = fs.join(ctx.workspaceRoot, ".husky");
260
+ if (await fs.exists(huskyPath)) return {
261
+ category: "config",
262
+ name: "Hooks Config",
263
+ status: "warn",
264
+ message: "Husky detected but no hooks configured in .contractsrc.json",
265
+ details: "Add hooks config to run contractspec checks from git hooks",
266
+ fix: {
267
+ description: "Add pre-commit hooks configuration",
268
+ apply: async () => {
269
+ try {
270
+ config["hooks"] = { "pre-commit": ["contractspec validate **/*.operation.ts", "contractspec integrity check"] };
271
+ await fs.writeFile(configPath, formatJson(config));
272
+ return {
273
+ success: true,
274
+ message: "Added hooks configuration"
275
+ };
276
+ } catch (err) {
277
+ return {
278
+ success: false,
279
+ message: `Failed: ${err instanceof Error ? err.message : String(err)}`
280
+ };
281
+ }
282
+ }
283
+ }
284
+ };
285
+ return {
286
+ category: "config",
287
+ name: "Hooks Config",
288
+ status: "pass",
289
+ message: "No hooks configured (optional)"
290
+ };
291
+ } catch {
292
+ return {
293
+ category: "config",
294
+ name: "Hooks Config",
295
+ status: "skip",
296
+ message: "Could not parse config"
297
+ };
298
+ }
299
+ }
168
300
 
169
301
  //#endregion
170
302
  export { runConfigChecks };
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":["results: CheckResult[]","missingFields: string[]"],"sources":["../../../../src/services/doctor/checks/config.ts"],"sourcesContent":["/**\n * Configuration file health checks.\n */\n\nimport type { FsAdapter } from '../../../ports/fs';\nimport type { CheckResult, CheckContext, FixResult } from '../types';\nimport { generateContractsrcConfig } from '../../setup/config-generators';\nimport { formatJson } from '../../setup/file-merger';\n\n/**\n * Run configuration-related health checks.\n */\nexport async function runConfigChecks(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n // Check if .contractsrc.json exists\n results.push(await checkContractsrcExists(fs, ctx));\n\n // Check if .contractsrc.json is valid\n results.push(await checkContractsrcValid(fs, ctx));\n\n // Check required fields in config\n results.push(await checkContractsrcFields(fs, ctx));\n\n return results;\n}\n\n/**\n * Check if .contractsrc.json exists.\n */\nasync function checkContractsrcExists(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n const configPath = fs.join(ctx.workspaceRoot, '.contractsrc.json');\n\n const exists = await fs.exists(configPath);\n if (exists) {\n return {\n category: 'config',\n name: 'Config File Exists',\n status: 'pass',\n message: '.contractsrc.json found',\n };\n }\n\n return {\n category: 'config',\n name: 'Config File Exists',\n status: 'fail',\n message: '.contractsrc.json not found',\n fix: {\n description: 'Create .contractsrc.json with defaults',\n apply: async (): Promise<FixResult> => {\n try {\n const defaults = generateContractsrcConfig({\n workspaceRoot: ctx.workspaceRoot,\n interactive: false,\n targets: [],\n });\n await fs.writeFile(configPath, formatJson(defaults));\n return { success: true, message: 'Created .contractsrc.json' };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { success: false, message: `Failed to create: ${msg}` };\n }\n },\n },\n };\n}\n\n/**\n * Check if .contractsrc.json is valid JSON.\n */\nasync function checkContractsrcValid(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n const configPath = fs.join(ctx.workspaceRoot, '.contractsrc.json');\n\n const exists = await fs.exists(configPath);\n if (!exists) {\n return {\n category: 'config',\n name: 'Config Valid JSON',\n status: 'skip',\n message: 'Config file does not exist',\n };\n }\n\n try {\n const content = await fs.readFile(configPath);\n JSON.parse(content);\n\n return {\n category: 'config',\n name: 'Config Valid JSON',\n status: 'pass',\n message: '.contractsrc.json is valid JSON',\n };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n\n return {\n category: 'config',\n name: 'Config Valid JSON',\n status: 'fail',\n message: '.contractsrc.json is not valid JSON',\n details: msg,\n fix: {\n description: 'Replace with valid default config',\n apply: async (): Promise<FixResult> => {\n try {\n const defaults = generateContractsrcConfig({\n workspaceRoot: ctx.workspaceRoot,\n interactive: false,\n targets: [],\n });\n await fs.writeFile(configPath, formatJson(defaults));\n return { success: true, message: 'Replaced with valid config' };\n } catch (err) {\n const m = err instanceof Error ? err.message : String(err);\n return { success: false, message: `Failed: ${m}` };\n }\n },\n },\n };\n }\n}\n\n/**\n * Check required fields in .contractsrc.json.\n */\nasync function checkContractsrcFields(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n const configPath = fs.join(ctx.workspaceRoot, '.contractsrc.json');\n\n const exists = await fs.exists(configPath);\n if (!exists) {\n return {\n category: 'config',\n name: 'Config Fields',\n status: 'skip',\n message: 'Config file does not exist',\n };\n }\n\n try {\n const content = await fs.readFile(configPath);\n const config = JSON.parse(content) as Record<string, unknown>;\n\n const missingFields: string[] = [];\n\n // Check for recommended fields\n if (!config['outputDir']) {\n missingFields.push('outputDir');\n }\n if (!config['conventions']) {\n missingFields.push('conventions');\n }\n\n if (missingFields.length === 0) {\n return {\n category: 'config',\n name: 'Config Fields',\n status: 'pass',\n message: 'All recommended fields present',\n };\n }\n\n return {\n category: 'config',\n name: 'Config Fields',\n status: 'warn',\n message: `Missing recommended fields: ${missingFields.join(', ')}`,\n fix: {\n description: 'Add missing fields with defaults',\n apply: async (): Promise<FixResult> => {\n try {\n const defaults = generateContractsrcConfig({\n workspaceRoot: ctx.workspaceRoot,\n interactive: false,\n targets: [],\n }) as Record<string, unknown>;\n\n // Merge missing fields\n for (const field of missingFields) {\n if (defaults[field] !== undefined) {\n config[field] = defaults[field];\n }\n }\n\n await fs.writeFile(configPath, formatJson(config));\n return { success: true, message: 'Added missing fields' };\n } catch (err) {\n const m = err instanceof Error ? err.message : String(err);\n return { success: false, message: `Failed: ${m}` };\n }\n },\n },\n };\n } catch {\n return {\n category: 'config',\n name: 'Config Fields',\n status: 'skip',\n message: 'Could not parse config',\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config.js","names":["results: CheckResult[]","missingFields: string[]"],"sources":["../../../../src/services/doctor/checks/config.ts"],"sourcesContent":["/**\n * Configuration file health checks.\n */\n\nimport type { FsAdapter } from '../../../ports/fs';\nimport type { CheckResult, CheckContext, FixResult } from '../types';\nimport { generateContractsrcConfig } from '../../setup/config-generators';\nimport { formatJson } from '../../setup/file-merger';\n\n/**\n * Run configuration-related health checks.\n */\nexport async function runConfigChecks(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n // Check if .contractsrc.json exists\n results.push(await checkContractsrcExists(fs, ctx));\n\n // Check if .contractsrc.json is valid\n results.push(await checkContractsrcValid(fs, ctx));\n\n // Check required fields in config\n results.push(await checkContractsrcFields(fs, ctx));\n\n // Check versioning configuration\n results.push(await checkVersioningConfig(fs, ctx));\n\n // Check hooks configuration\n results.push(await checkHooksConfig(fs, ctx));\n\n return results;\n}\n\n/**\n * Check if .contractsrc.json exists.\n */\nasync function checkContractsrcExists(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n const configPath = fs.join(ctx.workspaceRoot, '.contractsrc.json');\n\n const exists = await fs.exists(configPath);\n if (exists) {\n return {\n category: 'config',\n name: 'Config File Exists',\n status: 'pass',\n message: '.contractsrc.json found',\n };\n }\n\n return {\n category: 'config',\n name: 'Config File Exists',\n status: 'fail',\n message: '.contractsrc.json not found',\n fix: {\n description: 'Create .contractsrc.json with defaults',\n apply: async (): Promise<FixResult> => {\n try {\n const defaults = generateContractsrcConfig({\n workspaceRoot: ctx.workspaceRoot,\n interactive: false,\n targets: [],\n });\n await fs.writeFile(configPath, formatJson(defaults));\n return { success: true, message: 'Created .contractsrc.json' };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { success: false, message: `Failed to create: ${msg}` };\n }\n },\n },\n };\n}\n\n/**\n * Check if .contractsrc.json is valid JSON.\n */\nasync function checkContractsrcValid(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n const configPath = fs.join(ctx.workspaceRoot, '.contractsrc.json');\n\n const exists = await fs.exists(configPath);\n if (!exists) {\n return {\n category: 'config',\n name: 'Config Valid JSON',\n status: 'skip',\n message: 'Config file does not exist',\n };\n }\n\n try {\n const content = await fs.readFile(configPath);\n JSON.parse(content);\n\n return {\n category: 'config',\n name: 'Config Valid JSON',\n status: 'pass',\n message: '.contractsrc.json is valid JSON',\n };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n\n return {\n category: 'config',\n name: 'Config Valid JSON',\n status: 'fail',\n message: '.contractsrc.json is not valid JSON',\n details: msg,\n fix: {\n description: 'Replace with valid default config',\n apply: async (): Promise<FixResult> => {\n try {\n const defaults = generateContractsrcConfig({\n workspaceRoot: ctx.workspaceRoot,\n interactive: false,\n targets: [],\n });\n await fs.writeFile(configPath, formatJson(defaults));\n return { success: true, message: 'Replaced with valid config' };\n } catch (err) {\n const m = err instanceof Error ? err.message : String(err);\n return { success: false, message: `Failed: ${m}` };\n }\n },\n },\n };\n }\n}\n\n/**\n * Check required fields in .contractsrc.json.\n */\nasync function checkContractsrcFields(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n const configPath = fs.join(ctx.workspaceRoot, '.contractsrc.json');\n\n const exists = await fs.exists(configPath);\n if (!exists) {\n return {\n category: 'config',\n name: 'Config Fields',\n status: 'skip',\n message: 'Config file does not exist',\n };\n }\n\n try {\n const content = await fs.readFile(configPath);\n const config = JSON.parse(content) as Record<string, unknown>;\n\n const missingFields: string[] = [];\n\n // Check for recommended fields\n if (!config['outputDir']) {\n missingFields.push('outputDir');\n }\n if (!config['conventions']) {\n missingFields.push('conventions');\n }\n\n if (missingFields.length === 0) {\n return {\n category: 'config',\n name: 'Config Fields',\n status: 'pass',\n message: 'All recommended fields present',\n };\n }\n\n return {\n category: 'config',\n name: 'Config Fields',\n status: 'warn',\n message: `Missing recommended fields: ${missingFields.join(', ')}`,\n fix: {\n description: 'Add missing fields with defaults',\n apply: async (): Promise<FixResult> => {\n try {\n const defaults = generateContractsrcConfig({\n workspaceRoot: ctx.workspaceRoot,\n interactive: false,\n targets: [],\n }) as Record<string, unknown>;\n\n // Merge missing fields\n for (const field of missingFields) {\n if (defaults[field] !== undefined) {\n config[field] = defaults[field];\n }\n }\n\n await fs.writeFile(configPath, formatJson(config));\n return { success: true, message: 'Added missing fields' };\n } catch (err) {\n const m = err instanceof Error ? err.message : String(err);\n return { success: false, message: `Failed: ${m}` };\n }\n },\n },\n };\n } catch {\n return {\n category: 'config',\n name: 'Config Fields',\n status: 'skip',\n message: 'Could not parse config',\n };\n }\n}\n\n/**\n * Check if versioning configuration is present.\n */\nasync function checkVersioningConfig(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n const configPath = fs.join(ctx.workspaceRoot, '.contractsrc.json');\n\n const exists = await fs.exists(configPath);\n if (!exists) {\n return {\n category: 'config',\n name: 'Versioning Config',\n status: 'skip',\n message: 'Config file does not exist',\n };\n }\n\n try {\n const content = await fs.readFile(configPath);\n const config = JSON.parse(content) as Record<string, unknown>;\n\n if (config['versioning']) {\n const versioning = config['versioning'] as Record<string, unknown>;\n const hasChangesets = versioning['integrateWithChangesets'] === true;\n\n return {\n category: 'config',\n name: 'Versioning Config',\n status: 'pass',\n message: hasChangesets\n ? 'Versioning configured with Changesets integration'\n : 'Versioning configured',\n };\n }\n\n return {\n category: 'config',\n name: 'Versioning Config',\n status: 'warn',\n message: 'Versioning configuration not found',\n details:\n 'Consider adding versioning config for automated version bumps and changelog generation',\n fix: {\n description: 'Add versioning configuration with defaults',\n apply: async (): Promise<FixResult> => {\n try {\n config['versioning'] = {\n autoBump: false,\n bumpStrategy: 'impact',\n changelogTiers: ['spec', 'library', 'monorepo'],\n format: 'keep-a-changelog',\n commitChanges: false,\n createTags: false,\n integrateWithChangesets: true,\n };\n await fs.writeFile(configPath, formatJson(config));\n return { success: true, message: 'Added versioning configuration' };\n } catch (err) {\n const m = err instanceof Error ? err.message : String(err);\n return { success: false, message: `Failed: ${m}` };\n }\n },\n },\n };\n } catch {\n return {\n category: 'config',\n name: 'Versioning Config',\n status: 'skip',\n message: 'Could not parse config',\n };\n }\n}\n\n/**\n * Check if hooks configuration is present.\n */\nasync function checkHooksConfig(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n const configPath = fs.join(ctx.workspaceRoot, '.contractsrc.json');\n\n const exists = await fs.exists(configPath);\n if (!exists) {\n return {\n category: 'config',\n name: 'Hooks Config',\n status: 'skip',\n message: 'Config file does not exist',\n };\n }\n\n try {\n const content = await fs.readFile(configPath);\n const config = JSON.parse(content) as Record<string, unknown>;\n\n if (config['hooks']) {\n const hooks = config['hooks'] as Record<string, unknown>;\n const hookCount = Object.keys(hooks).length;\n\n return {\n category: 'config',\n name: 'Hooks Config',\n status: 'pass',\n message: `${hookCount} git hook(s) configured`,\n };\n }\n\n // Check if husky is installed\n const huskyPath = fs.join(ctx.workspaceRoot, '.husky');\n const hasHusky = await fs.exists(huskyPath);\n\n if (hasHusky) {\n return {\n category: 'config',\n name: 'Hooks Config',\n status: 'warn',\n message: 'Husky detected but no hooks configured in .contractsrc.json',\n details: 'Add hooks config to run contractspec checks from git hooks',\n fix: {\n description: 'Add pre-commit hooks configuration',\n apply: async (): Promise<FixResult> => {\n try {\n config['hooks'] = {\n 'pre-commit': [\n 'contractspec validate **/*.operation.ts',\n 'contractspec integrity check',\n ],\n };\n await fs.writeFile(configPath, formatJson(config));\n return { success: true, message: 'Added hooks configuration' };\n } catch (err) {\n const m = err instanceof Error ? err.message : String(err);\n return { success: false, message: `Failed: ${m}` };\n }\n },\n },\n };\n }\n\n return {\n category: 'config',\n name: 'Hooks Config',\n status: 'pass',\n message: 'No hooks configured (optional)',\n };\n } catch {\n return {\n category: 'config',\n name: 'Hooks Config',\n status: 'skip',\n message: 'Could not parse config',\n };\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { FsAdapter } from "../../ports/fs.js";
2
+ import { LoggerAdapter } from "../../ports/logger.js";
3
+ import { HookRunOptions, HookRunResult } from "./types.js";
4
+
5
+ //#region src/services/hooks/hooks-service.d.ts
6
+
7
+ interface ServiceAdapters {
8
+ fs: FsAdapter;
9
+ logger: LoggerAdapter;
10
+ }
11
+ /**
12
+ * Run a configured git hook.
13
+ *
14
+ * Note: Uses node:child_process for compatibility with VSCode (Node.js) and CLI (Bun).
15
+ * Although Bun shell ($) is preferred for scripts, this shared bundle must support both runtimes.
16
+ */
17
+ declare function runHook(adapters: ServiceAdapters, options: HookRunOptions): Promise<HookRunResult>;
18
+ /**
19
+ * Get available hooks from configuration.
20
+ */
21
+ declare function getAvailableHooks(adapters: ServiceAdapters, workspaceRoot: string): Promise<string[]>;
22
+ //#endregion
23
+ export { getAvailableHooks, runHook };
24
+ //# sourceMappingURL=hooks-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-service.d.ts","names":[],"sources":["../../../src/services/hooks/hooks-service.ts"],"sourcesContent":[],"mappings":";;;;;;UA2BU,eAAA,CAkBA;EAkHY,EAAA,EAnIhB,SAmIgB;UAlIZ;;;;;;;;iBAaY,OAAA,WACV,0BACD,iBACR,QAAQ;;;;iBAkHW,iBAAA,WACV,yCAET"}