@dzhechkov/harness-core 0.3.8 → 0.3.10

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/index.d.ts CHANGED
@@ -12,11 +12,13 @@ export * from './operations.js';
12
12
  export * from './workflows.js';
13
13
  export { createSkill } from './create-skill.js';
14
14
  export type { CreateSkillOptions, CreateSkillResult } from './create-skill.js';
15
- export { checkUpstream, loadSourcesManifest } from './sync-upstream.js';
16
- export type { SyncUpstreamReport, UpstreamCheckResult, SourcesManifest } from './sync-upstream.js';
15
+ export { checkUpstream, checkAllUpstream, discoverSourcePackages, loadSourcesManifest } from './sync-upstream.js';
16
+ export type { SyncUpstreamReport, UpstreamCheckResult, SourcesManifest, SourcePackageInfo } from './sync-upstream.js';
17
17
  export { benchmarkSkill, benchmarkSkills, compareSkills } from './benchmark.js';
18
18
  export { buildRegistry, searchRegistry, filterByCategory } from './registry.js';
19
19
  export { recommend } from './recommend.js';
20
+ export { pretrain } from './pretrain.js';
21
+ export type { PretrainResult, DetectedTech } from './pretrain.js';
20
22
  export type { RecommendationReport, SkillRecommendation } from './recommend.js';
21
23
  export { discoverPackages, publishPackages } from './publish.js';
22
24
  export { fetchAllDownloads } from './downloads.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,yDAAyD;AACzD,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAE5C,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACxE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAChF,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACjE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC7D,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,yDAAyD;AACzD,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAE5C,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAClH,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACtH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAChF,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACjE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC7D,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -11,10 +11,11 @@ export * from './targets.js';
11
11
  export * from './operations.js';
12
12
  export * from './workflows.js';
13
13
  export { createSkill } from './create-skill.js';
14
- export { checkUpstream, loadSourcesManifest } from './sync-upstream.js';
14
+ export { checkUpstream, checkAllUpstream, discoverSourcePackages, loadSourcesManifest } from './sync-upstream.js';
15
15
  export { benchmarkSkill, benchmarkSkills, compareSkills } from './benchmark.js';
16
16
  export { buildRegistry, searchRegistry, filterByCategory } from './registry.js';
17
17
  export { recommend } from './recommend.js';
18
+ export { pretrain } from './pretrain.js';
18
19
  export { discoverPackages, publishPackages } from './publish.js';
19
20
  export { fetchAllDownloads } from './downloads.js';
20
21
  export { discoverInstalled, checkUpgrades } from './upgrade.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,yDAAyD;AACzD,MAAM,CAAC,MAAM,oBAAoB,GAAG,OAAO,CAAC;AAE5C,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAExE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,yDAAyD;AACzD,MAAM,CAAC,MAAM,oBAAoB,GAAG,OAAO,CAAC;AAE5C,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAElH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Pretrain — bootstrap intelligence by analyzing the target project.
