@kb-labs/devkit 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,6 +24,9 @@ import fs from 'node:fs';
24
24
  import path from 'node:path';
25
25
  import { fileURLToPath } from 'node:url';
26
26
 
27
+ // Shared package discovery — supports both flat and categorized layouts
28
+ import { findPackages as _findPackagePaths } from './lib/find-packages.mjs';
29
+
27
30
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
28
31
 
29
32
  // ANSI colors
@@ -56,37 +59,13 @@ const options = {
56
59
  };
57
60
 
58
61
  /**
59
- * Find all packages
62
+ * Find all packages (returns objects with path, dir)
60
63
  */
61
64
  function findPackages(rootDir) {
62
- const packages = [];
63
- const entries = fs.readdirSync(rootDir, { withFileTypes: true });
64
-
65
- for (const entry of entries) {
66
- if (!entry.isDirectory() || !entry.name.startsWith('kb-labs-')) {continue;}
67
-
68
- const repoPath = path.join(rootDir, entry.name);
69
- const packagesDir = path.join(repoPath, 'packages');
70
-
71
- if (!fs.existsSync(packagesDir)) {continue;}
72
-
73
- const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });
74
-
75
- for (const pkgDir of packageDirs) {
76
- if (!pkgDir.isDirectory()) {continue;}
77
-
78
- const packageJsonPath = path.join(packagesDir, pkgDir.name, 'package.json');
79
-
80
- if (fs.existsSync(packageJsonPath)) {
81
- packages.push({
82
- path: packageJsonPath,
83
- dir: path.join(packagesDir, pkgDir.name),
84
- });
85
- }
86
- }
87
- }
88
-
89
- return packages;
65
+ return _findPackagePaths(rootDir).map((pkgPath) => ({
66
+ path: pkgPath,
67
+ dir: path.dirname(pkgPath),
68
+ }));
90
69
  }
91
70
 
