icopilot 2.2.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/CHANGELOG.md +250 -0
- package/LICENSE +21 -0
- package/README.md +214 -0
- package/bin/icopilot.js +6 -0
- package/dist/acp/router.js +123 -0
- package/dist/acp/schema.js +53 -0
- package/dist/agents/aggregator.js +187 -0
- package/dist/agents/custom-agents.js +97 -0
- package/dist/agents/goal-driven.js +411 -0
- package/dist/agents/multi-repo.js +350 -0
- package/dist/agents/parallel-runner.js +181 -0
- package/dist/agents/router.js +144 -0
- package/dist/agents/self-heal.js +481 -0
- package/dist/agents/tdd-agent.js +278 -0
- package/dist/api/github-models.js +158 -0
- package/dist/bridge/ide-bridge.js +479 -0
- package/dist/cloud/routine-executor.js +34 -0
- package/dist/cloud/routine-scheduler.js +67 -0
- package/dist/cloud/routine-storage.js +297 -0
- package/dist/commands/acp-cmd.js +143 -0
- package/dist/commands/actions-cmd.js +624 -0
- package/dist/commands/agent-cmd.js +144 -0
- package/dist/commands/alias-cmd.js +132 -0
- package/dist/commands/bookmark-cmd.js +77 -0
- package/dist/commands/changelog-cmd.js +99 -0
- package/dist/commands/changes-cmd.js +120 -0
- package/dist/commands/clipboard-cmd.js +217 -0
- package/dist/commands/cloud-routine-cmd.js +265 -0
- package/dist/commands/codegen-cmd.js +544 -0
- package/dist/commands/compare-cmd.js +116 -0
- package/dist/commands/context-cmd.js +247 -0
- package/dist/commands/context-viz-cmd.js +43 -0
- package/dist/commands/conventions-cmd.js +116 -0
- package/dist/commands/cost-cmd.js +51 -0
- package/dist/commands/deps-cmd.js +294 -0
- package/dist/commands/diagram-cmd.js +658 -0
- package/dist/commands/diff-review-cmd.js +92 -0
- package/dist/commands/doc-cmd.js +412 -0
- package/dist/commands/doctor-cmd.js +152 -0
- package/dist/commands/editor-cmd.js +49 -0
- package/dist/commands/env-cmd.js +86 -0
- package/dist/commands/explain-cmd.js +78 -0
- package/dist/commands/explain-shell-cmd.js +22 -0
- package/dist/commands/explore-cmd.js +231 -0
- package/dist/commands/feedback-cmd.js +98 -0
- package/dist/commands/fix-cmd.js +17 -0
- package/dist/commands/generate-cmd.js +38 -0
- package/dist/commands/git-extra.js +197 -0
- package/dist/commands/git-log-cmd.js +98 -0
- package/dist/commands/git-undo-cmd.js +137 -0
- package/dist/commands/git.js +155 -0
- package/dist/commands/history-cmd.js +122 -0
- package/dist/commands/index-cmd.js +65 -0
- package/dist/commands/init-cmd.js +73 -0
- package/dist/commands/lint-cmd.js +133 -0
- package/dist/commands/memory-cmd.js +98 -0
- package/dist/commands/metrics-cmd.js +97 -0
- package/dist/commands/mode-prefix.js +30 -0
- package/dist/commands/multi-cmd.js +44 -0
- package/dist/commands/notify-cmd.js +204 -0
- package/dist/commands/profile-cmd.js +101 -0
- package/dist/commands/prompts.js +17 -0
- package/dist/commands/rag-cmd.js +60 -0
- package/dist/commands/readme-cmd.js +564 -0
- package/dist/commands/reasoning-cmd.js +34 -0
- package/dist/commands/refactor-cmd.js +96 -0
- package/dist/commands/release-cmd.js +450 -0
- package/dist/commands/repo-cmd.js +195 -0
- package/dist/commands/route-cmd.js +21 -0
- package/dist/commands/schedule-cmd.js +109 -0
- package/dist/commands/search-cmd.js +47 -0
- package/dist/commands/security-cmd.js +156 -0
- package/dist/commands/settings-cmd.js +238 -0
- package/dist/commands/skill-cmd.js +338 -0
- package/dist/commands/slash.js +2721 -0
- package/dist/commands/snippets-cmd.js +83 -0
- package/dist/commands/space-cmd.js +92 -0
- package/dist/commands/stash-cmd.js +156 -0
- package/dist/commands/stats-cmd.js +36 -0
- package/dist/commands/style-cmd.js +85 -0
- package/dist/commands/suggest-cmd.js +40 -0
- package/dist/commands/summary-cmd.js +138 -0
- package/dist/commands/task-cmd.js +58 -0
- package/dist/commands/team-memory-cmd.js +97 -0
- package/dist/commands/template-cmd.js +475 -0
- package/dist/commands/test-cmd.js +146 -0
- package/dist/commands/todo-cmd.js +172 -0
- package/dist/commands/tokens-cmd.js +277 -0
- package/dist/commands/trigger-cmd.js +147 -0
- package/dist/commands/undo-cmd.js +18 -0
- package/dist/commands/voice-cmd.js +89 -0
- package/dist/commands/watch-cmd.js +110 -0
- package/dist/commands/web-cmd.js +183 -0
- package/dist/commands/worktree-cmd.js +119 -0
- package/dist/config-profile.js +66 -0
- package/dist/config.js +288 -0
- package/dist/context/compactor.js +53 -0
- package/dist/context/dep-context.js +329 -0
- package/dist/context/file-refs.js +54 -0
- package/dist/context/git-context.js +229 -0
- package/dist/context/image-input.js +66 -0
- package/dist/context/memory.js +55 -0
- package/dist/context/persistent-memory.js +104 -0
- package/dist/context/pinned.js +96 -0
- package/dist/context/priority.js +150 -0
- package/dist/context/read-only.js +48 -0
- package/dist/context/smart-files.js +286 -0
- package/dist/context/team-memory.js +156 -0
- package/dist/extensions/loader.js +149 -0
- package/dist/extensions/marketplace.js +49 -0
- package/dist/extensions/slack-provider.js +181 -0
- package/dist/extensions/team.js +56 -0
- package/dist/extensions/teams-provider.js +222 -0
- package/dist/extensions/voice.js +18 -0
- package/dist/hooks/lifecycle.js +215 -0
- package/dist/hooks/precommit.js +463 -0
- package/dist/index/embeddings.js +23 -0
- package/dist/index/indexer.js +86 -0
- package/dist/index/retrieve.js +20 -0
- package/dist/index/store.js +95 -0
- package/dist/index.js +286 -0
- package/dist/intelligence/dead-code.js +457 -0
- package/dist/intelligence/error-watch.js +263 -0
- package/dist/intelligence/navigation.js +141 -0
- package/dist/intelligence/stack-trace.js +210 -0
- package/dist/intelligence/symbol-index.js +410 -0
- package/dist/knowledge/auto-memory.js +412 -0
- package/dist/knowledge/conventions.js +475 -0
- package/dist/knowledge/corrections.js +213 -0
- package/dist/knowledge/rag.js +450 -0
- package/dist/knowledge/style-learner.js +324 -0
- package/dist/logger.js +35 -0
- package/dist/mcp/client.js +144 -0
- package/dist/mcp/config.js +24 -0
- package/dist/mcp/index.js +89 -0
- package/dist/modes/auto-compact.js +20 -0
- package/dist/modes/autopilot.js +157 -0
- package/dist/modes/background.js +82 -0
- package/dist/modes/interactive.js +187 -0
- package/dist/modes/oneshot.js +36 -0
- package/dist/modes/tui.js +265 -0
- package/dist/modes/turn.js +342 -0
- package/dist/notifications/manager.js +107 -0
- package/dist/plugins/marketplace.js +244 -0
- package/dist/providers/custom-provider.js +298 -0
- package/dist/providers/local-model.js +121 -0
- package/dist/routing/profiles.js +44 -0
- package/dist/routing/router.js +18 -0
- package/dist/sandbox/container.js +151 -0
- package/dist/security/audit.js +237 -0
- package/dist/security/content-filter.js +449 -0
- package/dist/security/proxy.js +301 -0
- package/dist/security/retention.js +281 -0
- package/dist/security/roles.js +252 -0
- package/dist/server/api-server.js +679 -0
- package/dist/session/bookmarks.js +72 -0
- package/dist/session/cloud-session.js +291 -0
- package/dist/session/handoff.js +405 -0
- package/dist/session/manager.js +35 -0
- package/dist/session/session.js +296 -0
- package/dist/session/share.js +313 -0
- package/dist/session/undo-journal.js +91 -0
- package/dist/snippets/store.js +60 -0
- package/dist/spaces/space-config.js +156 -0
- package/dist/spaces/space.js +220 -0
- package/dist/stats/store.js +101 -0
- package/dist/tools/apply-patch.js +134 -0
- package/dist/tools/auto-check.js +218 -0
- package/dist/tools/diff-edit.js +150 -0
- package/dist/tools/diff-prompt.js +36 -0
- package/dist/tools/edit-file.js +66 -0
- package/dist/tools/file-ops.js +205 -0
- package/dist/tools/glob.js +17 -0
- package/dist/tools/grep.js +56 -0
- package/dist/tools/image.js +194 -0
- package/dist/tools/list-directory.js +228 -0
- package/dist/tools/memory.js +17 -0
- package/dist/tools/multi-edit.js +299 -0
- package/dist/tools/policy.js +95 -0
- package/dist/tools/registry.js +484 -0
- package/dist/tools/retry.js +74 -0
- package/dist/tools/run-in-terminal.js +162 -0
- package/dist/tools/safety.js +64 -0
- package/dist/tools/sandbox.js +15 -0
- package/dist/tools/search-symbols.js +212 -0
- package/dist/tools/shell.js +118 -0
- package/dist/tools/web.js +167 -0
- package/dist/ui/prompt.js +37 -0
- package/dist/ui/render.js +96 -0
- package/dist/ui/screen.js +13 -0
- package/dist/ui/theme.js +56 -0
- package/dist/util/browser.js +34 -0
- package/dist/util/completion.js +350 -0
- package/dist/util/cost.js +28 -0
- package/dist/util/keybindings.js +113 -0
- package/dist/util/lazy.js +26 -0
- package/dist/util/perf.js +25 -0
- package/dist/util/token-worker.js +11 -0
- package/dist/util/tokens.js +50 -0
- package/dist/workflows/builtins.js +128 -0
- package/dist/workflows/engine.js +496 -0
- package/dist/workflows/file-trigger.js +197 -0
- package/package.json +79 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { theme } from '../ui/theme.js';
|
|
4
|
+
const PACKAGE_MANAGERS = [
|
|
5
|
+
{ file: 'package-lock.json', name: 'npm' },
|
|
6
|
+
{ file: 'yarn.lock', name: 'yarn' },
|
|
7
|
+
{ file: 'pnpm-lock.yaml', name: 'pnpm' },
|
|
8
|
+
{ file: 'Cargo.lock', name: 'cargo' },
|
|
9
|
+
{ file: 'go.sum', name: 'go' },
|
|
10
|
+
{ file: 'requirements.txt', name: 'pip' },
|
|
11
|
+
{ file: 'Pipfile.lock', name: 'pip' },
|
|
12
|
+
{ file: 'Gemfile.lock', name: 'bundler' },
|
|
13
|
+
];
|
|
14
|
+
function readText(filePath) {
|
|
15
|
+
try {
|
|
16
|
+
return fs.readFileSync(filePath, 'utf8');
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function readJson(filePath) {
|
|
23
|
+
const text = readText(filePath);
|
|
24
|
+
if (!text)
|
|
25
|
+
return undefined;
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(text);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function uniqueDependencies(dependencies) {
|
|
34
|
+
const seen = new Set();
|
|
35
|
+
const unique = [];
|
|
36
|
+
for (const dependency of dependencies) {
|
|
37
|
+
const key = `${dependency.type}:${dependency.name}`;
|
|
38
|
+
if (seen.has(key))
|
|
39
|
+
continue;
|
|
40
|
+
seen.add(key);
|
|
41
|
+
unique.push(dependency);
|
|
42
|
+
}
|
|
43
|
+
return unique.sort((left, right) => left.name.localeCompare(right.name));
|
|
44
|
+
}
|
|
45
|
+
function parsePackageJsonDependencies(cwd) {
|
|
46
|
+
const pkg = readJson(path.join(cwd, 'package.json'));
|
|
47
|
+
if (!pkg)
|
|
48
|
+
return [];
|
|
49
|
+
const prod = Object.entries(pkg.dependencies ?? {}).map(([name, current]) => ({
|
|
50
|
+
name,
|
|
51
|
+
current,
|
|
52
|
+
type: 'prod',
|
|
53
|
+
}));
|
|
54
|
+
const dev = Object.entries(pkg.devDependencies ?? {}).map(([name, current]) => ({
|
|
55
|
+
name,
|
|
56
|
+
current,
|
|
57
|
+
type: 'dev',
|
|
58
|
+
}));
|
|
59
|
+
return uniqueDependencies([...prod, ...dev]);
|
|
60
|
+
}
|
|
61
|
+
function extractRequirement(line) {
|
|
62
|
+
const trimmed = line.split('#')[0]?.trim();
|
|
63
|
+
if (!trimmed || trimmed.startsWith('-'))
|
|
64
|
+
return null;
|
|
65
|
+
const match = /^([A-Za-z0-9._-]+)(?:\[[^\]]+\])?\s*([<>=!~].+)?$/u.exec(trimmed);
|
|
66
|
+
if (!match)
|
|
67
|
+
return null;
|
|
68
|
+
const [, name, specifier] = match;
|
|
69
|
+
return {
|
|
70
|
+
name,
|
|
71
|
+
current: specifier?.trim() || 'unspecified',
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function parseRequirementsDependencies(cwd) {
|
|
75
|
+
const requirements = readText(path.join(cwd, 'requirements.txt'));
|
|
76
|
+
if (requirements) {
|
|
77
|
+
return uniqueDependencies(requirements
|
|
78
|
+
.split(/\r?\n/u)
|
|
79
|
+
.map((line) => extractRequirement(line))
|
|
80
|
+
.filter((dependency) => Boolean(dependency))
|
|
81
|
+
.map((dependency) => ({ ...dependency, type: 'prod' })));
|
|
82
|
+
}
|
|
83
|
+
const pipfile = readJson(path.join(cwd, 'Pipfile.lock'));
|
|
84
|
+
if (!pipfile)
|
|
85
|
+
return [];
|
|
86
|
+
const prod = Object.entries(pipfile.default ?? {}).map(([name, metadata]) => ({
|
|
87
|
+
name,
|
|
88
|
+
current: metadata.version ?? 'unspecified',
|
|
89
|
+
type: 'prod',
|
|
90
|
+
}));
|
|
91
|
+
const dev = Object.entries(pipfile.develop ?? {}).map(([name, metadata]) => ({
|
|
92
|
+
name,
|
|
93
|
+
current: metadata.version ?? 'unspecified',
|
|
94
|
+
type: 'dev',
|
|
95
|
+
}));
|
|
96
|
+
return uniqueDependencies([...prod, ...dev]);
|
|
97
|
+
}
|
|
98
|
+
function extractCargoVersion(value) {
|
|
99
|
+
const quoted = /"([^"]+)"/u.exec(value);
|
|
100
|
+
if (quoted?.[1])
|
|
101
|
+
return quoted[1];
|
|
102
|
+
const versionField = /version\s*=\s*"([^"]+)"/u.exec(value);
|
|
103
|
+
if (versionField?.[1])
|
|
104
|
+
return versionField[1];
|
|
105
|
+
return value.trim() || 'unspecified';
|
|
106
|
+
}
|
|
107
|
+
function parseCargoDependencies(cwd) {
|
|
108
|
+
const cargoToml = readText(path.join(cwd, 'Cargo.toml'));
|
|
109
|
+
if (!cargoToml)
|
|
110
|
+
return [];
|
|
111
|
+
const dependencies = [];
|
|
112
|
+
let currentType = null;
|
|
113
|
+
for (const rawLine of cargoToml.split(/\r?\n/u)) {
|
|
114
|
+
const line = rawLine.trim();
|
|
115
|
+
if (!line || line.startsWith('#'))
|
|
116
|
+
continue;
|
|
117
|
+
if (line === '[dependencies]') {
|
|
118
|
+
currentType = 'prod';
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (line === '[dev-dependencies]') {
|
|
122
|
+
currentType = 'dev';
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (line.startsWith('[')) {
|
|
126
|
+
currentType = null;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (!currentType)
|
|
130
|
+
continue;
|
|
131
|
+
const eqIndex = line.indexOf('=');
|
|
132
|
+
if (eqIndex <= 0)
|
|
133
|
+
continue;
|
|
134
|
+
const name = line.slice(0, eqIndex).trim();
|
|
135
|
+
const current = extractCargoVersion(line.slice(eqIndex + 1));
|
|
136
|
+
dependencies.push({ name, current, type: currentType });
|
|
137
|
+
}
|
|
138
|
+
return uniqueDependencies(dependencies);
|
|
139
|
+
}
|
|
140
|
+
function parseGoDependencies(cwd) {
|
|
141
|
+
const goMod = readText(path.join(cwd, 'go.mod'));
|
|
142
|
+
const dependencies = [];
|
|
143
|
+
if (goMod) {
|
|
144
|
+
let inRequireBlock = false;
|
|
145
|
+
for (const rawLine of goMod.split(/\r?\n/u)) {
|
|
146
|
+
const line = rawLine.trim();
|
|
147
|
+
if (!line || line.startsWith('//'))
|
|
148
|
+
continue;
|
|
149
|
+
if (line === 'require (') {
|
|
150
|
+
inRequireBlock = true;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (inRequireBlock && line === ')') {
|
|
154
|
+
inRequireBlock = false;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (line.startsWith('require ')) {
|
|
158
|
+
const parts = line.replace(/^require\s+/u, '').split(/\s+/u);
|
|
159
|
+
if (parts.length >= 2) {
|
|
160
|
+
dependencies.push({ name: parts[0], current: parts[1], type: 'prod' });
|
|
161
|
+
}
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (!inRequireBlock)
|
|
165
|
+
continue;
|
|
166
|
+
const parts = line.split(/\s+/u);
|
|
167
|
+
if (parts.length >= 2) {
|
|
168
|
+
dependencies.push({ name: parts[0], current: parts[1], type: 'prod' });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (dependencies.length > 0)
|
|
173
|
+
return uniqueDependencies(dependencies);
|
|
174
|
+
const goSum = readText(path.join(cwd, 'go.sum'));
|
|
175
|
+
if (!goSum)
|
|
176
|
+
return [];
|
|
177
|
+
for (const rawLine of goSum.split(/\r?\n/u)) {
|
|
178
|
+
const line = rawLine.trim();
|
|
179
|
+
if (!line)
|
|
180
|
+
continue;
|
|
181
|
+
const parts = line.split(/\s+/u);
|
|
182
|
+
if (parts.length < 2 || parts[0]?.endsWith('/go.mod'))
|
|
183
|
+
continue;
|
|
184
|
+
dependencies.push({ name: parts[0], current: parts[1], type: 'prod' });
|
|
185
|
+
}
|
|
186
|
+
return uniqueDependencies(dependencies);
|
|
187
|
+
}
|
|
188
|
+
function parseBundlerDependencies(cwd) {
|
|
189
|
+
const gemfileLock = readText(path.join(cwd, 'Gemfile.lock'));
|
|
190
|
+
if (!gemfileLock)
|
|
191
|
+
return [];
|
|
192
|
+
const dependencies = [];
|
|
193
|
+
let inDependenciesSection = false;
|
|
194
|
+
for (const rawLine of gemfileLock.split(/\r?\n/u)) {
|
|
195
|
+
const line = rawLine.replace(/\t/gu, ' ');
|
|
196
|
+
const trimmed = line.trim();
|
|
197
|
+
if (trimmed === 'DEPENDENCIES') {
|
|
198
|
+
inDependenciesSection = true;
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (!inDependenciesSection)
|
|
202
|
+
continue;
|
|
203
|
+
if (!trimmed)
|
|
204
|
+
break;
|
|
205
|
+
if (/^[A-Z][A-Z\s]+$/u.test(trimmed))
|
|
206
|
+
break;
|
|
207
|
+
const match = /^\s{2,}([A-Za-z0-9_.-]+)(?:\s+\(([^)]+)\))?$/u.exec(line);
|
|
208
|
+
if (!match)
|
|
209
|
+
continue;
|
|
210
|
+
dependencies.push({
|
|
211
|
+
name: match[1],
|
|
212
|
+
current: match[2]?.trim() || 'unspecified',
|
|
213
|
+
type: 'prod',
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return uniqueDependencies(dependencies);
|
|
217
|
+
}
|
|
218
|
+
function readDependencies(cwd, packageManager) {
|
|
219
|
+
switch (packageManager) {
|
|
220
|
+
case 'npm':
|
|
221
|
+
case 'yarn':
|
|
222
|
+
case 'pnpm':
|
|
223
|
+
return parsePackageJsonDependencies(cwd);
|
|
224
|
+
case 'pip':
|
|
225
|
+
return parseRequirementsDependencies(cwd);
|
|
226
|
+
case 'cargo':
|
|
227
|
+
return parseCargoDependencies(cwd);
|
|
228
|
+
case 'go':
|
|
229
|
+
return parseGoDependencies(cwd);
|
|
230
|
+
case 'bundler':
|
|
231
|
+
return parseBundlerDependencies(cwd);
|
|
232
|
+
default:
|
|
233
|
+
return [];
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function buildPrompt(packageManager, dependencies) {
|
|
237
|
+
const dependencyLines = dependencies.map((dependency) => `- [${dependency.type}] ${dependency.name}: ${dependency.current}`);
|
|
238
|
+
return [
|
|
239
|
+
`Analyze this ${packageManager} dependency list for the current project.`,
|
|
240
|
+
'Focus on:',
|
|
241
|
+
'1. Outdated packages or risky version pins',
|
|
242
|
+
'2. Known security vulnerabilities to investigate',
|
|
243
|
+
'3. Unnecessary or duplicate dependencies',
|
|
244
|
+
'4. Dependency optimization and maintenance suggestions',
|
|
245
|
+
'',
|
|
246
|
+
'Dependencies:',
|
|
247
|
+
...dependencyLines,
|
|
248
|
+
].join('\n');
|
|
249
|
+
}
|
|
250
|
+
export function detectPackageManager(cwd) {
|
|
251
|
+
for (const entry of PACKAGE_MANAGERS) {
|
|
252
|
+
if (fs.existsSync(path.join(cwd, entry.file))) {
|
|
253
|
+
return entry.name;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
export function buildDepsPayload(cwd) {
|
|
259
|
+
const packageManager = detectPackageManager(cwd);
|
|
260
|
+
if (!packageManager) {
|
|
261
|
+
return { error: 'No supported package manager detected in the current directory.' };
|
|
262
|
+
}
|
|
263
|
+
const dependencies = readDependencies(cwd, packageManager);
|
|
264
|
+
return {
|
|
265
|
+
packageManager,
|
|
266
|
+
dependencies,
|
|
267
|
+
prompt: buildPrompt(packageManager, dependencies),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
export function depsCommand(cwd) {
|
|
271
|
+
const payload = buildDepsPayload(cwd);
|
|
272
|
+
if ('error' in payload) {
|
|
273
|
+
return `${theme.warn(payload.error)}\n${theme.dim('Supported manifests: package-lock.json, yarn.lock, pnpm-lock.yaml, Cargo.lock, go.sum, requirements.txt, Pipfile.lock, Gemfile.lock.')}\n`;
|
|
274
|
+
}
|
|
275
|
+
const prodCount = payload.dependencies.filter((dependency) => dependency.type === 'prod').length;
|
|
276
|
+
const devCount = payload.dependencies.length - prodCount;
|
|
277
|
+
const preview = payload.dependencies
|
|
278
|
+
.slice(0, 8)
|
|
279
|
+
.map((dependency) => ` ${dependency.type === 'prod' ? theme.ok('prod') : theme.hl('dev ')} ${dependency.name} ${theme.dim(`(${dependency.current})`)}`);
|
|
280
|
+
const remainder = payload.dependencies.length > preview.length
|
|
281
|
+
? [` ${theme.dim(`…and ${payload.dependencies.length - preview.length} more`)}`]
|
|
282
|
+
: [];
|
|
283
|
+
return [
|
|
284
|
+
theme.brand('Dependency overview'),
|
|
285
|
+
` package manager: ${theme.hl(payload.packageManager)}`,
|
|
286
|
+
` total dependencies: ${theme.hl(String(payload.dependencies.length))}`,
|
|
287
|
+
` prod: ${theme.ok(String(prodCount))} dev: ${theme.hl(String(devCount))}`,
|
|
288
|
+
` summary: ${theme.dim('Prompt ready for outdated package review, vulnerability checks, dependency cleanup, and optimization suggestions.')}`,
|
|
289
|
+
...(preview.length > 0
|
|
290
|
+
? ['', ...preview, ...remainder]
|
|
291
|
+
: ['', ` ${theme.dim('No dependencies parsed from the manifest.')}`]),
|
|
292
|
+
'',
|
|
293
|
+
].join('\n');
|
|
294
|
+
}
|