roguelike-cli 1.0.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/INSTALL.md +108 -0
- package/bin/rlc +4 -0
- package/dist/ai/claude.js +115 -0
- package/dist/commands/init.js +175 -0
- package/dist/config/config.js +85 -0
- package/dist/index.js +29 -0
- package/dist/interactive/commands.js +552 -0
- package/dist/interactive/index.js +180 -0
- package/dist/interactive/startup.js +38 -0
- package/dist/storage/nodeConfig.js +109 -0
- package/dist/storage/storage.js +155 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/schemaParser.js +217 -0
- package/package.json +45 -0
- package/src/ai/claude.ts +139 -0
- package/src/commands/init.ts +159 -0
- package/src/config/config.ts +69 -0
- package/src/index.ts +37 -0
- package/src/interactive/commands.ts +625 -0
- package/src/interactive/index.ts +174 -0
- package/src/interactive/startup.ts +38 -0
- package/src/storage/nodeConfig.ts +109 -0
- package/src/storage/storage.ts +143 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/schemaParser.ts +259 -0
- package/tsconfig.json +19 -0
package/INSTALL.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
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
|
+
|
package/bin/rlc
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateSchemaWithAI = generateSchemaWithAI;
|
|
7
|
+
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
8
|
+
const SYSTEM_PROMPT = `You are a schema generator. Based on user input, generate EITHER:
|
|
9
|
+
|
|
10
|
+
1. **BLOCK DIAGRAM** - when user mentions: "schema", "architecture", "infrastructure", "diagram", "system"
|
|
11
|
+
Use box-drawing to create visual blocks with connections:
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
\`\`\`
|
|
15
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
16
|
+
│ Kubernetes Cluster │
|
|
17
|
+
│ │
|
|
18
|
+
│ ┌──────────────────┐ ┌──────────────────┐ │
|
|
19
|
+
│ │ Control Plane │ │ Worker Nodes │ │
|
|
20
|
+
│ │ │◄────►│ │ │
|
|
21
|
+
│ │ - API Server │ │ - Node Pool 1 │ │
|
|
22
|
+
│ │ - Scheduler │ │ - Node Pool 2 │ │
|
|
23
|
+
│ │ - etcd │ │ - GPU Pool │ │
|
|
24
|
+
│ └────────┬─────────┘ └────────┬─────────┘ │
|
|
25
|
+
│ │ │ │
|
|
26
|
+
│ └──────────┬───────────────┘ │
|
|
27
|
+
│ │ │
|
|
28
|
+
│ ┌──────────────────┐│┌──────────────────┐ │
|
|
29
|
+
│ │ PostgreSQL │││ Redis │ │
|
|
30
|
+
│ └──────────────────┘│└──────────────────┘ │
|
|
31
|
+
└─────────────────────────────────────────────────────────────┘
|
|
32
|
+
\`\`\`
|
|
33
|
+
|
|
34
|
+
2. **TREE STRUCTURE** - when user mentions: "todo", "tasks", "list", "steps", "plan"
|
|
35
|
+
Use tree format:
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
\`\`\`
|
|
39
|
+
├── Phase 1: Setup
|
|
40
|
+
│ ├── Create repository
|
|
41
|
+
│ ├── Setup CI/CD
|
|
42
|
+
│ └── Configure environment
|
|
43
|
+
├── Phase 2: Development
|
|
44
|
+
│ ├── Backend API
|
|
45
|
+
│ └── Frontend UI
|
|
46
|
+
└── Phase 3: Deploy
|
|
47
|
+
\`\`\`
|
|
48
|
+
|
|
49
|
+
Rules:
|
|
50
|
+
1. Extract a short title for filename
|
|
51
|
+
2. If user says "schema" or "architecture" - ALWAYS use BLOCK DIAGRAM format
|
|
52
|
+
3. If user says "todo" or "tasks" - use TREE format
|
|
53
|
+
4. Keep context from previous messages
|
|
54
|
+
|
|
55
|
+
Respond with JSON:
|
|
56
|
+
{
|
|
57
|
+
"title": "short-title",
|
|
58
|
+
"format": "block" or "tree",
|
|
59
|
+
"content": "the actual ASCII art schema here"
|
|
60
|
+
}`;
|
|
61
|
+
async function generateSchemaWithAI(input, config, signal, history) {
|
|
62
|
+
if (!config.apiKey) {
|
|
63
|
+
throw new Error('API key not set. Use config:apiKey=<key> to set it.');
|
|
64
|
+
}
|
|
65
|
+
const client = new sdk_1.default({
|
|
66
|
+
apiKey: config.apiKey,
|
|
67
|
+
});
|
|
68
|
+
// Build messages from history or just the current input
|
|
69
|
+
const messages = [];
|
|
70
|
+
if (history && history.length > 0) {
|
|
71
|
+
// Add previous messages for context
|
|
72
|
+
for (const msg of history.slice(0, -1)) { // exclude the last one (current input)
|
|
73
|
+
messages.push({
|
|
74
|
+
role: msg.role,
|
|
75
|
+
content: msg.role === 'assistant'
|
|
76
|
+
? `Previous schema generated:\n${msg.content}`
|
|
77
|
+
: msg.content
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Add current user input
|
|
82
|
+
messages.push({
|
|
83
|
+
role: 'user',
|
|
84
|
+
content: input
|
|
85
|
+
});
|
|
86
|
+
try {
|
|
87
|
+
const model = config.model || 'claude-sonnet-4-20250514';
|
|
88
|
+
const message = await client.messages.create({
|
|
89
|
+
model: model,
|
|
90
|
+
max_tokens: 2000,
|
|
91
|
+
system: SYSTEM_PROMPT,
|
|
92
|
+
messages: messages,
|
|
93
|
+
});
|
|
94
|
+
const content = message.content[0];
|
|
95
|
+
if (content.type !== 'text') {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
const text = content.text.trim();
|
|
99
|
+
let jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
100
|
+
if (!jsonMatch) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
104
|
+
// AI now returns ready content
|
|
105
|
+
const schemaContent = parsed.content || '';
|
|
106
|
+
return {
|
|
107
|
+
title: parsed.title || 'schema',
|
|
108
|
+
content: schemaContent,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
console.error('AI Error:', error.message);
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.initCommand = initCommand;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const os = __importStar(require("os"));
|
|
40
|
+
const config_1 = require("../config/config");
|
|
41
|
+
function question(query) {
|
|
42
|
+
return new Promise((resolve) => {
|
|
43
|
+
process.stdout.write(query);
|
|
44
|
+
let input = '';
|
|
45
|
+
const onData = (chunk) => {
|
|
46
|
+
const str = chunk.toString();
|
|
47
|
+
for (const char of str) {
|
|
48
|
+
if (char === '\n' || char === '\r') {
|
|
49
|
+
process.stdin.removeListener('data', onData);
|
|
50
|
+
process.stdout.write('\n');
|
|
51
|
+
resolve(input);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
else if (char === '\x7f' || char === '\b') {
|
|
55
|
+
// Backspace
|
|
56
|
+
if (input.length > 0) {
|
|
57
|
+
input = input.slice(0, -1);
|
|
58
|
+
process.stdout.write('\b \b');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (char >= ' ') {
|
|
62
|
+
input += char;
|
|
63
|
+
process.stdout.write(char);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
process.stdin.on('data', onData);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// Recursive copy function
|
|
71
|
+
function copyRecursive(src, dest) {
|
|
72
|
+
const stat = fs.statSync(src);
|
|
73
|
+
if (stat.isDirectory()) {
|
|
74
|
+
if (!fs.existsSync(dest)) {
|
|
75
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
76
|
+
}
|
|
77
|
+
const entries = fs.readdirSync(src);
|
|
78
|
+
for (const entry of entries) {
|
|
79
|
+
copyRecursive(path.join(src, entry), path.join(dest, entry));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
fs.copyFileSync(src, dest);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async function initCommand() {
|
|
87
|
+
console.log('\n╔═══════════════════════════════════════╗');
|
|
88
|
+
console.log('║ ROGUELIKE CLI INITIALIZATION WIZARD ║');
|
|
89
|
+
console.log('╚═══════════════════════════════════════╝\n');
|
|
90
|
+
// Get existing config if any
|
|
91
|
+
const existingConfig = await (0, config_1.initConfig)();
|
|
92
|
+
const oldStoragePath = existingConfig?.storagePath;
|
|
93
|
+
// 1. Root directory
|
|
94
|
+
const defaultRoot = path.join(os.homedir(), '.rlc', 'notes');
|
|
95
|
+
const rootDirAnswer = await question(`Root directory for notes [${defaultRoot}]: `);
|
|
96
|
+
const rootDir = rootDirAnswer.trim() || defaultRoot;
|
|
97
|
+
// Check if we need to migrate data
|
|
98
|
+
if (oldStoragePath && oldStoragePath !== rootDir && fs.existsSync(oldStoragePath)) {
|
|
99
|
+
const entries = fs.readdirSync(oldStoragePath);
|
|
100
|
+
if (entries.length > 0) {
|
|
101
|
+
const migrateAnswer = await question(`\nMigrate existing data from ${oldStoragePath}? [Y/n]: `);
|
|
102
|
+
if (migrateAnswer.toLowerCase() !== 'n') {
|
|
103
|
+
if (!fs.existsSync(rootDir)) {
|
|
104
|
+
fs.mkdirSync(rootDir, { recursive: true });
|
|
105
|
+
}
|
|
106
|
+
console.log(`Migrating data...`);
|
|
107
|
+
for (const entry of entries) {
|
|
108
|
+
const srcPath = path.join(oldStoragePath, entry);
|
|
109
|
+
const destPath = path.join(rootDir, entry);
|
|
110
|
+
copyRecursive(srcPath, destPath);
|
|
111
|
+
}
|
|
112
|
+
console.log(`Migrated ${entries.length} items to ${rootDir}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (!fs.existsSync(rootDir)) {
|
|
117
|
+
fs.mkdirSync(rootDir, { recursive: true });
|
|
118
|
+
console.log(`Created directory: ${rootDir}`);
|
|
119
|
+
}
|
|
120
|
+
// 2. AI Provider selection
|
|
121
|
+
console.log('\nSelect AI Provider:');
|
|
122
|
+
console.log(' 1. Claude Sonnet 4.5');
|
|
123
|
+
console.log(' 2. Claude Opus 4.5');
|
|
124
|
+
console.log(' 3. GPT-4o (latest)');
|
|
125
|
+
console.log(' 4. Gemini 3 Pro');
|
|
126
|
+
console.log(' 5. Grok (latest)');
|
|
127
|
+
const aiChoice = await question('\nEnter choice [1-5] (default: 1): ');
|
|
128
|
+
const aiProviders = [
|
|
129
|
+
{ name: 'claude', model: 'claude-sonnet-4-20250514', apiUrl: 'https://api.anthropic.com' },
|
|
130
|
+
{ name: 'claude-opus', model: 'claude-opus-4-20250514', apiUrl: 'https://api.anthropic.com' },
|
|
131
|
+
{ name: 'openai', model: 'gpt-4o', apiUrl: 'https://api.openai.com' },
|
|
132
|
+
{ name: 'gemini', model: 'gemini-3-pro', apiUrl: 'https://generativelanguage.googleapis.com' },
|
|
133
|
+
{ name: 'grok', model: 'grok-beta', apiUrl: 'https://api.x.ai' },
|
|
134
|
+
];
|
|
135
|
+
const selectedIndex = parseInt(aiChoice.trim()) - 1 || 0;
|
|
136
|
+
const selectedProvider = aiProviders[selectedIndex] || aiProviders[0];
|
|
137
|
+
console.log(`Selected: ${selectedProvider.name} (${selectedProvider.model})`);
|
|
138
|
+
// 3. API Key - reuse existing if not provided
|
|
139
|
+
const existingApiKey = existingConfig?.apiKey || '';
|
|
140
|
+
const hasExistingKey = existingApiKey.length > 0;
|
|
141
|
+
const keyPrompt = hasExistingKey
|
|
142
|
+
? `\nAPI key for ${selectedProvider.name} [press Enter to keep existing]: `
|
|
143
|
+
: `\nEnter API key for ${selectedProvider.name}: `;
|
|
144
|
+
const apiKeyInput = await question(keyPrompt);
|
|
145
|
+
const apiKey = apiKeyInput.trim() || existingApiKey;
|
|
146
|
+
if (!apiKey) {
|
|
147
|
+
console.log('Warning: API key not set. You can set it later with config:apiKey=<key>');
|
|
148
|
+
}
|
|
149
|
+
else if (apiKeyInput.trim()) {
|
|
150
|
+
console.log('API key saved');
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
console.log('Using existing API key');
|
|
154
|
+
}
|
|
155
|
+
// Save config
|
|
156
|
+
const config = {
|
|
157
|
+
aiProvider: selectedProvider.name,
|
|
158
|
+
apiKey: apiKey,
|
|
159
|
+
apiUrl: selectedProvider.apiUrl,
|
|
160
|
+
storagePath: rootDir,
|
|
161
|
+
currentPath: rootDir,
|
|
162
|
+
model: selectedProvider.model,
|
|
163
|
+
};
|
|
164
|
+
(0, config_1.saveConfig)(config);
|
|
165
|
+
// Ensure storage directory exists
|
|
166
|
+
if (!fs.existsSync(rootDir)) {
|
|
167
|
+
fs.mkdirSync(rootDir, { recursive: true });
|
|
168
|
+
}
|
|
169
|
+
console.log('\n╔═══════════════════════════════════════╗');
|
|
170
|
+
console.log('║ INITIALIZATION COMPLETE ║');
|
|
171
|
+
console.log('╚═══════════════════════════════════════╝\n');
|
|
172
|
+
console.log(`Root directory: ${rootDir}`);
|
|
173
|
+
console.log(`AI Provider: ${selectedProvider.name}`);
|
|
174
|
+
console.log(`Model: ${selectedProvider.model}\n`);
|
|
175
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.initConfig = initConfig;
|
|
37
|
+
exports.saveConfig = saveConfig;
|
|
38
|
+
exports.getConfig = getConfig;
|
|
39
|
+
exports.updateConfig = updateConfig;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const os = __importStar(require("os"));
|
|
43
|
+
const CONFIG_FILE = path.join(os.homedir(), '.rlc', 'config.json');
|
|
44
|
+
const DEFAULT_STORAGE = path.join(os.homedir(), '.rlc', 'notes');
|
|
45
|
+
async function initConfig() {
|
|
46
|
+
const configDir = path.dirname(CONFIG_FILE);
|
|
47
|
+
if (!fs.existsSync(configDir)) {
|
|
48
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
49
|
+
}
|
|
50
|
+
if (!fs.existsSync(CONFIG_FILE)) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const configData = fs.readFileSync(CONFIG_FILE, 'utf-8');
|
|
54
|
+
const config = JSON.parse(configData);
|
|
55
|
+
if (!fs.existsSync(config.storagePath)) {
|
|
56
|
+
fs.mkdirSync(config.storagePath, { recursive: true });
|
|
57
|
+
}
|
|
58
|
+
if (!config.currentPath) {
|
|
59
|
+
config.currentPath = config.storagePath;
|
|
60
|
+
}
|
|
61
|
+
if (!config.model) {
|
|
62
|
+
config.model = 'claude-sonnet-4-20250514';
|
|
63
|
+
}
|
|
64
|
+
return config;
|
|
65
|
+
}
|
|
66
|
+
function saveConfig(config) {
|
|
67
|
+
const configDir = path.dirname(CONFIG_FILE);
|
|
68
|
+
if (!fs.existsSync(configDir)) {
|
|
69
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
70
|
+
}
|
|
71
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
72
|
+
}
|
|
73
|
+
function getConfig() {
|
|
74
|
+
if (!fs.existsSync(CONFIG_FILE)) {
|
|
75
|
+
throw new Error('Config not initialized. Run rlc first.');
|
|
76
|
+
}
|
|
77
|
+
const configData = fs.readFileSync(CONFIG_FILE, 'utf-8');
|
|
78
|
+
return JSON.parse(configData);
|
|
79
|
+
}
|
|
80
|
+
function updateConfig(updates) {
|
|
81
|
+
const config = getConfig();
|
|
82
|
+
const updated = { ...config, ...updates };
|
|
83
|
+
saveConfig(updated);
|
|
84
|
+
return updated;
|
|
85
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const interactive_1 = require("./interactive");
|
|
5
|
+
const config_1 = require("./config/config");
|
|
6
|
+
const init_1 = require("./commands/init");
|
|
7
|
+
async function main() {
|
|
8
|
+
// Check for "rlc init" command line argument
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
if (args[0] === 'init') {
|
|
11
|
+
await (0, init_1.initCommand)();
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
let config = await (0, config_1.initConfig)();
|
|
15
|
+
if (!config) {
|
|
16
|
+
console.log('\n╔═══════════════════════════════════════╗');
|
|
17
|
+
console.log('║ ROGUELIKE CLI NOT INITIALIZED ║');
|
|
18
|
+
console.log('╚═══════════════════════════════════════╝\n');
|
|
19
|
+
console.log('Running init wizard...\n');
|
|
20
|
+
await (0, init_1.initCommand)();
|
|
21
|
+
config = await (0, config_1.initConfig)();
|
|
22
|
+
if (!config) {
|
|
23
|
+
console.log('Initialization failed. Please try again.');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
await (0, interactive_1.startInteractive)(config);
|
|
28
|
+
}
|
|
29
|
+
main().catch(console.error);
|