92
71
  /**
@@ -13,6 +13,9 @@ import fs from 'node:fs';
13
13
  import path from 'node:path';
14
14
  import { fileURLToPath } from 'node:url';
15
15
 
16
+ // Shared package discovery — supports both flat and categorized layouts
17
+ import { findPackages as _findPackagePaths } from './lib/find-packages.mjs';
18
+
16
19
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
17
20
 
18
21
  // ANSI colors
@@ -93,41 +96,12 @@ function validatePackage(packageJsonPath, repoName) {
93
96
  }
94
97
 
95
98
  function findPackages(rootDir) {
96
- const packages = [];
97
-
98
- // Find all kb-labs-* directories
99
- const entries = fs.readdirSync(rootDir, { withFileTypes: true });
100
-
101
- for (const entry of entries) {
102
- if (!entry.isDirectory() || !entry.name.startsWith('kb-labs-')) {continue;}
103
-
104
- const repoPath = path.join(rootDir, entry.name);
105
- const packagesDir = path.join(repoPath, 'packages');
106
-
107
- if (!fs.existsSync(packagesDir)) {continue;}
108
-
109
- const repoName = extractRepoName(entry.name);
110
- if (!repoName) {continue;}
111
-
112
- // Find all package.json files in packages/
113
- const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });
114
-
115
- for (const pkgDir of packageDirs) {
116
- if (!pkgDir.isDirectory()) {continue;}
117
-
118
- const packageJsonPath = path.join(packagesDir, pkgDir.name, 'package.json');
119
-
120
- if (fs.existsSync(packageJsonPath)) {
121
- packages.push({
122
- path: packageJsonPath,
123
- repoName,
124
- repoPath: entry.name,
125
- });
126
- }
127
- }
128
- }
129
-
130
- return packages;
99
+ return _findPackagePaths(rootDir).map((pkgPath) => {
100
+ const parts = pkgPath.split(path.sep);
101
+ const repoDir = parts.find((p) => p.startsWith('kb-labs-')) || 'unknown';
102
+ const repoName = extractRepoName(repoDir);
103
+ return { path: pkgPath, repoName, repoPath: repoDir };
104
+ }).filter((p) => p.repoName);
131
105
  }
132
106
 
133
107
  function main() {
@@ -20,6 +20,9 @@ import fs from 'node:fs';
20
20
  import path from 'node:path';
21
21
  import { fileURLToPath } from 'node:url';
22
22
 
23
+ // Shared package discovery — supports both flat and categorized layouts
24
+ import { findPackages } from './lib/find-packages.mjs';
25
+
23
26
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
24
27
 
25
28
  // ANSI colors
@@ -49,40 +52,6 @@ const options = {
49
52
  all: !args.includes('--graph') && !args.includes('--stats') && !args.includes('--tree'),
50
53
  };
51
54
 
52
- /**
53
- * Find all packages in monorepo
54
- */
55
- function findPackages(rootDir, filterPackage) {
56
- const packages = [];
57
- const entries = fs.readdirSync(rootDir, { withFileTypes: true });
58
-
59
- for (const entry of entries) {
60
- if (!entry.isDirectory() || !entry.name.startsWith('kb-labs-')) {continue;}
61
-
62
- const repoPath = path.join(rootDir, entry.name);
63
- const packagesDir = path.join(repoPath, 'packages');
64
-
65
- if (!fs.existsSync(packagesDir)) {continue;}
66
-
67
- const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });
68
-
69
- for (const pkgDir of packageDirs) {
70
- if (!pkgDir.isDirectory()) {continue;}
71
-
72
- // Filter by package name if specified
73
- if (filterPackage && pkgDir.name !== filterPackage) {continue;}
74
-
75
- const packageJsonPath = path.join(packagesDir, pkgDir.name, 'package.json');
76
-
77
- if (fs.existsSync(packageJsonPath)) {
78
- packages.push(packageJsonPath);
79
- }
80
- }
81
- }
82
-
83
- return packages;
84
- }
85
-
86
55
  /**
87
56
  * Build dependency graph
88
57
  */
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Shared package discovery for KB Labs workspace.
3
+ *
4
+ * Supports both flat and categorized workspace layouts.
5
+ * All devkit tools should import this instead of inlining their own findPackages.
6
+ */
7
+
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+
11
+ const CATEGORIES = ['platform', 'plugins', 'infra', 'templates', 'installer', 'sites'];
12
+
13
+ /**
14
+ * Find all KB Labs packages in the workspace.
15
+ *
16
+ * Scans for kb-labs-* directories in:
17
+ * Scans root level (flat: kb-labs-*) and category level (platform/kb-labs-*, plugins/kb-labs-*, etc.).
18
+ * Also scans apps/ directories for app-style packages.
19
+ *
20
+ * @param {string} rootDir - Workspace root directory
21
+ * @param {string} [filterPackage] - Optional package name filter (e.g., 'core-cli')
22
+ * @returns {string[]} Array of package.json file paths
23
+ */
24
+ export function findPackages(rootDir, filterPackage) {
25
+ const packages = [];
26
+
27
+ // Collect all repo directories (both flat and categorized)
28
+ const repoDirs = [];
29
+
30
+ const rootEntries = fs.readdirSync(rootDir, { withFileTypes: true });
31
+ for (const entry of rootEntries) {
32
+ if (!entry.isDirectory()) continue;
33
+
34
+ if (entry.name.startsWith('kb-labs-')) {
35
+ // Flat layout: kb-labs-* at root
36
+ repoDirs.push(path.join(rootDir, entry.name));
37
+ } else if (CATEGORIES.includes(entry.name)) {
38
+ // Categorized layout: platform/kb-labs-*, plugins/kb-labs-*, etc.
39
+ const categoryPath = path.join(rootDir, entry.name);
40
+ try {
41
+ const categoryEntries = fs.readdirSync(categoryPath, { withFileTypes: true });
42
+ for (const catEntry of categoryEntries) {
43
+ if (catEntry.isDirectory() && catEntry.name.startsWith('kb-labs-')) {
44
+ repoDirs.push(path.join(categoryPath, catEntry.name));
45
+ }
46
+ }
47
+ } catch {
48
+ // Category dir not readable, skip
49
+ }
50
+ }
51
+ }
52
+
53
+ // Scan each repo for packages/ and apps/ subdirectories
54
+ for (const repoPath of repoDirs) {
55
+ for (const subdir of ['packages', 'apps']) {
56
+ const pkgsDir = path.join(repoPath, subdir);
57
+ if (!fs.existsSync(pkgsDir)) continue;
58
+
59
+ try {
60
+ const pkgDirs = fs.readdirSync(pkgsDir, { withFileTypes: true });
61
+ for (const pkgDir of pkgDirs) {
62
+ if (!pkgDir.isDirectory()) continue;
63
+ if (filterPackage && pkgDir.name !== filterPackage) continue;
64
+
65
+ const packageJsonPath = path.join(pkgsDir, pkgDir.name, 'package.json');
66
+ if (fs.existsSync(packageJsonPath)) {
67
+ packages.push(packageJsonPath);
68
+ }
69
+ }
70
+ } catch {
71
+ // Dir not readable, skip
72
+ }
73
+ }
74
+ }
75
+
76
+ return packages;
77
+ }
package/eslint/node.js CHANGED
@@ -18,7 +18,9 @@ export default [
18
18
  '**/*.d.ts',
19
19
  '**/scripts/**',
20
20
  '**/eslint.config.*',
21
- '**/bootstrap.js'
21
+ '**/tsup.config.*',
22
+ '**/bootstrap.js',
23
+ '**/tsup.config.bundled_*.mjs'
22
24
  ]
