crewx 0.8.7-rc.21 → 0.8.7-rc.22
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/assets/{MarketPage-aY16UW1_.js → MarketPage-lLBtAENs.js} +10 -15
- package/dist/assets/{PromptTab-C3aTJS6u.js → PromptTab-Daq54dMi.js} +1 -1
- package/dist/assets/_baseUniq-BJDqmZBO.js +1 -0
- package/dist/assets/{arc-BCQAokB1.js → arc-ByjRIa5p.js} +1 -1
- package/dist/assets/{architectureDiagram-UYN6MBPD-Bc87ujv2.js → architectureDiagram-UYN6MBPD-DcKpqSFb.js} +1 -1
- package/dist/assets/{blockDiagram-ZHA2E4KO-wC9uH8Lb.js → blockDiagram-ZHA2E4KO-YvUeULT5.js} +1 -1
- package/dist/assets/{c4Diagram-6F5ED5ID-CqB7lqni.js → c4Diagram-6F5ED5ID-vggzH2N5.js} +1 -1
- package/dist/assets/channel-1Y6YooBb.js +1 -0
- package/dist/assets/{chunk-5HRBRIJM-Cc1L17Eh.js → chunk-5HRBRIJM-BbaQwJkn.js} +1 -1
- package/dist/assets/{chunk-7U56Z5CX-Df3nu_7G.js → chunk-7U56Z5CX-DVYVpFaa.js} +1 -1
- package/dist/assets/{chunk-ASOPGD6M-DIXslLG-.js → chunk-ASOPGD6M-CXEvWb-8.js} +1 -1
- package/dist/assets/{chunk-KFBOBJHC-FytVljyP.js → chunk-KFBOBJHC-CadVXFV3.js} +1 -1
- package/dist/assets/{chunk-T2TOU4HS-CU5z-cXq.js → chunk-T2TOU4HS-lDZr1sVF.js} +1 -1
- package/dist/assets/{chunk-TMUBEWPD-CWo1AFyn.js → chunk-TMUBEWPD-D5A0MrFD.js} +1 -1
- package/dist/assets/classDiagram-LNE6IOMH-CDxkV2JV.js +1 -0
- package/dist/assets/classDiagram-v2-MQ7JQ4JX-CDxkV2JV.js +1 -0
- package/dist/assets/clone-6xznz_9G.js +1 -0
- package/dist/assets/{dagre-4EVJKHTY-CgZW5tg4.js → dagre-4EVJKHTY-Bncx7Ijq.js} +1 -1
- package/dist/assets/{diagram-QW4FP2JN-CJAng8RC.js → diagram-QW4FP2JN-RkxVNs99.js} +1 -1
- package/dist/assets/{erDiagram-6RL3IURR-C1uHztHX.js → erDiagram-6RL3IURR-DIiKqQdx.js} +1 -1
- package/dist/assets/{flowDiagram-7ASYPVHJ-Yiu2odO-.js → flowDiagram-7ASYPVHJ-DQ5PN7v6.js} +1 -1
- package/dist/assets/{ganttDiagram-NTVNEXSI-tutc0dJP.js → ganttDiagram-NTVNEXSI-BeNWGpB6.js} +1 -1
- package/dist/assets/{gitGraph-YCYPL57B-C3jM6T4G.js → gitGraph-YCYPL57B-CdMe059q.js} +1 -1
- package/dist/assets/{gitGraphDiagram-NRZ2UAAF-0aqHEKzz.js → gitGraphDiagram-NRZ2UAAF-BEke5TyK.js} +1 -1
- package/dist/assets/{graph-DC224ILV.js → graph-DyQIwWJd.js} +1 -1
- package/dist/assets/{infoDiagram-A4XQUW5V-Do7Mpzkx.js → infoDiagram-A4XQUW5V-CUcC8I_5.js} +1 -1
- package/dist/assets/{journeyDiagram-G5WM74LC-DAruEJc7.js → journeyDiagram-G5WM74LC-CQ5DqAH5.js} +1 -1
- package/dist/assets/{kanban-definition-QRCXZQQD-DB63vLR0.js → kanban-definition-QRCXZQQD-BBsgOii7.js} +1 -1
- package/dist/assets/{layout-BiYH5x6Q.js → layout-D7vBs_Wy.js} +1 -1
- package/dist/assets/{linear-CLyGW2s0.js → linear-CEOF9oJz.js} +1 -1
- package/dist/assets/{main-CEKkUqZb.js → main-Bx1nZ7_p.js} +278 -273
- package/dist/assets/main-C4ebvOIJ.css +10 -0
- package/dist/assets/{min-ChJMFU2N.js → min-RK9J5Utn.js} +1 -1
- package/dist/assets/{mindmap-definition-GWI6TPTV-CtADqQgd.js → mindmap-definition-GWI6TPTV-BXvEU7qC.js} +1 -1
- package/dist/assets/{pieDiagram-YF2LJOPJ-BSOfzo3O.js → pieDiagram-YF2LJOPJ-TrXqcpni.js} +1 -1
- package/dist/assets/{quadrantDiagram-OS5C2QUG-BLBQNFVb.js → quadrantDiagram-OS5C2QUG-B-chTEU4.js} +1 -1
- package/dist/assets/{requirementDiagram-MIRIMTAZ-DqorvuS6.js → requirementDiagram-MIRIMTAZ-BgJhNLp_.js} +1 -1
- package/dist/assets/{sankeyDiagram-Y46BX6SQ-4NDcrLkB.js → sankeyDiagram-Y46BX6SQ-BVsgYKK7.js} +1 -1
- package/dist/assets/{sequenceDiagram-G6AWOVSC-yha6BxK2.js → sequenceDiagram-G6AWOVSC-ByJOpkq3.js} +1 -1
- package/dist/assets/{stateDiagram-MAYHULR4-XJ_I41ez.js → stateDiagram-MAYHULR4-Dw7lUL1B.js} +1 -1
- package/dist/assets/stateDiagram-v2-4JROLMXI-DYJiM3bF.js +1 -0
- package/dist/assets/{timeline-definition-U7ZMHBDA-DCNrmvE7.js → timeline-definition-U7ZMHBDA-CSoEYs60.js} +1 -1
- package/dist/assets/{xychartDiagram-6QU3TZC5-9N-Ohhdp.js → xychartDiagram-6QU3TZC5-0_rG7p3L.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +8 -8
- package/packages/cli/package.json +1 -1
- package/dist/assets/_baseUniq-DxEFlwNt.js +0 -1
- package/dist/assets/channel-DNLHkiNp.js +0 -1
- package/dist/assets/classDiagram-LNE6IOMH-B430Onym.js +0 -1
- package/dist/assets/classDiagram-v2-MQ7JQ4JX-B430Onym.js +0 -1
- package/dist/assets/clone-B9O3E3P1.js +0 -1
- package/dist/assets/main-D3YeRndF.css +0 -10
- package/dist/assets/stateDiagram-v2-4JROLMXI-CxcyPJO2.js +0 -1
- package/dist-server/adapters/adapter.module.js +0 -35
- package/dist-server/adapters/adapter.service.js +0 -79
- package/dist-server/adapters/http-router.service.js +0 -91
- package/dist-server/app.module.js +0 -111
- package/dist-server/bootstrap/crewx-server.js +0 -80
- package/dist-server/bootstrap/tls.js +0 -138
- package/dist-server/common/analytics.client.js +0 -180
- package/dist-server/common/analytics.module.js +0 -21
- package/dist-server/common/cors.js +0 -15
- package/dist-server/common/decorators/project.decorator.js +0 -21
- package/dist-server/common/decorators/workspace.decorator.js +0 -24
- package/dist-server/common/device-id.js +0 -33
- package/dist-server/common/interceptor/api-id-header.interceptor.js +0 -53
- package/dist-server/common/interceptor/http-logging.interceptor.js +0 -124
- package/dist-server/common/limits/defaults.js +0 -13
- package/dist-server/common/limits/limits-provider.js +0 -6
- package/dist-server/common/limits/limits.controller.js +0 -38
- package/dist-server/common/limits/limits.module.js +0 -24
- package/dist-server/common/limits/local-limits.provider.js +0 -27
- package/dist-server/common/middleware/workspace.middleware.js +0 -210
- package/dist-server/common/repository.exception-filter.js +0 -48
- package/dist-server/common/workspace-context.store.js +0 -25
- package/dist-server/domain/agent/agent.controller.js +0 -96
- package/dist-server/domain/agent/agent.module.js +0 -27
- package/dist-server/domain/agent/agent.service.js +0 -335
- package/dist-server/domain/agent/agent.types.js +0 -3
- package/dist-server/domain/agent/dto/create-agent.dto.js +0 -80
- package/dist-server/domain/agent/dto/preview-prompt.dto.js +0 -77
- package/dist-server/domain/agent/dto/provider-meta.dto.js +0 -2
- package/dist-server/domain/agent/dto/update-agent.dto.js +0 -92
- package/dist-server/domain/agent/provider.controller.js +0 -38
- package/dist-server/domain/agent/template-processor.service.js +0 -71
- package/dist-server/domain/auth/auth.constants.js +0 -4
- package/dist-server/domain/auth/auth.controller.js +0 -123
- package/dist-server/domain/auth/auth.module.js +0 -47
- package/dist-server/domain/auth/decorators/public.decorator.js +0 -7
- package/dist-server/domain/auth/guards/base-auth.guard.js +0 -66
- package/dist-server/domain/auth/session-store.js +0 -26
- package/dist-server/domain/auth/utils/ip.utils.js +0 -31
- package/dist-server/domain/box/box.controller.js +0 -77
- package/dist-server/domain/box/box.module.js +0 -21
- package/dist-server/domain/box/box.service.js +0 -97
- package/dist-server/domain/box/dto/create-box.dto.js +0 -74
- package/dist-server/domain/cli/cli.controller.js +0 -136
- package/dist-server/domain/cli/cli.module.js +0 -21
- package/dist-server/domain/cli/cli.service.js +0 -598
- package/dist-server/domain/cli/dto/login-cli.dto.js +0 -25
- package/dist-server/domain/cli/dto/update-cli.dto.js +0 -31
- package/dist-server/domain/doc/doc.controller.js +0 -95
- package/dist-server/domain/doc/doc.module.js +0 -21
- package/dist-server/domain/doc/doc.service.js +0 -368
- package/dist-server/domain/doc/dto/doc.dto.js +0 -64
- package/dist-server/domain/document/document.controller.js +0 -57
- package/dist-server/domain/document/document.module.js +0 -22
- package/dist-server/domain/document/document.service.js +0 -274
- package/dist-server/domain/document/dto/register-document.dto.js +0 -24
- package/dist-server/domain/fs/dto/mkdir-request.dto.js +0 -47
- package/dist-server/domain/fs/dto/mkdir-response.dto.js +0 -2
- package/dist-server/domain/fs/dto/quick-access.dto.js +0 -2
- package/dist-server/domain/fs/dto/tree-node.dto.js +0 -2
- package/dist-server/domain/fs/dto/tree-query.dto.js +0 -35
- package/dist-server/domain/fs/fs.controller.js +0 -63
- package/dist-server/domain/fs/fs.module.js +0 -22
- package/dist-server/domain/fs/fs.service.js +0 -303
- package/dist-server/domain/git/git.module.js +0 -20
- package/dist-server/domain/git/git.service.js +0 -222
- package/dist-server/domain/goal/dto/goal.dto.js +0 -49
- package/dist-server/domain/goal/goal.controller.js +0 -86
- package/dist-server/domain/goal/goal.module.js +0 -22
- package/dist-server/domain/goal/goal.service.js +0 -197
- package/dist-server/domain/goal/parser/goal-md-parser.js +0 -166
- package/dist-server/domain/goal/parser/goal-md-serializer.js +0 -110
- package/dist-server/domain/health/health.controller.js +0 -57
- package/dist-server/domain/health/health.module.js +0 -19
- package/dist-server/domain/knowledge/dto/graph-knowledge.dto.js +0 -27
- package/dist-server/domain/knowledge/dto/knowledge.dto.js +0 -71
- package/dist-server/domain/knowledge/knowledge.controller.js +0 -122
- package/dist-server/domain/knowledge/knowledge.module.js +0 -21
- package/dist-server/domain/knowledge/knowledge.service.js +0 -538
- package/dist-server/domain/market/dto/add-registry.dto.js +0 -32
- package/dist-server/domain/market/dto/install-market.dto.js +0 -30
- package/dist-server/domain/market/market.controller.js +0 -163
- package/dist-server/domain/market/market.module.js +0 -22
- package/dist-server/domain/market/market.service.js +0 -1447
- package/dist-server/domain/mcp/browser-session.store.js +0 -247
- package/dist-server/domain/mcp/crewx-tool.factory.js +0 -119
- package/dist-server/domain/mcp/mcp-auth.guard.js +0 -61
- package/dist-server/domain/mcp/mcp.constants.js +0 -4
- package/dist-server/domain/mcp/mcp.controller.js +0 -125
- package/dist-server/domain/mcp/mcp.dto.js +0 -12
- package/dist-server/domain/mcp/mcp.module.js +0 -49
- package/dist-server/domain/mcp/mcp.service.js +0 -684
- package/dist-server/domain/mcp/tool-router.service.js +0 -120
- package/dist-server/domain/message/dto/list-messages.dto.js +0 -57
- package/dist-server/domain/message/dto/send-message.dto.js +0 -45
- package/dist-server/domain/message/message.controller.js +0 -73
- package/dist-server/domain/message/message.module.js +0 -25
- package/dist-server/domain/message/message.service.js +0 -160
- package/dist-server/domain/onboarding/onboarding.controller.js +0 -97
- package/dist-server/domain/onboarding/onboarding.module.js +0 -23
- package/dist-server/domain/onboarding/onboarding.service.js +0 -106
- package/dist-server/domain/onboarding/onboarding.types.js +0 -2
- package/dist-server/domain/onboarding/presets/custom.js +0 -10
- package/dist-server/domain/onboarding/presets/dev-team.js +0 -41
- package/dist-server/domain/onboarding/presets/index.js +0 -15
- package/dist-server/domain/onboarding/presets/marketing-team.js +0 -29
- package/dist-server/domain/onboarding/presets/planning-team.js +0 -29
- package/dist-server/domain/onboarding/presets/solo.js +0 -17
- package/dist-server/domain/planner/dto/planner.dto.js +0 -58
- package/dist-server/domain/planner/planner.controller.js +0 -74
- package/dist-server/domain/planner/planner.module.js +0 -22
- package/dist-server/domain/planner/planner.service.js +0 -269
- package/dist-server/domain/project/dto/create-project.dto.js +0 -46
- package/dist-server/domain/project/dto/update-project.dto.js +0 -60
- package/dist-server/domain/project/project.controller.js +0 -129
- package/dist-server/domain/project/project.module.js +0 -22
- package/dist-server/domain/project/project.service.js +0 -173
- package/dist-server/domain/settings/settings.controller.js +0 -52
- package/dist-server/domain/settings/settings.module.js +0 -22
- package/dist-server/domain/settings/settings.service.js +0 -105
- package/dist-server/domain/task/dto/all-tasks.dto.js +0 -55
- package/dist-server/domain/task/dto/list-tasks.dto.js +0 -69
- package/dist-server/domain/task/dto/search-tasks.dto.js +0 -66
- package/dist-server/domain/task/dto/send-message.dto.js +0 -31
- package/dist-server/domain/task/dto/task-status.dto.js +0 -34
- package/dist-server/domain/task/dto/workspace-usage.dto.js +0 -38
- package/dist-server/domain/task/task.constants.js +0 -5
- package/dist-server/domain/task/task.controller.js +0 -169
- package/dist-server/domain/task/task.module.js +0 -23
- package/dist-server/domain/task/task.service.js +0 -775
- package/dist-server/domain/thread/dto/build-context.dto.js +0 -42
- package/dist-server/domain/thread/dto/list-messages.dto.js +0 -49
- package/dist-server/domain/thread/dto/list-threads.dto.js +0 -70
- package/dist-server/domain/thread/dto/search-threads.dto.js +0 -13
- package/dist-server/domain/thread/dto/update-thread.dto.js +0 -23
- package/dist-server/domain/thread/thread.controller.js +0 -160
- package/dist-server/domain/thread/thread.module.js +0 -23
- package/dist-server/domain/thread/thread.service.js +0 -419
- package/dist-server/domain/usage/usage.controller.js +0 -118
- package/dist-server/domain/usage/usage.module.js +0 -21
- package/dist-server/domain/usage/usage.service.js +0 -358
- package/dist-server/domain/usage/usage.types.js +0 -4
- package/dist-server/domain/wbs/wbs.controller.js +0 -51
- package/dist-server/domain/wbs/wbs.module.js +0 -21
- package/dist-server/domain/wbs/wbs.service.js +0 -94
- package/dist-server/domain/workflow/workflow.controller.js +0 -53
- package/dist-server/domain/workflow/workflow.module.js +0 -21
- package/dist-server/domain/workflow/workflow.service.js +0 -209
- package/dist-server/domain/workspace/dto/create-workspace.dto.js +0 -45
- package/dist-server/domain/workspace/dto/switch-workspace.dto.js +0 -32
- package/dist-server/domain/workspace/dto/workspace-info.dto.js +0 -2
- package/dist-server/domain/workspace/workspace.controller.js +0 -98
- package/dist-server/domain/workspace/workspace.module.js +0 -22
- package/dist-server/domain/workspace/workspace.service.js +0 -198
- package/dist-server/main.js +0 -204
- package/dist-server/modules/crewx-pool.service.js +0 -75
- package/dist-server/modules/crewx.module.js +0 -47
- package/dist-server/repository/base-sqlite.repository.js +0 -18
- package/dist-server/repository/box.repository.js +0 -99
- package/dist-server/repository/message.repository.js +0 -22
- package/dist-server/repository/project.repository.js +0 -51
- package/dist-server/repository/repository.module.js +0 -34
- package/dist-server/repository/request-log.repository.js +0 -96
- package/dist-server/repository/task.repository.js +0 -105
- package/dist-server/repository/thread.repository.js +0 -165
- package/dist-server/shared/crewx-home.js +0 -58
- package/dist-server/shared/crewx-state.js +0 -66
- package/dist-server/test-utils/compat-database.js +0 -30
- package/dist-server/utils/tokenizer.js +0 -8
|
@@ -1,598 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.CliService = void 0;
|
|
10
|
-
exports.getShellEnv = getShellEnv;
|
|
11
|
-
exports.resetShellEnvCache = resetShellEnvCache;
|
|
12
|
-
exports.filterNodeModulesBin = filterNodeModulesBin;
|
|
13
|
-
exports.resolveCliPathGuard = resolveCliPathGuard;
|
|
14
|
-
exports.execCommand = execCommand;
|
|
15
|
-
exports.parseVersion = parseVersion;
|
|
16
|
-
exports.isOlderVersion = isOlderVersion;
|
|
17
|
-
exports.findLatestVersion = findLatestVersion;
|
|
18
|
-
const common_1 = require("@nestjs/common");
|
|
19
|
-
const child_process_1 = require("child_process");
|
|
20
|
-
const fs_1 = require("fs");
|
|
21
|
-
const os_1 = require("os");
|
|
22
|
-
const path_1 = require("path");
|
|
23
|
-
const util_1 = require("util");
|
|
24
|
-
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
25
|
-
const isWindows = process.platform === 'win32';
|
|
26
|
-
const logger = new common_1.Logger('CliService');
|
|
27
|
-
// Cache the shell env Promise (not the value) to prevent race conditions.
|
|
28
|
-
// Multiple concurrent callers will await the same promise instead of
|
|
29
|
-
// each spawning their own interactive shell.
|
|
30
|
-
let envPromise = null;
|
|
31
|
-
function parseEnvOutput(stdout) {
|
|
32
|
-
const env = {};
|
|
33
|
-
for (const line of stdout.split('\n')) {
|
|
34
|
-
const idx = line.indexOf('=');
|
|
35
|
-
if (idx > 0) {
|
|
36
|
-
env[line.slice(0, idx)] = line.slice(idx + 1);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return env;
|
|
40
|
-
}
|
|
41
|
-
async function tryShellEnv(shell, flags) {
|
|
42
|
-
try {
|
|
43
|
-
const { stdout } = await execAsync(`${shell} ${flags} 'env'`, { timeout: 10000 });
|
|
44
|
-
const env = parseEnvOutput(stdout);
|
|
45
|
-
if (env.PATH && env.PATH !== process.env.PATH) {
|
|
46
|
-
return env;
|
|
47
|
-
}
|
|
48
|
-
return env;
|
|
49
|
-
}
|
|
50
|
-
catch (err) {
|
|
51
|
-
logger.debug(`Shell env detection failed with "${shell} ${flags}": ${err instanceof Error ? err.message : err}`);
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
// Resolves the user's shell environment once; subsequent calls return the same promise.
|
|
56
|
-
function getShellEnv() {
|
|
57
|
-
if (envPromise)
|
|
58
|
-
return envPromise;
|
|
59
|
-
envPromise = (async () => {
|
|
60
|
-
if (isWindows) {
|
|
61
|
-
return process.env;
|
|
62
|
-
}
|
|
63
|
-
const shell = process.env.SHELL || '/bin/bash';
|
|
64
|
-
const strategies = [
|
|
65
|
-
{ flags: '-ic', desc: 'interactive' },
|
|
66
|
-
{ flags: '-lc', desc: 'login' },
|
|
67
|
-
];
|
|
68
|
-
for (const { flags, desc } of strategies) {
|
|
69
|
-
const env = await tryShellEnv(shell, flags);
|
|
70
|
-
if (env) {
|
|
71
|
-
const merged = { ...process.env, ...env };
|
|
72
|
-
logger.log(`Detected shell env via ${shell} ${flags} (${desc})`);
|
|
73
|
-
logger.log(`Detected shell env PATH: ${merged.PATH?.substring(0, 200)}...`);
|
|
74
|
-
return merged;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
logger.warn('Shell env detection failed for all strategies, using process.env');
|
|
78
|
-
return process.env;
|
|
79
|
-
})();
|
|
80
|
-
return envPromise;
|
|
81
|
-
}
|
|
82
|
-
// Reset the cached env promise (useful for testing)
|
|
83
|
-
function resetShellEnvCache() {
|
|
84
|
-
envPromise = null;
|
|
85
|
-
}
|
|
86
|
-
function getUserShell() {
|
|
87
|
-
return process.env.SHELL || '/bin/zsh';
|
|
88
|
-
}
|
|
89
|
-
// Removes cwd/node_modules/.bin from a PATH string to prevent local shims
|
|
90
|
-
// from shadowing globally-installed CLIs (Windows-primary issue; applied
|
|
91
|
-
// conservatively on both platforms).
|
|
92
|
-
function filterNodeModulesBin(pathStr, cwd) {
|
|
93
|
-
const localBin = (0, path_1.resolve)(cwd, 'node_modules', '.bin');
|
|
94
|
-
const separator = isWindows ? ';' : ':';
|
|
95
|
-
return pathStr
|
|
96
|
-
.split(separator)
|
|
97
|
-
.filter((p) => {
|
|
98
|
-
if (!p)
|
|
99
|
-
return true;
|
|
100
|
-
const normalized = (0, path_1.resolve)(p);
|
|
101
|
-
return isWindows
|
|
102
|
-
? normalized.toLowerCase() !== localBin.toLowerCase()
|
|
103
|
-
: normalized !== localBin;
|
|
104
|
-
})
|
|
105
|
-
.join(separator);
|
|
106
|
-
}
|
|
107
|
-
// Returns null when resolvedPath is under cwd/node_modules (local shim guard).
|
|
108
|
-
function resolveCliPathGuard(rawPath, cwd) {
|
|
109
|
-
if (!rawPath)
|
|
110
|
-
return null;
|
|
111
|
-
const nodeModulesDir = (0, path_1.resolve)(cwd, 'node_modules');
|
|
112
|
-
const normalized = (0, path_1.resolve)(rawPath);
|
|
113
|
-
const prefix = nodeModulesDir + path_1.sep;
|
|
114
|
-
if (isWindows) {
|
|
115
|
-
if (normalized.toLowerCase().startsWith(prefix.toLowerCase()) || normalized.toLowerCase() === nodeModulesDir.toLowerCase()) {
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
if (normalized.startsWith(prefix) || normalized === nodeModulesDir) {
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return rawPath;
|
|
125
|
-
}
|
|
126
|
-
// Execute a command inside the user's actual login shell so that
|
|
127
|
-
// PATH ordering (nvm, homebrew, etc.) matches what the user sees
|
|
128
|
-
// in their terminal.
|
|
129
|
-
async function execCommand(cmd, timeout = 10000) {
|
|
130
|
-
if (isWindows) {
|
|
131
|
-
// Strip cwd/node_modules/.bin from PATH so local shims (e.g. transitive
|
|
132
|
-
// @openai/codex installed via peerDeps) cannot shadow global CLIs.
|
|
133
|
-
const env = {};
|
|
134
|
-
for (const [k, v] of Object.entries(process.env)) {
|
|
135
|
-
if (v !== undefined)
|
|
136
|
-
env[k] = v;
|
|
137
|
-
}
|
|
138
|
-
if (env.PATH) {
|
|
139
|
-
env.PATH = filterNodeModulesBin(env.PATH, process.cwd());
|
|
140
|
-
}
|
|
141
|
-
return execAsync(cmd, { timeout, shell: process.env.ComSpec || 'cmd.exe', env });
|
|
142
|
-
}
|
|
143
|
-
const shell = getUserShell();
|
|
144
|
-
// Use -ilc (interactive + login) so zsh builds PATH from scratch
|
|
145
|
-
// via .zprofile + .zshrc, not inheriting VSCode's polluted env.
|
|
146
|
-
// Unix: minimal env with no PATH means the shell rebuilds it via -ilc;
|
|
147
|
-
// node_modules/.bin never appears in the reconstructed PATH.
|
|
148
|
-
const escapedCmd = cmd.replace(/'/g, "'\\''");
|
|
149
|
-
return execAsync(`${shell} -ilc '${escapedCmd}'`, {
|
|
150
|
-
timeout,
|
|
151
|
-
env: {
|
|
152
|
-
HOME: process.env.HOME || '',
|
|
153
|
-
USER: process.env.USER || '',
|
|
154
|
-
SHELL: process.env.SHELL || shell,
|
|
155
|
-
TERM: process.env.TERM || 'xterm-256color',
|
|
156
|
-
DISABLE_AUTO_UPDATE: 'true',
|
|
157
|
-
},
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
// Parse version string (supports semver with prerelease)
|
|
161
|
-
function parseVersion(versionOutput) {
|
|
162
|
-
if (!versionOutput)
|
|
163
|
-
return '';
|
|
164
|
-
const match = versionOutput.match(/v?(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/);
|
|
165
|
-
return match ? match[1] : versionOutput.split('\n')[0].slice(0, 30).trim();
|
|
166
|
-
}
|
|
167
|
-
// Compare semver: returns true if v1 < v2 (prerelease-aware)
|
|
168
|
-
function isOlderVersion(v1, v2) {
|
|
169
|
-
if (!v1 || !v2)
|
|
170
|
-
return false;
|
|
171
|
-
const parse = (v) => {
|
|
172
|
-
const [core, pre] = v.split('-');
|
|
173
|
-
const parts = core.split('.').map(Number);
|
|
174
|
-
return { parts, pre: pre || '' };
|
|
175
|
-
};
|
|
176
|
-
const a = parse(v1);
|
|
177
|
-
const b = parse(v2);
|
|
178
|
-
for (let i = 0; i < 3; i++) {
|
|
179
|
-
if ((a.parts[i] || 0) < (b.parts[i] || 0))
|
|
180
|
-
return true;
|
|
181
|
-
if ((a.parts[i] || 0) > (b.parts[i] || 0))
|
|
182
|
-
return false;
|
|
183
|
-
}
|
|
184
|
-
// Same core: prerelease < release (1.0.0-rc.1 < 1.0.0)
|
|
185
|
-
if (a.pre && !b.pre)
|
|
186
|
-
return true;
|
|
187
|
-
if (!a.pre && b.pre)
|
|
188
|
-
return false;
|
|
189
|
-
if (a.pre && b.pre)
|
|
190
|
-
return a.pre.localeCompare(b.pre, undefined, { numeric: true }) < 0;
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
// Pick the highest version from a list of semver strings
|
|
194
|
-
function findLatestVersion(versions) {
|
|
195
|
-
if (!versions.length)
|
|
196
|
-
return 'unknown';
|
|
197
|
-
let latest = versions[0];
|
|
198
|
-
for (let i = 1; i < versions.length; i++) {
|
|
199
|
-
if (isOlderVersion(latest, versions[i])) {
|
|
200
|
-
latest = versions[i];
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
return latest;
|
|
204
|
-
}
|
|
205
|
-
// CLI-specific login commands (SSOT)
|
|
206
|
-
// NOTE: commands must be non-interactive (no stdin prompts) — they run with stdio:'ignore'
|
|
207
|
-
const LOGIN_COMMANDS = {
|
|
208
|
-
claude: 'claude auth login',
|
|
209
|
-
gemini: 'gemini', // first launch triggers Google OAuth browser flow
|
|
210
|
-
codex: 'codex login',
|
|
211
|
-
copilot: 'gh auth login --web -h github.com -p https',
|
|
212
|
-
};
|
|
213
|
-
const CLI_LIST = [
|
|
214
|
-
{
|
|
215
|
-
name: 'claude',
|
|
216
|
-
displayName: 'Claude Code',
|
|
217
|
-
provider: 'Anthropic',
|
|
218
|
-
packageName: '@anthropic-ai/claude-code',
|
|
219
|
-
versionCommand: 'claude --version',
|
|
220
|
-
loginCommand: LOGIN_COMMANDS['claude'],
|
|
221
|
-
installStrategy: 'npm',
|
|
222
|
-
},
|
|
223
|
-
{
|
|
224
|
-
name: 'codex',
|
|
225
|
-
displayName: 'Codex CLI',
|
|
226
|
-
provider: 'OpenAI',
|
|
227
|
-
packageName: '@openai/codex',
|
|
228
|
-
versionCommand: 'codex --version',
|
|
229
|
-
loginCommand: LOGIN_COMMANDS['codex'],
|
|
230
|
-
installStrategy: 'npm',
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
name: 'gemini',
|
|
234
|
-
displayName: 'Gemini CLI',
|
|
235
|
-
provider: 'Google',
|
|
236
|
-
packageName: '@google/gemini-cli',
|
|
237
|
-
versionCommand: 'gemini --version',
|
|
238
|
-
loginCommand: LOGIN_COMMANDS['gemini'],
|
|
239
|
-
installStrategy: 'npm',
|
|
240
|
-
deprecated: 'Antigravity CLI로 전환하세요 (2026-06-18 종료)',
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
name: 'antigravity',
|
|
244
|
-
displayName: 'Antigravity',
|
|
245
|
-
provider: 'Google',
|
|
246
|
-
packageName: '',
|
|
247
|
-
versionCommand: 'agy --version',
|
|
248
|
-
loginCommand: null,
|
|
249
|
-
installStrategy: 'script',
|
|
250
|
-
installScript: 'curl -fsSL https://antigravity.google/cli/install.sh | bash',
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
name: 'copilot',
|
|
254
|
-
displayName: 'GitHub Copilot',
|
|
255
|
-
provider: 'GitHub',
|
|
256
|
-
packageName: '@github/copilot',
|
|
257
|
-
versionCommand: 'copilot --version',
|
|
258
|
-
loginCommand: LOGIN_COMMANDS['copilot'],
|
|
259
|
-
installStrategy: 'npm',
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
name: 'opencode',
|
|
263
|
-
displayName: 'OpenCode',
|
|
264
|
-
provider: 'OpenCode',
|
|
265
|
-
packageName: 'opencode-ai',
|
|
266
|
-
versionCommand: 'opencode --version',
|
|
267
|
-
loginCommand: null,
|
|
268
|
-
installStrategy: 'npm',
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
name: 'crewx',
|
|
272
|
-
displayName: 'CrewX',
|
|
273
|
-
provider: 'CrewX',
|
|
274
|
-
packageName: 'crewx',
|
|
275
|
-
versionCommand: 'crewx --version',
|
|
276
|
-
loginCommand: null,
|
|
277
|
-
installStrategy: 'npm',
|
|
278
|
-
},
|
|
279
|
-
];
|
|
280
|
-
let CliService = class CliService {
|
|
281
|
-
async getVersions() {
|
|
282
|
-
const results = [];
|
|
283
|
-
for (const cli of CLI_LIST) {
|
|
284
|
-
if (cli.installStrategy === 'script') {
|
|
285
|
-
const currentVersion = await this.getCurrentVersion(cli.versionCommand);
|
|
286
|
-
results.push({
|
|
287
|
-
name: cli.name,
|
|
288
|
-
displayName: cli.displayName,
|
|
289
|
-
provider: cli.provider,
|
|
290
|
-
installed: currentVersion !== null,
|
|
291
|
-
currentVersion,
|
|
292
|
-
latestVersion: null,
|
|
293
|
-
updateAvailable: false,
|
|
294
|
-
packageName: cli.packageName,
|
|
295
|
-
});
|
|
296
|
-
continue;
|
|
297
|
-
}
|
|
298
|
-
// Primary: global npm (immune to node_modules/.bin shim)
|
|
299
|
-
let currentVersion = await this.getNpmGlobalVersion(cli.packageName);
|
|
300
|
-
let installed = currentVersion !== null;
|
|
301
|
-
// Fallback: --version command (execCommand PATH guard prevents local shim)
|
|
302
|
-
if (!installed) {
|
|
303
|
-
currentVersion = await this.getCurrentVersion(cli.versionCommand);
|
|
304
|
-
installed = currentVersion !== null;
|
|
305
|
-
}
|
|
306
|
-
const latestVersion = await this.getLatestVersion(cli.packageName);
|
|
307
|
-
results.push({
|
|
308
|
-
name: cli.name,
|
|
309
|
-
displayName: cli.displayName,
|
|
310
|
-
provider: cli.provider,
|
|
311
|
-
installed,
|
|
312
|
-
currentVersion,
|
|
313
|
-
latestVersion,
|
|
314
|
-
updateAvailable: currentVersion !== null && latestVersion !== 'unknown' && isOlderVersion(currentVersion, latestVersion),
|
|
315
|
-
packageName: cli.packageName,
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
return results;
|
|
319
|
-
}
|
|
320
|
-
async update(name, version) {
|
|
321
|
-
const cli = CLI_LIST.find((c) => c.name === name);
|
|
322
|
-
if (!cli) {
|
|
323
|
-
throw new common_1.NotFoundException(`CLI not found: ${name}`);
|
|
324
|
-
}
|
|
325
|
-
const previousVersion = (await this.getCurrentVersion(cli.versionCommand)) ||
|
|
326
|
-
(await this.getNpmGlobalVersion(cli.packageName));
|
|
327
|
-
if (cli.installStrategy === 'script') {
|
|
328
|
-
return {
|
|
329
|
-
name: cli.name,
|
|
330
|
-
previousVersion: previousVersion || 'none',
|
|
331
|
-
newVersion: previousVersion || 'unknown',
|
|
332
|
-
message: `${cli.displayName}은 npm으로 업데이트할 수 없습니다. 터미널에서 실행: ${cli.installScript}`,
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
const targetVersion = version || 'latest';
|
|
336
|
-
try {
|
|
337
|
-
await execCommand(`npm install -g ${cli.packageName}@${targetVersion}`, 60000);
|
|
338
|
-
}
|
|
339
|
-
catch (error) {
|
|
340
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
341
|
-
throw new common_1.InternalServerErrorException(`Update failed: ${errorMessage}`);
|
|
342
|
-
}
|
|
343
|
-
// Use npm list as primary source — some CLIs (e.g. copilot) report different versions via --version
|
|
344
|
-
const newVersion = (await this.getNpmGlobalVersion(cli.packageName)) ||
|
|
345
|
-
(await this.getCurrentVersion(cli.versionCommand));
|
|
346
|
-
return {
|
|
347
|
-
name: cli.name,
|
|
348
|
-
previousVersion: previousVersion || 'none',
|
|
349
|
-
newVersion: newVersion || 'unknown',
|
|
350
|
-
message: `Updated ${cli.displayName} from ${previousVersion || 'none'} to ${newVersion || 'unknown'}`,
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
async setupBatch(names, send) {
|
|
354
|
-
const toInstall = [];
|
|
355
|
-
const toLogin = [];
|
|
356
|
-
for (const name of names) {
|
|
357
|
-
const cli = CLI_LIST.find((c) => c.name === name);
|
|
358
|
-
if (!cli)
|
|
359
|
-
continue;
|
|
360
|
-
if (cli.installStrategy === 'script') {
|
|
361
|
-
send('log', { cli: cli.name, text: `${cli.displayName} — 수동 설치: ${cli.installScript}`, type: 'output' });
|
|
362
|
-
continue;
|
|
363
|
-
}
|
|
364
|
-
const currentVersion = await this.getCurrentVersion(cli.versionCommand);
|
|
365
|
-
const installed = currentVersion !== null || !!(await this.getNpmGlobalVersion(cli.packageName));
|
|
366
|
-
const authenticated = await this.checkAuthenticated(cli.name);
|
|
367
|
-
if (!installed)
|
|
368
|
-
toInstall.push(cli);
|
|
369
|
-
if (authenticated !== true && cli.loginCommand)
|
|
370
|
-
toLogin.push(cli);
|
|
371
|
-
}
|
|
372
|
-
// Phase 1: parallel install
|
|
373
|
-
if (toInstall.length > 0) {
|
|
374
|
-
const installPromises = toInstall.map(async (cli) => {
|
|
375
|
-
send('status', { cli: cli.name, status: 'installing' });
|
|
376
|
-
send('log', { cli: cli.name, text: `$ npm install -g ${cli.packageName}`, type: 'command' });
|
|
377
|
-
try {
|
|
378
|
-
await execCommand(`npm install -g ${cli.packageName}@latest`, 120000);
|
|
379
|
-
send('status', { cli: cli.name, status: 'installed' });
|
|
380
|
-
send('log', { cli: cli.name, text: `✔ ${cli.displayName} installed`, type: 'success' });
|
|
381
|
-
}
|
|
382
|
-
catch (err) {
|
|
383
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
384
|
-
send('status', { cli: cli.name, status: 'failed' });
|
|
385
|
-
send('log', { cli: cli.name, text: `✘ ${cli.displayName}: ${msg}`, type: 'error' });
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
await Promise.allSettled(installPromises);
|
|
389
|
-
}
|
|
390
|
-
// Phase 2: sequential login check (we can't run login commands server-side, just report status)
|
|
391
|
-
for (const cli of toLogin) {
|
|
392
|
-
send('status', { cli: cli.name, status: 'login_needed' });
|
|
393
|
-
send('log', { cli: cli.name, text: `$ ${cli.loginCommand}`, type: 'command' });
|
|
394
|
-
send('log', { cli: cli.name, text: `Run this command in your terminal to log in`, type: 'output' });
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
spawnLogin(name) {
|
|
398
|
-
const cli = CLI_LIST.find((c) => c.name === name);
|
|
399
|
-
if (!cli || !cli.loginCommand) {
|
|
400
|
-
return { name, loginCommand: '', spawned: false };
|
|
401
|
-
}
|
|
402
|
-
const child = (0, child_process_1.spawn)(cli.loginCommand, [], {
|
|
403
|
-
detached: true,
|
|
404
|
-
stdio: 'ignore',
|
|
405
|
-
shell: true,
|
|
406
|
-
});
|
|
407
|
-
child.unref();
|
|
408
|
-
return { name: cli.name, loginCommand: cli.loginCommand, spawned: true };
|
|
409
|
-
}
|
|
410
|
-
async check(name) {
|
|
411
|
-
const cli = CLI_LIST.find((c) => c.name === name);
|
|
412
|
-
if (!cli) {
|
|
413
|
-
return {
|
|
414
|
-
name,
|
|
415
|
-
installed: false,
|
|
416
|
-
currentVersion: null,
|
|
417
|
-
latestVersion: 'unknown',
|
|
418
|
-
path: null,
|
|
419
|
-
authenticated: null,
|
|
420
|
-
loginCommand: null,
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
if (cli.installStrategy === 'script') {
|
|
424
|
-
const currentVersion = await this.getCurrentVersion(cli.versionCommand);
|
|
425
|
-
const authenticated = await this.checkAuthenticated(name);
|
|
426
|
-
return {
|
|
427
|
-
name: cli.name,
|
|
428
|
-
installed: currentVersion !== null,
|
|
429
|
-
currentVersion,
|
|
430
|
-
latestVersion: null,
|
|
431
|
-
path: null,
|
|
432
|
-
authenticated,
|
|
433
|
-
loginCommand: cli.loginCommand,
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
// Primary: global npm (immune to node_modules/.bin shim)
|
|
437
|
-
let currentVersion = await this.getNpmGlobalVersion(cli.packageName);
|
|
438
|
-
let installed = currentVersion !== null;
|
|
439
|
-
// Fallback: --version command (execCommand PATH guard prevents local shim)
|
|
440
|
-
if (!installed) {
|
|
441
|
-
currentVersion = await this.getCurrentVersion(cli.versionCommand);
|
|
442
|
-
installed = currentVersion !== null;
|
|
443
|
-
}
|
|
444
|
-
const latestVersion = await this.getLatestVersion(cli.packageName);
|
|
445
|
-
const path = await this.getCliPath(cli.versionCommand.split(' ')[0]);
|
|
446
|
-
const authenticated = await this.checkAuthenticated(cli.name);
|
|
447
|
-
return {
|
|
448
|
-
name: cli.name,
|
|
449
|
-
installed,
|
|
450
|
-
currentVersion,
|
|
451
|
-
latestVersion,
|
|
452
|
-
path,
|
|
453
|
-
authenticated,
|
|
454
|
-
loginCommand: cli.loginCommand,
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
async checkAuthenticated(cliName) {
|
|
458
|
-
switch (cliName) {
|
|
459
|
-
case 'claude':
|
|
460
|
-
return this.checkClaudeAuth();
|
|
461
|
-
case 'codex':
|
|
462
|
-
return this.checkCodexAuth();
|
|
463
|
-
case 'copilot':
|
|
464
|
-
return this.checkCopilotAuth();
|
|
465
|
-
case 'gemini':
|
|
466
|
-
return this.checkGeminiAuth();
|
|
467
|
-
case 'antigravity':
|
|
468
|
-
return null; // 인증 방식 미확정, 실측 후 보완
|
|
469
|
-
default:
|
|
470
|
-
return null;
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
async checkClaudeAuth() {
|
|
474
|
-
try {
|
|
475
|
-
const { stdout } = await execCommand('claude auth status --json', 10000);
|
|
476
|
-
try {
|
|
477
|
-
const parsed = JSON.parse(stdout.trim());
|
|
478
|
-
return parsed.loggedIn === true;
|
|
479
|
-
}
|
|
480
|
-
catch {
|
|
481
|
-
return this.parseAuthString(stdout);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
catch (err) {
|
|
485
|
-
const e = err;
|
|
486
|
-
const output = e.stdout || e.stderr || '';
|
|
487
|
-
const parsed = this.parseAuthString(output);
|
|
488
|
-
if (parsed !== null)
|
|
489
|
-
return parsed;
|
|
490
|
-
return false;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
async checkCodexAuth() {
|
|
494
|
-
try {
|
|
495
|
-
const { stdout, stderr } = await execCommand('codex login status', 10000);
|
|
496
|
-
// codex outputs to stderr
|
|
497
|
-
const output = stdout || stderr;
|
|
498
|
-
return this.parseAuthString(output);
|
|
499
|
-
}
|
|
500
|
-
catch {
|
|
501
|
-
// exit != 0 means not logged in
|
|
502
|
-
return false;
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
async checkCopilotAuth() {
|
|
506
|
-
try {
|
|
507
|
-
const { stdout, stderr } = await execCommand('gh auth status', 10000);
|
|
508
|
-
const output = stdout || stderr;
|
|
509
|
-
const lower = output.toLowerCase();
|
|
510
|
-
if (lower.includes('logged in'))
|
|
511
|
-
return true;
|
|
512
|
-
return false;
|
|
513
|
-
}
|
|
514
|
-
catch {
|
|
515
|
-
// exit != 0 means not logged in
|
|
516
|
-
return false;
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
checkGeminiAuth() {
|
|
520
|
-
const credsPath = (0, path_1.join)((0, os_1.homedir)(), '.gemini', 'oauth_creds.json');
|
|
521
|
-
return (0, fs_1.existsSync)(credsPath);
|
|
522
|
-
}
|
|
523
|
-
parseAuthString(stdout) {
|
|
524
|
-
const lower = stdout.toLowerCase();
|
|
525
|
-
if (lower.includes('not authenticated') || lower.includes('not logged in'))
|
|
526
|
-
return false;
|
|
527
|
-
if (lower.includes('logged in') || lower.includes('authenticated'))
|
|
528
|
-
return true;
|
|
529
|
-
return null;
|
|
530
|
-
}
|
|
531
|
-
async getAvailableVersions(name) {
|
|
532
|
-
const cli = CLI_LIST.find((c) => c.name === name);
|
|
533
|
-
if (!cli) {
|
|
534
|
-
return { name, versions: [] };
|
|
535
|
-
}
|
|
536
|
-
if (cli.installStrategy === 'script') {
|
|
537
|
-
return { name, versions: [] };
|
|
538
|
-
}
|
|
539
|
-
try {
|
|
540
|
-
const { stdout } = await execCommand(`npm view ${cli.packageName} versions --json`, 15000);
|
|
541
|
-
const parsed = JSON.parse(stdout.trim());
|
|
542
|
-
// npm returns a single string when only one version exists
|
|
543
|
-
const all = Array.isArray(parsed) ? parsed : [parsed];
|
|
544
|
-
// Semver: versions with a hyphen are prerelease (rc, alpha, beta, nightly, platform builds, etc.)
|
|
545
|
-
const stable = all.filter(v => !v.includes('-'));
|
|
546
|
-
const versions = stable.reverse().slice(0, 20);
|
|
547
|
-
return { name, versions };
|
|
548
|
-
}
|
|
549
|
-
catch {
|
|
550
|
-
return { name, versions: [] };
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
async getCurrentVersion(command) {
|
|
554
|
-
try {
|
|
555
|
-
const { stdout } = await execCommand(command);
|
|
556
|
-
const version = parseVersion(stdout.trim());
|
|
557
|
-
return version || null;
|
|
558
|
-
}
|
|
559
|
-
catch {
|
|
560
|
-
return null;
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
async getNpmGlobalVersion(packageName) {
|
|
564
|
-
try {
|
|
565
|
-
const { stdout } = await execCommand(`npm list -g ${packageName} --depth=0 --json`, 10000);
|
|
566
|
-
const parsed = JSON.parse(stdout.trim());
|
|
567
|
-
const version = parsed?.dependencies?.[packageName]?.version;
|
|
568
|
-
return version || null;
|
|
569
|
-
}
|
|
570
|
-
catch {
|
|
571
|
-
return null;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
async getLatestVersion(packageName) {
|
|
575
|
-
try {
|
|
576
|
-
const { stdout } = await execCommand(`npm view ${packageName}@latest version`, 15000);
|
|
577
|
-
return stdout.trim() || 'unknown';
|
|
578
|
-
}
|
|
579
|
-
catch {
|
|
580
|
-
return 'unknown';
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
async getCliPath(command) {
|
|
584
|
-
try {
|
|
585
|
-
const cmd = isWindows ? `where ${command}` : `which ${command}`;
|
|
586
|
-
const { stdout } = await execCommand(cmd);
|
|
587
|
-
const rawPath = stdout.trim().split('\n')[0];
|
|
588
|
-
return resolveCliPathGuard(rawPath, process.cwd());
|
|
589
|
-
}
|
|
590
|
-
catch {
|
|
591
|
-
return null;
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
};
|
|
595
|
-
exports.CliService = CliService;
|
|
596
|
-
exports.CliService = CliService = __decorate([
|
|
597
|
-
(0, common_1.Injectable)()
|
|
598
|
-
], CliService);
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.LoginCliDto = void 0;
|
|
13
|
-
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
-
const class_validator_1 = require("class-validator");
|
|
15
|
-
class LoginCliDto {
|
|
16
|
-
name;
|
|
17
|
-
}
|
|
18
|
-
exports.LoginCliDto = LoginCliDto;
|
|
19
|
-
__decorate([
|
|
20
|
-
(0, swagger_1.ApiProperty)({ description: 'CLI tool name', enum: ['claude', 'codex', 'gemini', 'copilot'] }),
|
|
21
|
-
(0, class_validator_1.IsString)(),
|
|
22
|
-
(0, class_validator_1.IsNotEmpty)(),
|
|
23
|
-
(0, class_validator_1.IsIn)(['claude', 'codex', 'gemini', 'copilot']),
|
|
24
|
-
__metadata("design:type", String)
|
|
25
|
-
], LoginCliDto.prototype, "name", void 0);
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.UpdateCliDto = void 0;
|
|
13
|
-
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
-
const class_validator_1 = require("class-validator");
|
|
15
|
-
class UpdateCliDto {
|
|
16
|
-
name;
|
|
17
|
-
version;
|
|
18
|
-
}
|
|
19
|
-
exports.UpdateCliDto = UpdateCliDto;
|
|
20
|
-
__decorate([
|
|
21
|
-
(0, swagger_1.ApiProperty)({ description: 'CLI tool name to update' }),
|
|
22
|
-
(0, class_validator_1.IsString)(),
|
|
23
|
-
(0, class_validator_1.IsNotEmpty)(),
|
|
24
|
-
__metadata("design:type", String)
|
|
25
|
-
], UpdateCliDto.prototype, "name", void 0);
|
|
26
|
-
__decorate([
|
|
27
|
-
(0, swagger_1.ApiPropertyOptional)({ description: 'Version to install (default: latest)', example: '1.0.0' }),
|
|
28
|
-
(0, class_validator_1.IsString)(),
|
|
29
|
-
(0, class_validator_1.IsOptional)(),
|
|
30
|
-
__metadata("design:type", String)
|
|
31
|
-
], UpdateCliDto.prototype, "version", void 0);
|