uda-cli 0.2.0 → 0.4.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.
package/README.md CHANGED
@@ -1,66 +1,96 @@
1
1
  # UDA (Universal Dev AI)
2
2
 
3
- AI-agnostic context engineering + RAG CLI tool for game development.
3
+ AI-agnostic context engineering + RAG CLI tool for game development. Local, file-based, zero cloud dependency.
4
4
 
5
5
  ## Features
6
6
 
7
- - **Local RAG**: LanceDB + MiniLM embeddings - no API keys needed
7
+ - **Local RAG**: LanceDB + MiniLM embeddings no API keys needed
8
8
  - **Multi-AI Support**: Claude, Cursor, Windsurf, AGENTS.md, Raw export
9
9
  - **Plugin System**: Git-based engine plugins (Unity, Godot, Unreal, etc.)
10
+ - **Guided Setup**: Interactive plugin installation during `uda init`
10
11
  - **Workflow Engine**: YAML-defined AI-assisted workflows
11
- - **Project Context**: Automatic knowledge base management
12
+ - **AI-Native Integration**: Generates CLAUDE.md, skills, and agent files automatically
12
13
 
13
14
  ## Installation
14
15
 
15
16
  ```bash
16
- npm install -g uda
17
+ npm install -g uda-cli
18
+ ```
19
+
20
+ Or run directly:
21
+
22
+ ```bash
23
+ npx uda-cli init
17
24
  ```
18
25
 
19
26
  ## Quick Start
20
27
 
21
28
  ```bash
22
- # Initialize UDA in your project
29
+ # Initialize UDA in your game project (auto-detects engine)
23
30
  uda init
24
31
 
25
- # Scan and index knowledge
26
- uda scan
32
+ # The init wizard will:
33
+ # 1. Create .uda/ directory
34
+ # 2. Detect your engine (Unity/Godot/Unreal)
35
+ # 3. Prompt to install the official plugin
36
+ # 4. Scan and index knowledge
37
+ # 5. Generate AI tool files (CLAUDE.md, .cursorrules, etc.)
38
+ ```
27
39
 
28
- # Search knowledge base
29
- uda search "MonoBehaviour lifecycle"
40
+ ### Init Options
30
41
 
31
- # Export to your AI tool
32
- uda export --format claude
42
+ ```bash
43
+ uda init # Interactive (auto-detect engine)
44
+ uda init --engine unity # Specify engine explicitly
45
+ uda init --skip-plugin # Skip plugin prompt (CI/automation)
33
46
  ```
34
47
 
35
48
  ## Commands
36
49
 
37
- - `uda init` - Initialize UDA in current project
38
- - `uda sync` - Generate AI tool files from knowledge base
39
- - `uda search <query>` - Search knowledge base
40
- - `uda learn <source>` - Teach knowledge to RAG
41
- - `uda scan` - Scan project and index into RAG
42
- - `uda plugin <action>` - Manage engine plugins
43
- - `uda export --format <type>` - Export knowledge to specific format
44
- - `uda status` - Show UDA system status
45
- - `uda config [key] [value]` - Manage UDA settings
46
-
47
- ## Supported Formats
48
-
49
- - **claude**: Generates CLAUDE.md and .claude/ skills
50
- - **cursor**: Generates .cursorrules
51
- - **agents-md**: Generates AGENTS.md
52
- - **raw**: Generates full-context.md
50
+ | Command | Description |
51
+ |---------|-------------|
52
+ | `uda init` | Initialize UDA in current project |
53
+ | `uda sync` | Generate AI tool files from knowledge base |
54
+ | `uda scan` | Scan project and index into RAG |
55
+ | `uda search <query>` | Search knowledge base |
56
+ | `uda learn <source>` | Teach knowledge to RAG |
57
+ | `uda logs` | View Unity console logs |
58
+ | `uda plugin add <repo>` | Install an engine plugin |
59
+ | `uda plugin update <name>` | Update an installed plugin |
60
+ | `uda plugin update-all` | Update all plugins |
61
+ | `uda export --format <type>` | Export knowledge to specific format |
62
+ | `uda status` | Show UDA system status |
63
+ | `uda config [key] [value]` | Manage UDA settings |
64
+
65
+ ## Supported AI Tools
66
+
67
+ | Format | Generated Files | Status |
68
+ |--------|----------------|--------|
69
+ | **claude** | `CLAUDE.md`, `.claude/skills/`, `.claude/agents/` | Available |
70
+ | **cursor** | `.cursorrules` | Coming soon |
71
+ | **windsurf** | `.windsurfrules` | Coming soon |
72
+ | **agents-md** | `AGENTS.md` | Coming soon |
73
+ | **raw** | `full-context.md` | Coming soon |
53
74
 
