tmpa-cli 1.0.15 → 1.0.16
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/bin/index.js +98 -52
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -68,12 +68,11 @@ function saveRegistry(registry) {
|
|
|
68
68
|
|
|
69
69
|
// UI Popup Card Helper
|
|
70
70
|
function drawBox(title, contentLines, borderColor = C.cyan) {
|
|
71
|
-
const width =
|
|
71
|
+
const width = 64;
|
|
72
72
|
console.log(`${borderColor}┌${'─'.repeat(width - 2)}┐${C.reset}`);
|
|
73
73
|
console.log(`${borderColor}│ ${C.bold}${title.padEnd(width - 4)}${C.reset}${borderColor} │${C.reset}`);
|
|
74
74
|
console.log(`${borderColor}├${'─'.repeat(width - 2)}┤${C.reset}`);
|
|
75
75
|
contentLines.forEach(line => {
|
|
76
|
-
// Basic text padding layout
|
|
77
76
|
console.log(`${borderColor}│${C.reset} ${line.padEnd(width - 4)} ${borderColor}│${C.reset}`);
|
|
78
77
|
});
|
|
79
78
|
console.log(`${borderColor}└${'─'.repeat(width - 2)}┘${C.reset}`);
|
|
@@ -93,22 +92,29 @@ ${C.c3} ██║ ██║╚██╔╝██║██╔═══╝ █
|
|
|
93
92
|
${C.c4} ██║ ██║ ╚═╝ ██║██║ ██║ ██║${C.reset}
|
|
94
93
|
${C.c4} ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝${C.reset}
|
|
95
94
|
${C.darkGray}────────────────────────────────────────────────────────────${C.reset}
|
|
96
|
-
${C.reset}The Multi Platform AI ${C.green}[
|
|
95
|
+
${C.reset}The Multi Platform AI ${C.green}[Dynamic Tool Slash Engine]${C.reset}
|
|
97
96
|
${C.gray}/config | /models | /skill | /mcp | /connect | /scan | /exit${C.reset}
|
|
98
97
|
${C.darkGray}────────────────────────────────────────────────────────────${C.reset}
|
|
99
98
|
`);
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
// System Context Builder
|
|
103
|
-
function getActiveToolsContext() {
|
|
101
|
+
// Dynamic System Context Builder
|
|
102
|
+
function getActiveToolsContext(forcedTool = null) {
|
|
104
103
|
let contextParts = [];
|
|
104
|
+
|
|
105
|
+
if (forcedTool) {
|
|
106
|
+
contextParts.push(`[CRITICAL INSTRUCTION: FORCED TOOL EXECUTION]`);
|
|
107
|
+
contextParts.push(`User explicitly called tool command: /${forcedTool.type}-${forcedTool.name}`);
|
|
108
|
+
contextParts.push(`Target Path/URL: ${forcedTool.target}`);
|
|
109
|
+
contextParts.push(`You MUST use and invoke this ${forcedTool.type.toUpperCase()} tool to handle user prompt below.\n`);
|
|
110
|
+
}
|
|
105
111
|
|
|
106
112
|
const activeSkills = Object.keys(registry.skills || {});
|
|
107
113
|
if (activeSkills.length > 0) {
|
|
108
114
|
contextParts.push("AVAILABLE SKILLS:");
|
|
109
115
|
activeSkills.forEach(name => {
|
|
110
116
|
const s = registry.skills[name];
|
|
111
|
-
contextParts.push(`-
|
|
117
|
+
contextParts.push(`- /skill-${name} -> Path: ${s.path}`);
|
|
112
118
|
});
|
|
113
119
|
}
|
|
114
120
|
|
|
@@ -117,17 +123,16 @@ function getActiveToolsContext() {
|
|
|
117
123
|
contextParts.push("AVAILABLE MCP SERVERS:");
|
|
118
124
|
activeMCP.forEach(name => {
|
|
119
125
|
const m = registry.mcp[name];
|
|
120
|
-
contextParts.push(`-
|
|
126
|
+
contextParts.push(`- /mcp-${name} -> Target: ${m.target} (${m.type})`);
|
|
121
127
|
});
|
|
122
128
|
}
|
|
123
129
|
|
|
124
130
|
if (contextParts.length === 0) return "";
|
|
125
131
|
|
|
126
|
-
return "\n\n[SYSTEM CONTEXT:
|
|
127
|
-
"\nIf user wants to execute a skill/MCP, assist them using available tools.\n";
|
|
132
|
+
return "\n\n[SYSTEM CONTEXT: REGISTERED TOOLS & PROTOCOLS]\n" + contextParts.join("\n") + "\n";
|
|
128
133
|
}
|
|
129
134
|
|
|
130
|
-
// Handlers for Skills with
|
|
135
|
+
// Handlers for Skills with Dynamic Command Helper
|
|
131
136
|
function listSkills() {
|
|
132
137
|
console.log(`\n${C.cyan}=== Registered Skills ===${C.reset}`);
|
|
133
138
|
const keys = Object.keys(registry.skills || {});
|
|
@@ -143,21 +148,24 @@ function listSkills() {
|
|
|
143
148
|
});
|
|
144
149
|
console.log('');
|
|
145
150
|
|
|
146
|
-
// Interactive Action Helper Popup
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
`
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
151
|
+
// Interactive Action Helper Popup with dynamic slash commands
|
|
152
|
+
const lines = [
|
|
153
|
+
`${C.bold}Perintah Instan yang Bisa Kamu Ketik Langsung:${C.reset}`,
|
|
154
|
+
``
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
keys.forEach(name => {
|
|
158
|
+
lines.push(` ${C.yellow}/skill-${name}${C.reset} <prompt kamu>`);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
lines.push(``);
|
|
162
|
+
lines.push(`${C.gray}Contoh: ${C.yellow}/skill-${keys[0]} buatkan animasi intro${C.reset}`);
|
|
163
|
+
|
|
164
|
+
drawBox("⚡ COMMAND INSTAN SKILL TERSEDIA", lines, C.c1);
|
|
157
165
|
console.log('');
|
|
158
166
|
}
|
|
159
167
|
|
|
160
|
-
// Handlers for MCP with
|
|
168
|
+
// Handlers for MCP with Dynamic Command Helper
|
|
161
169
|
function listMCP() {
|
|
162
170
|
console.log(`\n${C.cyan}=== Registered MCP (Model Context Protocol) Servers ===${C.reset}`);
|
|
163
171
|
const keys = Object.keys(registry.mcp || {});
|
|
@@ -173,17 +181,20 @@ function listMCP() {
|
|
|
173
181
|
});
|
|
174
182
|
console.log('');
|
|
175
183
|
|
|
176
|
-
// Interactive Action Helper Popup
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
`
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
184
|
+
// Interactive Action Helper Popup with dynamic slash commands
|
|
185
|
+
const lines = [
|
|
186
|
+
`${C.bold}Perintah Instan MCP yang Bisa Kamu Ketik Langsung:${C.reset}`,
|
|
187
|
+
``
|
|
188
|
+
];
|
|
189
|
+
|
|
190
|
+
keys.forEach(name => {
|
|
191
|
+
lines.push(` ${C.yellow}/mcp-${name}${C.reset} <prompt kamu>`);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
lines.push(``);
|
|
195
|
+
lines.push(`${C.gray}Contoh: ${C.yellow}/mcp-${keys[0]} sinkronkan file terbaru${C.reset}`);
|
|
196
|
+
|
|
197
|
+
drawBox("🔌 COMMAND INSTAN MCP TERSEDIA", lines, C.c4);
|
|
187
198
|
console.log('');
|
|
188
199
|
}
|
|
189
200
|
|
|
@@ -210,7 +221,7 @@ function connectResource(inputArgs) {
|
|
|
210
221
|
status: 'Active'
|
|
211
222
|
};
|
|
212
223
|
saveRegistry(registry);
|
|
213
|
-
console.log(`${C.green}[+] Skill "${skillName}"
|
|
224
|
+
console.log(`${C.green}[+] Skill "${skillName}" terhubung! Akses instan: /skill-${skillName}${C.reset}\n`);
|
|
214
225
|
} else if (type === 'mcp') {
|
|
215
226
|
const mcpName = path.basename(resolvedPath, path.extname(resolvedPath));
|
|
216
227
|
registry.mcp = registry.mcp || {};
|
|
@@ -221,13 +232,12 @@ function connectResource(inputArgs) {
|
|
|
221
232
|
status: 'Connected'
|
|
222
233
|
};
|
|
223
234
|
saveRegistry(registry);
|
|
224
|
-
console.log(`${C.green}[+] MCP
|
|
235
|
+
console.log(`${C.green}[+] MCP "${mcpName}" terhubung! Akses instan: /mcp-${mcpName}${C.reset}\n`);
|
|
225
236
|
} else {
|
|
226
237
|
console.log(`${C.red}[x] Tipe tidak dikenal. Gunakan "skill" atau "mcp".${C.reset}\n`);
|
|
227
238
|
}
|
|
228
239
|
}
|
|
229
240
|
|
|
230
|
-
// Deep Multi-Location Scanner Function with Result Popup Card
|
|
231
241
|
function scanResources() {
|
|
232
242
|
console.log(`\n${C.yellow}[...] Memindai lokasi internal, home user, Gemini CLI & Claude Desktop...${C.reset}`);
|
|
233
243
|
registry = loadRegistry();
|
|
@@ -261,10 +271,10 @@ function scanResources() {
|
|
|
261
271
|
|
|
262
272
|
if (type === 'skill' && !registry.skills[name]) {
|
|
263
273
|
registry.skills[name] = { path: fullPath, connectedAt: new Date().toISOString(), status: 'Active' };
|
|
264
|
-
newDetected.push(
|
|
274
|
+
newDetected.push(`/skill-${name}`);
|
|
265
275
|
} else if (type === 'mcp' && !registry.mcp[name]) {
|
|
266
276
|
registry.mcp[name] = { target: fullPath, type: 'local', connectedAt: new Date().toISOString(), status: 'Connected' };
|
|
267
|
-
newDetected.push(
|
|
277
|
+
newDetected.push(`/mcp-${name}`);
|
|
268
278
|
}
|
|
269
279
|
});
|
|
270
280
|
} catch (e) {}
|
|
@@ -272,24 +282,20 @@ function scanResources() {
|
|
|
272
282
|
});
|
|
273
283
|
|
|
274
284
|
saveRegistry(registry);
|
|
275
|
-
|
|
276
285
|
console.log(`${C.green}[+] Pemindaian selesai.${C.reset}\n`);
|
|
277
286
|
|
|
278
|
-
// POPUP CARD SUMMARY FOR SCAN RESULTS
|
|
279
287
|
if (newDetected.length > 0) {
|
|
280
|
-
drawBox("🎉
|
|
281
|
-
`${C.green}
|
|
282
|
-
...newDetected.slice(0,
|
|
283
|
-
newDetected.length >
|
|
288
|
+
drawBox("🎉 COMMAND INSTAN BARU TERDETEKSI!", [
|
|
289
|
+
`${C.green}Kamu sekarang bisa langsung menggunakan perintah ini:${C.reset}`,
|
|
290
|
+
...newDetected.slice(0, 5).map(cmd => ` • ${C.yellow}${cmd}${C.reset} <prompt>`),
|
|
291
|
+
newDetected.length > 5 ? ` ...dan ${newDetected.length - 5} command lainnya.` : '',
|
|
284
292
|
``,
|
|
285
|
-
`${C.
|
|
293
|
+
`${C.cyan}Ketik /skill atau /mcp untuk melihat semua command.${C.reset}`
|
|
286
294
|
], C.green);
|
|
287
295
|
} else {
|
|
288
296
|
drawBox("ℹ️ HASIL PEMINDAIAN", [
|
|
289
|
-
`Tidak ada
|
|
290
|
-
`
|
|
291
|
-
``,
|
|
292
|
-
`Gunakan ${C.yellow}/skill${C.reset} atau ${C.yellow}/mcp${C.reset} untuk melihat item aktif.`
|
|
297
|
+
`Tidak ada Skill atau MCP baru yang terdeteksi.`,
|
|
298
|
+
`Ketik ${C.yellow}/skill${C.reset} atau ${C.yellow}/mcp${C.reset} untuk melihat command instan yang aktif.`
|
|
293
299
|
], C.gray);
|
|
294
300
|
}
|
|
295
301
|
console.log('');
|
|
@@ -448,12 +454,16 @@ async function fetchAvailableModels() {
|
|
|
448
454
|
}
|
|
449
455
|
}
|
|
450
456
|
|
|
451
|
-
async function handleChat(prompt) {
|
|
457
|
+
async function handleChat(prompt, forcedTool = null) {
|
|
452
458
|
if (!config.apiKey) {
|
|
453
459
|
console.log(`${C.yellow}[!] API Key is not set.${C.reset}`);
|
|
454
460
|
return askConfig(() => startPrompt());
|
|
455
461
|
}
|
|
456
462
|
|
|
463
|
+
if (forcedTool) {
|
|
464
|
+
console.log(`${C.cyan}[🚀 Executing via ${forcedTool.type.toUpperCase()}: ${forcedTool.name}]${C.reset}`);
|
|
465
|
+
}
|
|
466
|
+
|
|
457
467
|
console.log(`${C.yellow}TMPA CLI processing...${C.reset}`);
|
|
458
468
|
|
|
459
469
|
try {
|
|
@@ -461,8 +471,8 @@ async function handleChat(prompt) {
|
|
|
461
471
|
let headers = { 'Content-Type': 'application/json' };
|
|
462
472
|
let bodyData = {};
|
|
463
473
|
|
|
464
|
-
const toolsContext = getActiveToolsContext();
|
|
465
|
-
const fullPrompt = prompt + toolsContext;
|
|
474
|
+
const toolsContext = getActiveToolsContext(forcedTool);
|
|
475
|
+
const fullPrompt = (prompt || "Jalankan instruksi tool ini.") + toolsContext;
|
|
466
476
|
|
|
467
477
|
if (url.includes('googleapis.com')) {
|
|
468
478
|
url = `${url}?key=${config.apiKey}`;
|
|
@@ -559,6 +569,42 @@ function startPrompt() {
|
|
|
559
569
|
startPrompt();
|
|
560
570
|
} else if (cmd === '/uninstall') {
|
|
561
571
|
handleUninstall();
|
|
572
|
+
} else if (cmd.startsWith('/skill-')) {
|
|
573
|
+
// Dynamic Slash Command for Skill: /skill-remotion-vidio <prompt>
|
|
574
|
+
const fullCmd = cmd.slice(7).trim(); // remove '/skill-'
|
|
575
|
+
const spaceIdx = fullCmd.indexOf(' ');
|
|
576
|
+
let skillName = fullCmd;
|
|
577
|
+
let userPrompt = '';
|
|
578
|
+
|
|
579
|
+
if (spaceIdx !== -1) {
|
|
580
|
+
skillName = fullCmd.slice(0, spaceIdx);
|
|
581
|
+
userPrompt = fullCmd.slice(spaceIdx + 1).trim();
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
if (registry.skills && registry.skills[skillName]) {
|
|
585
|
+
handleChat(userPrompt, { type: 'skill', name: skillName, target: registry.skills[skillName].path });
|
|
586
|
+
} else {
|
|
587
|
+
console.log(`${C.red}[x] Skill "${skillName}" tidak ditemukan di registry. Ketik /skill untuk melihat daftar.${C.reset}\n`);
|
|
588
|
+
startPrompt();
|
|
589
|
+
}
|
|
590
|
+
} else if (cmd.startsWith('/mcp-')) {
|
|
591
|
+
// Dynamic Slash Command for MCP: /mcp-stitch <prompt>
|
|
592
|
+
const fullCmd = cmd.slice(5).trim(); // remove '/mcp-'
|
|
593
|
+
const spaceIdx = fullCmd.indexOf(' ');
|
|
594
|
+
let mcpName = fullCmd;
|
|
595
|
+
let userPrompt = '';
|
|
596
|
+
|
|
597
|
+
if (spaceIdx !== -1) {
|
|
598
|
+
mcpName = fullCmd.slice(0, spaceIdx);
|
|
599
|
+
userPrompt = fullCmd.slice(spaceIdx + 1).trim();
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
if (registry.mcp && registry.mcp[mcpName]) {
|
|
603
|
+
handleChat(userPrompt, { type: 'mcp', name: mcpName, target: registry.mcp[mcpName].target });
|
|
604
|
+
} else {
|
|
605
|
+
console.log(`${C.red}[x] MCP "${mcpName}" tidak ditemukan di registry. Ketik /mcp untuk melihat daftar.${C.reset}\n`);
|
|
606
|
+
startPrompt();
|
|
607
|
+
}
|
|
562
608
|
} else if (cmd === '') {
|
|
563
609
|
startPrompt();
|
|
564
610
|
} else {
|