3
+ *
4
+ * Scans the project's file structure, package.json, and tech stack to
5
+ * automatically recommend the right skills and presets. Runs during
6
+ * `dz init --pretrain` to eliminate manual preset selection.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ /** Detected technology in the project. */
11
+ export interface DetectedTech {
12
+ readonly name: string;
13
+ readonly category: string;
14
+ readonly confidence: number;
15
+ readonly source: string;
16
+ }
17
+ /** Pretrain analysis result. */
18
+ export interface PretrainResult {
19
+ readonly projectName: string;
20
+ readonly techs: readonly DetectedTech[];
21
+ readonly recommendedPresets: readonly string[];
22
+ readonly recommendedSkills: readonly string[];
23
+ readonly projectType: string;
24
+ readonly hasTests: boolean;
25
+ readonly hasDocker: boolean;
26
+ readonly hasCI: boolean;
27
+ readonly hasTerraform: boolean;
28
+ readonly hasKubernetes: boolean;
29
+ readonly packageCount: number;
30
+ }
31
+ /** Run pretrain analysis on a project. */
32
+ export declare function pretrain(projectRoot: string): PretrainResult;
33
+ //# sourceMappingURL=pretrain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pretrain.d.ts","sourceRoot":"","sources":["../src/pretrain.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,0CAA0C;AAC1C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,gCAAgC;AAChC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AA8KD,0CAA0C;AAC1C,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CAuE5D"}
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Pretrain — bootstrap intelligence by analyzing the target project.
3
+ *
4
+ * Scans the project's file structure, package.json, and tech stack to
5
+ * automatically recommend the right skills and presets. Runs during
6
+ * `dz init --pretrain` to eliminate manual preset selection.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
11
+ import { join } from 'node:path';
12
+ /** Tech detection rules: file/pattern → tech. */
13
+ const DETECTORS = [
14
+ // Languages/Frameworks
15
+ { glob: 'package.json', tech: 'node.js', category: 'runtime' },
16
+ { glob: 'tsconfig.json', tech: 'typescript', category: 'language' },
17
+ { glob: 'requirements.txt', tech: 'python', category: 'runtime' },
18
+ { glob: 'pyproject.toml', tech: 'python', category: 'runtime' },
19
+ { glob: 'go.mod', tech: 'go', category: 'runtime' },
20
+ { glob: 'Cargo.toml', tech: 'rust', category: 'runtime' },
21
+ { glob: 'Gemfile', tech: 'ruby', category: 'runtime' },
22
+ // Frontend
23
+ { glob: 'next.config', tech: 'next.js', category: 'frontend' },
24
+ { glob: 'vite.config', tech: 'vite', category: 'frontend' },
25
+ { glob: 'tailwind.config', tech: 'tailwind', category: 'frontend' },
26
+ // Databases
27
+ { glob: 'prisma', tech: 'prisma', category: 'database' },
28
+ { glob: 'drizzle.config', tech: 'drizzle', category: 'database' },
29
+ { glob: 'knexfile', tech: 'knex', category: 'database' },
30
+ // Infrastructure
31
+ { glob: 'Dockerfile', tech: 'docker', category: 'infra' },
32
+ { glob: 'docker-compose', tech: 'docker-compose', category: 'infra' },
33
+ { glob: '.github/workflows', tech: 'github-actions', category: 'ci' },
34
+ { glob: '.gitlab-ci.yml', tech: 'gitlab-ci', category: 'ci' },
35
+ { glob: 'terraform', tech: 'terraform', category: 'iac' },
36
+ { glob: '.tf', tech: 'terraform', category: 'iac' },
37
+ { glob: 'k8s', tech: 'kubernetes', category: 'infra' },
38
+ { glob: 'helm', tech: 'helm', category: 'infra' },
39
+ { glob: 'nginx.conf', tech: 'nginx', category: 'infra' },
40
+ // Testing
41
+ { glob: 'vitest.config', tech: 'vitest', category: 'testing' },
42
+ { glob: 'jest.config', tech: 'jest', category: 'testing' },
43
+ { glob: 'playwright.config', tech: 'playwright', category: 'testing' },
44
+ { glob: 'cypress.config', tech: 'cypress', category: 'testing' },
45
+ { glob: '.stryker', tech: 'stryker', category: 'testing' },
46
+ // Data
47
+ { glob: 'dbt_project.yml', tech: 'dbt', category: 'data' },
48
+ { glob: 'airflow', tech: 'airflow', category: 'data' },
49
+ // API
50
+ { glob: 'openapi', tech: 'openapi', category: 'api' },
51
+ { glob: 'swagger', tech: 'swagger', category: 'api' },
52
+ { glob: '.graphql', tech: 'graphql', category: 'api' },
53
+ { glob: 'schema.graphql', tech: 'graphql', category: 'api' },
54
+ // Cache/Queue
55
+ { glob: 'redis', tech: 'redis', category: 'cache' },
56
+ // Knowledge
57
+ { glob: '.obsidian', tech: 'obsidian', category: 'knowledge' },
58
+ ];
59
+ /** Map tech categories to recommended skills. */
60
+ const CATEGORY_TO_SKILLS = {
61
+ 'runtime': ['debugging', 'test-writer', 'pr-review'],
62
+ 'language': ['test-writer', 'pr-review'],
63
+ 'frontend': ['frontend-implementation', 'playwright-testing'],
64
+ 'database': ['database-review', 'database-migration'],
65
+ 'infra': ['docker-compose', 'kubernetes', 'nginx-config'],
66
+ 'ci': ['ci-fix', 'github-actions'],
67
+ 'iac': ['terraform'],
68
+ 'testing': ['test-writer', 'playwright-testing'],
69
+ 'data': ['data-pipeline'],
70
+ 'api': ['api-design', 'graphql-schema'],
71
+ 'cache': ['redis-patterns'],
72
+ 'knowledge': ['obsidian'],
73
+ };
74
+ /** Map detected skills to presets. */
75
+ const SKILL_TO_PRESET = {
76
+ 'pr-review': 'devops', 'security-audit': 'devops', 'test-writer': 'devops',
77
+ 'ci-fix': 'devops', 'terraform': 'devops', 'kubernetes': 'devops',
78
+ 'docker-compose': 'devops', 'api-design': 'devops', 'debugging': 'devops',
79
+ 'database-review': 'devops', 'database-migration': 'devops',
80
+ 'github-actions': 'devops', 'nginx-config': 'devops', 'redis-patterns': 'devops',
81
+ 'graphql-schema': 'devops', 'playwright-testing': 'devops',
82
+ 'data-pipeline': 'devops', 'incident-response': 'devops',
83
+ 'frontend-implementation': 'devops', 'monorepo-management': 'devops',
84
+ 'brave-search': 'mcp', 'gmail': 'mcp', 'notion': 'mcp', 'obsidian': 'mcp',
85
+ 'git-mcp': 'mcp', 'context7': 'mcp',
86
+ };
87
+ /** Scan project directory for files matching detectors. */
88
+ function scanProject(projectRoot) {
89
+ const techs = [];
90
+ const seen = new Set();
91
+ // Check top-level files
92
+ let entries = [];
93
+ try {
94
+ entries = readdirSync(projectRoot).map((e) => e.toLowerCase());
95
+ }
96
+ catch {
97
+ return [];
98
+ }
99
+ for (const detector of DETECTORS) {
100
+ const globLower = detector.glob.toLowerCase();
101
+ const match = entries.some((e) => e.includes(globLower));
102
+ if (match && !seen.has(detector.tech)) {
103
+ seen.add(detector.tech);
104
+ techs.push({
105
+ name: detector.tech,
106
+ category: detector.category,
107
+ confidence: 0.9,
108
+ source: detector.glob,
109
+ });
110
+ }
111
+ }
112
+ // Check subdirectories (1 level deep)
113
+ for (const entry of entries) {
114
+ const subPath = join(projectRoot, entry);
115
+ try {
116
+ const subEntries = readdirSync(subPath).map((e) => e.toLowerCase());
117
+ for (const detector of DETECTORS) {
118
+ const globLower = detector.glob.toLowerCase();
119
+ if (subEntries.some((e) => e.includes(globLower)) && !seen.has(detector.tech)) {
120
+ seen.add(detector.tech);
121
+ techs.push({
122
+ name: detector.tech,
123
+ category: detector.category,
124
+ confidence: 0.7,
125
+ source: `${entry}/${detector.glob}`,
126
+ });
127
+ }
128
+ }
129
+ }
130
+ catch { /* not a directory or no access */ }
131
+ }
132
+ // Parse package.json for deps
133
+ const pkgPath = join(projectRoot, 'package.json');
134
+ if (existsSync(pkgPath)) {
135
+ try {
136
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
137
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
138
+ const depNames = Object.keys(allDeps).map((d) => d.toLowerCase());
139
+ const depDetectors = [
140
+ ['next', 'next.js', 'frontend'],
141
+ ['react', 'react', 'frontend'],
142
+ ['vue', 'vue', 'frontend'],
143
+ ['express', 'express', 'api'],
144
+ ['fastify', 'fastify', 'api'],
145
+ ['prisma', 'prisma', 'database'],
146
+ ['drizzle-orm', 'drizzle', 'database'],
147
+ ['redis', 'redis', 'cache'],
148
+ ['ioredis', 'redis', 'cache'],
149
+ ['bullmq', 'bullmq', 'queue'],
150
+ ['graphql', 'graphql', 'api'],
151
+ ['playwright', 'playwright', 'testing'],
152
+ ['vitest', 'vitest', 'testing'],
153
+ ['jest', 'jest', 'testing'],
154
+ ];
155
+ for (const [dep, tech, category] of depDetectors) {
156
+ if (depNames.some((d) => d.includes(dep)) && !seen.has(tech)) {
157
+ seen.add(tech);
158
+ techs.push({ name: tech, category, confidence: 0.8, source: `package.json dep: ${dep}` });
159
+ }
160
+ }
161
+ }
162
+ catch { /* invalid JSON */ }
163
+ }
164
+ return techs.sort((a, b) => b.confidence - a.confidence);
165
+ }
166
+ /** Run pretrain analysis on a project. */
167
+ export function pretrain(projectRoot) {
168
+ const techs = scanProject(projectRoot);
169
+ // Determine recommended skills from detected techs
170
+ const skillSet = new Set();
171
+ // Always recommend core skills
172
+ skillSet.add('pr-review');
173
+ skillSet.add('security-audit');
174
+ skillSet.add('debugging');
175
+ for (const tech of techs) {
176
+ const skills = CATEGORY_TO_SKILLS[tech.category] ?? [];
177
+ for (const s of skills)
178
+ skillSet.add(s);
179
+ }
180
+ const recommendedSkills = [...skillSet].sort();
181
+ // Determine recommended presets
182
+ const presetCounts = new Map();
183
+ for (const skill of recommendedSkills) {
184
+ const preset = SKILL_TO_PRESET[skill];
185
+ if (preset)
186
+ presetCounts.set(preset, (presetCounts.get(preset) ?? 0) + 1);
187
+ }
188
+ const recommendedPresets = [...presetCounts.entries()]
189
+ .sort((a, b) => b[1] - a[1])
190
+ .map(([name]) => name);
191
+ // Detect project type
192
+ const categories = new Set(techs.map((t) => t.category));
193
+ let projectType = 'generic';
194
+ if (categories.has('frontend') && categories.has('api'))
195
+ projectType = 'fullstack';
196
+ else if (categories.has('frontend'))
197
+ projectType = 'frontend';
198
+ else if (categories.has('api'))
199
+ projectType = 'backend';
200
+ else if (categories.has('data'))
201
+ projectType = 'data-engineering';
202
+ else if (categories.has('iac'))
203
+ projectType = 'infrastructure';
204
+ // Detect package count (monorepo check)
205
+ let packageCount = 1;
206
+ const pkgPath = join(projectRoot, 'pnpm-workspace.yaml');
207
+ if (existsSync(pkgPath)) {
208
+ try {
209
+ const dirs = readdirSync(join(projectRoot, 'packages'), { withFileTypes: true })
210
+ .filter((e) => e.isDirectory());
211
+ packageCount = dirs.length;
212
+ if (packageCount > 3)
213
+ skillSet.add('monorepo-management');
214
+ }
215
+ catch { /* no packages dir */ }
216
+ }
217
+ // Get project name
218
+ let projectName = 'unknown';
219
+ const rootPkg = join(projectRoot, 'package.json');
220
+ if (existsSync(rootPkg)) {
221
+ try {
222
+ const pkg = JSON.parse(readFileSync(rootPkg, 'utf-8'));
223
+ projectName = pkg.name ?? 'unknown';
224
+ }
225
+ catch { /* */ }
226
+ }
227
+ return {
228
+ projectName,
229
+ techs,
230
+ recommendedPresets,
231
+ recommendedSkills: [...skillSet].sort(),
232
+ projectType,
233
+ hasTests: techs.some((t) => t.category === 'testing'),
234
+ hasDocker: techs.some((t) => t.name === 'docker' || t.name === 'docker-compose'),
235
+ hasCI: techs.some((t) => t.category === 'ci'),
236
+ hasTerraform: techs.some((t) => t.name === 'terraform'),
237
+ hasKubernetes: techs.some((t) => t.name === 'kubernetes' || t.name === 'helm'),
238
+ packageCount,
239
+ };
240
+ }
241
+ //# sourceMappingURL=pretrain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pretrain.js","sourceRoot":"","sources":["../src/pretrain.ts"],"names":[],"mappings":"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"}
@@ -45,6 +45,17 @@ export interface SyncUpstreamReport {
45
45
  }
