roguelike-cli 1.0.0 → 1.2.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 +214 -0
- package/dist/ai/claude.js +1 -0
- package/dist/interactive/commands.js +79 -10
- package/dist/interactive/startup.js +2 -1
- package/package.json +1 -1
- package/src/ai/claude.ts +2 -0
- package/src/interactive/commands.ts +100 -16
- package/src/interactive/startup.ts +2 -1
- package/INSTALL.md +0 -108
package/README.md
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Roguelike CLI
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
|
|
|
5
|
+
|
|
|
6
|
+
+ \
|
|
7
|
+
\.G_.*=.
|
|
8
|
+
`(#'/.\ |
|
|
9
|
+
.>' (_--.
|
|
10
|
+
_=/d ,^\
|
|
11
|
+
~~ \)-' '
|
|
12
|
+
/ |
|
|
13
|
+
' '
|
|
14
|
+
|
|
15
|
+
╔═════════════════════════╗
|
|
16
|
+
║ Roguelike CLI v1.1 ║
|
|
17
|
+
╚═════════════════════════╝
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
AI-powered interactive terminal for creating schemas, architectures and todo lists.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm i -g roguelike-cli
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
rlc
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
First run will start the setup wizard to configure:
|
|
35
|
+
- Storage path for your notes
|
|
36
|
+
- AI provider (Claude, GPT, Gemini, Grok)
|
|
37
|
+
- API key
|
|
38
|
+
|
|
39
|
+
## Commands
|
|
40
|
+
|
|
41
|
+
| Command | Description |
|
|
42
|
+
|---------|-------------|
|
|
43
|
+
| `ls` | List all schemas, todos, and notes |
|
|
44
|
+
| `tree` | Show directory tree structure |
|
|
45
|
+
| `tree -A` | Show tree with files |
|
|
46
|
+
| `tree --depth=N` | Limit tree depth |
|
|
47
|
+
| `cd <node>` | Navigate into a node |
|
|
48
|
+
| `cd ..` | Go back to parent |
|
|
49
|
+
| `..` | Same as cd .. |
|
|
50
|
+
| `pwd` | Show current path |
|
|
51
|
+
| `open` | Open current folder in Finder |
|
|
52
|
+
| `open <folder>` | Open specific folder in Finder |
|
|
53
|
+
| `mkdir <name>` | Create new folder |
|
|
54
|
+
| `cp <src> <dest>` | Copy file or folder |
|
|
55
|
+
| `mv <src> <dest>` | Move/rename file or folder |
|
|
56
|
+
| `rm <name>` | Delete file |
|
|
57
|
+
| `rm -rf <name>` | Delete folder recursively |
|
|
58
|
+
| `config` | Show configuration |
|
|
59
|
+
| `config:apiKey=<key>` | Set API key |
|
|
60
|
+
| `init` | Run setup wizard |
|
|
61
|
+
| `help` | Show examples |
|
|
62
|
+
| `clean` | Show items to delete |
|
|
63
|
+
| `clean --yes` | Delete all items in current folder |
|
|
64
|
+
| `exit` / `quit` | Exit the program |
|
|
65
|
+
|
|
66
|
+
## Workflow
|
|
67
|
+
|
|
68
|
+
1. Type description (e.g., `todo: deploy app`)
|
|
69
|
+
2. AI generates schema preview
|
|
70
|
+
3. Refine with more instructions if needed
|
|
71
|
+
4. Type `save` to save or `cancel` to discard
|
|
72
|
+
|
|
73
|
+
**Todo** creates folder structure, **Schema** saves as `.rlc.schema` file.
|
|
74
|
+
|
|
75
|
+
## Clipboard
|
|
76
|
+
|
|
77
|
+
Add `| pbcopy` (macOS), `| copy` or `| clip` (Windows) to any command:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
> ls | pbcopy
|
|
81
|
+
> tree | pbcopy
|
|
82
|
+
> config | copy
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Examples
|
|
86
|
+
|
|
87
|
+
### Todo List
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
> todo opening company in delaware
|
|
91
|
+
|
|
92
|
+
├── register business name
|
|
93
|
+
├── file incorporation papers
|
|
94
|
+
├── get EIN number
|
|
95
|
+
└── Branch: legal
|
|
96
|
+
└── open business bank account
|
|
97
|
+
|
|
98
|
+
[Type "save" to create folder opening-company-in-delaware/]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Cloud Infrastructure Schema
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
> yandex cloud production infrastructure
|
|
105
|
+
|
|
106
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
107
|
+
│ Yandex Cloud │
|
|
108
|
+
│ │
|
|
109
|
+
│ ┌──────────────────┐ ┌──────────────────┐ │
|
|
110
|
+
│ │ back-fastapi │ │ admin-next │ │
|
|
111
|
+
│ │ (VM) │ │ (VM) │ │
|
|
112
|
+
│ └────────┬─────────┘ └──────────────────┘ │
|
|
113
|
+
│ │ │
|
|
114
|
+
│ ├──────────────────┬─────────────────┐ │
|
|
115
|
+
│ │ │ │ │
|
|
116
|
+
│ ┌────────▼────────┐ ┌─────▼──────┐ ┌──────▼────────┐ │
|
|
117
|
+
│ │ PostgreSQL │ │ Redis │ │ Cloudflare │ │
|
|
118
|
+
│ │ (Existing DB) │ │ Cluster │ │ R2 Storage │ │
|
|
119
|
+
│ └─────────────────┘ └────────────┘ └───────────────┘ │
|
|
120
|
+
└─────────────────────────────────────────────────────────────┘
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Web Application Architecture
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
> architecture production redis web application
|
|
127
|
+
|
|
128
|
+
├── load-balancer
|
|
129
|
+
├── web-servers
|
|
130
|
+
│ ├── app-server-1
|
|
131
|
+
│ ├── app-server-2
|
|
132
|
+
│ └── app-server-3
|
|
133
|
+
├── redis
|
|
134
|
+
│ ├── cache-cluster
|
|
135
|
+
│ └── session-store
|
|
136
|
+
└── database
|
|
137
|
+
├── postgres-primary
|
|
138
|
+
└── postgres-replica
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Kubernetes Cluster
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
> kubernetes cluster with postgres and redis
|
|
145
|
+
|
|
146
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
147
|
+
│ Kubernetes cluster with clusters postgres │
|
|
148
|
+
│ │
|
|
149
|
+
│ ┌──────────────┐ ┌──────────────┐ │
|
|
150
|
+
│ │ postgres │ │ redis │ │
|
|
151
|
+
│ │ │ │ │ │
|
|
152
|
+
│ │ primary-pod │ │ cache-pod-1 │ │
|
|
153
|
+
│ │ replica-pod-1│ │ cache-pod-2 │ │
|
|
154
|
+
│ │ replica-pod-2│ │ │ │
|
|
155
|
+
│ └──────┬───────┘ └──────┬───────┘ │
|
|
156
|
+
│ │ │ │
|
|
157
|
+
│ └──────────┬───────────┘ │
|
|
158
|
+
│ │ │
|
|
159
|
+
│ ┌───────▼────────┐ │
|
|
160
|
+
│ │ worker-zones │ │
|
|
161
|
+
│ │ zone-1 │ │
|
|
162
|
+
│ │ zone-2 │ │
|
|
163
|
+
│ └────────────────┘ │
|
|
164
|
+
└─────────────────────────────────────────────────────────────┘
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Recipe Steps
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
> todo bake cookies
|
|
171
|
+
|
|
172
|
+
├── Prep
|
|
173
|
+
│ ├── Gather ingredients
|
|
174
|
+
│ └── Preheat oven (375°F)
|
|
175
|
+
├── Mix
|
|
176
|
+
│ ├── Cream butter + sugar
|
|
177
|
+
│ ├── Add eggs + vanilla
|
|
178
|
+
│ └── Mix in flour
|
|
179
|
+
├── Bake
|
|
180
|
+
│ ├── Shape cookies
|
|
181
|
+
│ └── Bake 8-10 min
|
|
182
|
+
└── Cool & store
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Project Planning
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
> todo launch startup
|
|
189
|
+
|
|
190
|
+
├── Phase 1: Ideation
|
|
191
|
+
│ ├── Market research
|
|
192
|
+
│ ├── Define MVP
|
|
193
|
+
│ └── Create business plan
|
|
194
|
+
├── Phase 2: Development
|
|
195
|
+
│ ├── Build prototype
|
|
196
|
+
│ ├── User testing
|
|
197
|
+
│ └── Iterate
|
|
198
|
+
├── Phase 3: Launch
|
|
199
|
+
│ ├── Marketing campaign
|
|
200
|
+
│ ├── Press release
|
|
201
|
+
│ └── Launch day
|
|
202
|
+
└── Phase 4: Growth
|
|
203
|
+
├── Gather feedback
|
|
204
|
+
├── Scale infrastructure
|
|
205
|
+
└── Hire team
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Website
|
|
209
|
+
|
|
210
|
+
**https://www.rlc.rocks**
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
MIT
|
package/dist/ai/claude.js
CHANGED
|
@@ -41,6 +41,58 @@ const child_process_1 = require("child_process");
|
|
|
41
41
|
const storage_1 = require("../storage/storage");
|
|
42
42
|
const nodeConfig_1 = require("../storage/nodeConfig");
|
|
43
43
|
const claude_1 = require("../ai/claude");
|
|
44
|
+
// Parse tree ASCII art and create folder structure
|
|
45
|
+
function createFoldersFromTree(rootPath, treeContent) {
|
|
46
|
+
// Create root folder
|
|
47
|
+
if (!fs.existsSync(rootPath)) {
|
|
48
|
+
fs.mkdirSync(rootPath, { recursive: true });
|
|
49
|
+
}
|
|
50
|
+
// Parse tree lines
|
|
51
|
+
const lines = treeContent.split('\n');
|
|
52
|
+
const stack = [{ path: rootPath, indent: -1 }];
|
|
53
|
+
for (const line of lines) {
|
|
54
|
+
// Skip empty lines
|
|
55
|
+
if (!line.trim())
|
|
56
|
+
continue;
|
|
57
|
+
// Extract node name from tree line
|
|
58
|
+
// Patterns: "├── Name", "└── Name", "│ ├── Name", etc.
|
|
59
|
+
const match = line.match(/^([\s│]*)[├└]──\s*(.+)$/);
|
|
60
|
+
if (!match)
|
|
61
|
+
continue;
|
|
62
|
+
const prefix = match[1];
|
|
63
|
+
let nodeName = match[2].trim();
|
|
64
|
+
// Calculate indent level (each │ or space block = 1 level)
|
|
65
|
+
const indent = Math.floor(prefix.replace(/│/g, ' ').length / 4);
|
|
66
|
+
// Clean node name - remove extra info in parentheses, brackets
|
|
67
|
+
nodeName = nodeName.replace(/\s*\([^)]*\)\s*/g, '').trim();
|
|
68
|
+
nodeName = nodeName.replace(/\s*\[[^\]]*\]\s*/g, '').trim();
|
|
69
|
+
// Create safe folder name
|
|
70
|
+
const safeName = nodeName
|
|
71
|
+
.toLowerCase()
|
|
72
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
73
|
+
.replace(/^-+|-+$/g, '');
|
|
74
|
+
if (!safeName)
|
|
75
|
+
continue;
|
|
76
|
+
// Pop stack until we find parent
|
|
77
|
+
while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {
|
|
78
|
+
stack.pop();
|
|
79
|
+
}
|
|
80
|
+
const parentPath = stack[stack.length - 1].path;
|
|
81
|
+
const folderPath = path.join(parentPath, safeName);
|
|
82
|
+
// Create folder
|
|
83
|
+
if (!fs.existsSync(folderPath)) {
|
|
84
|
+
fs.mkdirSync(folderPath, { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
// Create node config
|
|
87
|
+
(0, nodeConfig_1.writeNodeConfig)(folderPath, {
|
|
88
|
+
name: nodeName,
|
|
89
|
+
createdAt: new Date().toISOString(),
|
|
90
|
+
updatedAt: new Date().toISOString(),
|
|
91
|
+
});
|
|
92
|
+
// Push to stack
|
|
93
|
+
stack.push({ path: folderPath, indent });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
44
96
|
// Global session state
|
|
45
97
|
exports.sessionState = {
|
|
46
98
|
pending: null,
|
|
@@ -485,18 +537,31 @@ Examples:
|
|
|
485
537
|
www.rlc.rocks`
|
|
486
538
|
});
|
|
487
539
|
}
|
|
488
|
-
// Save command - save pending schema
|
|
540
|
+
// Save command - save pending schema/todo
|
|
489
541
|
if (command === 'save') {
|
|
490
542
|
if (!exports.sessionState.pending) {
|
|
491
543
|
return wrapResult({ output: 'Nothing to save. Create a schema first.' });
|
|
492
544
|
}
|
|
493
|
-
const
|
|
494
|
-
const
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
545
|
+
const pending = exports.sessionState.pending;
|
|
546
|
+
const safeName = pending.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
547
|
+
if (pending.format === 'tree') {
|
|
548
|
+
// Create folder structure from tree ASCII art
|
|
549
|
+
const rootPath = path.join(currentPath, safeName);
|
|
550
|
+
createFoldersFromTree(rootPath, pending.content);
|
|
551
|
+
// Clear session
|
|
552
|
+
exports.sessionState.pending = null;
|
|
553
|
+
exports.sessionState.history = [];
|
|
554
|
+
return wrapResult({ output: `Created todo folder: ${safeName}/` });
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
// Save as .rlc.schema file
|
|
558
|
+
const schemaPath = (0, nodeConfig_1.saveSchemaFile)(currentPath, pending.title, pending.content);
|
|
559
|
+
const filename = path.basename(schemaPath);
|
|
560
|
+
// Clear session
|
|
561
|
+
exports.sessionState.pending = null;
|
|
562
|
+
exports.sessionState.history = [];
|
|
563
|
+
return wrapResult({ output: `Saved: ${filename}` });
|
|
564
|
+
}
|
|
500
565
|
}
|
|
501
566
|
// Cancel command - discard pending schema
|
|
502
567
|
if (command === 'cancel') {
|
|
@@ -539,13 +604,17 @@ www.rlc.rocks`
|
|
|
539
604
|
exports.sessionState.pending = {
|
|
540
605
|
title: schema.title,
|
|
541
606
|
content: schema.content,
|
|
607
|
+
format: schema.format,
|
|
542
608
|
tree: schema.tree
|
|
543
609
|
};
|
|
544
610
|
// Add assistant response to history
|
|
545
611
|
exports.sessionState.history.push({ role: 'assistant', content: schema.content });
|
|
546
|
-
const
|
|
612
|
+
const safeName = schema.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
613
|
+
const saveHint = schema.format === 'tree'
|
|
614
|
+
? `[Type "save" to create folder ${safeName}/, or refine with more instructions]`
|
|
615
|
+
: `[Type "save" to save as ${safeName}.rlc.schema, or refine with more instructions]`;
|
|
547
616
|
return wrapResult({
|
|
548
|
-
output: `\n${schema.content}\n\n
|
|
617
|
+
output: `\n${schema.content}\n\n${saveHint}`
|
|
549
618
|
});
|
|
550
619
|
}
|
|
551
620
|
return wrapResult({ output: 'Could not generate schema. Make sure API key is set.' });
|
|
@@ -17,7 +17,6 @@ const ASCII_ART = [
|
|
|
17
17
|
'',
|
|
18
18
|
'╔═════════════════════════╗',
|
|
19
19
|
'║ Roguelike CLI v1.0 ║',
|
|
20
|
-
'║ www.rlc.rocks ║',
|
|
21
20
|
'╚═════════════════════════╝',
|
|
22
21
|
'',
|
|
23
22
|
' Commands: ls, cd, mkdir, open, cp, mv, rm, tree, pwd, clean',
|
|
@@ -26,6 +25,8 @@ const ASCII_ART = [
|
|
|
26
25
|
' Workflow: <description> -> refine -> save',
|
|
27
26
|
' init - setup, config - settings, help - examples',
|
|
28
27
|
'',
|
|
28
|
+
' www.rlc.rocks',
|
|
29
|
+
'',
|
|
29
30
|
' Ready...',
|
|
30
31
|
'',
|
|
31
32
|
];
|
package/package.json
CHANGED
package/src/ai/claude.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { Config } from '../config/config';
|
|
|
4
4
|
export interface GeneratedSchema {
|
|
5
5
|
title: string;
|
|
6
6
|
content: string;
|
|
7
|
+
format: 'block' | 'tree';
|
|
7
8
|
tree?: any[];
|
|
8
9
|
}
|
|
9
10
|
|
|
@@ -130,6 +131,7 @@ export async function generateSchemaWithAI(
|
|
|
130
131
|
return {
|
|
131
132
|
title: parsed.title || 'schema',
|
|
132
133
|
content: schemaContent,
|
|
134
|
+
format: parsed.format || 'block',
|
|
133
135
|
};
|
|
134
136
|
} catch (error: any) {
|
|
135
137
|
console.error('AI Error:', error.message);
|
|
@@ -3,9 +3,72 @@ import * as fs from 'fs';
|
|
|
3
3
|
import { execSync } from 'child_process';
|
|
4
4
|
import { Config } from '../config/config';
|
|
5
5
|
import { listSchemas, navigateToNode, getTree } from '../storage/storage';
|
|
6
|
-
import { saveSchemaFile } from '../storage/nodeConfig';
|
|
6
|
+
import { saveSchemaFile, writeNodeConfig } from '../storage/nodeConfig';
|
|
7
7
|
import { generateSchemaWithAI } from '../ai/claude';
|
|
8
8
|
|
|
9
|
+
// Parse tree ASCII art and create folder structure
|
|
10
|
+
function createFoldersFromTree(rootPath: string, treeContent: string): void {
|
|
11
|
+
// Create root folder
|
|
12
|
+
if (!fs.existsSync(rootPath)) {
|
|
13
|
+
fs.mkdirSync(rootPath, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Parse tree lines
|
|
17
|
+
const lines = treeContent.split('\n');
|
|
18
|
+
const stack: { path: string; indent: number }[] = [{ path: rootPath, indent: -1 }];
|
|
19
|
+
|
|
20
|
+
for (const line of lines) {
|
|
21
|
+
// Skip empty lines
|
|
22
|
+
if (!line.trim()) continue;
|
|
23
|
+
|
|
24
|
+
// Extract node name from tree line
|
|
25
|
+
// Patterns: "├── Name", "└── Name", "│ ├── Name", etc.
|
|
26
|
+
const match = line.match(/^([\s│]*)[├└]──\s*(.+)$/);
|
|
27
|
+
if (!match) continue;
|
|
28
|
+
|
|
29
|
+
const prefix = match[1];
|
|
30
|
+
let nodeName = match[2].trim();
|
|
31
|
+
|
|
32
|
+
// Calculate indent level (each │ or space block = 1 level)
|
|
33
|
+
const indent = Math.floor(prefix.replace(/│/g, ' ').length / 4);
|
|
34
|
+
|
|
35
|
+
// Clean node name - remove extra info in parentheses, brackets
|
|
36
|
+
nodeName = nodeName.replace(/\s*\([^)]*\)\s*/g, '').trim();
|
|
37
|
+
nodeName = nodeName.replace(/\s*\[[^\]]*\]\s*/g, '').trim();
|
|
38
|
+
|
|
39
|
+
// Create safe folder name
|
|
40
|
+
const safeName = nodeName
|
|
41
|
+
.toLowerCase()
|
|
42
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
43
|
+
.replace(/^-+|-+$/g, '');
|
|
44
|
+
|
|
45
|
+
if (!safeName) continue;
|
|
46
|
+
|
|
47
|
+
// Pop stack until we find parent
|
|
48
|
+
while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {
|
|
49
|
+
stack.pop();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const parentPath = stack[stack.length - 1].path;
|
|
53
|
+
const folderPath = path.join(parentPath, safeName);
|
|
54
|
+
|
|
55
|
+
// Create folder
|
|
56
|
+
if (!fs.existsSync(folderPath)) {
|
|
57
|
+
fs.mkdirSync(folderPath, { recursive: true });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Create node config
|
|
61
|
+
writeNodeConfig(folderPath, {
|
|
62
|
+
name: nodeName,
|
|
63
|
+
createdAt: new Date().toISOString(),
|
|
64
|
+
updatedAt: new Date().toISOString(),
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Push to stack
|
|
68
|
+
stack.push({ path: folderPath, indent });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
9
72
|
export interface CommandResult {
|
|
10
73
|
output?: string;
|
|
11
74
|
newPath?: string;
|
|
@@ -16,6 +79,7 @@ export interface CommandResult {
|
|
|
16
79
|
export interface PendingSchema {
|
|
17
80
|
title: string;
|
|
18
81
|
content: string;
|
|
82
|
+
format: 'block' | 'tree';
|
|
19
83
|
tree?: any[];
|
|
20
84
|
}
|
|
21
85
|
|
|
@@ -533,25 +597,40 @@ www.rlc.rocks`
|
|
|
533
597
|
});
|
|
534
598
|
}
|
|
535
599
|
|
|
536
|
-
// Save command - save pending schema
|
|
600
|
+
// Save command - save pending schema/todo
|
|
537
601
|
if (command === 'save') {
|
|
538
602
|
if (!sessionState.pending) {
|
|
539
603
|
return wrapResult({ output: 'Nothing to save. Create a schema first.' });
|
|
540
604
|
}
|
|
541
605
|
|
|
542
|
-
const
|
|
543
|
-
|
|
544
|
-
sessionState.pending.title,
|
|
545
|
-
sessionState.pending.content
|
|
546
|
-
);
|
|
547
|
-
const relativePath = path.relative(config.storagePath, schemaPath);
|
|
548
|
-
const filename = path.basename(schemaPath);
|
|
549
|
-
|
|
550
|
-
// Clear session
|
|
551
|
-
sessionState.pending = null;
|
|
552
|
-
sessionState.history = [];
|
|
606
|
+
const pending = sessionState.pending;
|
|
607
|
+
const safeName = pending.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
553
608
|
|
|
554
|
-
|
|
609
|
+
if (pending.format === 'tree') {
|
|
610
|
+
// Create folder structure from tree ASCII art
|
|
611
|
+
const rootPath = path.join(currentPath, safeName);
|
|
612
|
+
createFoldersFromTree(rootPath, pending.content);
|
|
613
|
+
|
|
614
|
+
// Clear session
|
|
615
|
+
sessionState.pending = null;
|
|
616
|
+
sessionState.history = [];
|
|
617
|
+
|
|
618
|
+
return wrapResult({ output: `Created todo folder: ${safeName}/` });
|
|
619
|
+
} else {
|
|
620
|
+
// Save as .rlc.schema file
|
|
621
|
+
const schemaPath = saveSchemaFile(
|
|
622
|
+
currentPath,
|
|
623
|
+
pending.title,
|
|
624
|
+
pending.content
|
|
625
|
+
);
|
|
626
|
+
const filename = path.basename(schemaPath);
|
|
627
|
+
|
|
628
|
+
// Clear session
|
|
629
|
+
sessionState.pending = null;
|
|
630
|
+
sessionState.history = [];
|
|
631
|
+
|
|
632
|
+
return wrapResult({ output: `Saved: ${filename}` });
|
|
633
|
+
}
|
|
555
634
|
}
|
|
556
635
|
|
|
557
636
|
// Cancel command - discard pending schema
|
|
@@ -607,16 +686,21 @@ www.rlc.rocks`
|
|
|
607
686
|
sessionState.pending = {
|
|
608
687
|
title: schema.title,
|
|
609
688
|
content: schema.content,
|
|
689
|
+
format: schema.format,
|
|
610
690
|
tree: schema.tree
|
|
611
691
|
};
|
|
612
692
|
|
|
613
693
|
// Add assistant response to history
|
|
614
694
|
sessionState.history.push({ role: 'assistant', content: schema.content });
|
|
615
695
|
|
|
616
|
-
const
|
|
696
|
+
const safeName = schema.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
697
|
+
|
|
698
|
+
const saveHint = schema.format === 'tree'
|
|
699
|
+
? `[Type "save" to create folder ${safeName}/, or refine with more instructions]`
|
|
700
|
+
: `[Type "save" to save as ${safeName}.rlc.schema, or refine with more instructions]`;
|
|
617
701
|
|
|
618
702
|
return wrapResult({
|
|
619
|
-
output: `\n${schema.content}\n\n
|
|
703
|
+
output: `\n${schema.content}\n\n${saveHint}`
|
|
620
704
|
});
|
|
621
705
|
}
|
|
622
706
|
|
|
@@ -15,7 +15,6 @@ const ASCII_ART = [
|
|
|
15
15
|
'',
|
|
16
16
|
'╔═════════════════════════╗',
|
|
17
17
|
'║ Roguelike CLI v1.0 ║',
|
|
18
|
-
'║ www.rlc.rocks ║',
|
|
19
18
|
'╚═════════════════════════╝',
|
|
20
19
|
'',
|
|
21
20
|
' Commands: ls, cd, mkdir, open, cp, mv, rm, tree, pwd, clean',
|
|
@@ -24,6 +23,8 @@ const ASCII_ART = [
|
|
|
24
23
|
' Workflow: <description> -> refine -> save',
|
|
25
24
|
' init - setup, config - settings, help - examples',
|
|
26
25
|
'',
|
|
26
|
+
' www.rlc.rocks',
|
|
27
|
+
'',
|
|
27
28
|
' Ready...',
|
|
28
29
|
'',
|
|
29
30
|
];
|
package/INSTALL.md
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
# Roguelike CLI - Installation Guide
|
|
2
|
-
|
|
3
|
-
## Local Development Setup
|
|
4
|
-
|
|
5
|
-
1. Install dependencies:
|
|
6
|
-
```bash
|
|
7
|
-
cd cli
|
|
8
|
-
npm install
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
2. Build the project:
|
|
12
|
-
```bash
|
|
13
|
-
npm run build
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
3. Link locally for testing:
|
|
17
|
-
```bash
|
|
18
|
-
npm link
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
This will make `rlc` command available globally.
|
|
22
|
-
|
|
23
|
-
4. Test the installation:
|
|
24
|
-
```bash
|
|
25
|
-
rlc
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## First Run
|
|
29
|
-
|
|
30
|
-
Run `init` to configure:
|
|
31
|
-
```bash
|
|
32
|
-
rlc
|
|
33
|
-
> init
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Or set API key manually:
|
|
37
|
-
```bash
|
|
38
|
-
> config:apiKey=your-api-key-here
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## How to Use
|
|
42
|
-
|
|
43
|
-
### View config
|
|
44
|
-
```bash
|
|
45
|
-
> config
|
|
46
|
-
Provider: claude
|
|
47
|
-
Model: claude-sonnet-4-20250514
|
|
48
|
-
API Key: sk-ant-a...1234
|
|
49
|
-
Storage: /Users/you/.rlc/notes
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Create schema or todo
|
|
53
|
-
```bash
|
|
54
|
-
> todo opening company in delaware
|
|
55
|
-
> architecture kubernetes cluster with postgres
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### Navigation
|
|
59
|
-
```bash
|
|
60
|
-
> ls # list files (columns)
|
|
61
|
-
> cd my-project # go into folder
|
|
62
|
-
> cd .. # go back
|
|
63
|
-
> pwd # current path
|
|
64
|
-
> tree # show tree structure
|
|
65
|
-
> tree -A # show tree with files
|
|
66
|
-
> tree --depth=2 # limit depth
|
|
67
|
-
> open # open folder in Finder
|
|
68
|
-
> open my-folder # open specific folder
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### Copy to clipboard
|
|
72
|
-
Add `| pbcopy` (macOS), `| copy` or `| clip` (Windows) to any command:
|
|
73
|
-
```bash
|
|
74
|
-
> ls | pbcopy
|
|
75
|
-
> tree | pbcopy
|
|
76
|
-
> config | pbcopy
|
|
77
|
-
> pwd | pbcopy
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### File operations
|
|
81
|
-
```bash
|
|
82
|
-
> mkdir my-note # create folder
|
|
83
|
-
> cp source dest # copy
|
|
84
|
-
> mv source dest # move/rename
|
|
85
|
-
> rm file # delete file
|
|
86
|
-
> rm -rf folder # delete folder
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## Uninstall
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
npm unlink -g roguelike-cli
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
## Troubleshooting
|
|
96
|
-
|
|
97
|
-
If you get "command not found":
|
|
98
|
-
- Make sure `npm link` was run successfully
|
|
99
|
-
- Check that `~/.npm-global/bin` or similar is in your PATH
|
|
100
|
-
|
|
101
|
-
If API errors occur:
|
|
102
|
-
- Verify your API key is set: `config`
|
|
103
|
-
- Check that you have credits/access to Claude API
|
|
104
|
-
|
|
105
|
-
## Website
|
|
106
|
-
|
|
107
|
-
https://www.rlc.rocks
|
|
108
|
-
|