@exreve/exk 1.0.29 → 1.0.31
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/dist/agentSession.js +3 -99
- package/dist/app-child.js +0 -41
- package/dist/index.js +0 -50
- package/dist/moduleMcpServer.js +5 -82
- package/dist/ttc-cli.tar.gz +0 -0
- package/package.json +1 -1
package/dist/agentSession.js
CHANGED
|
@@ -320,26 +320,15 @@ export class AgentSessionManager {
|
|
|
320
320
|
existingSession.model = model;
|
|
321
321
|
}
|
|
322
322
|
// Update enabled modules and settings if provided
|
|
323
|
-
const newModules = handler.enabledModules;
|
|
324
|
-
if (newModules) {
|
|
325
|
-
existingSession.enabledModules = newModules;
|
|
326
|
-
}
|
|
327
|
-
const newModuleSettings = handler.moduleSettings;
|
|
328
|
-
if (newModuleSettings) {
|
|
329
|
-
existingSession.moduleSettings = newModuleSettings;
|
|
330
|
-
}
|
|
331
|
-
existingSession.userChoiceEnabled = handler.userChoiceEnabled || false;
|
|
332
323
|
// Ensure abort controller is fresh for new queries
|
|
333
324
|
existingSession.abortController = new AbortController();
|
|
334
|
-
// Update handler
|
|
325
|
+
// Update handler reference
|
|
335
326
|
this.sessionHandlers.set(sessionId, handler);
|
|
336
327
|
return;
|
|
337
328
|
}
|
|
338
329
|
// Store the handler for this session
|
|
339
330
|
this.sessionHandlers.set(sessionId, handler);
|
|
340
331
|
const abortController = new AbortController();
|
|
341
|
-
const enabledModules = handler.enabledModules || [];
|
|
342
|
-
const moduleSettings = handler.moduleSettings || {};
|
|
343
332
|
// Restore claudeSessionId from disk (survives CLI restart)
|
|
344
333
|
const persistedState = loadSessionState(sessionId);
|
|
345
334
|
const restoredClaudeSessionId = persistedState?.claudeSessionId;
|
|
@@ -359,9 +348,6 @@ export class AgentSessionManager {
|
|
|
359
348
|
claudeProcessGroupId: undefined,
|
|
360
349
|
currentPromptId: undefined,
|
|
361
350
|
model: sessionModel,
|
|
362
|
-
userChoiceEnabled: handler.userChoiceEnabled || false,
|
|
363
|
-
enabledModules,
|
|
364
|
-
moduleSettings
|
|
365
351
|
});
|
|
366
352
|
// Auto-regenerate CLAUDE.md for fresh project context
|
|
367
353
|
await this.regenerateClaudeMd(projectPath);
|
|
@@ -519,9 +505,7 @@ export class AgentSessionManager {
|
|
|
519
505
|
apiKey: CLAUDE_CONFIG.apiKey,
|
|
520
506
|
model: CLAUDE_CONFIG.model,
|
|
521
507
|
tools: { type: 'preset', preset: 'claude_code' },
|
|
522
|
-
disallowedTools:
|
|
523
|
-
? ['AskUserQuestion', 'analyze_image'] // Disable built-in analyze_image when we have our own
|
|
524
|
-
: ['AskUserQuestion'],
|
|
508
|
+
disallowedTools: ['AskUserQuestion', 'analyze_image'], // Disable built-in analyze_image (we provide our own via MCP)
|
|
525
509
|
settingSources: ['project'], // Enable CLAUDE.md loading
|
|
526
510
|
permissionMode: 'bypassPermissions',
|
|
527
511
|
allowDangerouslySkipPermissions: true,
|
|
@@ -1230,11 +1214,6 @@ export class AgentSessionManager {
|
|
|
1230
1214
|
session.currentPromptId = undefined;
|
|
1231
1215
|
// 8. Remove from emergency stop tracking
|
|
1232
1216
|
this.emergencyStopInProgress.delete(sessionId);
|
|
1233
|
-
// 9. Resolve any pending choice request with null (cancelled)
|
|
1234
|
-
if (session.pendingChoice) {
|
|
1235
|
-
session.pendingChoice.resolve({ choiceId: session.pendingChoice.request.choiceId, selectedValue: null });
|
|
1236
|
-
session.pendingChoice = undefined;
|
|
1237
|
-
}
|
|
1238
1217
|
const message = currentPromptId
|
|
1239
1218
|
? `Emergency stop: Cancelled prompt '${currentPromptId}' and cleared ${queueSize} queued prompts`
|
|
1240
1219
|
: `Emergency stop: Cleared ${queueSize} queued prompts`;
|
|
@@ -1258,84 +1237,9 @@ export class AgentSessionManager {
|
|
|
1258
1237
|
console.log(`[buildMcpServer] No session found for ${sessionId}`);
|
|
1259
1238
|
return undefined;
|
|
1260
1239
|
}
|
|
1261
|
-
|
|
1262
|
-
console.log(`[buildMcpServer] Session ${sessionId}: enabledModules=${JSON.stringify(enabledModules)}, attachmentDir=${attachmentDir || 'none'}`);
|
|
1263
|
-
if (enabledModules.length === 0 && !attachmentDir) {
|
|
1264
|
-
console.log(`[buildMcpServer] No enabled modules and no attachments, skipping MCP server creation`);
|
|
1265
|
-
return undefined;
|
|
1266
|
-
}
|
|
1267
|
-
const handler = this.sessionHandlers.get(sessionId);
|
|
1240
|
+
console.log(`[buildMcpServer] Session ${sessionId}: attachmentDir=${attachmentDir || 'none'}`);
|
|
1268
1241
|
return createModuleMcpServer({
|
|
1269
|
-
enabledModules,
|
|
1270
|
-
moduleSettings: session.moduleSettings || {},
|
|
1271
1242
|
attachmentDir,
|
|
1272
|
-
onChoiceRequest: handler?.onChoiceRequest
|
|
1273
|
-
? async (request) => {
|
|
1274
|
-
return new Promise((resolve) => {
|
|
1275
|
-
const sess = this.sessions.get(sessionId);
|
|
1276
|
-
if (sess) {
|
|
1277
|
-
sess.pendingChoice = { request, resolve };
|
|
1278
|
-
handler.onChoiceRequest(request);
|
|
1279
|
-
}
|
|
1280
|
-
else {
|
|
1281
|
-
resolve({ choiceId: request.choiceId, selectedValue: null });
|
|
1282
|
-
}
|
|
1283
|
-
});
|
|
1284
|
-
}
|
|
1285
|
-
: undefined
|
|
1286
|
-
});
|
|
1287
|
-
}
|
|
1288
|
-
/**
|
|
1289
|
-
* Handle user choice response from frontend
|
|
1290
|
-
*/
|
|
1291
|
-
async handleChoiceResponse(sessionId, response) {
|
|
1292
|
-
const session = this.sessions.get(sessionId);
|
|
1293
|
-
if (!session) {
|
|
1294
|
-
console.error(`[agentSession] Session ${sessionId} not found for choice response`);
|
|
1295
|
-
return;
|
|
1296
|
-
}
|
|
1297
|
-
if (!session.pendingChoice) {
|
|
1298
|
-
console.warn(`[agentSession] No pending choice for session ${sessionId}`);
|
|
1299
|
-
return;
|
|
1300
|
-
}
|
|
1301
|
-
if (session.pendingChoice.request.choiceId !== response.choiceId) {
|
|
1302
|
-
console.warn(`[agentSession] Choice ID mismatch: expected ${session.pendingChoice.request.choiceId}, got ${response.choiceId}`);
|
|
1303
|
-
return;
|
|
1304
|
-
}
|
|
1305
|
-
// Resolve the pending choice promise
|
|
1306
|
-
session.pendingChoice.resolve(response);
|
|
1307
|
-
session.pendingChoice = undefined;
|
|
1308
|
-
}
|
|
1309
|
-
/**
|
|
1310
|
-
* Request user choice during agent execution
|
|
1311
|
-
*/
|
|
1312
|
-
async requestUserChoice(sessionId, request) {
|
|
1313
|
-
const session = this.sessions.get(sessionId);
|
|
1314
|
-
if (!session) {
|
|
1315
|
-
throw new Error(`Session ${sessionId} not found`);
|
|
1316
|
-
}
|
|
1317
|
-
// Check if user choice is enabled for this session
|
|
1318
|
-
if (!session.userChoiceEnabled) {
|
|
1319
|
-
throw new Error('User choice is not enabled for this session');
|
|
1320
|
-
}
|
|
1321
|
-
// Create a promise that will be resolved when the user responds
|
|
1322
|
-
return new Promise((resolve) => {
|
|
1323
|
-
session.pendingChoice = { request, resolve };
|
|
1324
|
-
// Emit the choice request through the onOutput callback
|
|
1325
|
-
// This will be picked up by the CLI and sent to the frontend
|
|
1326
|
-
const handler = this.sessionHandlers.get(sessionId);
|
|
1327
|
-
if (handler?.onChoiceRequest) {
|
|
1328
|
-
handler.onChoiceRequest(request);
|
|
1329
|
-
}
|
|
1330
|
-
// Set timeout if specified
|
|
1331
|
-
if (request.timeout) {
|
|
1332
|
-
setTimeout(() => {
|
|
1333
|
-
if (session.pendingChoice?.request.choiceId === request.choiceId) {
|
|
1334
|
-
session.pendingChoice.resolve({ choiceId: request.choiceId, selectedValue: null });
|
|
1335
|
-
session.pendingChoice = undefined;
|
|
1336
|
-
}
|
|
1337
|
-
}, request.timeout);
|
|
1338
|
-
}
|
|
1339
1243
|
});
|
|
1340
1244
|
}
|
|
1341
1245
|
}
|
package/dist/app-child.js
CHANGED
|
@@ -1341,15 +1341,6 @@ async function runDaemon(foreground = false, email) {
|
|
|
1341
1341
|
socket.emit('session:error', { sessionId, error: 'Session not found or projectPath missing' });
|
|
1342
1342
|
return;
|
|
1343
1343
|
}
|
|
1344
|
-
// Check if user choice is enabled from the prompt data (sent by backend)
|
|
1345
|
-
// Backend now includes enabledModules in the session:prompt event
|
|
1346
|
-
const enabledModules = data.enabledModules || [];
|
|
1347
|
-
const moduleSettings = data.moduleSettings || {};
|
|
1348
|
-
const userChoiceEnabled = enabledModules.includes('user-choice') || false;
|
|
1349
|
-
if (foreground) {
|
|
1350
|
-
console.log(`[CLI] Enabled modules: ${enabledModules.join(', ') || 'none'}`);
|
|
1351
|
-
console.log(`[CLI] User choice enabled: ${userChoiceEnabled}`);
|
|
1352
|
-
}
|
|
1353
1344
|
// Store in activeSessions with promptId and model
|
|
1354
1345
|
activeSessions.set(sessionId, { projectPath, currentPromptId: promptId, model });
|
|
1355
1346
|
// Capture promptId in closure to prevent race conditions when multiple prompts arrive quickly
|
|
@@ -1363,9 +1354,6 @@ async function runDaemon(foreground = false, email) {
|
|
|
1363
1354
|
await agentSessionManager.createSession({
|
|
1364
1355
|
sessionId,
|
|
1365
1356
|
projectPath,
|
|
1366
|
-
userChoiceEnabled, // Pass user choice enabled setting from backend
|
|
1367
|
-
enabledModules, // Pass enabled modules for MCP server
|
|
1368
|
-
moduleSettings, // Pass module settings for MCP server
|
|
1369
1357
|
onOutput: (output) => {
|
|
1370
1358
|
// Serialize data to string if it's an object
|
|
1371
1359
|
const dataString = typeof output.data === 'string'
|
|
@@ -1393,16 +1381,6 @@ async function runDaemon(foreground = false, email) {
|
|
|
1393
1381
|
// The actual session:result is emitted from sendPrompt handler below
|
|
1394
1382
|
// This handler is kept for backward compatibility but may not be used
|
|
1395
1383
|
},
|
|
1396
|
-
onChoiceRequest: (request) => {
|
|
1397
|
-
// Emit choice request to frontend
|
|
1398
|
-
socket.emit('user:choice:request', {
|
|
1399
|
-
sessionId,
|
|
1400
|
-
choiceId: request.choiceId,
|
|
1401
|
-
question: request.question,
|
|
1402
|
-
options: request.options,
|
|
1403
|
-
timeout: request.timeout
|
|
1404
|
-
});
|
|
1405
|
-
}
|
|
1406
1384
|
});
|
|
1407
1385
|
// Send prompt - status updates will be emitted from agentSession when processing starts/completes
|
|
1408
1386
|
await agentSessionManager.sendPrompt(sessionId, prompt, enhancers || [], {
|
|
@@ -1555,25 +1533,6 @@ async function runDaemon(foreground = false, email) {
|
|
|
1555
1533
|
callback?.({ success: false, message: error.message });
|
|
1556
1534
|
}
|
|
1557
1535
|
});
|
|
1558
|
-
// Handle user choice response from frontend
|
|
1559
|
-
socket.on('user:choice:response', async (data) => {
|
|
1560
|
-
try {
|
|
1561
|
-
const { sessionId, choiceId, selectedValue } = data;
|
|
1562
|
-
if (foreground) {
|
|
1563
|
-
console.log(`[CLI] 📝 Received user choice response: choiceId=${choiceId}, selectedValue=${selectedValue}`);
|
|
1564
|
-
}
|
|
1565
|
-
// Forward the response to the agent session manager
|
|
1566
|
-
await agentSessionManager.handleChoiceResponse(sessionId, {
|
|
1567
|
-
choiceId,
|
|
1568
|
-
selectedValue
|
|
1569
|
-
});
|
|
1570
|
-
}
|
|
1571
|
-
catch (error) {
|
|
1572
|
-
if (foreground) {
|
|
1573
|
-
console.error(`✗ Error handling user choice response: ${error.message}`);
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
});
|
|
1577
1536
|
socket.on('connect', () => {
|
|
1578
1537
|
if (foreground) {
|
|
1579
1538
|
console.log(`✓ Connected to backend at ${config.apiUrl}`);
|
package/dist/index.js
CHANGED
|
@@ -1286,24 +1286,6 @@ async function runDaemon(foreground = false, email) {
|
|
|
1286
1286
|
socket.emit('session:error', { sessionId, error: 'Session not found or projectPath missing' });
|
|
1287
1287
|
return;
|
|
1288
1288
|
}
|
|
1289
|
-
// Check if user choice is enabled from the prompt data (sent by backend)
|
|
1290
|
-
// Backend now includes enabledModules in the session:prompt event
|
|
1291
|
-
const enabledModules = data.enabledModules || [];
|
|
1292
|
-
const moduleSettings = data.moduleSettings || {};
|
|
1293
|
-
const userChoiceEnabled = enabledModules.includes('user-choice') || false;
|
|
1294
|
-
if (foreground) {
|
|
1295
|
-
console.log(`[CLI] Enabled modules: ${enabledModules.join(', ') || 'none'}`);
|
|
1296
|
-
console.log(`[CLI] User choice enabled: ${userChoiceEnabled}`);
|
|
1297
|
-
}
|
|
1298
|
-
// Store in activeSessions with promptId and model
|
|
1299
|
-
activeSessions.set(sessionId, { projectPath, currentPromptId: promptId, model });
|
|
1300
|
-
if (!projectPath) {
|
|
1301
|
-
if (foreground) {
|
|
1302
|
-
console.error(`✗ Session not found: ${sessionId} (missing projectPath)`);
|
|
1303
|
-
}
|
|
1304
|
-
socket.emit('session:error', { sessionId, error: 'Session not found or projectPath missing' });
|
|
1305
|
-
return;
|
|
1306
|
-
}
|
|
1307
1289
|
// Store in activeSessions with promptId and model
|
|
1308
1290
|
activeSessions.set(sessionId, { projectPath, currentPromptId: promptId, model });
|
|
1309
1291
|
// Capture promptId in closure to prevent race conditions when multiple prompts arrive quickly
|
|
@@ -1317,9 +1299,6 @@ async function runDaemon(foreground = false, email) {
|
|
|
1317
1299
|
await agentSessionManager.createSession({
|
|
1318
1300
|
sessionId,
|
|
1319
1301
|
projectPath,
|
|
1320
|
-
userChoiceEnabled, // Pass user choice enabled setting from backend
|
|
1321
|
-
enabledModules, // Pass enabled modules for MCP server
|
|
1322
|
-
moduleSettings, // Pass module settings for MCP server
|
|
1323
1302
|
onOutput: (output) => {
|
|
1324
1303
|
// Serialize data to string if it's an object
|
|
1325
1304
|
const dataString = typeof output.data === 'string'
|
|
@@ -1347,16 +1326,6 @@ async function runDaemon(foreground = false, email) {
|
|
|
1347
1326
|
// The actual session:result is emitted from sendPrompt handler below
|
|
1348
1327
|
// This handler is kept for backward compatibility but may not be used
|
|
1349
1328
|
},
|
|
1350
|
-
onChoiceRequest: (request) => {
|
|
1351
|
-
// Emit choice request to frontend
|
|
1352
|
-
socket.emit('user:choice:request', {
|
|
1353
|
-
sessionId,
|
|
1354
|
-
choiceId: request.choiceId,
|
|
1355
|
-
question: request.question,
|
|
1356
|
-
options: request.options,
|
|
1357
|
-
timeout: request.timeout
|
|
1358
|
-
});
|
|
1359
|
-
}
|
|
1360
1329
|
});
|
|
1361
1330
|
// Send prompt - status updates will be emitted from agentSession when processing starts/completes
|
|
1362
1331
|
await agentSessionManager.sendPrompt(sessionId, prompt, enhancers || [], {
|
|
@@ -1509,25 +1478,6 @@ async function runDaemon(foreground = false, email) {
|
|
|
1509
1478
|
callback?.({ success: false, message: error.message });
|
|
1510
1479
|
}
|
|
1511
1480
|
});
|
|
1512
|
-
// Handle user choice response from frontend
|
|
1513
|
-
socket.on('user:choice:response', async (data) => {
|
|
1514
|
-
try {
|
|
1515
|
-
const { sessionId, choiceId, selectedValue } = data;
|
|
1516
|
-
if (foreground) {
|
|
1517
|
-
console.log(`[CLI] 📝 Received user choice response: choiceId=${choiceId}, selectedValue=${selectedValue}`);
|
|
1518
|
-
}
|
|
1519
|
-
// Forward the response to the agent session manager
|
|
1520
|
-
await agentSessionManager.handleChoiceResponse(sessionId, {
|
|
1521
|
-
choiceId,
|
|
1522
|
-
selectedValue
|
|
1523
|
-
});
|
|
1524
|
-
}
|
|
1525
|
-
catch (error) {
|
|
1526
|
-
if (foreground) {
|
|
1527
|
-
console.error(`✗ Error handling user choice response: ${error.message}`);
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
});
|
|
1531
1481
|
// Handle image save request - saves base64 images to tmp directory
|
|
1532
1482
|
socket.on('image:save', async (data) => {
|
|
1533
1483
|
try {
|
package/dist/moduleMcpServer.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Module MCP Server
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* This allows the agent to interact with modules like user-choice through standard tool calls.
|
|
6
|
-
* Also provides built-in tools like analyze_image for vision capabilities.
|
|
4
|
+
* Provides built-in tools like analyze_image for vision capabilities.
|
|
7
5
|
*/
|
|
8
6
|
import { createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk';
|
|
9
7
|
import { z } from 'zod';
|
|
@@ -11,67 +9,6 @@ import * as fs from 'fs';
|
|
|
11
9
|
import * as path from 'path';
|
|
12
10
|
import * as os from 'os';
|
|
13
11
|
import { getOpenrouterApiKey } from './agentSession.js';
|
|
14
|
-
/**
|
|
15
|
-
* Create a tool for the user-choice module
|
|
16
|
-
*/
|
|
17
|
-
function createUserChoiceTool(onChoiceRequest) {
|
|
18
|
-
const schema = {
|
|
19
|
-
question: z.string(),
|
|
20
|
-
options: z.array(z.object({ label: z.string(), value: z.string() })),
|
|
21
|
-
timeout: z.number().optional()
|
|
22
|
-
};
|
|
23
|
-
return tool('user_choice_request', 'Request user input when making decisions. Use this when you need the user to choose between options or provide input on a decision. This tool will present a modal to the user with your question and wait for their response.', schema, async (args, _extra) => {
|
|
24
|
-
if (!onChoiceRequest) {
|
|
25
|
-
return {
|
|
26
|
-
content: [
|
|
27
|
-
{
|
|
28
|
-
type: 'text',
|
|
29
|
-
text: 'Error: User choice is not enabled. Please use an alternative approach or ask the user directly.'
|
|
30
|
-
}
|
|
31
|
-
],
|
|
32
|
-
isError: true
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
const choiceId = `choice-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
36
|
-
try {
|
|
37
|
-
const response = await onChoiceRequest({
|
|
38
|
-
choiceId,
|
|
39
|
-
question: args.question,
|
|
40
|
-
options: args.options,
|
|
41
|
-
timeout: args.timeout
|
|
42
|
-
});
|
|
43
|
-
if (response.selectedValue === null) {
|
|
44
|
-
return {
|
|
45
|
-
content: [
|
|
46
|
-
{
|
|
47
|
-
type: 'text',
|
|
48
|
-
text: 'The user did not respond within the timeout period. Please proceed with a reasonable default or ask again.'
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
return {
|
|
54
|
-
content: [
|
|
55
|
-
{
|
|
56
|
-
type: 'text',
|
|
57
|
-
text: `The user selected: ${response.selectedValue}`
|
|
58
|
-
}
|
|
59
|
-
]
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
return {
|
|
64
|
-
content: [
|
|
65
|
-
{
|
|
66
|
-
type: 'text',
|
|
67
|
-
text: `Error requesting user choice: ${error instanceof Error ? error.message : String(error)}`
|
|
68
|
-
}
|
|
69
|
-
],
|
|
70
|
-
isError: true
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
12
|
/**
|
|
76
13
|
* Convert a file to a data URI for vision API consumption
|
|
77
14
|
*/
|
|
@@ -141,26 +78,12 @@ function createAnalyzeImageTool(attachmentDir) {
|
|
|
141
78
|
});
|
|
142
79
|
}
|
|
143
80
|
/**
|
|
144
|
-
*
|
|
145
|
-
*/
|
|
146
|
-
function getModuleTools(config) {
|
|
147
|
-
const tools = [];
|
|
148
|
-
// User choice module
|
|
149
|
-
if (config.enabledModules.includes('user-choice')) {
|
|
150
|
-
tools.push(createUserChoiceTool(config.onChoiceRequest));
|
|
151
|
-
}
|
|
152
|
-
// Always add analyze_image tool if attachmentDir is provided (i.e. there are attachments)
|
|
153
|
-
if (config.attachmentDir) {
|
|
154
|
-
tools.push(createAnalyzeImageTool(config.attachmentDir));
|
|
155
|
-
}
|
|
156
|
-
// Add more module tools here as they are implemented
|
|
157
|
-
return tools;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Create the module MCP server
|
|
81
|
+
* Create the MCP server with built-in tools (always includes analyze_image)
|
|
161
82
|
*/
|
|
162
83
|
export function createModuleMcpServer(config) {
|
|
163
|
-
const tools =
|
|
84
|
+
const tools = [];
|
|
85
|
+
// Always add analyze_image tool (uses OpenRouter key from ai-config via backend)
|
|
86
|
+
tools.push(createAnalyzeImageTool(config.attachmentDir));
|
|
164
87
|
const server = createSdkMcpServer({
|
|
165
88
|
name: 'claude-voice-modules',
|
|
166
89
|
version: '1.0.0',
|
package/dist/ttc-cli.tar.gz
CHANGED
|
Binary file
|