23
25
  },
24
26
 
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Strict ESLint preset for KB Labs plugins.
3
+ *
4
+ * Extends the base node.js preset with architectural boundary enforcement:
5
+ * plugins can only import from @kb-labs/sdk and their own internal packages.
6
+ *
7
+ * Usage in plugin's eslint.config.js:
8
+ * import pluginPreset from '@kb-labs/devkit/eslint/plugin.js';
9
+ * export default [...pluginPreset];
10
+ */
11
+
12
+ import nodePreset from './node.js'
13
+
14
+ // Packages that plugins are allowed to import from
15
+ const ALLOWED_EXTERNAL = [
16
+ '@kb-labs/sdk',
17
+ ]
18
+
19
+ // Platform internals that plugins must NOT import directly
20
+ const FORBIDDEN_PATTERNS = [
21
+ '@kb-labs/core-*',
22
+ '@kb-labs/cli-*',
23
+ '@kb-labs/shared-*',
24
+ '@kb-labs/plugin-*',
25
+ '@kb-labs/workflow-*',
26
+ '@kb-labs/rest-api-*',
27
+ '@kb-labs/studio-*',
28
+ '@kb-labs/adapters-*',
29
+ '@kb-labs/gateway-*',
30
+ '@kb-labs/host-agent-*',
31
+ '@kb-labs/state-*',
32
+ '@kb-labs/tenant',
33
+ '@kb-labs/perm-*',
34
+ ]
35
+
36
+ export default [
37
+ ...nodePreset,
38
+
39
+ {
40
+ rules: {
41
+ 'no-restricted-imports': ['error', {
42
+ patterns: FORBIDDEN_PATTERNS.map(pattern => ({
43
+ group: [pattern],
44
+ message: `Plugins must depend only on @kb-labs/sdk. Direct imports from platform internals are not allowed. Re-export what you need through SDK.`,
45
+ })),
46
+ }],
47
+ },
48
+ },
49
+ ]
50
+
51
+ export { ALLOWED_EXTERNAL, FORBIDDEN_PATTERNS }
package/eslint/react.js CHANGED
@@ -17,7 +17,8 @@ export default [
17
17
  '**/*.config.js',
18
18
  '**/*.config.ts',
19
19
  '**/vitest-setup.ts',
20
- '**/vitest.setup.ts'
20
+ '**/vitest.setup.ts',
21
+ '**/tsup.config.bundled_*.mjs'
21
22
  ]