46
46
  /** Load sources.json from a skills package directory. */
47
47
  export declare function loadSourcesManifest(packageDir: string): SourcesManifest | undefined;
48
+ /** Info about a package with external sources. */
49
+ export interface SourcePackageInfo {
50
+ readonly name: string;
51
+ readonly dir: string;
52
+ readonly origin: OriginMeta;
53
+ readonly skillCount: number;
54
+ }
55
+ /** Discover all packages with sources.json in the monorepo. */
56
+ export declare function discoverSourcePackages(monorepoRoot: string): SourcePackageInfo[];
57
+ /** Check all packages with sources.json against upstream. */
58
+ export declare function checkAllUpstream(monorepoRoot: string): Promise<SyncUpstreamReport[]>;
48
59
  /**
49
60
  * Check all skills in a sources.json manifest against their upstream.
50
61
  * Compares line counts as a quick diff indicator (full diff would be too verbose).
@@ -1 +1 @@
1
- {"version":3,"file":"sync-upstream.d.ts","sourceRoot":"","sources":["../src/sync-upstream.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,uCAAuC;AACvC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,gCAAgC;AAChC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,+BAA+B;AAC/B,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC9C;AAED,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,aAAa,GAAG,eAAe,CAAC;IAC5E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,4CAA4C;AAC5C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACjD;AAED,yDAAyD;AACzD,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAKnF;AA6BD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAiD/F"}
1
+ {"version":3,"file":"sync-upstream.d.ts","sourceRoot":"","sources":["../src/sync-upstream.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,uCAAuC;AACvC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,gCAAgC;AAChC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,+BAA+B;AAC/B,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC9C;AAED,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,aAAa,GAAG,eAAe,CAAC;IAC5E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,4CAA4C;AAC5C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACjD;AAED,yDAAyD;AACzD,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAKnF;AAED,kDAAkD;AAClD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,+DAA+D;AAC/D,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAmBhF;AAED,6DAA6D;AAC7D,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAQ1F;AA6BD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAiD/F"}
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * @packageDocumentation
6
6
  */
