@kosuke-ai/cli 0.0.1

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 (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +132 -0
  3. package/dist/index.d.ts +18 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +105 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/kosuke/commands/analyse.d.ts +15 -0
  8. package/dist/kosuke/commands/analyse.d.ts.map +1 -0
  9. package/dist/kosuke/commands/analyse.js +308 -0
  10. package/dist/kosuke/commands/analyse.js.map +1 -0
  11. package/dist/kosuke/commands/sync-rules.d.ts +8 -0
  12. package/dist/kosuke/commands/sync-rules.d.ts.map +1 -0
  13. package/dist/kosuke/commands/sync-rules.js +364 -0
  14. package/dist/kosuke/commands/sync-rules.js.map +1 -0
  15. package/dist/kosuke/types.d.ts +31 -0
  16. package/dist/kosuke/types.d.ts.map +1 -0
  17. package/dist/kosuke/types.js +5 -0
  18. package/dist/kosuke/types.js.map +1 -0
  19. package/dist/kosuke/utils/batch-creator.d.ts +14 -0
  20. package/dist/kosuke/utils/batch-creator.d.ts.map +1 -0
  21. package/dist/kosuke/utils/batch-creator.js +76 -0
  22. package/dist/kosuke/utils/batch-creator.js.map +1 -0
  23. package/dist/kosuke/utils/file-discovery.d.ts +15 -0
  24. package/dist/kosuke/utils/file-discovery.d.ts.map +1 -0
  25. package/dist/kosuke/utils/file-discovery.js +81 -0
  26. package/dist/kosuke/utils/file-discovery.js.map +1 -0
  27. package/dist/kosuke/utils/git.d.ts +29 -0
  28. package/dist/kosuke/utils/git.d.ts.map +1 -0
  29. package/dist/kosuke/utils/git.js +72 -0
  30. package/dist/kosuke/utils/git.js.map +1 -0
  31. package/dist/kosuke/utils/github.d.ts +17 -0
  32. package/dist/kosuke/utils/github.d.ts.map +1 -0
  33. package/dist/kosuke/utils/github.js +22 -0
  34. package/dist/kosuke/utils/github.js.map +1 -0
  35. package/dist/kosuke/utils/validator.d.ts +22 -0
  36. package/dist/kosuke/utils/validator.d.ts.map +1 -0
  37. package/dist/kosuke/utils/validator.js +65 -0
  38. package/dist/kosuke/utils/validator.js.map +1 -0
  39. package/package.json +52 -0
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Git utilities for Kosuke CLI
3
+ */
4
+ import type { GitInfo } from '../types.js';
5
+ /**
6
+ * Get current repository info from git remote
7
+ */
8
+ export declare function getCurrentRepo(): Promise<GitInfo>;
9
+ /**
10
+ * Detect if running in kosuke-template repository itself
11
+ */
12
+ export declare function isKosukeTemplateRepo(): Promise<boolean>;
13
+ /**
14
+ * Create and checkout a new branch
15
+ */
16
+ export declare function createBranch(branchName: string, baseBranch?: string): Promise<void>;
17
+ /**
18
+ * Commit changes with a message
19
+ */
20
+ export declare function commit(message: string): Promise<void>;
21
+ /**
22
+ * Push current branch to origin
23
+ */
24
+ export declare function push(branchName: string): Promise<void>;
25
+ /**
26
+ * Reset working directory to HEAD
27
+ */
28
+ export declare function reset(): Promise<void>;
29
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../../kosuke/utils/git.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAkBvD;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO7D;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,GAAE,MAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAejG;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3D;AAED;;GAEG;AACH,wBAAsB,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5D;AAED;;GAEG;AACH,wBAAsB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3C"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Git utilities for Kosuke CLI
3
+ */
4
+ import simpleGit from 'simple-git';
5
+ const git = simpleGit();
6
+ /**
7
+ * Get current repository info from git remote
8
+ */
9
+ export async function getCurrentRepo() {
10
+ const remotes = await git.getRemotes(true);
11
+ const origin = remotes.find((r) => r.name === 'origin');
12
+ if (!origin?.refs?.push) {
13
+ throw new Error('Could not determine repository from git remote origin');
14
+ }
15
+ // Parse GitHub URL (supports both HTTPS and SSH)
16
+ const match = origin.refs.push.match(/github\.com[/:]([\w-]+)\/([\w-]+?)(?:\.git)?$/) ||
17
+ origin.refs.push.match(/^([\w-]+)\/([\w-]+)$/);
18
+ if (!match) {
19
+ throw new Error(`Could not parse GitHub repository from URL: ${origin.refs.push}`);
20
+ }
21
+ return { owner: match[1], repo: match[2] };
22
+ }
23
+ /**
24
+ * Detect if running in kosuke-template repository itself
25
+ */
26
+ export async function isKosukeTemplateRepo() {
27
+ try {
28
+ const { owner, repo } = await getCurrentRepo();
29
+ return owner === 'Kosuke-Org' && repo === 'kosuke-template';
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ /**
36
+ * Create and checkout a new branch
37
+ */
38
+ export async function createBranch(branchName, baseBranch = 'main') {
39
+ await git.checkout(baseBranch);
40
+ await git.pull('origin', baseBranch);
41
+ // Delete local branch if exists
42
+ try {
43
+ const branches = await git.branchLocal();
44
+ if (branches.all.includes(branchName)) {
45
+ await git.deleteLocalBranch(branchName, true);
46
+ }
47
+ }
48
+ catch {
49
+ // Branch doesn't exist, continue
50
+ }
51
+ await git.checkoutLocalBranch(branchName);
52
+ }
53
+ /**
54
+ * Commit changes with a message
55
+ */
56
+ export async function commit(message) {
57
+ await git.add(['-A']);
58
+ await git.commit(message, ['--no-verify']);
59
+ }
60
+ /**
61
+ * Push current branch to origin
62
+ */
63
+ export async function push(branchName) {
64
+ await git.push('origin', branchName, ['--set-upstream']);
65
+ }
66
+ /**
67
+ * Reset working directory to HEAD
68
+ */
69
+ export async function reset() {
70
+ await git.reset(['--hard', 'HEAD']);
71
+ }
72
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../../kosuke/utils/git.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,SAA6B,MAAM,YAAY,CAAC;AAGvD,MAAM,GAAG,GAAc,SAAS,EAAE,CAAC;AAEnC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAExD,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,iDAAiD;IACjD,MAAM,KAAK,GACT,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,+CAA+C,CAAC;QACvE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAEjD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,+CAA+C,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC;QACH,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC;QAC/C,OAAO,KAAK,KAAK,YAAY,IAAI,IAAI,KAAK,iBAAiB,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAkB,EAAE,aAAqB,MAAM;IAChF,MAAM,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC/B,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAErC,gCAAgC;IAChC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;QACzC,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACtC,MAAM,GAAG,CAAC,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,iCAAiC;IACnC,CAAC;IAED,MAAM,GAAG,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAe;IAC1C,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACtB,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,UAAkB;IAC3C,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * GitHub API utilities for Kosuke CLI
3
+ */
4
+ interface CreatePROptions {
5
+ owner: string;
6
+ repo: string;
7
+ title: string;
8
+ body: string;
9
+ head: string;
10
+ base: string;
11
+ }
12
+ /**
13
+ * Create a pull request
14
+ */
15
+ export declare function createPullRequest(options: CreatePROptions): Promise<string>;
16
+ export {};
17
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../kosuke/utils/github.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAWjF"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * GitHub API utilities for Kosuke CLI
3
+ */
4
+ import { Octokit } from '@octokit/rest';
5
+ const octokit = new Octokit({
6
+ auth: process.env.GITHUB_TOKEN,
7
+ });
8
+ /**
9
+ * Create a pull request
10
+ */
11
+ export async function createPullRequest(options) {
12
+ const { data: pr } = await octokit.pulls.create({
13
+ owner: options.owner,
14
+ repo: options.repo,
15
+ title: options.title,
16
+ head: options.head,
17
+ base: options.base,
18
+ body: options.body,
19
+ });
20
+ return pr.html_url;
21
+ }
22
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../../../kosuke/utils/github.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;IAC1B,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;CAC/B,CAAC,CAAC;AAWH;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAwB;IAC9D,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;QAC9C,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC,CAAC;IAEH,OAAO,EAAE,CAAC,QAAQ,CAAC;AACrB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Code validation utilities (lint, typecheck)
3
+ */
4
+ interface ValidationResult {
5
+ success: boolean;
6
+ output?: string;
7
+ error?: string;
8
+ }
9
+ /**
10
+ * Run ESLint with auto-fix
11
+ */
12
+ export declare function runLint(): Promise<ValidationResult>;
13
+ /**
14
+ * Run TypeScript type checking
15
+ */
16
+ export declare function runTypecheck(): Promise<ValidationResult>;
17
+ /**
18
+ * Run formatting
19
+ */
20
+ export declare function runFormat(): Promise<ValidationResult>;
21
+ export {};
22
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../kosuke/utils/validator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,UAAU,gBAAgB;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAezD;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAe9D;AAED;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAe3D"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Code validation utilities (lint, typecheck)
3
+ */
4
+ import { execSync } from 'child_process';
5
+ /**
6
+ * Run ESLint with auto-fix
7
+ */
8
+ export async function runLint() {
9
+ try {
10
+ const output = execSync('bun run lint --fix', {
11
+ cwd: process.cwd(),
12
+ encoding: 'utf-8',
13
+ stdio: 'pipe',
14
+ });
15
+ return { success: true, output };
16
+ }
17
+ catch (error) {
18
+ const err = error;
19
+ return {
20
+ success: false,
21
+ error: err.stdout || err.stderr || err.message,
22
+ };
23
+ }
24
+ }
25
+ /**
26
+ * Run TypeScript type checking
27
+ */
28
+ export async function runTypecheck() {
29
+ try {
30
+ const output = execSync('bun run typecheck', {
31
+ cwd: process.cwd(),
32
+ encoding: 'utf-8',
33
+ stdio: 'pipe',
34
+ });
35
+ return { success: true, output };
36
+ }
37
+ catch (error) {
38
+ const err = error;
39
+ return {
40
+ success: false,
41
+ error: err.stdout || err.stderr || err.message,
42
+ };
43
+ }
44
+ }
45
+ /**
46
+ * Run formatting
47
+ */
48
+ export async function runFormat() {
49
+ try {
50
+ const output = execSync('bun run format', {
51
+ cwd: process.cwd(),
52
+ encoding: 'utf-8',
53
+ stdio: 'pipe',
54
+ });
55
+ return { success: true, output };
56
+ }
57
+ catch (error) {
58
+ const err = error;
59
+ return {
60
+ success: false,
61
+ error: err.stdout || err.stderr || err.message,
62
+ };
63
+ }
64
+ }
65
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../kosuke/utils/validator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAQzC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,oBAAoB,EAAE;YAC5C,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;YAClB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,KAA+D,CAAC;QAC5E,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO;SAC/C,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,mBAAmB,EAAE;YAC3C,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;YAClB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,KAA+D,CAAC;QAC5E,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO;SAC/C,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,gBAAgB,EAAE;YACxC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;YAClB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,KAA+D,CAAC;QAC5E,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO;SAC/C,CAAC;IACJ,CAAC;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@kosuke-ai/cli",
3
+ "version": "0.0.1",
4
+ "description": "Kosuke CLI - Development automation tool for syncing rules and analyzing code quality",
5
+ "keywords": [
6
+ "CLI",
7
+ "automation",
8
+ "code-quality",
9
+ "claude-ai"
10
+ ],
11
+ "homepage": "https://github.com/Kosuke-Org/kosuke-cli#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/Kosuke-Org/kosuke-cli/issues"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/Kosuke-Org/kosuke-cli.git"
18
+ },
19
+ "license": "ISC",
20
+ "author": "filippo.pedrazzini@kosuke.ai",
21
+ "type": "module",
22
+ "main": "dist/index.js",
23
+ "types": "dist/index.d.ts",
24
+ "bin": {
25
+ "kosuke": "dist/index.js"
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "scripts": {
33
+ "build": "tsc",
34
+ "clean": "rm -rf dist",
35
+ "prepublishOnly": "npm run clean && npm run build",
36
+ "dev": "tsx index.ts",
37
+ "test": "echo \"Error: no test specified\" && exit 1"
38
+ },
39
+ "dependencies": {
40
+ "@anthropic-ai/claude-agent-sdk": "^0.1.0",
41
+ "@octokit/rest": "^20.0.0",
42
+ "dotenv": "^16.4.0",
43
+ "glob": "^10.3.0",
44
+ "ignore": "^5.3.0",
45
+ "simple-git": "^3.22.0"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^20.11.0",
49
+ "tsx": "^4.7.0",
50
+ "typescript": "^5.3.0"
51
+ }
52
+ }