22
23
  },
23
24
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kb-labs/devkit",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "description": "Shared developer toolkit for KB Labs projects: TS/ESLint/Prettier/Vitest/Tsup presets and reusable GitHub Actions.",
6
6
  "files": [
@@ -65,8 +65,10 @@
65
65
  "./eslint/": "./eslint/",
66
66
  "./eslint/node.js": "./eslint/node.js",
67
67
  "./eslint/react.js": "./eslint/react.js",
68
+ "./eslint/plugin.js": "./eslint/plugin.js",
68
69
  "./eslint/node": "./eslint/node.js",
69
70
  "./eslint/react": "./eslint/react.js",
71
+ "./eslint/plugin": "./eslint/plugin.js",
70
72
  "./prettier/": "./prettier/",
71
73
  "./prettier/index.json": "./prettier/index.json",
72
74
  "./vitest/": "./vitest/",
@@ -101,6 +103,26 @@
101
103
  "./tsup/external-sync": "./tsup/external-sync.mjs",
102
104
  "./sync": "./sync/index.mjs"
103
105
  },
106
+ "scripts": {
107
+ "clean": "rimraf dist",
108
+ "build": "echo \"@kb-labs/devkit: nothing to build\"",
109
+ "lint": "echo \"@kb-labs/devkit: lint skipped (plain JS/MJS, not TS project)\" && exit 0",
110
+ "lint:fix": "eslint . --fix --ignore-pattern 'dist/**'",
111
+ "test": "vitest run --passWithNoTests",
112
+ "test:watch": "vitest --passWithNoTests",
113
+ "paths": "node ./bin/devkit-paths.mjs",
114
+ "fixtures": "node scripts/fixtures.js –help",
115
+ "fixtures:check": "node scripts/fixtures.js –action=check",
116
+ "fixtures:lint": "node scripts/fixtures.js –action=lint",
117
+ "fixtures:test": "node scripts/fixtures.js –action=test",
118
+ "fixtures:build": "node scripts/fixtures.js –action=build",
119
+ "fixtures:bootstrap": "node scripts/fixtures.js –action=bootstrap",
120
+ "fixtures:clean": "node scripts/fixtures.js –action=clean",
121
+ "fixtures:ci": "node scripts/fixtures.js –action=check –since=${GITHUB_BASE_REF:-origin/main} –concurrency=3 || node scripts/fixtures.js –action=check",
122
+ "postinstall": "kb-devkit-tsup-external --generate || true",
123
+ "dev": "tsup --config tsup.config.ts --watch",
124
+ "type-check": "echo \"@kb-labs/devkit: type-check skipped (plain JS/MJS, not TS project)\" && exit 0"
125
+ },
104
126
  "peerDependencies": {
105
127
  "@playwright/test": "*",
106
128
  "eslint": "^9.35.0",
@@ -135,11 +157,14 @@
135
157
  "dependencies": {
136
158
  "eslint-import-resolver-typescript": "^3.10.1",
137
159
  "eslint-plugin-import": "^2.32.0",
160
+ "eslint-plugin-jsx-a11y": "^6.10.0",
161
+ "eslint-plugin-react-hooks": "^5.2.0",
138
162
  "eslint-plugin-unused-imports": "^4.1.4",
139
163
  "glob": "^11.0.0",
140
164
  "yaml": "^2.8.0"
141
165
  },
142
166
  "devDependencies": {
167
+ "@kb-labs/devkit": "link:./",
143
168
  "@types/node": "^24.3.3",
144
169
  "@vitest/coverage-v8": "^3.2.4",
145
170
  "eslint": "^9.35.0",
@@ -152,9 +177,9 @@
152
177
  "tsup": "^8.5.0",
153
178
  "typescript": "^5.9.2",
154
179
  "typescript-eslint": "^8.44.0",
155
- "vitest": "^3.2.4",
156
- "@kb-labs/devkit": "1.0.0"
180
+ "vitest": "^3.2.4"
157
181
  },
182
+ "packageManager": "pnpm@9.11.0+sha512.0a203ffaed5a3f63242cd064c8fb5892366c103e328079318f78062f24ea8c9d50bc6a47aa3567cabefd824d170e78fa2745ed1f16b132e16436146b7688f19b",
158
183
  "engines": {
159
184
  "node": ">=20.0.0",
160
185
  "pnpm": ">=9.11.0"
@@ -162,25 +187,5 @@
162
187
  "license": "MIT",
163
188
  "publishConfig": {
164
189
  "access": "public"
165
- },
166
- "scripts": {
167
- "clean": "rimraf dist",
168
- "build": "echo \"@kb-labs/devkit: nothing to build\"",
169
- "lint": "eslint . --ignore-pattern 'dist/**'",
170
- "lint:fix": "eslint . --fix --ignore-pattern 'dist/**'",
171
- "test": "vitest run --passWithNoTests",
172
- "test:watch": "vitest --passWithNoTests",
173
- "paths": "node ./bin/devkit-paths.mjs",
174
- "fixtures": "node scripts/fixtures.js –help",
175
- "fixtures:check": "node scripts/fixtures.js –action=check",
176
- "fixtures:lint": "node scripts/fixtures.js –action=lint",
177
- "fixtures:test": "node scripts/fixtures.js –action=test",
178
- "fixtures:build": "node scripts/fixtures.js –action=build",
179
- "fixtures:bootstrap": "node scripts/fixtures.js –action=bootstrap",
180
- "fixtures:clean": "node scripts/fixtures.js –action=clean",
181
- "fixtures:ci": "node scripts/fixtures.js –action=check –since=${GITHUB_BASE_REF:-origin/main} –concurrency=3 || node scripts/fixtures.js –action=check",
182
- "postinstall": "kb-devkit-tsup-external --generate || true",
183
- "dev": "tsup --config tsup.config.ts --watch",
184
- "type-check": "tsc --noEmit"
185
190
  }
186
- }
191
+ }
package/sync/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  // Public API: sync runner used by bin and by consumers via import('@kb-labs/devkit/sync')
2
2
  import { createHash } from 'node:crypto';
