uda-cli 0.2.1 → 0.4.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/README.md +7 -7
- package/package.json +2 -2
- package/src/cli.js +17 -0
- package/src/commands/clean.js +134 -0
package/README.md
CHANGED
|
@@ -64,13 +64,13 @@ uda init --skip-plugin # Skip plugin prompt (CI/automation)
|
|
|
64
64
|
|
|
65
65
|
## Supported AI Tools
|
|
66
66
|
|
|
67
|
-
| Format | Generated Files |
|
|
68
|
-
|
|
69
|
-
| **claude** | `CLAUDE.md`, `.claude/skills/`, `.claude/agents/` |
|
|
70
|
-
| **cursor** | `.cursorrules` |
|
|
71
|
-
| **windsurf** | `.windsurfrules` |
|
|
72
|
-
| **agents-md** | `AGENTS.md` |
|
|
73
|
-
| **raw** | `full-context.md` |
|
|
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 |
|
|
74
74
|
|
|
75
75
|
## Plugin System
|
|
76
76
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uda-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
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,7 +16,7 @@
|
|
|
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
21
|
"dev": "node bin/uda.js",
|
|
22
22
|
"preversion": "npm test",
|
package/src/cli.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { dirname, join } from 'path';
|
|
1
4
|
import { Command } from 'commander';
|
|
2
5
|
import { handleLearn } from './commands/learn.js';
|
|
3
6
|
import { handleSearch } from './commands/search.js';
|
|
@@ -10,10 +13,18 @@ import { handleConfig } from './commands/config.js';
|
|
|
10
13
|
import { handlePluginUpdate } from './commands/plugin.js';
|
|
11
14
|
import { handleExport } from './commands/export.js';
|
|
12
15
|
import { handleLogs } from './commands/logs.js';
|
|
16
|
+
import { handleClean } from './commands/clean.js';
|
|
17
|
+
|
|
18
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
|
|
13
20
|
|
|
14
21
|
export function createCli() {
|
|
15
22
|
const program = new Command();
|
|
16
23
|
|
|
24
|
+
program
|
|
25
|
+
.name('uda')
|
|
26
|
+
.version(pkg.version);
|
|
27
|
+
|
|
17
28
|
program
|
|
18
29
|
.command('init')
|
|
19
30
|
.description('Initialize UDA in current project')
|
|
@@ -103,5 +114,11 @@ export function createCli() {
|
|
|
103
114
|
.option('-l, --last <count>', 'Show last N entries')
|
|
104
115
|
.action(handleLogs);
|
|
105
116
|
|
|
117
|
+
program
|
|
118
|
+
.command('clean')
|
|
119
|
+
.description('Remove UDA from current project')
|
|
120
|
+
.option('-f, --force', 'Skip confirmation prompt')
|
|
121
|
+
.action(handleClean);
|
|
122
|
+
|
|
106
123
|
return program;
|
|
107
124
|
}
|
|
@@ -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
|
+
}
|