uda-cli 0.2.1 → 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
@@ -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.2.1",
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,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
@@ -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();
@@ -103,5 +104,11 @@ export function createCli() {
103
104
  .option('-l, --last <count>', 'Show last N entries')
104
105
  .action(handleLogs);
105
106
 
107
+ program
108
+ .command('clean')
109
+ .description('Remove UDA from current project')
110
+ .option('-f, --force', 'Skip confirmation prompt')
111
+ .action(handleClean);
112
+
106
113
  return program;
107
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
+ }