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.
@@ -0,0 +1,180 @@
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.startInteractive = startInteractive;
37
+ const readline = __importStar(require("readline"));
38
+ const fs = __importStar(require("fs"));
39
+ const startup_1 = require("./startup");
40
+ const commands_1 = require("./commands");
41
+ const config_1 = require("../config/config");
42
+ function getCompletions(currentPath) {
43
+ if (!fs.existsSync(currentPath)) {
44
+ return [];
45
+ }
46
+ const entries = fs.readdirSync(currentPath, { withFileTypes: true });
47
+ const completions = [];
48
+ for (const entry of entries) {
49
+ if (entry.name.startsWith('.'))
50
+ continue;
51
+ completions.push(entry.name);
52
+ }
53
+ return completions;
54
+ }
55
+ async function startInteractive(initialConfig) {
56
+ await (0, startup_1.showStartupAnimation)();
57
+ let config = initialConfig;
58
+ // Use object to hold currentPath so closures always get the current value
59
+ const state = {
60
+ currentPath: config.currentPath
61
+ };
62
+ // Completer function that uses state.currentPath
63
+ const completer = (line) => {
64
+ try {
65
+ const trimmed = line.trim();
66
+ if (!trimmed) {
67
+ return [[], ''];
68
+ }
69
+ // Find the last word using regex to get exact position
70
+ const lastWordMatch = line.match(/(\S+)$/);
71
+ if (!lastWordMatch) {
72
+ return [[], line];
73
+ }
74
+ const lastWord = lastWordMatch[1];
75
+ const lastWordStart = lastWordMatch.index;
76
+ const prefix = line.substring(lastWordStart);
77
+ const parts = trimmed.split(/\s+/);
78
+ const command = parts[0]?.toLowerCase() || '';
79
+ // Only autocomplete if we're in a command that takes a path argument
80
+ const commandsThatNeedCompletion = ['cd', 'open', 'cp', 'rm', 'mkdir'];
81
+ if (commandsThatNeedCompletion.includes(command) && parts.length > 1) {
82
+ const completions = getCompletions(state.currentPath);
83
+ const hits = completions.filter((c) => c.toLowerCase().startsWith(lastWord.toLowerCase()));
84
+ return [hits.length > 0 ? hits : [], prefix];
85
+ }
86
+ // If we're typing a command name itself
87
+ if (parts.length === 1) {
88
+ const commandCompletions = ['ls', 'cd', 'mkdir', 'open', 'cp', 'rm', 'tree', 'pwd', 'init', 'config', 'help', 'save', 'cancel', 'clean', 'exit', 'quit', '..', '...'];
89
+ const hits = commandCompletions.filter((c) => c.toLowerCase().startsWith(lastWord.toLowerCase()));
90
+ return [hits.length > 0 ? hits : commandCompletions, prefix];
91
+ }
92
+ return [[], line];
93
+ }
94
+ catch (e) {
95
+ // Return empty completion on any error to prevent crash
96
+ return [[], line];
97
+ }
98
+ };
99
+ const rl = readline.createInterface({
100
+ input: process.stdin,
101
+ output: process.stdout,
102
+ prompt: '> ',
103
+ completer: completer,
104
+ });
105
+ let isProcessingCommand = false;
106
+ let currentCommandAbortController = null;
107
+ // Override SIGINT to cancel commands instead of exiting
108
+ process.on('SIGINT', () => {
109
+ if (isProcessingCommand) {
110
+ // Cancel current command but stay in program
111
+ if (currentCommandAbortController) {
112
+ currentCommandAbortController.abort();
113
+ currentCommandAbortController = null;
114
+ }
115
+ isProcessingCommand = false;
116
+ console.log('\n^C');
117
+ rl.prompt();
118
+ }
119
+ else {
120
+ // Clear the line if not processing
121
+ rl.write('\x1B[2K\r> ');
122
+ }
123
+ });
124
+ rl.on('line', async (input) => {
125
+ const trimmed = input.trim();
126
+ if (trimmed === 'exit' || trimmed === 'quit') {
127
+ rl.close();
128
+ return;
129
+ }
130
+ if (trimmed === '') {
131
+ rl.prompt();
132
+ return;
133
+ }
134
+ // Create abort controller for this command
135
+ currentCommandAbortController = new AbortController();
136
+ isProcessingCommand = true;
137
+ const abortController = currentCommandAbortController;
138
+ try {
139
+ const result = await (0, commands_1.processCommand)(trimmed, state.currentPath, config, abortController.signal);
140
+ if (abortController.signal.aborted) {
141
+ rl.prompt();
142
+ return;
143
+ }
144
+ if (result.reloadConfig) {
145
+ const newConfig = await (0, config_1.initConfig)();
146
+ if (newConfig) {
147
+ config = newConfig;
148
+ state.currentPath = config.currentPath;
149
+ }
150
+ }
151
+ if (result.newPath) {
152
+ state.currentPath = result.newPath;
153
+ }
154
+ if (result.output) {
155
+ console.log(result.output);
156
+ }
157
+ }
158
+ catch (error) {
159
+ if (error.name === 'AbortError' || abortController.signal.aborted) {
160
+ console.log('\nCommand cancelled.');
161
+ }
162
+ else {
163
+ console.error(`Error: ${error.message}`);
164
+ }
165
+ }
166
+ finally {
167
+ isProcessingCommand = false;
168
+ currentCommandAbortController = null;
169
+ }
170
+ rl.prompt();
171
+ });
172
+ rl.on('close', () => {
173
+ if (process.stdin.isTTY) {
174
+ process.stdin.setRawMode(false);
175
+ }
176
+ console.log('\nGoodbye!');
177
+ process.exit(0);
178
+ });
179
+ rl.prompt();
180
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.showStartupAnimation = showStartupAnimation;
4
+ const utils_1 = require("../utils");
5
+ const ASCII_ART = [
6
+ '',
7
+ ' |',
8
+ ' |',
9
+ ' + \\',
10
+ ' \\.G_.*=.',
11
+ ' `(#\'/.\|',
12
+ ' .>\' (_--.',
13
+ ' _=/d ,^\\',
14
+ '~~ \\)-\' \'',
15
+ ' / |',
16
+ ' \' \'',
17
+ '',
18
+ '╔═════════════════════════╗',
19
+ '║ Roguelike CLI v1.0 ║',
20
+ '║ www.rlc.rocks ║',
21
+ '╚═════════════════════════╝',
22
+ '',
23
+ ' Commands: ls, cd, mkdir, open, cp, mv, rm, tree, pwd, clean',
24
+ ' TAB to autocomplete, | pbcopy to copy output',
25
+ '',
26
+ ' Workflow: <description> -> refine -> save',
27
+ ' init - setup, config - settings, help - examples',
28
+ '',
29
+ ' Ready...',
30
+ '',
31
+ ];
32
+ async function showStartupAnimation() {
33
+ for (const line of ASCII_ART) {
34
+ console.log(line);
35
+ await (0, utils_1.sleep)(15);
36
+ }
37
+ await (0, utils_1.sleep)(100);
38
+ }
@@ -0,0 +1,109 @@
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.readNodeConfig = readNodeConfig;
37
+ exports.writeNodeConfig = writeNodeConfig;
38
+ exports.createNode = createNode;
39
+ exports.saveSchemaFile = saveSchemaFile;
40
+ exports.readSchemaFile = readSchemaFile;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const CONFIG_FILE = '.rlc.json';
44
+ function readNodeConfig(nodePath) {
45
+ const configPath = path.join(nodePath, CONFIG_FILE);
46
+ if (!fs.existsSync(configPath)) {
47
+ return null;
48
+ }
49
+ try {
50
+ const data = fs.readFileSync(configPath, 'utf-8');
51
+ return JSON.parse(data);
52
+ }
53
+ catch {
54
+ return null;
55
+ }
56
+ }
57
+ function writeNodeConfig(nodePath, config) {
58
+ if (!fs.existsSync(nodePath)) {
59
+ fs.mkdirSync(nodePath, { recursive: true });
60
+ }
61
+ const configPath = path.join(nodePath, CONFIG_FILE);
62
+ const existing = readNodeConfig(nodePath);
63
+ const updated = {
64
+ ...existing,
65
+ ...config,
66
+ updatedAt: new Date().toISOString(),
67
+ createdAt: existing?.createdAt || new Date().toISOString(),
68
+ };
69
+ fs.writeFileSync(configPath, JSON.stringify(updated, null, 2), 'utf-8');
70
+ }
71
+ function createNode(parentPath, name, options) {
72
+ const safeName = name
73
+ .toLowerCase()
74
+ .replace(/[^a-z0-9]+/g, '-')
75
+ .replace(/^-+|-+$/g, '');
76
+ const nodePath = path.join(parentPath, safeName);
77
+ const config = {
78
+ name,
79
+ deadline: options?.deadline,
80
+ branch: options?.branch,
81
+ zone: options?.zone,
82
+ description: options?.description,
83
+ createdAt: new Date().toISOString(),
84
+ updatedAt: new Date().toISOString(),
85
+ metadata: options?.metadata,
86
+ };
87
+ writeNodeConfig(nodePath, config);
88
+ return nodePath;
89
+ }
90
+ // Save schema content to .rlc.schema file
91
+ function saveSchemaFile(dirPath, filename, content) {
92
+ if (!fs.existsSync(dirPath)) {
93
+ fs.mkdirSync(dirPath, { recursive: true });
94
+ }
95
+ const safeName = filename
96
+ .toLowerCase()
97
+ .replace(/[^a-z0-9]+/g, '-')
98
+ .replace(/^-+|-+$/g, '');
99
+ const schemaPath = path.join(dirPath, `${safeName}.rlc.schema`);
100
+ fs.writeFileSync(schemaPath, content, 'utf-8');
101
+ return schemaPath;
102
+ }
103
+ // Read schema file
104
+ function readSchemaFile(filePath) {
105
+ if (!fs.existsSync(filePath)) {
106
+ return null;
107
+ }
108
+ return fs.readFileSync(filePath, 'utf-8');
109
+ }
@@ -0,0 +1,155 @@
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.listSchemas = listSchemas;
37
+ exports.navigateToNode = navigateToNode;
38
+ exports.readSchema = readSchema;
39
+ exports.getTree = getTree;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const nodeConfig_1 = require("./nodeConfig");
43
+ function listSchemas(dirPath) {
44
+ if (!fs.existsSync(dirPath)) {
45
+ return [];
46
+ }
47
+ const items = [];
48
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true });
49
+ for (const entry of entries) {
50
+ const fullPath = path.join(dirPath, entry.name);
51
+ // Skip hidden files
52
+ if (entry.name.startsWith('.')) {
53
+ continue;
54
+ }
55
+ if (entry.isDirectory()) {
56
+ const config = (0, nodeConfig_1.readNodeConfig)(fullPath);
57
+ items.push({
58
+ name: entry.name,
59
+ path: fullPath,
60
+ config,
61
+ });
62
+ }
63
+ }
64
+ return items.sort((a, b) => a.name.localeCompare(b.name));
65
+ }
66
+ function navigateToNode(currentPath, nodeName) {
67
+ const schemas = listSchemas(currentPath);
68
+ const node = schemas.find(s => s.name.toLowerCase() === nodeName.toLowerCase());
69
+ if (!node) {
70
+ return null;
71
+ }
72
+ if (fs.statSync(node.path).isDirectory()) {
73
+ return node.path;
74
+ }
75
+ return node.path;
76
+ }
77
+ function readSchema(nodePath) {
78
+ // Read node config and return its info
79
+ const config = (0, nodeConfig_1.readNodeConfig)(nodePath);
80
+ if (!config) {
81
+ return null;
82
+ }
83
+ let output = `${config.name}`;
84
+ if (config.deadline)
85
+ output += `\nDeadline: ${config.deadline}`;
86
+ if (config.branch)
87
+ output += `\nBranch: ${config.branch}`;
88
+ if (config.zone)
89
+ output += `\nZone: ${config.zone}`;
90
+ if (config.description)
91
+ output += `\n${config.description}`;
92
+ return output;
93
+ }
94
+ function getTree(dirPath, prefix = '', isLast = true, maxDepth = 10, currentDepth = 0, showFiles = false) {
95
+ if (currentDepth >= maxDepth) {
96
+ return [];
97
+ }
98
+ const lines = [];
99
+ // Get items - either just folders or all entries
100
+ let items = [];
101
+ if (showFiles) {
102
+ // Show all files and folders
103
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true });
104
+ for (const entry of entries) {
105
+ if (entry.name.startsWith('.'))
106
+ continue;
107
+ const fullPath = path.join(dirPath, entry.name);
108
+ const config = entry.isDirectory() ? (0, nodeConfig_1.readNodeConfig)(fullPath) : null;
109
+ items.push({
110
+ name: entry.name,
111
+ path: fullPath,
112
+ isDir: entry.isDirectory(),
113
+ config
114
+ });
115
+ }
116
+ // Sort: folders first, then files
117
+ items.sort((a, b) => {
118
+ if (a.isDir !== b.isDir)
119
+ return a.isDir ? -1 : 1;
120
+ return a.name.localeCompare(b.name);
121
+ });
122
+ }
123
+ else {
124
+ // Only folders (original behavior)
125
+ const schemas = listSchemas(dirPath);
126
+ items = schemas.map(s => ({
127
+ name: s.name,
128
+ path: s.path,
129
+ isDir: true,
130
+ config: s.config
131
+ }));
132
+ }
133
+ items.forEach((item, index) => {
134
+ const isItemLast = index === items.length - 1;
135
+ const connector = isItemLast ? '└──' : '├──';
136
+ const currentPrefix = prefix + (isLast ? ' ' : '│ ');
137
+ let displayName = item.name;
138
+ // Add file indicator
139
+ if (!item.isDir) {
140
+ displayName = `* ${displayName}`;
141
+ }
142
+ if (item.config?.deadline) {
143
+ displayName += ` [${item.config.deadline}]`;
144
+ }
145
+ if (item.config?.branch) {
146
+ displayName += ` (${item.config.branch})`;
147
+ }
148
+ lines.push(`${prefix}${connector} ${displayName}`);
149
+ if (item.isDir) {
150
+ const childLines = getTree(item.path, currentPrefix, isItemLast, maxDepth, currentDepth + 1, showFiles);
151
+ lines.push(...childLines);
152
+ }
153
+ });
154
+ return lines;
155
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sleep = sleep;
4
+ function sleep(ms) {
5
+ return new Promise(resolve => setTimeout(resolve, ms));
6
+ }