@dainprotocol/cli 1.0.16 → 1.0.19
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/commands/build.js +2 -2
- package/dist/commands/config.js +2 -2
- package/dist/commands/deploy.js +2 -2
- package/dist/commands/dev.js +2 -2
- package/dist/commands/init.js +2 -2
- package/dist/commands/testchat.js +195 -0
- package/dist/index.js +8 -0
- package/dist/templates/default/src/index.ts +1 -1
- package/dist/utils.js +3 -3
- package/package.json +4 -1
- package/templates/default/src/index.ts +1 -1
package/dist/commands/build.js
CHANGED
|
@@ -32,8 +32,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
34
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
35
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
36
|
-
return g =
|
|
35
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
36
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
37
37
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
38
38
|
function step(op) {
|
|
39
39
|
if (f) throw new TypeError("Generator is already executing.");
|
package/dist/commands/config.js
CHANGED
|
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g =
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
14
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
15
|
function step(op) {
|
|
16
16
|
if (f) throw new TypeError("Generator is already executing.");
|
package/dist/commands/deploy.js
CHANGED
|
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g =
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
14
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
15
|
function step(op) {
|
|
16
16
|
if (f) throw new TypeError("Generator is already executing.");
|
package/dist/commands/dev.js
CHANGED
|
@@ -20,8 +20,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
20
20
|
});
|
|
21
21
|
};
|
|
22
22
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
-
return g =
|
|
23
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
24
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
25
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
26
|
function step(op) {
|
|
27
27
|
if (f) throw new TypeError("Generator is already executing.");
|
package/dist/commands/init.js
CHANGED
|
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g =
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
14
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
15
|
function step(op) {
|
|
16
16
|
if (f) throw new TypeError("Generator is already executing.");
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
30
|
+
if (mod && mod.__esModule) return mod;
|
|
31
|
+
var result = {};
|
|
32
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
33
|
+
__setModuleDefault(result, mod);
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
37
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
38
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
39
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
40
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
41
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
42
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
46
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
47
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
48
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
49
|
+
function step(op) {
|
|
50
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
51
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
52
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
53
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
54
|
+
switch (op[0]) {
|
|
55
|
+
case 0: case 1: t = op; break;
|
|
56
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
57
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
58
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
59
|
+
default:
|
|
60
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
61
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
62
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
63
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
64
|
+
if (t[2]) _.ops.pop();
|
|
65
|
+
_.trys.pop(); continue;
|
|
66
|
+
}
|
|
67
|
+
op = body.call(thisArg, _);
|
|
68
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
69
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
73
|
+
exports.default = testchat;
|
|
74
|
+
var anthropic_1 = require("@ai-sdk/anthropic");
|
|
75
|
+
var ai_1 = require("ai");
|
|
76
|
+
require("dotenv/config");
|
|
77
|
+
var readline = __importStar(require("node:readline/promises"));
|
|
78
|
+
var client_1 = require("@dainprotocol/service-sdk/client");
|
|
79
|
+
var utils_1 = require("../utils");
|
|
80
|
+
var terminal = readline.createInterface({
|
|
81
|
+
input: process.stdin,
|
|
82
|
+
output: process.stdout,
|
|
83
|
+
});
|
|
84
|
+
function chat(dainConnection) {
|
|
85
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
86
|
+
var allTools, toolBoxes, _i, toolBoxes_1, toolBox, toolBoxTools, messages, toolResponseAvailable, userInput, _a, text, toolCalls, toolResults, responseMessages, _b, toolCalls_1, _c, toolName, args, _d, toolResults_1, _e, toolName, result, error_1;
|
|
87
|
+
return __generator(this, function (_f) {
|
|
88
|
+
switch (_f.label) {
|
|
89
|
+
case 0:
|
|
90
|
+
allTools = {};
|
|
91
|
+
return [4 /*yield*/, dainConnection.getToolboxes()];
|
|
92
|
+
case 1:
|
|
93
|
+
toolBoxes = _f.sent();
|
|
94
|
+
_i = 0, toolBoxes_1 = toolBoxes;
|
|
95
|
+
_f.label = 2;
|
|
96
|
+
case 2:
|
|
97
|
+
if (!(_i < toolBoxes_1.length)) return [3 /*break*/, 5];
|
|
98
|
+
toolBox = toolBoxes_1[_i];
|
|
99
|
+
if (!toolBox.id)
|
|
100
|
+
return [3 /*break*/, 4];
|
|
101
|
+
return [4 /*yield*/, dainConnection.loadToolbox(toolBox.id, true)];
|
|
102
|
+
case 3:
|
|
103
|
+
toolBoxTools = _f.sent();
|
|
104
|
+
allTools = __assign(__assign({}, allTools), toolBoxTools);
|
|
105
|
+
_f.label = 4;
|
|
106
|
+
case 4:
|
|
107
|
+
_i++;
|
|
108
|
+
return [3 /*break*/, 2];
|
|
109
|
+
case 5:
|
|
110
|
+
messages = [];
|
|
111
|
+
toolResponseAvailable = false;
|
|
112
|
+
_f.label = 6;
|
|
113
|
+
case 6:
|
|
114
|
+
if (!true) return [3 /*break*/, 12];
|
|
115
|
+
if (!!toolResponseAvailable) return [3 /*break*/, 8];
|
|
116
|
+
return [4 /*yield*/, terminal.question('You: ')];
|
|
117
|
+
case 7:
|
|
118
|
+
userInput = _f.sent();
|
|
119
|
+
if (userInput.toLowerCase() === 'exit') {
|
|
120
|
+
console.log('Goodbye!');
|
|
121
|
+
terminal.close();
|
|
122
|
+
return [2 /*return*/];
|
|
123
|
+
}
|
|
124
|
+
messages.push({ role: 'user', content: userInput });
|
|
125
|
+
_f.label = 8;
|
|
126
|
+
case 8:
|
|
127
|
+
_f.trys.push([8, 10, , 11]);
|
|
128
|
+
console.log("messages", messages);
|
|
129
|
+
return [4 /*yield*/, (0, ai_1.generateText)({
|
|
130
|
+
model: (0, anthropic_1.anthropic)('claude-3-5-sonnet-20240620'),
|
|
131
|
+
system: " Keep your responses brief but insightful.\n use lots of emojis, to show your enthusiasm!\n Your name is Butterfly, Built by the team at Dain. \n You are given tools only use them if they ask for it or if it helps you accomplish the task.\n when explaining topics you can use diagrams to help visualize the concepts.\n if the user asks for a tool, you can use it to help them\n You always answer the with markdown formatting. use markdown when it would be possible.\n You support the following markdown headings, bold, italic, links, tables, lists, code blocks, and blockquotes.\n You do not support images and never include images. You can also use emojis to show enthusiasm!\n Tools often have UI components that directly display to the user, once they are displayed you dont need to repeat the tool name or what it does or what its supposed to output, assume the user can already see the output.\n",
|
|
132
|
+
tools: allTools,
|
|
133
|
+
messages: messages,
|
|
134
|
+
maxSteps: 5
|
|
135
|
+
})];
|
|
136
|
+
case 9:
|
|
137
|
+
_a = _f.sent(), text = _a.text, toolCalls = _a.toolCalls, toolResults = _a.toolResults, responseMessages = _a.responseMessages;
|
|
138
|
+
toolResponseAvailable = false;
|
|
139
|
+
if (text) {
|
|
140
|
+
process.stdout.write("\nAssistant: ".concat(text));
|
|
141
|
+
}
|
|
142
|
+
for (_b = 0, toolCalls_1 = toolCalls; _b < toolCalls_1.length; _b++) {
|
|
143
|
+
_c = toolCalls_1[_b], toolName = _c.toolName, args = _c.args;
|
|
144
|
+
process.stdout.write("\nTool call: '".concat(toolName, "' ").concat(JSON.stringify(args)));
|
|
145
|
+
}
|
|
146
|
+
for (_d = 0, toolResults_1 = toolResults; _d < toolResults_1.length; _d++) {
|
|
147
|
+
_e = toolResults_1[_d], toolName = _e.toolName, result = _e.result;
|
|
148
|
+
process.stdout.write("\nTool response: '".concat(toolName, "' ").concat(JSON.stringify(result)));
|
|
149
|
+
}
|
|
150
|
+
process.stdout.write('\n\n');
|
|
151
|
+
messages.push.apply(messages, responseMessages);
|
|
152
|
+
toolResponseAvailable = toolCalls.length > 0;
|
|
153
|
+
return [3 /*break*/, 11];
|
|
154
|
+
case 10:
|
|
155
|
+
error_1 = _f.sent();
|
|
156
|
+
console.error('Error generating response:', error_1);
|
|
157
|
+
return [3 /*break*/, 11];
|
|
158
|
+
case 11: return [3 /*break*/, 6];
|
|
159
|
+
case 12: return [2 /*return*/];
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function testchat(options) {
|
|
165
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
166
|
+
var config, url, agentAuth, dainConnection;
|
|
167
|
+
return __generator(this, function (_a) {
|
|
168
|
+
switch (_a.label) {
|
|
169
|
+
case 0:
|
|
170
|
+
config = (0, utils_1.getDainConfig)(options.config);
|
|
171
|
+
url = options.url || process.env.TEST_CHAT_URL;
|
|
172
|
+
if (!url) {
|
|
173
|
+
console.error('Error: Please provide a URL using --url option or set TEST_CHAT_URL in your .env file');
|
|
174
|
+
process.exit(1);
|
|
175
|
+
}
|
|
176
|
+
if (!process.env.ANTHROPIC_API_KEY) {
|
|
177
|
+
console.error('Error: ANTHROPIC_API_KEY is not set in your .env file');
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
if (!config['api-key']) {
|
|
181
|
+
throw new Error("'api-key' is required when using development proxy");
|
|
182
|
+
}
|
|
183
|
+
agentAuth = new client_1.DainClientAuth({
|
|
184
|
+
apiKey: config['api-key']
|
|
185
|
+
});
|
|
186
|
+
dainConnection = new client_1.DainServiceConnection(url, agentAuth);
|
|
187
|
+
console.log('Starting chat session. Type "exit" to end the conversation.');
|
|
188
|
+
return [4 /*yield*/, chat(dainConnection)];
|
|
189
|
+
case 1:
|
|
190
|
+
_a.sent();
|
|
191
|
+
return [2 /*return*/];
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ var dev_1 = __importDefault(require("./commands/dev"));
|
|
|
10
10
|
var deploy_1 = __importDefault(require("./commands/deploy"));
|
|
11
11
|
var build_1 = __importDefault(require("./commands/build"));
|
|
12
12
|
var start_1 = __importDefault(require("./commands/start"));
|
|
13
|
+
var testchat_1 = __importDefault(require("./commands/testchat"));
|
|
13
14
|
var program = new commander_1.Command();
|
|
14
15
|
program
|
|
15
16
|
.name('dain')
|
|
@@ -57,6 +58,13 @@ program
|
|
|
57
58
|
.action(function (options) {
|
|
58
59
|
(0, start_1.default)(options);
|
|
59
60
|
});
|
|
61
|
+
program
|
|
62
|
+
.command('testchat')
|
|
63
|
+
.description('Start a chat session with a DAIN service')
|
|
64
|
+
.option('--url <url>', 'The URL of the DAIN service')
|
|
65
|
+
.action(function (options) {
|
|
66
|
+
(0, testchat_1.default)(options);
|
|
67
|
+
});
|
|
60
68
|
program.parse(process.argv);
|
|
61
69
|
// Add a catch-all command for unknown commands
|
|
62
70
|
program.on('command:*', function () {
|
package/dist/utils.js
CHANGED
|
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g =
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
14
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
15
|
function step(op) {
|
|
16
16
|
if (f) throw new TypeError("Generator is already executing.");
|
|
@@ -116,7 +116,7 @@ function setupProxy(port, apiKey, config) {
|
|
|
116
116
|
return [4 /*yield*/, client.start(parseInt(port))];
|
|
117
117
|
case 2:
|
|
118
118
|
tunnelUrl = _a.sent();
|
|
119
|
-
spinner.succeed(chalk_1.default.green("
|
|
119
|
+
spinner.succeed(chalk_1.default.green("\n------------------------------------------------------------\nYour service is available publicly at: ") + chalk_1.default.cyan.underline("".concat(tunnelUrl)) + chalk_1.default.green("\n------------------------------------------------------------\n"));
|
|
120
120
|
return [2 /*return*/, client];
|
|
121
121
|
case 3:
|
|
122
122
|
error_1 = _a.sent();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dainprotocol/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.19",
|
|
4
4
|
"description": "CLI for Dain Protocol",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -15,9 +15,12 @@
|
|
|
15
15
|
"templates"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
+
"@ai-sdk/anthropic": "^0.0.50",
|
|
19
|
+
"@dainprotocol/service-sdk": "^1.0.14",
|
|
18
20
|
"@dainprotocol/tunnel": "^1.0.2",
|
|
19
21
|
"@types/fs-extra": "^11.0.4",
|
|
20
22
|
"@types/localtunnel": "^2.0.4",
|
|
23
|
+
"ai": "^3.3.41",
|
|
21
24
|
"chalk": "^4.1.2",
|
|
22
25
|
"chokidar": "^3.6.0",
|
|
23
26
|
"commander": "^11.1.0",
|