uloop-cli 0.44.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.
- package/.prettierrc.json +28 -0
- package/CLAUDE.md +61 -0
- package/dist/cli.bundle.cjs +4761 -0
- package/dist/cli.bundle.cjs.map +7 -0
- package/eslint.config.mjs +72 -0
- package/jest.config.cjs +19 -0
- package/package.json +61 -0
- package/src/__tests__/cli-e2e.test.ts +349 -0
- package/src/__tests__/setup.ts +24 -0
- package/src/arg-parser.ts +128 -0
- package/src/cli.ts +489 -0
- package/src/default-tools.json +355 -0
- package/src/direct-unity-client.ts +125 -0
- package/src/execute-tool.ts +155 -0
- package/src/port-resolver.ts +60 -0
- package/src/project-root.ts +31 -0
- package/src/simple-framer.ts +97 -0
- package/src/skills/bundled-skills.ts +64 -0
- package/src/skills/markdown.d.ts +4 -0
- package/src/skills/skill-definitions/uloop-capture-gameview/SKILL.md +39 -0
- package/src/skills/skill-definitions/uloop-clear-console/SKILL.md +34 -0
- package/src/skills/skill-definitions/uloop-compile/SKILL.md +37 -0
- package/src/skills/skill-definitions/uloop-execute-dynamic-code/SKILL.md +79 -0
- package/src/skills/skill-definitions/uloop-execute-menu-item/SKILL.md +43 -0
- package/src/skills/skill-definitions/uloop-find-game-objects/SKILL.md +46 -0
- package/src/skills/skill-definitions/uloop-focus-window/SKILL.md +34 -0
- package/src/skills/skill-definitions/uloop-get-hierarchy/SKILL.md +44 -0
- package/src/skills/skill-definitions/uloop-get-logs/SKILL.md +45 -0
- package/src/skills/skill-definitions/uloop-get-menu-items/SKILL.md +44 -0
- package/src/skills/skill-definitions/uloop-get-project-info/SKILL.md +34 -0
- package/src/skills/skill-definitions/uloop-get-provider-details/SKILL.md +45 -0
- package/src/skills/skill-definitions/uloop-get-version/SKILL.md +31 -0
- package/src/skills/skill-definitions/uloop-run-tests/SKILL.md +43 -0
- package/src/skills/skill-definitions/uloop-unity-search/SKILL.md +44 -0
- package/src/skills/skills-command.ts +118 -0
- package/src/skills/skills-manager.ts +135 -0
- package/src/tool-cache.ts +104 -0
- package/src/version.ts +7 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uloop-get-provider-details
|
|
3
|
+
description: Get Unity Search provider details via uloop CLI. Use when you need to: (1) Discover available search providers, (2) Understand search capabilities and filters, (3) Configure searches with specific provider options.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# uloop get-provider-details
|
|
7
|
+
|
|
8
|
+
Get detailed information about Unity Search providers.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uloop get-provider-details [options]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Parameters
|
|
17
|
+
|
|
18
|
+
| Parameter | Type | Default | Description |
|
|
19
|
+
|-----------|------|---------|-------------|
|
|
20
|
+
| `--provider-id` | string | - | Specific provider ID to query |
|
|
21
|
+
| `--active-only` | boolean | `false` | Only show active providers |
|
|
22
|
+
| `--include-descriptions` | boolean | `true` | Include descriptions |
|
|
23
|
+
| `--sort-by-priority` | boolean | `true` | Sort by priority |
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# List all providers
|
|
29
|
+
uloop get-provider-details
|
|
30
|
+
|
|
31
|
+
# Get specific provider
|
|
32
|
+
uloop get-provider-details --provider-id asset
|
|
33
|
+
|
|
34
|
+
# Active providers only
|
|
35
|
+
uloop get-provider-details --active-only
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Output
|
|
39
|
+
|
|
40
|
+
Returns JSON:
|
|
41
|
+
- `Providers`: array of provider info (ID, name, description, priority)
|
|
42
|
+
|
|
43
|
+
## Notes
|
|
44
|
+
|
|
45
|
+
Use provider IDs with `uloop unity-search --providers` option.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uloop-get-version
|
|
3
|
+
description: Get uLoopMCP version information via uloop CLI. Use when you need to: (1) Check uLoopMCP package version, (2) Verify installation is working correctly, (3) Troubleshoot version compatibility issues.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# uloop get-version
|
|
7
|
+
|
|
8
|
+
Get uLoopMCP version information.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uloop get-version
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Parameters
|
|
17
|
+
|
|
18
|
+
None.
|
|
19
|
+
|
|
20
|
+
## Examples
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Get version info
|
|
24
|
+
uloop get-version
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Output
|
|
28
|
+
|
|
29
|
+
Returns JSON with version information:
|
|
30
|
+
- uLoopMCP package version
|
|
31
|
+
- CLI version
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uloop-run-tests
|
|
3
|
+
description: Execute Unity Test Runner via uloop CLI. Use when you need to: (1) Run unit tests (EditMode tests), (2) Run integration tests (PlayMode tests), (3) Verify code changes don't break existing functionality.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# uloop run-tests
|
|
7
|
+
|
|
8
|
+
Execute Unity Test Runner.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uloop run-tests [options]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Parameters
|
|
17
|
+
|
|
18
|
+
| Parameter | Type | Default | Description |
|
|
19
|
+
|-----------|------|---------|-------------|
|
|
20
|
+
| `--test-mode` | string | `EditMode` | Test mode: `EditMode`, `PlayMode` |
|
|
21
|
+
| `--filter-type` | string | `all` | Filter type: `all`, `exact`, `regex`, `assembly` |
|
|
22
|
+
| `--filter-value` | string | - | Filter value (test name, pattern, or assembly) |
|
|
23
|
+
| `--save-xml` | boolean | `false` | Save test results as XML |
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Run all EditMode tests
|
|
29
|
+
uloop run-tests
|
|
30
|
+
|
|
31
|
+
# Run PlayMode tests
|
|
32
|
+
uloop run-tests --test-mode PlayMode
|
|
33
|
+
|
|
34
|
+
# Run specific test
|
|
35
|
+
uloop run-tests --filter-type exact --filter-value "MyTest.TestMethod"
|
|
36
|
+
|
|
37
|
+
# Run tests matching pattern
|
|
38
|
+
uloop run-tests --filter-type regex --filter-value ".*Integration.*"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Output
|
|
42
|
+
|
|
43
|
+
Returns JSON with test results including pass/fail counts and details.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uloop-unity-search
|
|
3
|
+
description: Search Unity project via uloop CLI. Use when you need to: (1) Find assets by name or type (scenes, prefabs, scripts, materials), (2) Search for project resources using Unity's search system, (3) Locate files within the Unity project.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# uloop unity-search
|
|
7
|
+
|
|
8
|
+
Search Unity project using Unity Search.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uloop unity-search [options]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Parameters
|
|
17
|
+
|
|
18
|
+
| Parameter | Type | Default | Description |
|
|
19
|
+
|-----------|------|---------|-------------|
|
|
20
|
+
| `--search-query` | string | - | Search query |
|
|
21
|
+
| `--providers` | array | - | Search providers (e.g., `asset`, `scene`, `find`) |
|
|
22
|
+
| `--max-results` | integer | `50` | Maximum number of results |
|
|
23
|
+
| `--save-to-file` | boolean | `false` | Save results to file |
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Search for assets
|
|
29
|
+
uloop unity-search --search-query "Player"
|
|
30
|
+
|
|
31
|
+
# Search with specific provider
|
|
32
|
+
uloop unity-search --search-query "t:Prefab" --providers asset
|
|
33
|
+
|
|
34
|
+
# Limit results
|
|
35
|
+
uloop unity-search --search-query "*.cs" --max-results 20
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Output
|
|
39
|
+
|
|
40
|
+
Returns JSON array of search results with paths and metadata.
|
|
41
|
+
|
|
42
|
+
## Notes
|
|
43
|
+
|
|
44
|
+
Use `uloop get-provider-details` to discover available search providers.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI command definitions for skills management.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import {
|
|
7
|
+
getAllSkillStatuses,
|
|
8
|
+
installAllSkills,
|
|
9
|
+
uninstallAllSkills,
|
|
10
|
+
getInstallDir,
|
|
11
|
+
getTotalSkillCount,
|
|
12
|
+
} from './skills-manager.js';
|
|
13
|
+
|
|
14
|
+
export function registerSkillsCommand(program: Command): void {
|
|
15
|
+
const skillsCmd = program.command('skills').description('Manage uloop skills for Claude Code');
|
|
16
|
+
|
|
17
|
+
skillsCmd
|
|
18
|
+
.command('list')
|
|
19
|
+
.description('List all uloop skills and their installation status')
|
|
20
|
+
.option('-g, --global', 'Check global installation (~/.claude/skills/)')
|
|
21
|
+
.action((options: { global?: boolean }) => {
|
|
22
|
+
listSkills(options.global ?? false);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
skillsCmd
|
|
26
|
+
.command('install')
|
|
27
|
+
.description('Install all uloop skills')
|
|
28
|
+
.option('-g, --global', 'Install to global location (~/.claude/skills/)')
|
|
29
|
+
.action((options: { global?: boolean }) => {
|
|
30
|
+
installSkills(options.global ?? false);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
skillsCmd
|
|
34
|
+
.command('uninstall')
|
|
35
|
+
.description('Uninstall all uloop skills')
|
|
36
|
+
.option('-g, --global', 'Uninstall from global location (~/.claude/skills/)')
|
|
37
|
+
.action((options: { global?: boolean }) => {
|
|
38
|
+
uninstallSkills(options.global ?? false);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function listSkills(global: boolean): void {
|
|
43
|
+
const location = global ? 'Global' : 'Project';
|
|
44
|
+
const dir = getInstallDir(global);
|
|
45
|
+
|
|
46
|
+
console.log(`\nuloop Skills Status (${location}):`);
|
|
47
|
+
console.log(`Location: ${dir}`);
|
|
48
|
+
console.log('='.repeat(50));
|
|
49
|
+
console.log('');
|
|
50
|
+
|
|
51
|
+
const statuses = getAllSkillStatuses(global);
|
|
52
|
+
|
|
53
|
+
for (const skill of statuses) {
|
|
54
|
+
const icon = getStatusIcon(skill.status);
|
|
55
|
+
const statusText = getStatusText(skill.status);
|
|
56
|
+
console.log(` ${icon} ${skill.name} (${statusText})`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log('');
|
|
60
|
+
console.log(`Total: ${getTotalSkillCount()} bundled skills`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function getStatusIcon(status: string): string {
|
|
64
|
+
switch (status) {
|
|
65
|
+
case 'installed':
|
|
66
|
+
return '\x1b[32m✓\x1b[0m';
|
|
67
|
+
case 'outdated':
|
|
68
|
+
return '\x1b[33m↑\x1b[0m';
|
|
69
|
+
case 'not_installed':
|
|
70
|
+
return '\x1b[31m✗\x1b[0m';
|
|
71
|
+
default:
|
|
72
|
+
return '?';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function getStatusText(status: string): string {
|
|
77
|
+
switch (status) {
|
|
78
|
+
case 'installed':
|
|
79
|
+
return 'installed';
|
|
80
|
+
case 'outdated':
|
|
81
|
+
return 'outdated';
|
|
82
|
+
case 'not_installed':
|
|
83
|
+
return 'not installed';
|
|
84
|
+
default:
|
|
85
|
+
return 'unknown';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function installSkills(global: boolean): void {
|
|
90
|
+
const location = global ? 'global' : 'project';
|
|
91
|
+
const dir = getInstallDir(global);
|
|
92
|
+
|
|
93
|
+
console.log(`\nInstalling uloop skills (${location})...`);
|
|
94
|
+
console.log('');
|
|
95
|
+
|
|
96
|
+
const result = installAllSkills(global);
|
|
97
|
+
|
|
98
|
+
console.log(`\x1b[32m✓\x1b[0m Installed: ${result.installed}`);
|
|
99
|
+
console.log(`\x1b[33m↑\x1b[0m Updated: ${result.updated}`);
|
|
100
|
+
console.log(`\x1b[90m-\x1b[0m Skipped (up-to-date): ${result.skipped}`);
|
|
101
|
+
console.log('');
|
|
102
|
+
console.log(`Skills installed to ${dir}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function uninstallSkills(global: boolean): void {
|
|
106
|
+
const location = global ? 'global' : 'project';
|
|
107
|
+
const dir = getInstallDir(global);
|
|
108
|
+
|
|
109
|
+
console.log(`\nUninstalling uloop skills (${location})...`);
|
|
110
|
+
console.log('');
|
|
111
|
+
|
|
112
|
+
const result = uninstallAllSkills(global);
|
|
113
|
+
|
|
114
|
+
console.log(`\x1b[31m✗\x1b[0m Removed: ${result.removed}`);
|
|
115
|
+
console.log(`\x1b[90m-\x1b[0m Not found: ${result.notFound}`);
|
|
116
|
+
console.log('');
|
|
117
|
+
console.log(`Skills removed from ${dir}`);
|
|
118
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills manager for installing/uninstalling/listing uloop skills.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from 'fs';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { homedir } from 'os';
|
|
8
|
+
import { BUNDLED_SKILLS, BundledSkill } from './bundled-skills.js';
|
|
9
|
+
|
|
10
|
+
export type SkillStatus = 'installed' | 'not_installed' | 'outdated';
|
|
11
|
+
|
|
12
|
+
export interface SkillInfo {
|
|
13
|
+
name: string;
|
|
14
|
+
status: SkillStatus;
|
|
15
|
+
path?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function getGlobalSkillsDir(): string {
|
|
19
|
+
return join(homedir(), '.claude', 'skills');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getProjectSkillsDir(): string {
|
|
23
|
+
return join(process.cwd(), '.claude', 'skills');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getSkillPath(skillDirName: string, global: boolean): string {
|
|
27
|
+
const baseDir = global ? getGlobalSkillsDir() : getProjectSkillsDir();
|
|
28
|
+
return join(baseDir, skillDirName, 'SKILL.md');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function isSkillInstalled(skill: BundledSkill, global: boolean): boolean {
|
|
32
|
+
const skillPath = getSkillPath(skill.dirName, global);
|
|
33
|
+
return existsSync(skillPath);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function isSkillOutdated(skill: BundledSkill, global: boolean): boolean {
|
|
37
|
+
const skillPath = getSkillPath(skill.dirName, global);
|
|
38
|
+
if (!existsSync(skillPath)) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
const installedContent = readFileSync(skillPath, 'utf-8');
|
|
42
|
+
return installedContent !== skill.content;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function getSkillStatus(skill: BundledSkill, global: boolean): SkillStatus {
|
|
46
|
+
if (!isSkillInstalled(skill, global)) {
|
|
47
|
+
return 'not_installed';
|
|
48
|
+
}
|
|
49
|
+
if (isSkillOutdated(skill, global)) {
|
|
50
|
+
return 'outdated';
|
|
51
|
+
}
|
|
52
|
+
return 'installed';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function getAllSkillStatuses(global: boolean): SkillInfo[] {
|
|
56
|
+
return BUNDLED_SKILLS.map((skill) => ({
|
|
57
|
+
name: skill.name,
|
|
58
|
+
status: getSkillStatus(skill, global),
|
|
59
|
+
path: isSkillInstalled(skill, global) ? getSkillPath(skill.dirName, global) : undefined,
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function installSkill(skill: BundledSkill, global: boolean): void {
|
|
64
|
+
const baseDir = global ? getGlobalSkillsDir() : getProjectSkillsDir();
|
|
65
|
+
const skillDir = join(baseDir, skill.dirName);
|
|
66
|
+
const skillPath = join(skillDir, 'SKILL.md');
|
|
67
|
+
|
|
68
|
+
mkdirSync(skillDir, { recursive: true });
|
|
69
|
+
writeFileSync(skillPath, skill.content, 'utf-8');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function uninstallSkill(skill: BundledSkill, global: boolean): boolean {
|
|
73
|
+
const baseDir = global ? getGlobalSkillsDir() : getProjectSkillsDir();
|
|
74
|
+
const skillDir = join(baseDir, skill.dirName);
|
|
75
|
+
|
|
76
|
+
if (!existsSync(skillDir)) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
rmSync(skillDir, { recursive: true, force: true });
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface InstallResult {
|
|
85
|
+
installed: number;
|
|
86
|
+
updated: number;
|
|
87
|
+
skipped: number;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function installAllSkills(global: boolean): InstallResult {
|
|
91
|
+
const result: InstallResult = { installed: 0, updated: 0, skipped: 0 };
|
|
92
|
+
|
|
93
|
+
for (const skill of BUNDLED_SKILLS) {
|
|
94
|
+
const status = getSkillStatus(skill, global);
|
|
95
|
+
|
|
96
|
+
if (status === 'not_installed') {
|
|
97
|
+
installSkill(skill, global);
|
|
98
|
+
result.installed++;
|
|
99
|
+
} else if (status === 'outdated') {
|
|
100
|
+
installSkill(skill, global);
|
|
101
|
+
result.updated++;
|
|
102
|
+
} else {
|
|
103
|
+
result.skipped++;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface UninstallResult {
|
|
111
|
+
removed: number;
|
|
112
|
+
notFound: number;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function uninstallAllSkills(global: boolean): UninstallResult {
|
|
116
|
+
const result: UninstallResult = { removed: 0, notFound: 0 };
|
|
117
|
+
|
|
118
|
+
for (const skill of BUNDLED_SKILLS) {
|
|
119
|
+
if (uninstallSkill(skill, global)) {
|
|
120
|
+
result.removed++;
|
|
121
|
+
} else {
|
|
122
|
+
result.notFound++;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function getInstallDir(global: boolean): string {
|
|
130
|
+
return global ? getGlobalSkillsDir() : getProjectSkillsDir();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function getTotalSkillCount(): number {
|
|
134
|
+
return BUNDLED_SKILLS.length;
|
|
135
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool cache management for CLI.
|
|
3
|
+
* Handles loading/saving tool definitions from .uloop/tools.json cache.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
import defaultToolsData from './default-tools.json';
|
|
9
|
+
import { findUnityProjectRoot } from './project-root.js';
|
|
10
|
+
|
|
11
|
+
export interface ToolProperty {
|
|
12
|
+
type: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
default?: unknown;
|
|
15
|
+
enum?: string[];
|
|
16
|
+
items?: { type: string };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ToolInputSchema {
|
|
20
|
+
type: string;
|
|
21
|
+
properties: Record<string, ToolProperty>;
|
|
22
|
+
required?: string[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface ToolDefinition {
|
|
26
|
+
name: string;
|
|
27
|
+
description: string;
|
|
28
|
+
inputSchema: ToolInputSchema;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ToolsCache {
|
|
32
|
+
version: string;
|
|
33
|
+
updatedAt?: string;
|
|
34
|
+
tools: ToolDefinition[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const CACHE_DIR = '.uloop';
|
|
38
|
+
const CACHE_FILE = 'tools.json';
|
|
39
|
+
|
|
40
|
+
function getCacheDir(): string {
|
|
41
|
+
const projectRoot = findUnityProjectRoot();
|
|
42
|
+
if (projectRoot === null) {
|
|
43
|
+
return join(process.cwd(), CACHE_DIR);
|
|
44
|
+
}
|
|
45
|
+
return join(projectRoot, CACHE_DIR);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function getCachePath(): string {
|
|
49
|
+
return join(getCacheDir(), CACHE_FILE);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Load default tools bundled with npm package.
|
|
54
|
+
*/
|
|
55
|
+
export function getDefaultTools(): ToolsCache {
|
|
56
|
+
return defaultToolsData as ToolsCache;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Load tools from cache file, falling back to default tools if cache doesn't exist.
|
|
61
|
+
*/
|
|
62
|
+
export function loadToolsCache(): ToolsCache {
|
|
63
|
+
const cachePath = getCachePath();
|
|
64
|
+
|
|
65
|
+
if (existsSync(cachePath)) {
|
|
66
|
+
try {
|
|
67
|
+
const content = readFileSync(cachePath, 'utf-8');
|
|
68
|
+
return JSON.parse(content) as ToolsCache;
|
|
69
|
+
} catch {
|
|
70
|
+
return getDefaultTools();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return getDefaultTools();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Save tools to cache file.
|
|
79
|
+
*/
|
|
80
|
+
export function saveToolsCache(cache: ToolsCache): void {
|
|
81
|
+
const cacheDir = getCacheDir();
|
|
82
|
+
const cachePath = getCachePath();
|
|
83
|
+
|
|
84
|
+
if (!existsSync(cacheDir)) {
|
|
85
|
+
mkdirSync(cacheDir, { recursive: true });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const content = JSON.stringify(cache, null, 2);
|
|
89
|
+
writeFileSync(cachePath, content, 'utf-8');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Check if cache file exists.
|
|
94
|
+
*/
|
|
95
|
+
export function hasCacheFile(): boolean {
|
|
96
|
+
return existsSync(getCachePath());
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Get the cache file path for display purposes.
|
|
101
|
+
*/
|
|
102
|
+
export function getCacheFilePath(): string {
|
|
103
|
+
return getCachePath();
|
|
104
|
+
}
|
package/src/version.ts
ADDED
package/tsconfig.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationMap": true,
|
|
14
|
+
"sourceMap": true,
|
|
15
|
+
"resolveJsonModule": true,
|
|
16
|
+
"allowSyntheticDefaultImports": true,
|
|
17
|
+
"types": ["node", "jest"]
|
|
18
|
+
},
|
|
19
|
+
"include": [
|
|
20
|
+
"src/**/*"
|
|
21
|
+
],
|
|
22
|
+
"exclude": [
|
|
23
|
+
"node_modules",
|
|
24
|
+
"dist"
|
|
25
|
+
]
|
|
26
|
+
}
|