roguelike-cli 1.2.1 → 1.2.2
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/LICENSE +21 -0
- package/README.md +18 -24
- package/dist/interactive/commands.js +122 -0
- package/package.json +1 -1
- package/src/interactive/commands.ts +138 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Creative Ventures
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ Instead of flat text files, your tasks become a **file system tree**. Nested tas
|
|
|
26
26
|
- **Navigate** your todos like directories (`cd`, `ls`, `tree`)
|
|
27
27
|
- **Attach files** directly to tasks (just put them in the folder)
|
|
28
28
|
- **Track dependencies** and blockers between tasks
|
|
29
|
-
- **Generate beautiful visualizations** — trees, block diagrams, and
|
|
29
|
+
- **Generate beautiful visualizations** — trees, block diagrams, and dungeon maps
|
|
30
30
|
- Let **AI help** you structure complex projects
|
|
31
31
|
|
|
32
32
|
## Why folders?
|
|
@@ -35,7 +35,7 @@ Instead of flat text files, your tasks become a **file system tree**. Nested tas
|
|
|
35
35
|
project/
|
|
36
36
|
├── phase-1-research/
|
|
37
37
|
│ ├── market-analysis/
|
|
38
|
-
│ │ └── competitors.xlsx
|
|
38
|
+
│ │ └── competitors.xlsx <- attach files directly
|
|
39
39
|
│ └── user-interviews/
|
|
40
40
|
├── phase-2-development/
|
|
41
41
|
│ ├── backend-api/
|
|
@@ -136,9 +136,9 @@ Now you can `cd development/backend-api` and drop your actual code files there!
|
|
|
136
136
|
└─────────────────────────────────────────────────────────────┘
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
### Dungeon Map View
|
|
139
|
+
### Dungeon Map View
|
|
140
140
|
|
|
141
|
-
Visualize your project as a dungeon map
|
|
141
|
+
Visualize your project as a dungeon map. Each room is a task, corridors show dependencies.
|
|
142
142
|
|
|
143
143
|
```
|
|
144
144
|
> map
|
|
@@ -146,32 +146,30 @@ Visualize your project as a dungeon map! Each room is a task, corridors show dep
|
|
|
146
146
|
████████████████████████████████████████
|
|
147
147
|
█ █ █
|
|
148
148
|
█ [Research] █ [Development] █
|
|
149
|
-
█
|
|
150
|
-
█
|
|
151
|
-
█ █
|
|
149
|
+
█ * Market █ * Backend █
|
|
150
|
+
█ * Users ──────+───* Frontend █
|
|
151
|
+
█ █ * Database █
|
|
152
152
|
█████████+███████████████████+██████████
|
|
153
153
|
│ │
|
|
154
154
|
█████████+███████████████████+██████████
|
|
155
155
|
█ █ █
|
|
156
156
|
█ [Launch] █ [Growth] █
|
|
157
|
-
█
|
|
158
|
-
█
|
|
159
|
-
█
|
|
157
|
+
█ * Marketing █ * Metrics █
|
|
158
|
+
█ * Press ──────+───* Feedback █
|
|
159
|
+
█ @ BOSS: Ship it! █ █
|
|
160
160
|
█ █ █
|
|
161
161
|
████████████████████████████████████████
|
|
162
162
|
|
|
163
|
-
Legend:
|
|
163
|
+
Legend: * Task @ Milestone + Door █ Wall
|
|
164
164
|
```
|
|
165
165
|
|
|
166
|
-
*Coming soon: Interactive dungeon exploration, XP for completed tasks, achievements!*
|
|
167
|
-
|
|
168
166
|
## Gamification (Roadmap)
|
|
169
167
|
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
-
|
|
168
|
+
- **XP System** — Earn experience for completing tasks
|
|
169
|
+
- **Achievements** — "First Blood", "100 Tasks", "Deep Nesting"
|
|
170
|
+
- **Boss Tasks** — Major milestones as boss fights
|
|
171
|
+
- **Dungeon Maps** — Explore your project as a roguelike dungeon
|
|
172
|
+
- **Stats** — Track velocity, streaks, completion rates
|
|
175
173
|
|
|
176
174
|
## Commands
|
|
177
175
|
|
|
@@ -180,6 +178,7 @@ Legend: ♦ Task ♣ Milestone + Door/Dependency █ Wall
|
|
|
180
178
|
| `ls` | List tasks and files |
|
|
181
179
|
| `tree` | Show task tree |
|
|
182
180
|
| `tree -A` | Include files |
|
|
181
|
+
| `map` | Dungeon map view |
|
|
183
182
|
| `cd <task>` | Enter task |
|
|
184
183
|
| `..` | Go back |
|
|
185
184
|
| `mkdir <name>` | Create task |
|
|
@@ -187,6 +186,7 @@ Legend: ♦ Task ♣ Milestone + Door/Dependency █ Wall
|
|
|
187
186
|
| `cp`, `mv`, `rm` | File operations |
|
|
188
187
|
| `config` | Settings |
|
|
189
188
|
| `help` | Examples |
|
|
189
|
+
| `v`, `version` | Show version |
|
|
190
190
|
|
|
191
191
|
## AI Integration
|
|
192
192
|
|
|
@@ -297,12 +297,6 @@ AI understands context and refines until you're happy.
|
|
|
297
297
|
|
|
298
298
|
**https://www.rlc.rocks**
|
|
299
299
|
|
|
300
|
-
## Inspired by
|
|
301
|
-
|
|
302
|
-
- [roguelike](https://www.npmjs.com/package/roguelike) — 2D dungeon map generator
|
|
303
|
-
- Unix philosophy — everything is a file
|
|
304
|
-
- GTD methodology — capture, organize, do
|
|
305
|
-
|
|
306
300
|
## License
|
|
307
301
|
|
|
308
302
|
MIT
|
|
@@ -93,6 +93,116 @@ function createFoldersFromTree(rootPath, treeContent) {
|
|
|
93
93
|
stack.push({ path: folderPath, indent });
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
+
// Generate dungeon map visualization from folder structure
|
|
97
|
+
function generateDungeonMap(dirPath) {
|
|
98
|
+
if (!fs.existsSync(dirPath)) {
|
|
99
|
+
return 'Directory does not exist.';
|
|
100
|
+
}
|
|
101
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
102
|
+
const folders = entries.filter(e => e.isDirectory() && !e.name.startsWith('.'));
|
|
103
|
+
if (folders.length === 0) {
|
|
104
|
+
return 'No rooms to display. Create some tasks first.';
|
|
105
|
+
}
|
|
106
|
+
const lines = [];
|
|
107
|
+
const roomWidth = 20;
|
|
108
|
+
const roomsPerRow = 2;
|
|
109
|
+
const wall = '█';
|
|
110
|
+
const door = '+';
|
|
111
|
+
const task = '*';
|
|
112
|
+
const milestone = '@';
|
|
113
|
+
// Group folders into rows of 2
|
|
114
|
+
const rows = [];
|
|
115
|
+
for (let i = 0; i < folders.length; i += roomsPerRow) {
|
|
116
|
+
rows.push(folders.slice(i, i + roomsPerRow));
|
|
117
|
+
}
|
|
118
|
+
// Top border
|
|
119
|
+
lines.push(' ' + wall.repeat(roomWidth * roomsPerRow + 3));
|
|
120
|
+
rows.forEach((row, rowIndex) => {
|
|
121
|
+
// Room content
|
|
122
|
+
for (let line = 0; line < 6; line++) {
|
|
123
|
+
let rowStr = ' ' + wall;
|
|
124
|
+
row.forEach((folder, colIndex) => {
|
|
125
|
+
const name = folder.name.replace(/-/g, ' ');
|
|
126
|
+
const displayName = name.length > roomWidth - 4
|
|
127
|
+
? name.substring(0, roomWidth - 7) + '...'
|
|
128
|
+
: name;
|
|
129
|
+
// Get sub-items
|
|
130
|
+
const subPath = path.join(dirPath, folder.name);
|
|
131
|
+
const subEntries = fs.existsSync(subPath)
|
|
132
|
+
? fs.readdirSync(subPath, { withFileTypes: true })
|
|
133
|
+
.filter(e => e.isDirectory() && !e.name.startsWith('.'))
|
|
134
|
+
: [];
|
|
135
|
+
if (line === 0) {
|
|
136
|
+
// Empty line
|
|
137
|
+
rowStr += ' '.repeat(roomWidth - 1) + wall;
|
|
138
|
+
}
|
|
139
|
+
else if (line === 1) {
|
|
140
|
+
// Room name
|
|
141
|
+
const title = `[${displayName}]`;
|
|
142
|
+
const padding = roomWidth - title.length - 1;
|
|
143
|
+
rowStr += ' ' + title + ' '.repeat(Math.max(0, padding - 1)) + wall;
|
|
144
|
+
}
|
|
145
|
+
else if (line >= 2 && line <= 4) {
|
|
146
|
+
// Sub-items
|
|
147
|
+
const itemIndex = line - 2;
|
|
148
|
+
if (itemIndex < subEntries.length) {
|
|
149
|
+
const subName = subEntries[itemIndex].name.replace(/-/g, ' ');
|
|
150
|
+
const shortName = subName.length > roomWidth - 6
|
|
151
|
+
? subName.substring(0, roomWidth - 9) + '...'
|
|
152
|
+
: subName;
|
|
153
|
+
const marker = subName.toLowerCase().includes('boss') ||
|
|
154
|
+
subName.toLowerCase().includes('launch') ||
|
|
155
|
+
subName.toLowerCase().includes('deploy')
|
|
156
|
+
? milestone : task;
|
|
157
|
+
const itemStr = `${marker} ${shortName}`;
|
|
158
|
+
const itemPadding = roomWidth - itemStr.length - 1;
|
|
159
|
+
rowStr += ' ' + itemStr + ' '.repeat(Math.max(0, itemPadding - 1)) + wall;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
rowStr += ' '.repeat(roomWidth - 1) + wall;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// Empty line
|
|
167
|
+
rowStr += ' '.repeat(roomWidth - 1) + wall;
|
|
168
|
+
}
|
|
169
|
+
// Add door between rooms
|
|
170
|
+
if (colIndex < row.length - 1 && line === 3) {
|
|
171
|
+
rowStr = rowStr.slice(0, -1) + door + door + door;
|
|
172
|
+
}
|
|
173
|
+
else if (colIndex < row.length - 1) {
|
|
174
|
+
rowStr = rowStr.slice(0, -1) + wall;
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
// Fill empty space if odd number of rooms
|
|
178
|
+
if (row.length < roomsPerRow) {
|
|
179
|
+
rowStr += ' '.repeat(roomWidth) + wall;
|
|
180
|
+
}
|
|
181
|
+
lines.push(rowStr);
|
|
182
|
+
}
|
|
183
|
+
// Bottom border with doors to next row
|
|
184
|
+
if (rowIndex < rows.length - 1) {
|
|
185
|
+
let borderStr = ' ' + wall.repeat(Math.floor(roomWidth / 2)) + door;
|
|
186
|
+
borderStr += wall.repeat(roomWidth - 1) + door;
|
|
187
|
+
borderStr += wall.repeat(Math.floor(roomWidth / 2) + 1);
|
|
188
|
+
lines.push(borderStr);
|
|
189
|
+
// Corridor
|
|
190
|
+
let corridorStr = ' ' + ' '.repeat(Math.floor(roomWidth / 2)) + '│';
|
|
191
|
+
corridorStr += ' '.repeat(roomWidth - 1) + '│';
|
|
192
|
+
lines.push(corridorStr);
|
|
193
|
+
borderStr = ' ' + wall.repeat(Math.floor(roomWidth / 2)) + door;
|
|
194
|
+
borderStr += wall.repeat(roomWidth - 1) + door;
|
|
195
|
+
borderStr += wall.repeat(Math.floor(roomWidth / 2) + 1);
|
|
196
|
+
lines.push(borderStr);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
// Bottom border
|
|
200
|
+
lines.push(' ' + wall.repeat(roomWidth * roomsPerRow + 3));
|
|
201
|
+
// Legend
|
|
202
|
+
lines.push('');
|
|
203
|
+
lines.push(`Legend: ${task} Task ${milestone} Milestone ${door} Door ${wall} Wall`);
|
|
204
|
+
return lines.join('\n');
|
|
205
|
+
}
|
|
96
206
|
// Global session state
|
|
97
207
|
exports.sessionState = {
|
|
98
208
|
pending: null,
|
|
@@ -168,6 +278,16 @@ async function processCommand(input, currentPath, config, signal) {
|
|
|
168
278
|
}
|
|
169
279
|
return result;
|
|
170
280
|
};
|
|
281
|
+
// Version command
|
|
282
|
+
if (command === 'v' || command === 'version') {
|
|
283
|
+
const pkg = require('../../package.json');
|
|
284
|
+
return wrapResult({ output: `Roguelike CLI v${pkg.version}` });
|
|
285
|
+
}
|
|
286
|
+
// Map command - dungeon visualization
|
|
287
|
+
if (command === 'map') {
|
|
288
|
+
const dungeonMap = generateDungeonMap(currentPath);
|
|
289
|
+
return wrapResult({ output: dungeonMap });
|
|
290
|
+
}
|
|
171
291
|
if (command === 'ls') {
|
|
172
292
|
if (!fs.existsSync(currentPath)) {
|
|
173
293
|
return wrapResult({ output: 'Directory does not exist.' });
|
|
@@ -432,6 +552,7 @@ Storage: ${config.storagePath}
|
|
|
432
552
|
tree - Show directory tree structure
|
|
433
553
|
tree -A - Show tree with files
|
|
434
554
|
tree --depth=N - Limit tree depth (e.g., --depth=2)
|
|
555
|
+
map - Dungeon map visualization
|
|
435
556
|
cd <node> - Navigate into a node
|
|
436
557
|
cd .. - Go back to parent
|
|
437
558
|
pwd - Show current path
|
|
@@ -444,6 +565,7 @@ Storage: ${config.storagePath}
|
|
|
444
565
|
rm -rf <name> - Delete folder recursively
|
|
445
566
|
config - Show configuration
|
|
446
567
|
config:apiKey=<key> - Set API key
|
|
568
|
+
v, version - Show version
|
|
447
569
|
<description> - Create schema/todo (AI generates preview)
|
|
448
570
|
save - Save pending schema to disk
|
|
449
571
|
cancel - Discard pending schema
|
package/package.json
CHANGED
|
@@ -69,6 +69,130 @@ function createFoldersFromTree(rootPath: string, treeContent: string): void {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
// Generate dungeon map visualization from folder structure
|
|
73
|
+
function generateDungeonMap(dirPath: string): string {
|
|
74
|
+
if (!fs.existsSync(dirPath)) {
|
|
75
|
+
return 'Directory does not exist.';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
79
|
+
const folders = entries.filter(e => e.isDirectory() && !e.name.startsWith('.'));
|
|
80
|
+
|
|
81
|
+
if (folders.length === 0) {
|
|
82
|
+
return 'No rooms to display. Create some tasks first.';
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const lines: string[] = [];
|
|
86
|
+
const roomWidth = 20;
|
|
87
|
+
const roomsPerRow = 2;
|
|
88
|
+
const wall = '█';
|
|
89
|
+
const door = '+';
|
|
90
|
+
const task = '*';
|
|
91
|
+
const milestone = '@';
|
|
92
|
+
|
|
93
|
+
// Group folders into rows of 2
|
|
94
|
+
const rows: typeof folders[] = [];
|
|
95
|
+
for (let i = 0; i < folders.length; i += roomsPerRow) {
|
|
96
|
+
rows.push(folders.slice(i, i + roomsPerRow));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Top border
|
|
100
|
+
lines.push(' ' + wall.repeat(roomWidth * roomsPerRow + 3));
|
|
101
|
+
|
|
102
|
+
rows.forEach((row, rowIndex) => {
|
|
103
|
+
// Room content
|
|
104
|
+
for (let line = 0; line < 6; line++) {
|
|
105
|
+
let rowStr = ' ' + wall;
|
|
106
|
+
|
|
107
|
+
row.forEach((folder, colIndex) => {
|
|
108
|
+
const name = folder.name.replace(/-/g, ' ');
|
|
109
|
+
const displayName = name.length > roomWidth - 4
|
|
110
|
+
? name.substring(0, roomWidth - 7) + '...'
|
|
111
|
+
: name;
|
|
112
|
+
|
|
113
|
+
// Get sub-items
|
|
114
|
+
const subPath = path.join(dirPath, folder.name);
|
|
115
|
+
const subEntries = fs.existsSync(subPath)
|
|
116
|
+
? fs.readdirSync(subPath, { withFileTypes: true })
|
|
117
|
+
.filter(e => e.isDirectory() && !e.name.startsWith('.'))
|
|
118
|
+
: [];
|
|
119
|
+
|
|
120
|
+
if (line === 0) {
|
|
121
|
+
// Empty line
|
|
122
|
+
rowStr += ' '.repeat(roomWidth - 1) + wall;
|
|
123
|
+
} else if (line === 1) {
|
|
124
|
+
// Room name
|
|
125
|
+
const title = `[${displayName}]`;
|
|
126
|
+
const padding = roomWidth - title.length - 1;
|
|
127
|
+
rowStr += ' ' + title + ' '.repeat(Math.max(0, padding - 1)) + wall;
|
|
128
|
+
} else if (line >= 2 && line <= 4) {
|
|
129
|
+
// Sub-items
|
|
130
|
+
const itemIndex = line - 2;
|
|
131
|
+
if (itemIndex < subEntries.length) {
|
|
132
|
+
const subName = subEntries[itemIndex].name.replace(/-/g, ' ');
|
|
133
|
+
const shortName = subName.length > roomWidth - 6
|
|
134
|
+
? subName.substring(0, roomWidth - 9) + '...'
|
|
135
|
+
: subName;
|
|
136
|
+
const marker = subName.toLowerCase().includes('boss') ||
|
|
137
|
+
subName.toLowerCase().includes('launch') ||
|
|
138
|
+
subName.toLowerCase().includes('deploy')
|
|
139
|
+
? milestone : task;
|
|
140
|
+
const itemStr = `${marker} ${shortName}`;
|
|
141
|
+
const itemPadding = roomWidth - itemStr.length - 1;
|
|
142
|
+
rowStr += ' ' + itemStr + ' '.repeat(Math.max(0, itemPadding - 1)) + wall;
|
|
143
|
+
} else {
|
|
144
|
+
rowStr += ' '.repeat(roomWidth - 1) + wall;
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
// Empty line
|
|
148
|
+
rowStr += ' '.repeat(roomWidth - 1) + wall;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Add door between rooms
|
|
152
|
+
if (colIndex < row.length - 1 && line === 3) {
|
|
153
|
+
rowStr = rowStr.slice(0, -1) + door + door + door;
|
|
154
|
+
} else if (colIndex < row.length - 1) {
|
|
155
|
+
rowStr = rowStr.slice(0, -1) + wall;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Fill empty space if odd number of rooms
|
|
160
|
+
if (row.length < roomsPerRow) {
|
|
161
|
+
rowStr += ' '.repeat(roomWidth) + wall;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
lines.push(rowStr);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Bottom border with doors to next row
|
|
168
|
+
if (rowIndex < rows.length - 1) {
|
|
169
|
+
let borderStr = ' ' + wall.repeat(Math.floor(roomWidth / 2)) + door;
|
|
170
|
+
borderStr += wall.repeat(roomWidth - 1) + door;
|
|
171
|
+
borderStr += wall.repeat(Math.floor(roomWidth / 2) + 1);
|
|
172
|
+
lines.push(borderStr);
|
|
173
|
+
|
|
174
|
+
// Corridor
|
|
175
|
+
let corridorStr = ' ' + ' '.repeat(Math.floor(roomWidth / 2)) + '│';
|
|
176
|
+
corridorStr += ' '.repeat(roomWidth - 1) + '│';
|
|
177
|
+
lines.push(corridorStr);
|
|
178
|
+
|
|
179
|
+
borderStr = ' ' + wall.repeat(Math.floor(roomWidth / 2)) + door;
|
|
180
|
+
borderStr += wall.repeat(roomWidth - 1) + door;
|
|
181
|
+
borderStr += wall.repeat(Math.floor(roomWidth / 2) + 1);
|
|
182
|
+
lines.push(borderStr);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// Bottom border
|
|
187
|
+
lines.push(' ' + wall.repeat(roomWidth * roomsPerRow + 3));
|
|
188
|
+
|
|
189
|
+
// Legend
|
|
190
|
+
lines.push('');
|
|
191
|
+
lines.push(`Legend: ${task} Task ${milestone} Milestone ${door} Door ${wall} Wall`);
|
|
192
|
+
|
|
193
|
+
return lines.join('\n');
|
|
194
|
+
}
|
|
195
|
+
|
|
72
196
|
export interface CommandResult {
|
|
73
197
|
output?: string;
|
|
74
198
|
newPath?: string;
|
|
@@ -181,6 +305,18 @@ export async function processCommand(
|
|
|
181
305
|
return result;
|
|
182
306
|
};
|
|
183
307
|
|
|
308
|
+
// Version command
|
|
309
|
+
if (command === 'v' || command === 'version') {
|
|
310
|
+
const pkg = require('../../package.json');
|
|
311
|
+
return wrapResult({ output: `Roguelike CLI v${pkg.version}` });
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Map command - dungeon visualization
|
|
315
|
+
if (command === 'map') {
|
|
316
|
+
const dungeonMap = generateDungeonMap(currentPath);
|
|
317
|
+
return wrapResult({ output: dungeonMap });
|
|
318
|
+
}
|
|
319
|
+
|
|
184
320
|
if (command === 'ls') {
|
|
185
321
|
if (!fs.existsSync(currentPath)) {
|
|
186
322
|
return wrapResult({ output: 'Directory does not exist.' });
|
|
@@ -491,6 +627,7 @@ Storage: ${config.storagePath}
|
|
|
491
627
|
tree - Show directory tree structure
|
|
492
628
|
tree -A - Show tree with files
|
|
493
629
|
tree --depth=N - Limit tree depth (e.g., --depth=2)
|
|
630
|
+
map - Dungeon map visualization
|
|
494
631
|
cd <node> - Navigate into a node
|
|
495
632
|
cd .. - Go back to parent
|
|
496
633
|
pwd - Show current path
|
|
@@ -503,6 +640,7 @@ Storage: ${config.storagePath}
|
|
|
503
640
|
rm -rf <name> - Delete folder recursively
|
|
504
641
|
config - Show configuration
|
|
505
642
|
config:apiKey=<key> - Set API key
|
|
643
|
+
v, version - Show version
|
|
506
644
|
<description> - Create schema/todo (AI generates preview)
|
|
507
645
|
save - Save pending schema to disk
|
|
508
646
|
cancel - Discard pending schema
|