54
75
  ## Plugin System
55
76
 
56
- Install engine-specific knowledge:
77
+ Plugins provide engine-specific knowledge, workflows, and agents. During `uda init`, you'll be prompted to install the default plugin for your detected engine.
57
78
 
58
79
  ```bash
59
- uda plugin add https://github.com/user/uda-plugin-unity.git
80
+ # Manual plugin management
81
+ uda plugin add https://github.com/Orhonbey/uda-unity-plugin.git
60
82
  uda plugin update unity
61
83
  uda plugin update-all
62
84
  ```
63
85
 
86
+ ### Available Plugins
87
+
88
+ | Engine | Plugin |
89
+ |--------|--------|
90
+ | Unity | [uda-unity-plugin](https://github.com/Orhonbey/uda-unity-plugin) |
91
+ | Godot | Coming soon |
92
+ | Unreal | Coming soon |
93
+
64
94
  ## Project Structure
65
95
 
66
96
  ```
@@ -70,8 +100,9 @@ uda plugin update-all
70
100
  │ ├── engine/ # Engine plugins (Unity, Godot, etc.)
71
101
  │ ├── project/ # Project-specific knowledge
72
102
  │ └── community/ # Community contributions
73
- ├── workflows/ # AI-assisted workflows
103
+ ├── workflows/ # AI-assisted workflows (YAML)
74
104
  ├── agents/ # Specialized AI agents
105
+ ├── logs/ # Engine logs (console.jsonl)
75
106
  ├── state/
76
107
  │ ├── current.md # Active work state
77
108
  │ ├── features/ # Feature specifications
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uda-cli",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Universal Dev AI — AI-agnostic context engineering + RAG for game development",
5
5
  "type": "module",
6
6
  "main": "./src/cli.js",
@@ -16,9 +16,11 @@
16
16
  "LICENSE"
17
17
  ],
18
18
  "scripts": {
19
- "test": "node --test src/**/*.test.js",
19
+ "test": "node --test --test-concurrency=1 src/**/*.test.js",
20
20
  "test:coverage": "node --test --experimental-test-coverage src/**/*.test.js",
21
- "dev": "node bin/uda.js"
21
+ "dev": "node bin/uda.js",
22
+ "preversion": "npm test",
23
+ "postversion": "git push origin main --follow-tags"
22
24
  },
23
25
  "keywords": [
24
26
  "ai",
@@ -32,6 +34,10 @@
32
34
  "vector-database",
33
35
  "embeddings"
34
36
  ],
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/Orhonbey/uda"
40
+ },
35
41
  "author": "UDA Contributors",
36
42
  "license": "MIT",
37
43
  "engines": {
package/src/cli.js CHANGED
@@ -10,6 +10,7 @@ import { handleConfig } from './commands/config.js';
10
10
  import { handlePluginUpdate } from './commands/plugin.js';
11
11
  import { handleExport } from './commands/export.js';
12
12
  import { handleLogs } from './commands/logs.js';
13
+ import { handleClean } from './commands/clean.js';
13
14
 
14
15
  export function createCli() {
15
16
  const program = new Command();
@@ -18,6 +19,7 @@ export function createCli() {
18
19
  .command('init')
19
20
  .description('Initialize UDA in current project')
20
21
  .option('-e, --engine <name>', 'Engine plugin to install (e.g. unity)')
22
+ .option('--skip-plugin', 'Skip plugin installation prompt')
21
23
  .action(handleInit);
22
24
 
23
25
  program
@@ -102,5 +104,11 @@ export function createCli() {
102
104
  .option('-l, --last <count>', 'Show last N entries')
103
105
  .action(handleLogs);
104
106
 
107
+ program
108
+ .command('clean')
109
+ .description('Remove UDA from current project')
110
+ .option('-f, --force', 'Skip confirmation prompt')
111
+ .action(handleClean);
112
+
105
113
  return program;
106
114
  }
@@ -0,0 +1,134 @@
1
+ // src/commands/clean.js — Remove UDA from current project
2
+ import { access, readdir, rm, unlink } from 'fs/promises'
3
+ import { createInterface } from 'readline'
4
+ import { join } from 'path'
5
+
6
+ const CLEAN_TARGETS = {
7
+ dirs: ['.uda', '.claude/commands/uda'],
8
+ files: ['CLAUDE.md', '.cursorrules', 'AGENTS.md'],
9
+ agentGlob: '.claude/agents',
10
+ agentPrefix: 'uda-',
11
+ }
12
+
13
+ async function exists(p) {
14
+ try {
15
+ await access(p)
16
+ return true
17
+ } catch {
18
+ return false
19
+ }
20
+ }
21
+
22
+ function ask(question) {
23
+ const rl = createInterface({ input: process.stdin, output: process.stdout })
24
+ return new Promise((resolve) => {
25
+ rl.question(question, (answer) => {
26
+ rl.close()
27
+ resolve(answer)
28
+ })
29
+ })
30
+ }
31
+
32
+ export async function handleClean(options = {}) {
33
+ const targets = {
34
+ dirs: [],
35
+ files: [],
36
+ }
37
+
38
+ // Check if .uda exists
39
+ const hasUda = await exists('.uda')
40
+ if (!hasUda) {
41
+ console.error('Hata: Bu dizinde UDA kurulu degil.')
42
+ process.exitCode = 1
43
+ return
44
+ }
45
+
46
+ // Collect directories
47
+ for (const dir of CLEAN_TARGETS.dirs) {
48
+ if (await exists(dir)) {
49
+ targets.dirs.push(dir)
50
+ }
51
+ }
52
+
53
+ // Collect files
54
+ for (const file of CLEAN_TARGETS.files) {
55
+ if (await exists(file)) {
56
+ targets.files.push(file)
57
+ }
58
+ }
59
+
60
+ // Collect agent files (only uda-*.md)
61
+ if (await exists(CLEAN_TARGETS.agentGlob)) {
62
+ try {
63
+ const agentFiles = await readdir(CLEAN_TARGETS.agentGlob)
64
+ for (const f of agentFiles) {
65
+ if (f.startsWith(CLEAN_TARGETS.agentPrefix) && f.endsWith('.md')) {
66
+ targets.files.push(join(CLEAN_TARGETS.agentGlob, f))
67
+ }
68
+ }
69
+ } catch {
70
+ // Ignore errors reading agents dir
71
+ }
72
+ }
73
+
74
+ // Show what will be deleted
75
+ console.log('UDA Clean — Silinecek dosyalar:')
76
+ console.log()
77
+
78
+ if (targets.dirs.length > 0) {
79
+ console.log(' Dizinler:')
80
+ for (const d of targets.dirs) {
81
+ console.log(` ${d}/`)
82
+ }
83
+ console.log()
84
+ }
85
+
86
+ if (targets.files.length > 0) {
87
+ console.log(' Dosyalar:')
88
+ for (const f of targets.files) {
89
+ console.log(` ${f}`)
90
+ }
91
+ console.log()
92
+ }
93
+
94
+ if (targets.dirs.length === 0 && targets.files.length === 0) {
95
+ console.log(' Silinecek dosya bulunamadi.')
96
+ return
97
+ }
98
+
99
+ // Ask for confirmation unless --force
100
+ if (!options.force) {
101
+ const answer = await ask('Bu islem geri alinamaz. Devam? (y/N): ')
102
+ if (answer.toLowerCase() !== 'y') {
103
+ console.log('Islem iptal edildi.')
104
+ return
105
+ }
106
+ console.log()
107
+ }
108
+
109
+ // Delete files first
110
+ let deletedFiles = 0
111
+ for (const f of targets.files) {
112
+ try {
113
+ await unlink(f)
114
+ deletedFiles++
115
+ } catch {
116
+ // Ignore errors
117
+ }
118
+ }
119
+
120
+ // Delete directories (in reverse order, nested first)
121
+ let deletedDirs = 0
122
+ const sortedDirs = [...targets.dirs].sort((a, b) => b.length - a.length)
123
+ for (const d of sortedDirs) {
124
+ try {
125
+ await rm(d, { recursive: true, force: true })
126
+ deletedDirs++
127
+ } catch {
128
+ // Ignore errors
129
+ }
130
+ }
131
+
132
+ console.log(`${deletedDirs} dizin, ${deletedFiles} dosya silindi.`)
133
+ console.log('UDA projeden kaldirildi.')
134
+ }
@@ -1,7 +1,16 @@
1
+ import { createInterface } from 'readline';
2
+ import { readFileSync } from 'fs';
3
+ import { fileURLToPath } from 'url';
4
+ import { dirname, join } from 'path';
1
5
  import { initProject } from '../core/init.js';
2
6
  import { handleScan } from './scan.js';
3
7
  import { handleSync } from './sync.js';
8
+ import { handlePluginAdd } from './plugin.js';
4
9
  import { validateEngine } from '../core/validators.js';
10
+ import { DEFAULT_PLUGINS } from '../core/constants.js';
11
+
12
+ const __dirname = dirname(fileURLToPath(import.meta.url));
13
+ const pkg = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf8'));
5
14
 
6
15
  export async function handleInit(options) {
7
16
  const root = process.cwd();
@@ -16,7 +25,7 @@ export async function handleInit(options) {
16
25
  }
17
26
  }
18
27
 
19
- console.log('UDA v0.2.0\n');
28
+ console.log(`UDA v${pkg.version}\n`);
20
29
 
21
30
  // Step 1: Create directory structure
22
31
  console.log('Creating project structure...');
@@ -29,11 +38,17 @@ export async function handleInit(options) {
29
38
  }
30
39
  console.log('✔ .uda/ directory created\n');
31
40
 
32
- // Step 2: Engine detection
41
+ // Step 2: Engine detection + plugin install prompt
33
42
  const engine = options.engine || await detectEngine(root);
34
43
  if (engine) {
35
44
  console.log(`✔ Engine detected: ${engine}`);
36
- console.log(` Run \`uda plugin add <repo>\` to install ${engine} plugin\n`);
45
+ const defaultUrl = DEFAULT_PLUGINS[engine];
46
+ if (defaultUrl && !options.skipPlugin) {
47
+ await promptPluginInstall(engine, defaultUrl);
48
+ } else if (!defaultUrl) {
49
+ console.log(` No default plugin available for ${engine}.`);
50
+ console.log(` Run \`uda plugin add <repo>\` to install a ${engine} plugin\n`);
51
+ }
37
52
  }