3
- import { cp, mkdir, readFile, readdir, writeFile, access } from 'node:fs/promises';
3
+ import { cp, mkdir, readFile, readdir, writeFile, access, chmod } from 'node:fs/promises';
4
4
  import { dirname, join, resolve, relative } from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import process from 'node:process';
@@ -57,7 +57,12 @@ const BASE_MAP = {
57
57
  from: resolve(DEVKIT_ROOT, 'templates/configs'),
58
58
  to: (root) => root, // Root of package
59
59
  type: 'configs', // Special type for config drift checking
60
- }
60
+ },
61
+ hooks: {
62
+ from: resolve(DEVKIT_ROOT, 'scripts/hooks'),
63
+ to: (root) => resolve(root, 'scripts/hooks'),
64
+ type: 'hooks', // Special type: also installs into .git/hooks/
65
+ },
61
66
  };
62
67
 
63
68
  function resolveFromDevkit(p) {
@@ -231,7 +236,7 @@ async function runCheck(root, effectiveMap, targets, { verbose, scope }) {
231
236
  for (const key of targets) {
232
237
  const { from, to, type } = effectiveMap[key];
233
238
  const dst = to(root);
234
- const res = await comparePaths(from, dst, type);
239
+ const res = await comparePaths(from, dst, type === 'hooks' ? 'dir' : type);
235
240
 
236
241
  const changed = (res.diffs.length + res.onlySrc.length + (considerOnlyDst ? res.onlyDst.length : 0)) > 0;
237
242
  const item = {
@@ -373,6 +378,7 @@ async function runSync(root, effectiveMap, targets, { force, verbose, dryRun })
373
378
  return [sf, join(dst, rel)];
374
379
  });
375
380
  }
381
+ const isHooks = type === 'hooks';
376
382
  const beforeState = await Promise.all(filePairs.map(async ([srcFile, dstFile]) => {
377
383
  const existed = await exists(dstFile);
378
384
  const hb = existed ? await sha256File(dstFile).catch(() => null) : null;
@@ -404,6 +410,24 @@ async function runSync(root, effectiveMap, targets, { force, verbose, dryRun })
404
410
  details.push({ key, action: 'synced', from, dst, type });
405
411
  log(`→ ${key}: ${created} created, ${updated} updated, ${keptF} kept`);
406
412
  log(`synced ${key} -> ${dst}`);
413
+
414
+ // For hooks: also install into .git/hooks/ and chmod +x
415
+ if (isHooks) {
416
+ const gitHooksDir = resolve(root, '.git', 'hooks');
417
+ const gitDirExists = await exists(resolve(root, '.git'));
418
+ if (gitDirExists) {
419
+ await mkdir(gitHooksDir, { recursive: true });
420
+ for (const [, dstFile] of filePairs) {
421
+ const hookName = dstFile.slice(dst.length + 1);
422
+ const gitHookDst = join(gitHooksDir, hookName);
423
+ await cp(dstFile, gitHookDst, { force: true });
424
+ await chmod(gitHookDst, 0o755);
425
+ }
426
+ log(`hooks installed into .git/hooks/`);
427
+ } else {
428
+ warn(`skip .git/hooks install — no .git directory found at ${root}`);
429
+ }
430
+ }
407
431
  }
408
432
  const finishedAt = Date.now();
409
433
  log('sync done', summary, `(force=${force}, dry-run=${!!dryRun})`);
@@ -1 +1 @@
1
- {"root":["../../../kb-labs-sdk/tsup.config.ts","../../../kb-labs-sdk/vitest.config.ts","../../../kb-labs-sdk/packages/sdk/tsup.config.ts","../../../kb-labs-sdk/packages/sdk/dist/index.d.ts","../../../kb-labs-sdk/packages/sdk/dist/testing/index.d.ts","../../../kb-labs-sdk/packages/sdk/src/index.ts","../../../kb-labs-sdk/packages/sdk/src/__tests__/exports.snapshot.test.ts","../../../kb-labs-sdk/packages/sdk/src/command/index.ts","../../../kb-labs-sdk/packages/sdk/src/manifest/index.ts","../../../kb-labs-sdk/packages/sdk/src/test/create-test-context.ts","../../../kb-labs-sdk/packages/sdk/src/test/index.ts","../../../kb-labs-sdk/packages/sdk/src/testing/index.ts","../../../kb-labs-sdk/packages/sdk/src/utils/index.ts","../../../kb-labs-sdk/eslint.config.js","../../../kb-labs-sdk/packages/sdk/eslint.config.js","../../../kb-labs-sdk/packages/sdk/dist/index.js","../../../kb-labs-sdk/packages/sdk/dist/testing/index.js","../../../kb-labs-sdk/packages/sdk/tsup.config.bundled_x0ijv4r35mr.mjs","../../../kb-labs-sdk/scripts/devkit-sync.mjs"],"errors":true,"version":"5.9.3"}
1
+ {"root":["../../../kb-labs-sdk/tsup.config.bin.ts","../../../kb-labs-sdk/tsup.config.cli.ts","../../../kb-labs-sdk/tsup.config.dual.ts","../../../kb-labs-sdk/tsup.config.ts","../../../kb-labs-sdk/vitest.config.ts","../../../kb-labs-sdk/packages/sdk/tsup.config.ts","../../../kb-labs-sdk/packages/sdk/dist/index.d.ts","../../../kb-labs-sdk/packages/sdk/dist/command/index.d.ts","../../../kb-labs-sdk/packages/sdk/dist/contracts/index.d.ts","../../../kb-labs-sdk/packages/sdk/dist/hooks/index.d.ts","../../../kb-labs-sdk/packages/sdk/dist/manifest/index.d.ts","../../../kb-labs-sdk/packages/sdk/dist/testing/index.d.ts","../../../kb-labs-sdk/packages/sdk/dist/types/index.d.ts","../../../kb-labs-sdk/packages/sdk/src/index.ts","../../../kb-labs-sdk/packages/sdk/src/__tests__/deep-behavior.test.ts","../../../kb-labs-sdk/packages/sdk/src/__tests__/entrypoint-contracts.test.ts","../../../kb-labs-sdk/packages/sdk/src/__tests__/exports.snapshot.test.ts","../../../kb-labs-sdk/packages/sdk/src/__type-tests__/sdk-typing.type-test.ts","../../../kb-labs-sdk/packages/sdk/src/command/index.ts","../../../kb-labs-sdk/packages/sdk/src/contracts/index.ts","../../../kb-labs-sdk/packages/sdk/src/hooks/index.ts","../../../kb-labs-sdk/packages/sdk/src/manifest/index.ts","../../../kb-labs-sdk/packages/sdk/src/test/create-test-context.ts","../../../kb-labs-sdk/packages/sdk/src/test/index.ts","../../../kb-labs-sdk/packages/sdk/src/testing/index.ts","../../../kb-labs-sdk/packages/sdk/src/types/index.ts","../../../kb-labs-sdk/packages/sdk/src/utils/index.ts","../../../kb-labs-sdk/eslint.config.js","../../../kb-labs-sdk/packages/sdk/eslint.config.js","../../../kb-labs-sdk/packages/sdk/dist/index.js","../../../kb-labs-sdk/packages/sdk/dist/command/index.js","../../../kb-labs-sdk/packages/sdk/dist/contracts/index.js","../../../kb-labs-sdk/packages/sdk/dist/hooks/index.js","../../../kb-labs-sdk/packages/sdk/dist/manifest/index.js","../../../kb-labs-sdk/packages/sdk/dist/testing/index.js","../../../kb-labs-sdk/packages/sdk/dist/types/index.js","../../../kb-labs-sdk/packages/sdk/scripts/check-api-removals.mjs","../../../kb-labs-sdk/packages/sdk/scripts/generate-export-glossary.mjs","../../../kb-labs-sdk/scripts/devkit-sync.mjs"],"errors":true,"version":"5.9.3"}
@@ -4,7 +4,8 @@
4
4
  "outDir": "dist",
5
5
  "declaration": true,
6
6
  "declarationMap": true,
7
- "skipLibCheck": true
7
+ "skipLibCheck": true,
8
+ "types": ["node"]
8
9
  },
9
10
  "include": [
10
11
  "src"
package/tsup/bin.js CHANGED
@@ -169,4 +169,9 @@ export default defineConfig({
169
169
  banner: {
170
170
  js: '#!/usr/bin/env node',
171
171
  },
172
+ ignoreWatch: [
173
+ '**/node_modules/**',
174
+ '**/dist/**',
175
+ '**/.git/**',
176
+ ],
172
177
  });
package/tsup/dual.js CHANGED
@@ -152,4 +152,9 @@ export default defineConfig({
152
152
  ...externalList, // Explicitly listed packages (workspace + local deps)
153
153
  /^@kb-labs\//, // Force all @kb-labs packages to be external
154
154
  ],
155
+ ignoreWatch: [
156
+ '**/node_modules/**',
157
+ '**/dist/**',
158
+ '**/.git/**',
159
+ ],
155
160
  })
package/tsup/node.js CHANGED
@@ -1,8 +1,40 @@
1
1
  import { defineConfig } from 'tsup'
2
2
  import { readTsupExternalSync } from './external-sync.mjs'
3
- import { readFileSync } from 'node:fs'
3
+ import { readFileSync, existsSync } from 'node:fs'
4
4
  import { join } from 'node:path'
5
5
 
6
+ /**
7
+ * Derive tsup entry points from package.json exports field.
8
+ * Maps each export value like "./dist/foo.js" → "src/foo.ts" (or root "foo.ts").
9
+ * Falls back to ['src/index.ts'] if no exports or src file not found.
10
+ */
11
+ function resolveEntryFromExports() {
12
+ try {
13
+ const pkgPath = join(process.cwd(), 'package.json')
14
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))
15
+ const exportsMap = pkg.exports ?? {}
16
+ const srcFiles = new Set()
17
+
18
+ for (const condition of Object.values(exportsMap)) {
19
+ // condition can be a string or { import, types, require, ... }
20
+ const importPath = typeof condition === 'string' ? condition
21
+ : (condition.import ?? condition.default ?? null)
22
+ if (!importPath || typeof importPath !== 'string') continue
23
+
24
+ // "./dist/foo.js" → "foo", then try "src/foo.ts" or "foo.ts"
25
+ const base = importPath.replace(/^\.\/dist\//, '').replace(/\.js$/, '')
26
+ const candidates = [`src/${base}.ts`, `${base}.ts`]
27
+ for (const c of candidates) {
28
+ if (existsSync(join(process.cwd(), c))) { srcFiles.add(c); break }
29
+ }
30
+ }
31
+
32
+ return srcFiles.size > 0 ? Array.from(srcFiles) : ['src/index.ts']
33
+ } catch {
34
+ return ['src/index.ts']
35
+ }
36
+ }
37
+
6
38
  function resolveExternalDependencies() {
7
39
  try {
8
40
  const pkgPath = join(process.cwd(), 'package.json')
@@ -32,11 +64,12 @@ function getExternal() {
32
64
  return resolveExternalDependencies()
33
65
  }
34
66
 
35
- // Pre-compute external list once at module load time
67
+ // Pre-compute external list and entry once at module load time
36
68
  const externalList = getExternal()
69
+ const entryFromExports = resolveEntryFromExports()
37
70
 
38
71
  export default defineConfig({
39
- entry: ['src/index.ts'],
72
+ entry: entryFromExports,
40
73
  format: ['esm'],
41
74
  target: 'es2022',
42
75
  sourcemap: true,
@@ -48,6 +81,11 @@ export default defineConfig({
48
81
  splitting: false,
49
82
  skipNodeModulesBundle: true,
50
83
  shims: false,
84
+ ignoreWatch: [
85
+ '**/node_modules/**',
86
+ '**/dist/**',
87
+ '**/.git/**',
88
+ ],
51
89
  // Mark all node_modules packages as external (including transitive deps)
52
90
  // Use noExternal: [] to prevent bundling any node_modules packages
53
91
  // This is more reliable than regex for ensuring transitive deps stay external
package/tsup/react-lib.js CHANGED
@@ -13,6 +13,11 @@ export default defineConfig({
13
13
  outDir: 'dist',
14
14
  splitting: false,
15
15
  skipNodeModulesBundle: true,
16
- shims: false
16
+ shims: false,
17
+ ignoreWatch: [
18
+ '**/node_modules/**',
19
+ '**/dist/**',
20
+ '**/.git/**',
21
+ ],
17
22
  })
18
23
 
package/tsup/sdk.js CHANGED
@@ -115,4 +115,9 @@ export default defineConfig({
115
115
  // CJS packages with dynamic require
116
116
  ...PROBLEMATIC_CJS_PACKAGES,
117
117
  ],
118
+ ignoreWatch: [
119
+ '**/node_modules/**',
120
+ '**/dist/**',
121
+ '**/.git/**',
122
+ ],
118
123
  });