7
- import { existsSync, readFileSync } from 'node:fs';
7
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
8
8
  import { join } from 'node:path';
9
9
  /** Load sources.json from a skills package directory. */
10
10
  export function loadSourcesManifest(packageDir) {
@@ -14,6 +14,39 @@ export function loadSourcesManifest(packageDir) {
14
14
  const raw = readFileSync(sourcesPath, 'utf-8');
15
15
  return JSON.parse(raw);
16
16
  }
17
+ /** Discover all packages with sources.json in the monorepo. */
18
+ export function discoverSourcePackages(monorepoRoot) {
19
+ const baseDir = join(monorepoRoot, 'packages', '@dzhechkov');
20
+ if (!existsSync(baseDir))
21
+ return [];
22
+ const results = [];
23
+ for (const entry of readdirSync(baseDir, { withFileTypes: true })) {
24
+ if (!entry.isDirectory())
25
+ continue;
26
+ const pkgDir = join(baseDir, entry.name);
27
+ const manifest = loadSourcesManifest(pkgDir);
28
+ if (manifest) {
29
+ results.push({
30
+ name: entry.name,
31
+ dir: pkgDir,
32
+ origin: manifest.origin,
33
+ skillCount: Object.keys(manifest.skills).length,
34
+ });
35
+ }
36
+ }
37
+ return results;
38
+ }
39
+ /** Check all packages with sources.json against upstream. */
40
+ export async function checkAllUpstream(monorepoRoot) {
41
+ const packages = discoverSourcePackages(monorepoRoot);
42
+ const reports = [];
43
+ for (const pkg of packages) {
44
+ const report = await checkUpstream(pkg.dir);
45
+ if (report)
46
+ reports.push(report);
47
+ }
48
+ return reports;
49
+ }
17
50
  /** Build the raw GitHub URL for a skill's SKILL.md. */
18
51
  function rawUrl(origin, skillPath) {
19
52
  return `https://raw.githubusercontent.com/${origin.repo}/${origin.branch}/${skillPath}`;
@@ -1 +1 @@
1
- {"version":3,"file":"sync-upstream.js","sourceRoot":"","sources":["../src/sync-upstream.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync-upstream.js","sourceRoot":"","sources":["../src/sync-upstream.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA8CjC,yDAAyD;AACzD,MAAM,UAAU,mBAAmB,CAAC,UAAkB;IACpD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACrD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/C,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;AAC5C,CAAC;AAUD,+DAA+D;AAC/D,MAAM,UAAU,sBAAsB,CAAC,YAAoB;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IAC7D,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpC,MAAM,OAAO,GAAwB,EAAE,CAAC;IACxC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAClE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YAAE,SAAS;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,GAAG,EAAE,MAAM;gBACX,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM;aAChD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,6DAA6D;AAC7D,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,YAAoB;IACzD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAC;IACtD,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5C,IAAI,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,uDAAuD;AACvD,SAAS,MAAM,CAAC,MAAkB,EAAE,SAAiB;IACnD,OAAO,qCAAqC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;AAC1F,CAAC;AAED,kDAAkD;AAClD,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,YAAoB,KAAK;IAC7D,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QACjE,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QACnE,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAC1F,CAAC;AACH,CAAC;AAED,qCAAqC;AACrC,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAkB;IACpD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAEhC,MAAM,OAAO,GAA0B,EAAE,CAAC;IAE1C,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAChE,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QAE3D,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;YAC5E,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;QAEtC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC;gBACX,OAAO;gBACP,UAAU,EAAE,MAAM,CAAC,IAAI;gBACvB,MAAM,EAAE,aAAa;gBACrB,KAAK,EAAE,QAAQ,CAAC,KAAK;aACtB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,UAAU,KAAK,aAAa,CAAC;QAE7C,OAAO,CAAC,IAAI,CAAC;YACX,OAAO;YACP,UAAU,EAAE,MAAM,CAAC,IAAI;YACvB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY;YAC1C,UAAU;YACV,aAAa;SACd,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,OAAO,EAAE,OAAO,CAAC,MAAM;QACvB,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM;QAC7D,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,MAAM;QACjE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,IAAI,CAAC,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC,MAAM;QAChG,MAAM,EAAE,OAAO;KAChB,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dzhechkov/harness-core",
3
- "version": "0.3.8",
3
+ "version": "0.3.10",
4
4
  "description": "Shared harness logic - skill loading, additive apply, and the init/sync/verify/doctor operations.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,12 +25,12 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "yaml": "^2.0.0",
28
- "@dzhechkov/adapter-codex": "0.2.0",
29
28
  "@dzhechkov/adapter-claude": "0.2.0",
30
29
  "@dzhechkov/adapter-openclaude": "0.1.0",
31
30
  "@dzhechkov/adapter-opencode": "0.2.0",
31
+ "@dzhechkov/adapter-hermes": "0.2.0",
32
32
  "@dzhechkov/core": "0.2.0",
33
- "@dzhechkov/adapter-hermes": "0.2.0"
33
+ "@dzhechkov/adapter-codex": "0.2.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^25.6.0",
package/src/index.ts CHANGED
@@ -14,11 +14,13 @@ export * from './operations.js';
14
14
  export * from './workflows.js';
15
15
  export { createSkill } from './create-skill.js';
16
16
  export type { CreateSkillOptions, CreateSkillResult } from './create-skill.js';
17
- export { checkUpstream, loadSourcesManifest } from './sync-upstream.js';
18
- export type { SyncUpstreamReport, UpstreamCheckResult, SourcesManifest } from './sync-upstream.js';
17
+ export { checkUpstream, checkAllUpstream, discoverSourcePackages, loadSourcesManifest } from './sync-upstream.js';
18
+ export type { SyncUpstreamReport, UpstreamCheckResult, SourcesManifest, SourcePackageInfo } from './sync-upstream.js';
19
19
  export { benchmarkSkill, benchmarkSkills, compareSkills } from './benchmark.js';
20
20
  export { buildRegistry, searchRegistry, filterByCategory } from './registry.js';
21
21
  export { recommend } from './recommend.js';
22
+ export { pretrain } from './pretrain.js';
23
+ export type { PretrainResult, DetectedTech } from './pretrain.js';
22
24
  export type { RecommendationReport, SkillRecommendation } from './recommend.js';
23
25
  export { discoverPackages, publishPackages } from './publish.js';
24
26
  export { fetchAllDownloads } from './downloads.js';
@@ -0,0 +1,281 @@
1
+ /**
2
+ * Pretrain — bootstrap intelligence by analyzing the target project.
3
+ *
4
+ * Scans the project's file structure, package.json, and tech stack to
5
+ * automatically recommend the right skills and presets. Runs during
6
+ * `dz init --pretrain` to eliminate manual preset selection.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+
11
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
12
+ import { join } from 'node:path';
13
+
14
+ /** Detected technology in the project. */
15
+ export interface DetectedTech {
16
+ readonly name: string;
17
+ readonly category: string;
18
+ readonly confidence: number;
19
+ readonly source: string;
20
+ }
21
+
22
+ /** Pretrain analysis result. */
23
+ export interface PretrainResult {
24
+ readonly projectName: string;
25
+ readonly techs: readonly DetectedTech[];
26
+ readonly recommendedPresets: readonly string[];
27
+ readonly recommendedSkills: readonly string[];
28
+ readonly projectType: string;
29
+ readonly hasTests: boolean;
30
+ readonly hasDocker: boolean;
31
+ readonly hasCI: boolean;
32
+ readonly hasTerraform: boolean;
33
+ readonly hasKubernetes: boolean;
34
+ readonly packageCount: number;
35
+ }
36
+
37
+ /** Tech detection rules: file/pattern → tech. */
38
+ const DETECTORS: { glob: string; tech: string; category: string }[] = [
39
+ // Languages/Frameworks
40
+ { glob: 'package.json', tech: 'node.js', category: 'runtime' },
41
+ { glob: 'tsconfig.json', tech: 'typescript', category: 'language' },
42
+ { glob: 'requirements.txt', tech: 'python', category: 'runtime' },
43
+ { glob: 'pyproject.toml', tech: 'python', category: 'runtime' },
44
+ { glob: 'go.mod', tech: 'go', category: 'runtime' },
45
+ { glob: 'Cargo.toml', tech: 'rust', category: 'runtime' },
46
+ { glob: 'Gemfile', tech: 'ruby', category: 'runtime' },
47
+
48
+ // Frontend
49
+ { glob: 'next.config', tech: 'next.js', category: 'frontend' },
50
+ { glob: 'vite.config', tech: 'vite', category: 'frontend' },
51
+ { glob: 'tailwind.config', tech: 'tailwind', category: 'frontend' },
52
+
53
+ // Databases
54
+ { glob: 'prisma', tech: 'prisma', category: 'database' },
55
+ { glob: 'drizzle.config', tech: 'drizzle', category: 'database' },
56
+ { glob: 'knexfile', tech: 'knex', category: 'database' },
57
+
58
+ // Infrastructure
59
+ { glob: 'Dockerfile', tech: 'docker', category: 'infra' },
60
+ { glob: 'docker-compose', tech: 'docker-compose', category: 'infra' },
61
+ { glob: '.github/workflows', tech: 'github-actions', category: 'ci' },
62
+ { glob: '.gitlab-ci.yml', tech: 'gitlab-ci', category: 'ci' },
63
+ { glob: 'terraform', tech: 'terraform', category: 'iac' },
64
+ { glob: '.tf', tech: 'terraform', category: 'iac' },
65
+ { glob: 'k8s', tech: 'kubernetes', category: 'infra' },
66
+ { glob: 'helm', tech: 'helm', category: 'infra' },
67
+ { glob: 'nginx.conf', tech: 'nginx', category: 'infra' },
68
+
69
+ // Testing
70
+ { glob: 'vitest.config', tech: 'vitest', category: 'testing' },
71
+ { glob: 'jest.config', tech: 'jest', category: 'testing' },
72
+ { glob: 'playwright.config', tech: 'playwright', category: 'testing' },
73
+ { glob: 'cypress.config', tech: 'cypress', category: 'testing' },
74
+ { glob: '.stryker', tech: 'stryker', category: 'testing' },
75
+
76
+ // Data
77
+ { glob: 'dbt_project.yml', tech: 'dbt', category: 'data' },
78
+ { glob: 'airflow', tech: 'airflow', category: 'data' },
79
+
80
+ // API
81
+ { glob: 'openapi', tech: 'openapi', category: 'api' },
82
+ { glob: 'swagger', tech: 'swagger', category: 'api' },
83
+ { glob: '.graphql', tech: 'graphql', category: 'api' },
84
+ { glob: 'schema.graphql', tech: 'graphql', category: 'api' },
85
+
86
+ // Cache/Queue
87
+ { glob: 'redis', tech: 'redis', category: 'cache' },
88
+
89
+ // Knowledge
90
+ { glob: '.obsidian', tech: 'obsidian', category: 'knowledge' },
91
+ ];
92
+
93
+ /** Map tech categories to recommended skills. */
94
+ const CATEGORY_TO_SKILLS: Record<string, string[]> = {
95
+ 'runtime': ['debugging', 'test-writer', 'pr-review'],
96
+ 'language': ['test-writer', 'pr-review'],
97
+ 'frontend': ['frontend-implementation', 'playwright-testing'],
98
+ 'database': ['database-review', 'database-migration'],
99
+ 'infra': ['docker-compose', 'kubernetes', 'nginx-config'],
100
+ 'ci': ['ci-fix', 'github-actions'],
101
+ 'iac': ['terraform'],
102
+ 'testing': ['test-writer', 'playwright-testing'],
103
+ 'data': ['data-pipeline'],
104
+ 'api': ['api-design', 'graphql-schema'],
105
+ 'cache': ['redis-patterns'],
106
+ 'knowledge': ['obsidian'],
107
+ };
108
+
109
+ /** Map detected skills to presets. */
110
+ const SKILL_TO_PRESET: Record<string, string> = {
111
+ 'pr-review': 'devops', 'security-audit': 'devops', 'test-writer': 'devops',
112
+ 'ci-fix': 'devops', 'terraform': 'devops', 'kubernetes': 'devops',
113
+ 'docker-compose': 'devops', 'api-design': 'devops', 'debugging': 'devops',
114
+ 'database-review': 'devops', 'database-migration': 'devops',
115
+ 'github-actions': 'devops', 'nginx-config': 'devops', 'redis-patterns': 'devops',
116
+ 'graphql-schema': 'devops', 'playwright-testing': 'devops',
117
+ 'data-pipeline': 'devops', 'incident-response': 'devops',
118
+ 'frontend-implementation': 'devops', 'monorepo-management': 'devops',
119
+ 'brave-search': 'mcp', 'gmail': 'mcp', 'notion': 'mcp', 'obsidian': 'mcp',
120
+ 'git-mcp': 'mcp', 'context7': 'mcp',
121
+ };
122
+
123
+ /** Scan project directory for files matching detectors. */
124
+ function scanProject(projectRoot: string): DetectedTech[] {
125
+ const techs: DetectedTech[] = [];
126
+ const seen = new Set<string>();
127
+
128
+ // Check top-level files
129
+ let entries: string[] = [];
130
+ try {
131
+ entries = readdirSync(projectRoot).map((e) => e.toLowerCase());
132
+ } catch { return []; }
133
+
134
+ for (const detector of DETECTORS) {
135
+ const globLower = detector.glob.toLowerCase();
136
+ const match = entries.some((e) => e.includes(globLower));
137
+ if (match && !seen.has(detector.tech)) {
138
+ seen.add(detector.tech);
139
+ techs.push({
140
+ name: detector.tech,
141
+ category: detector.category,
142
+ confidence: 0.9,
143
+ source: detector.glob,
144
+ });
145
+ }
146
+ }
147
+
148
+ // Check subdirectories (1 level deep)
149
+ for (const entry of entries) {
150
+ const subPath = join(projectRoot, entry);
151
+ try {
152
+ const subEntries = readdirSync(subPath).map((e) => e.toLowerCase());
153
+ for (const detector of DETECTORS) {
154
+ const globLower = detector.glob.toLowerCase();
155
+ if (subEntries.some((e) => e.includes(globLower)) && !seen.has(detector.tech)) {
156
+ seen.add(detector.tech);
157
+ techs.push({
158
+ name: detector.tech,
159
+ category: detector.category,
160
+ confidence: 0.7,
161
+ source: `${entry}/${detector.glob}`,
162
+ });
163
+ }
164
+ }
165
+ } catch { /* not a directory or no access */ }
166
+ }
167
+
168
+ // Parse package.json for deps
169
+ const pkgPath = join(projectRoot, 'package.json');
170
+ if (existsSync(pkgPath)) {
171
+ try {
172
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as {
173
+ name?: string;
174
+ dependencies?: Record<string, string>;
175
+ devDependencies?: Record<string, string>;
176
+ };
177
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
178
+ const depNames = Object.keys(allDeps).map((d) => d.toLowerCase());
179
+
180
+ const depDetectors: [string, string, string][] = [
181
+ ['next', 'next.js', 'frontend'],
182
+ ['react', 'react', 'frontend'],
183
+ ['vue', 'vue', 'frontend'],
184
+ ['express', 'express', 'api'],
185
+ ['fastify', 'fastify', 'api'],
186
+ ['prisma', 'prisma', 'database'],
187
+ ['drizzle-orm', 'drizzle', 'database'],
188
+ ['redis', 'redis', 'cache'],
189
+ ['ioredis', 'redis', 'cache'],
190
+ ['bullmq', 'bullmq', 'queue'],
191
+ ['graphql', 'graphql', 'api'],
192
+ ['playwright', 'playwright', 'testing'],
193
+ ['vitest', 'vitest', 'testing'],
194
+ ['jest', 'jest', 'testing'],
195
+ ];
196
+
197
+ for (const [dep, tech, category] of depDetectors) {
198
+ if (depNames.some((d) => d.includes(dep)) && !seen.has(tech)) {
199
+ seen.add(tech);
200
+ techs.push({ name: tech, category, confidence: 0.8, source: `package.json dep: ${dep}` });
201
+ }
202
+ }
203
+ } catch { /* invalid JSON */ }
204
+ }
205
+
206
+ return techs.sort((a, b) => b.confidence - a.confidence);
207
+ }
208
+
209
+ /** Run pretrain analysis on a project. */
210
+ export function pretrain(projectRoot: string): PretrainResult {
211
+ const techs = scanProject(projectRoot);
212
+
213
+ // Determine recommended skills from detected techs
214
+ const skillSet = new Set<string>();
215
+ // Always recommend core skills
216
+ skillSet.add('pr-review');
217
+ skillSet.add('security-audit');
218
+ skillSet.add('debugging');
219
+
220
+ for (const tech of techs) {
221
+ const skills = CATEGORY_TO_SKILLS[tech.category] ?? [];
222
+ for (const s of skills) skillSet.add(s);
223
+ }
224
+
225
+ const recommendedSkills = [...skillSet].sort();
226
+
227
+ // Determine recommended presets
228
+ const presetCounts = new Map<string, number>();
229
+ for (const skill of recommendedSkills) {
230
+ const preset = SKILL_TO_PRESET[skill];
231
+ if (preset) presetCounts.set(preset, (presetCounts.get(preset) ?? 0) + 1);
232
+ }
233
+ const recommendedPresets = [...presetCounts.entries()]
234
+ .sort((a, b) => b[1] - a[1])
235
+ .map(([name]) => name);
236
+
237
+ // Detect project type
238
+ const categories = new Set(techs.map((t) => t.category));
239
+ let projectType = 'generic';
240
+ if (categories.has('frontend') && categories.has('api')) projectType = 'fullstack';
241
+ else if (categories.has('frontend')) projectType = 'frontend';
242
+ else if (categories.has('api')) projectType = 'backend';
243
+ else if (categories.has('data')) projectType = 'data-engineering';
244
+ else if (categories.has('iac')) projectType = 'infrastructure';
245
+
246
+ // Detect package count (monorepo check)
247
+ let packageCount = 1;
248
+ const pkgPath = join(projectRoot, 'pnpm-workspace.yaml');
249
+ if (existsSync(pkgPath)) {
250
+ try {
251
+ const dirs = readdirSync(join(projectRoot, 'packages'), { withFileTypes: true })
252
+ .filter((e) => e.isDirectory());
253
+ packageCount = dirs.length;
254
+ if (packageCount > 3) skillSet.add('monorepo-management');
255
+ } catch { /* no packages dir */ }
256
+ }
257
+
258
+ // Get project name
259
+ let projectName = 'unknown';
260
+ const rootPkg = join(projectRoot, 'package.json');
261
+ if (existsSync(rootPkg)) {
262
+ try {
263
+ const pkg = JSON.parse(readFileSync(rootPkg, 'utf-8')) as { name?: string };
264
+ projectName = pkg.name ?? 'unknown';
265
+ } catch { /* */ }
266
+ }
267
+
268
+ return {
269
+ projectName,
270
+ techs,
271
+ recommendedPresets,
272
+ recommendedSkills: [...skillSet].sort(),
273
+ projectType,
274
+ hasTests: techs.some((t) => t.category === 'testing'),
275
+ hasDocker: techs.some((t) => t.name === 'docker' || t.name === 'docker-compose'),
276
+ hasCI: techs.some((t) => t.category === 'ci'),
277
+ hasTerraform: techs.some((t) => t.name === 'terraform'),
278
+ hasKubernetes: techs.some((t) => t.name === 'kubernetes' || t.name === 'helm'),
279
+ packageCount,
280
+ };
281
+ }
@@ -5,7 +5,7 @@
5
5
  * @packageDocumentation
6
6
  */
7
7
 
8
- import { existsSync, readFileSync } from 'node:fs';
8
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
9
9
  import { join } from 'node:path';
10
10
 
11
11
  /** A single skill's source mapping. */
@@ -60,6 +60,47 @@ export function loadSourcesManifest(packageDir: string): SourcesManifest | undef
60
60
  return JSON.parse(raw) as SourcesManifest;
61
61
  }
62
62
 
63
+ /** Info about a package with external sources. */
64
+ export interface SourcePackageInfo {
65
+ readonly name: string;
66
+ readonly dir: string;
67
+ readonly origin: OriginMeta;
68
+ readonly skillCount: number;
69
+ }
70
+
71
+ /** Discover all packages with sources.json in the monorepo. */
72
+ export function discoverSourcePackages(monorepoRoot: string): SourcePackageInfo[] {
73
+ const baseDir = join(monorepoRoot, 'packages', '@dzhechkov');
74
+ if (!existsSync(baseDir)) return [];
75
+
76
+ const results: SourcePackageInfo[] = [];
77
+ for (const entry of readdirSync(baseDir, { withFileTypes: true })) {
78
+ if (!entry.isDirectory()) continue;
79
+ const pkgDir = join(baseDir, entry.name);
80
+ const manifest = loadSourcesManifest(pkgDir);
81
+ if (manifest) {
82
+ results.push({
83
+ name: entry.name,
84
+ dir: pkgDir,
85
+ origin: manifest.origin,
86
+ skillCount: Object.keys(manifest.skills).length,
87
+ });
88
+ }
89
+ }
90
+ return results;
91
+ }
92
+
93
+ /** Check all packages with sources.json against upstream. */
94
+ export async function checkAllUpstream(monorepoRoot: string): Promise<SyncUpstreamReport[]> {
95
+ const packages = discoverSourcePackages(monorepoRoot);
96
+ const reports: SyncUpstreamReport[] = [];
97
+ for (const pkg of packages) {
98
+ const report = await checkUpstream(pkg.dir);
99
+ if (report) reports.push(report);
100
+ }
101
+ return reports;
102
+ }
103
+
63
104
  /** Build the raw GitHub URL for a skill's SKILL.md. */
64
105
  function rawUrl(origin: OriginMeta, skillPath: string): string {
65
106
  return `https://raw.githubusercontent.com/${origin.repo}/${origin.branch}/${skillPath}`;