38
53
 
39
54
  // Step 3: Initial scan
@@ -50,6 +65,48 @@ export async function handleInit(options) {
50
65
  console.log(' uda plugin add <git-repo>');
51
66
  }
52
67
 
68
+ async function promptPluginInstall(engine, defaultUrl) {
69
+ const answer = await ask(
70
+ `\n Install official ${engine} plugin?\n` +
71
+ ` [Y] Yes, install default (${defaultUrl})\n` +
72
+ ` [C] Custom — enter your own plugin URL\n` +
73
+ ` [N] No, skip\n` +
74
+ ` Choice (Y/c/n): `
75
+ );
76
+
77
+ const choice = answer.trim().toLowerCase();
78
+
79
+ if (choice === 'n') {
80
+ console.log(' Skipped plugin installation.\n');
81
+ return;
82
+ }
83
+
84
+ let repoUrl = defaultUrl;
85
+
86
+ if (choice === 'c') {
87
+ repoUrl = await ask(' Plugin git URL: ');
88
+ repoUrl = repoUrl.trim();
89
+ if (!repoUrl) {
90
+ console.log(' No URL provided. Skipped plugin installation.\n');
91
+ return;
92
+ }
93
+ }
94
+
95
+ console.log(`\n Installing ${engine} plugin...`);
96
+ await handlePluginAdd(repoUrl);
97
+ console.log('');
98
+ }
99
+
100
+ function ask(question) {
101
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
102
+ return new Promise((resolve) => {
103
+ rl.question(question, (answer) => {
104
+ rl.close();
105
+ resolve(answer);
106
+ });
107
+ });
108
+ }
109
+
53
110
  async function detectEngine(root) {
54
111
  const { existsSync } = await import('fs');
55
112
  const { join } = await import('path');
@@ -1,6 +1,12 @@
1
1
  // src/core/constants.js
2
2
  import { join } from 'path';
3
3
 
4
+ export const DEFAULT_PLUGINS = {
5
+ unity: 'https://github.com/Orhonbey/uda-unity-plugin.git',
6
+ // godot: 'https://github.com/SunalSpaciel/uda-godot-plugin.git',
7
+ // unreal: 'https://github.com/SunalSpaciel/uda-unreal-plugin.git',
8
+ };
9
+
4
10
  export const UDA_DIR = '.uda';
5
11
 
6
12
  export function udaPaths(root) {