ccjk 14.2.2 → 15.1.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/LICENSE +1 -1
- package/README.md +75 -338
- package/dist/cli.js +89 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/detect.js +15 -0
- package/dist/commands/detect.js.map +1 -0
- package/dist/commands/doctor.js +68 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/git-install.js +50 -0
- package/dist/commands/git-install.js.map +1 -0
- package/dist/commands/init.js +165 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mcp.js +66 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/menu.js +42 -0
- package/dist/commands/menu.js.map +1 -0
- package/dist/commands/profile.js +138 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/core/detect.js +24 -0
- package/dist/core/detect.js.map +1 -0
- package/dist/core/lint.js +49 -0
- package/dist/core/lint.js.map +1 -0
- package/dist/core/mcp.js +41 -0
- package/dist/core/mcp.js.map +1 -0
- package/dist/core/paths.js +9 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/profiles.js +104 -0
- package/dist/core/profiles.js.map +1 -0
- package/dist/core/providers.js +53 -0
- package/dist/core/providers.js.map +1 -0
- package/dist/core/settings.js +31 -0
- package/dist/core/settings.js.map +1 -0
- package/dist/core/slash-templates.js +56 -0
- package/dist/core/slash-templates.js.map +1 -0
- package/dist/core/tools.js +27 -0
- package/dist/core/tools.js.map +1 -0
- package/package.json +43 -164
- package/README.HONEST.md +0 -176
- package/README.en.md +0 -67
- package/README.ja.md +0 -67
- package/README.ko.md +0 -67
- package/README.zh-CN.md +0 -86
- package/bin/ccjk.mjs +0 -5
- package/bin/ccjk.ts +0 -222
- package/dist/chunks/agent-teams.mjs +0 -145
- package/dist/chunks/agent.mjs +0 -1439
- package/dist/chunks/agents.mjs +0 -3783
- package/dist/chunks/api-cli.mjs +0 -135
- package/dist/chunks/api-config-selector.mjs +0 -159
- package/dist/chunks/api-providers.mjs +0 -144
- package/dist/chunks/api.mjs +0 -115
- package/dist/chunks/auto-bootstrap.mjs +0 -358
- package/dist/chunks/auto-fixer.mjs +0 -95
- package/dist/chunks/auto-updater.mjs +0 -507
- package/dist/chunks/banner.mjs +0 -173
- package/dist/chunks/bash.mjs +0 -187
- package/dist/chunks/boost.mjs +0 -474
- package/dist/chunks/brain-config.mjs +0 -75
- package/dist/chunks/brain-status.mjs +0 -89
- package/dist/chunks/ccjk-agents.mjs +0 -416
- package/dist/chunks/ccjk-all.mjs +0 -1046
- package/dist/chunks/ccjk-config.mjs +0 -445
- package/dist/chunks/ccjk-hooks.mjs +0 -1074
- package/dist/chunks/ccjk-mcp.mjs +0 -763
- package/dist/chunks/ccjk-setup.mjs +0 -765
- package/dist/chunks/ccjk-skills.mjs +0 -518
- package/dist/chunks/ccr.mjs +0 -109
- package/dist/chunks/ccu.mjs +0 -40
- package/dist/chunks/check-updates.mjs +0 -117
- package/dist/chunks/claude-code-incremental-manager.mjs +0 -761
- package/dist/chunks/claude-config.mjs +0 -606
- package/dist/chunks/claude-config2.mjs +0 -62
- package/dist/chunks/claude-wrapper.mjs +0 -85
- package/dist/chunks/clavue-config.mjs +0 -1454
- package/dist/chunks/cleanup-migration.mjs +0 -20
- package/dist/chunks/cli-hook.mjs +0 -4096
- package/dist/chunks/cloud-sync.mjs +0 -29
- package/dist/chunks/code-type-resolver.mjs +0 -880
- package/dist/chunks/codex-config-switch.mjs +0 -452
- package/dist/chunks/codex-provider-manager.mjs +0 -238
- package/dist/chunks/codex-uninstaller.mjs +0 -404
- package/dist/chunks/codex.mjs +0 -2141
- package/dist/chunks/commands.mjs +0 -108
- package/dist/chunks/commands2.mjs +0 -421
- package/dist/chunks/commit.mjs +0 -140
- package/dist/chunks/completion.mjs +0 -517
- package/dist/chunks/config-consolidator.mjs +0 -172
- package/dist/chunks/config-switch.mjs +0 -334
- package/dist/chunks/config.mjs +0 -558
- package/dist/chunks/config2.mjs +0 -484
- package/dist/chunks/config3.mjs +0 -486
- package/dist/chunks/constants.mjs +0 -323
- package/dist/chunks/context-opt.mjs +0 -444
- package/dist/chunks/context.mjs +0 -974
- package/dist/chunks/dashboard.mjs +0 -481
- package/dist/chunks/doctor.mjs +0 -1301
- package/dist/chunks/eval.mjs +0 -502
- package/dist/chunks/evolution.mjs +0 -322
- package/dist/chunks/features.mjs +0 -715
- package/dist/chunks/fish.mjs +0 -181
- package/dist/chunks/fs-operations.mjs +0 -180
- package/dist/chunks/health-alerts.mjs +0 -830
- package/dist/chunks/help.mjs +0 -341
- package/dist/chunks/hook-installer.mjs +0 -48
- package/dist/chunks/impact.mjs +0 -651
- package/dist/chunks/index.mjs +0 -23
- package/dist/chunks/index10.mjs +0 -19
- package/dist/chunks/index11.mjs +0 -1171
- package/dist/chunks/index12.mjs +0 -218
- package/dist/chunks/index13.mjs +0 -679
- package/dist/chunks/index14.mjs +0 -1009
- package/dist/chunks/index15.mjs +0 -194
- package/dist/chunks/index2.mjs +0 -7637
- package/dist/chunks/index3.mjs +0 -171
- package/dist/chunks/index4.mjs +0 -26
- package/dist/chunks/index5.mjs +0 -19
- package/dist/chunks/index6.mjs +0 -19092
- package/dist/chunks/index7.mjs +0 -616
- package/dist/chunks/index8.mjs +0 -1602
- package/dist/chunks/index9.mjs +0 -5384
- package/dist/chunks/init.mjs +0 -1911
- package/dist/chunks/installer.mjs +0 -757
- package/dist/chunks/installer2.mjs +0 -103
- package/dist/chunks/interview.mjs +0 -2927
- package/dist/chunks/json-config.mjs +0 -60
- package/dist/chunks/linux.mjs +0 -3863
- package/dist/chunks/macos.mjs +0 -69
- package/dist/chunks/main.mjs +0 -635
- package/dist/chunks/manager.mjs +0 -1048
- package/dist/chunks/marketplace.mjs +0 -265
- package/dist/chunks/mcp-cli.mjs +0 -205
- package/dist/chunks/mcp-performance.mjs +0 -187
- package/dist/chunks/mcp.mjs +0 -667
- package/dist/chunks/memory-check.mjs +0 -2973
- package/dist/chunks/memory-paths.mjs +0 -259
- package/dist/chunks/memory-sync.mjs +0 -209
- package/dist/chunks/memory.mjs +0 -354
- package/dist/chunks/metrics-display.mjs +0 -153
- package/dist/chunks/monitor.mjs +0 -1856
- package/dist/chunks/notification.mjs +0 -1864
- package/dist/chunks/onboarding.mjs +0 -386
- package/dist/chunks/package.mjs +0 -3
- package/dist/chunks/paradigm.mjs +0 -74
- package/dist/chunks/permission-manager.mjs +0 -250
- package/dist/chunks/permissions.mjs +0 -265
- package/dist/chunks/persistence-manager.mjs +0 -801
- package/dist/chunks/persistence.mjs +0 -707
- package/dist/chunks/platform.mjs +0 -395
- package/dist/chunks/plugin.mjs +0 -1936
- package/dist/chunks/powershell.mjs +0 -213
- package/dist/chunks/prompts.mjs +0 -244
- package/dist/chunks/providers.mjs +0 -263
- package/dist/chunks/quick-actions.mjs +0 -335
- package/dist/chunks/quick-provider.mjs +0 -755
- package/dist/chunks/quick-setup.mjs +0 -421
- package/dist/chunks/remote.mjs +0 -497
- package/dist/chunks/research.mjs +0 -1904
- package/dist/chunks/rollback.mjs +0 -38
- package/dist/chunks/session-manager.mjs +0 -1371
- package/dist/chunks/session.mjs +0 -878
- package/dist/chunks/sessions.mjs +0 -106
- package/dist/chunks/silent-updater.mjs +0 -396
- package/dist/chunks/simple-config.mjs +0 -122
- package/dist/chunks/skill.mjs +0 -117
- package/dist/chunks/skill2.mjs +0 -9052
- package/dist/chunks/skills-sync.mjs +0 -1343
- package/dist/chunks/skills.mjs +0 -577
- package/dist/chunks/slash-commands.mjs +0 -208
- package/dist/chunks/smart-guide.mjs +0 -247
- package/dist/chunks/snapshot.mjs +0 -58
- package/dist/chunks/startup.mjs +0 -487
- package/dist/chunks/stats.mjs +0 -191
- package/dist/chunks/status.mjs +0 -471
- package/dist/chunks/team.mjs +0 -63
- package/dist/chunks/thinking.mjs +0 -626
- package/dist/chunks/trace.mjs +0 -57
- package/dist/chunks/uninstall.mjs +0 -852
- package/dist/chunks/update.mjs +0 -174
- package/dist/chunks/upgrade-manager.mjs +0 -204
- package/dist/chunks/upgrade.mjs +0 -133
- package/dist/chunks/version-checker.mjs +0 -891
- package/dist/chunks/vim.mjs +0 -903
- package/dist/chunks/windows.mjs +0 -14
- package/dist/chunks/workflows.mjs +0 -633
- package/dist/chunks/wsl.mjs +0 -129
- package/dist/chunks/zero-config.mjs +0 -871
- package/dist/chunks/zsh.mjs +0 -182
- package/dist/cli.d.mts +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.mjs +0 -2684
- package/dist/i18n/locales/en/agent-teams.json +0 -18
- package/dist/i18n/locales/en/agentBrowser.json +0 -80
- package/dist/i18n/locales/en/agents.json +0 -135
- package/dist/i18n/locales/en/api.json +0 -63
- package/dist/i18n/locales/en/ccjk-agents.json +0 -33
- package/dist/i18n/locales/en/ccjk-all.json +0 -23
- package/dist/i18n/locales/en/ccjk-skills.json +0 -22
- package/dist/i18n/locales/en/ccjk.json +0 -276
- package/dist/i18n/locales/en/ccr.json +0 -65
- package/dist/i18n/locales/en/claude-md.json +0 -73
- package/dist/i18n/locales/en/cli.json +0 -148
- package/dist/i18n/locales/en/cloud-setup.json +0 -31
- package/dist/i18n/locales/en/cloud-sync.json +0 -147
- package/dist/i18n/locales/en/cloud.json +0 -40
- package/dist/i18n/locales/en/cloudPlugins.json +0 -118
- package/dist/i18n/locales/en/codex.json +0 -184
- package/dist/i18n/locales/en/cometix.json +0 -29
- package/dist/i18n/locales/en/common.json +0 -68
- package/dist/i18n/locales/en/config.json +0 -108
- package/dist/i18n/locales/en/configuration.json +0 -236
- package/dist/i18n/locales/en/context.json +0 -85
- package/dist/i18n/locales/en/dashboard.json +0 -78
- package/dist/i18n/locales/en/errors.json +0 -26
- package/dist/i18n/locales/en/evolution.json +0 -54
- package/dist/i18n/locales/en/hooks.json +0 -74
- package/dist/i18n/locales/en/hooksSync.json +0 -133
- package/dist/i18n/locales/en/installation.json +0 -83
- package/dist/i18n/locales/en/interview.json +0 -104
- package/dist/i18n/locales/en/language.json +0 -19
- package/dist/i18n/locales/en/lsp.json +0 -78
- package/dist/i18n/locales/en/marketplace.json +0 -116
- package/dist/i18n/locales/en/mcp.json +0 -180
- package/dist/i18n/locales/en/memory.json +0 -23
- package/dist/i18n/locales/en/menu.json +0 -299
- package/dist/i18n/locales/en/multi-config.json +0 -79
- package/dist/i18n/locales/en/notification.json +0 -307
- package/dist/i18n/locales/en/permissions.json +0 -95
- package/dist/i18n/locales/en/persistence.json +0 -127
- package/dist/i18n/locales/en/plugins.json +0 -146
- package/dist/i18n/locales/en/quick-actions.json +0 -78
- package/dist/i18n/locales/en/registry.json +0 -54
- package/dist/i18n/locales/en/remote.json +0 -93
- package/dist/i18n/locales/en/sandbox.json +0 -44
- package/dist/i18n/locales/en/setup.json +0 -44
- package/dist/i18n/locales/en/shencha.json +0 -14
- package/dist/i18n/locales/en/skills.json +0 -100
- package/dist/i18n/locales/en/skillsSync.json +0 -74
- package/dist/i18n/locales/en/smartGuide.json +0 -49
- package/dist/i18n/locales/en/stats.json +0 -20
- package/dist/i18n/locales/en/subagent.json +0 -69
- package/dist/i18n/locales/en/superpowers.json +0 -117
- package/dist/i18n/locales/en/team.json +0 -7
- package/dist/i18n/locales/en/thinking.json +0 -65
- package/dist/i18n/locales/en/tools.json +0 -42
- package/dist/i18n/locales/en/uninstall.json +0 -56
- package/dist/i18n/locales/en/updater.json +0 -29
- package/dist/i18n/locales/en/vim.json +0 -169
- package/dist/i18n/locales/en/workflow.json +0 -55
- package/dist/i18n/locales/en/workspace.json +0 -108
- package/dist/i18n/locales/zh-CN/agent-teams.json +0 -18
- package/dist/i18n/locales/zh-CN/agentBrowser.json +0 -80
- package/dist/i18n/locales/zh-CN/agents.json +0 -135
- package/dist/i18n/locales/zh-CN/api.json +0 -63
- package/dist/i18n/locales/zh-CN/ccjk-agents.json +0 -33
- package/dist/i18n/locales/zh-CN/ccjk-all.json +0 -23
- package/dist/i18n/locales/zh-CN/ccjk-skills.json +0 -22
- package/dist/i18n/locales/zh-CN/ccjk.json +0 -276
- package/dist/i18n/locales/zh-CN/ccr.json +0 -65
- package/dist/i18n/locales/zh-CN/claude-md.json +0 -73
- package/dist/i18n/locales/zh-CN/cli.json +0 -148
- package/dist/i18n/locales/zh-CN/cloud-setup.json +0 -31
- package/dist/i18n/locales/zh-CN/cloud-sync.json +0 -147
- package/dist/i18n/locales/zh-CN/cloud.json +0 -40
- package/dist/i18n/locales/zh-CN/cloudPlugins.json +0 -118
- package/dist/i18n/locales/zh-CN/codex.json +0 -184
- package/dist/i18n/locales/zh-CN/cometix.json +0 -29
- package/dist/i18n/locales/zh-CN/common.json +0 -68
- package/dist/i18n/locales/zh-CN/config.json +0 -108
- package/dist/i18n/locales/zh-CN/configuration.json +0 -234
- package/dist/i18n/locales/zh-CN/context.json +0 -85
- package/dist/i18n/locales/zh-CN/dashboard.json +0 -78
- package/dist/i18n/locales/zh-CN/errors.json +0 -26
- package/dist/i18n/locales/zh-CN/evolution.json +0 -54
- package/dist/i18n/locales/zh-CN/hooks.json +0 -74
- package/dist/i18n/locales/zh-CN/hooksSync.json +0 -133
- package/dist/i18n/locales/zh-CN/installation.json +0 -83
- package/dist/i18n/locales/zh-CN/interview.json +0 -104
- package/dist/i18n/locales/zh-CN/language.json +0 -19
- package/dist/i18n/locales/zh-CN/lsp.json +0 -78
- package/dist/i18n/locales/zh-CN/marketplace.json +0 -116
- package/dist/i18n/locales/zh-CN/mcp.json +0 -180
- package/dist/i18n/locales/zh-CN/memory.json +0 -23
- package/dist/i18n/locales/zh-CN/menu.json +0 -299
- package/dist/i18n/locales/zh-CN/multi-config.json +0 -79
- package/dist/i18n/locales/zh-CN/notification.json +0 -307
- package/dist/i18n/locales/zh-CN/permissions.json +0 -95
- package/dist/i18n/locales/zh-CN/persistence.json +0 -127
- package/dist/i18n/locales/zh-CN/plugins.json +0 -146
- package/dist/i18n/locales/zh-CN/quick-actions.json +0 -78
- package/dist/i18n/locales/zh-CN/registry.json +0 -54
- package/dist/i18n/locales/zh-CN/remote.json +0 -93
- package/dist/i18n/locales/zh-CN/sandbox.json +0 -44
- package/dist/i18n/locales/zh-CN/setup.json +0 -44
- package/dist/i18n/locales/zh-CN/shencha.json +0 -14
- package/dist/i18n/locales/zh-CN/skills.json +0 -100
- package/dist/i18n/locales/zh-CN/skillsSync.json +0 -74
- package/dist/i18n/locales/zh-CN/smartGuide.json +0 -49
- package/dist/i18n/locales/zh-CN/stats.json +0 -20
- package/dist/i18n/locales/zh-CN/subagent.json +0 -69
- package/dist/i18n/locales/zh-CN/superpowers.json +0 -117
- package/dist/i18n/locales/zh-CN/team.json +0 -7
- package/dist/i18n/locales/zh-CN/thinking.json +0 -65
- package/dist/i18n/locales/zh-CN/tools.json +0 -42
- package/dist/i18n/locales/zh-CN/uninstall.json +0 -56
- package/dist/i18n/locales/zh-CN/updater.json +0 -29
- package/dist/i18n/locales/zh-CN/vim.json +0 -169
- package/dist/i18n/locales/zh-CN/workflow.json +0 -55
- package/dist/i18n/locales/zh-CN/workspace.json +0 -108
- package/dist/index.d.mts +0 -5658
- package/dist/index.d.ts +0 -5658
- package/dist/index.mjs +0 -3732
- package/dist/shared/ccjk.5bEolFrk.mjs +0 -254
- package/dist/shared/ccjk.8oaxX4iR.mjs +0 -90
- package/dist/shared/ccjk.B2U7DsPy.mjs +0 -31
- package/dist/shared/ccjk.B2f-cwUP.mjs +0 -468
- package/dist/shared/ccjk.BAGoDD49.mjs +0 -36
- package/dist/shared/ccjk.BBtCGd_g.mjs +0 -899
- package/dist/shared/ccjk.BFQ7yr5S.mjs +0 -16
- package/dist/shared/ccjk.BLsIiTqO.mjs +0 -449
- package/dist/shared/ccjk.BXv8aYs1.mjs +0 -170
- package/dist/shared/ccjk.BnsY5WxD.mjs +0 -171
- package/dist/shared/ccjk.BoApaI4j.mjs +0 -28
- package/dist/shared/ccjk.Bq8TqZG_.mjs +0 -189
- package/dist/shared/ccjk.BtrioX1Z.mjs +0 -25
- package/dist/shared/ccjk.Bx_rmYfN.mjs +0 -69
- package/dist/shared/ccjk.BzPbSEP2.mjs +0 -115
- package/dist/shared/ccjk.C0WLUnFV.mjs +0 -293
- package/dist/shared/ccjk.C1hANZTu.mjs +0 -19
- package/dist/shared/ccjk.C2jHOZVP.mjs +0 -52
- package/dist/shared/ccjk.CNhnT6uQ.mjs +0 -636
- package/dist/shared/ccjk.COweQ1RR.mjs +0 -5
- package/dist/shared/ccjk.CfKKcvWy.mjs +0 -126
- package/dist/shared/ccjk.Cjgrln_h.mjs +0 -297
- package/dist/shared/ccjk.CoCHVXl3.mjs +0 -3951
- package/dist/shared/ccjk.CwGZSTAK.mjs +0 -319
- package/dist/shared/ccjk.CxpGa6MC.mjs +0 -2724
- package/dist/shared/ccjk.D-magaEx.mjs +0 -763
- package/dist/shared/ccjk.D0g2ABGg.mjs +0 -171
- package/dist/shared/ccjk.D6ycHbak.mjs +0 -270
- package/dist/shared/ccjk.D75wivnp.mjs +0 -142
- package/dist/shared/ccjk.DDL-4C-k.mjs +0 -100
- package/dist/shared/ccjk.DFRPtmK_.mjs +0 -75
- package/dist/shared/ccjk.DMV3x5Sd.mjs +0 -299
- package/dist/shared/ccjk.DZ2LLOa-.mjs +0 -2195
- package/dist/shared/ccjk.DbigonEQ.mjs +0 -698
- package/dist/shared/ccjk.DcMvE7lf.mjs +0 -618
- package/dist/shared/ccjk.DeWpAShp.mjs +0 -1828
- package/dist/shared/ccjk.DhJ1kyDR.mjs +0 -30
- package/dist/shared/ccjk.DlTXS9rP.mjs +0 -224
- package/dist/shared/ccjk.DopKzo3z.mjs +0 -305
- package/dist/shared/ccjk.DsZsc4LR.mjs +0 -1280
- package/dist/shared/ccjk.DuzJZlgj.mjs +0 -418
- package/dist/shared/ccjk.Dxgd2vjc.mjs +0 -444
- package/dist/shared/ccjk.J8YiPsOw.mjs +0 -259
- package/dist/shared/ccjk.KfSWcGlE.mjs +0 -38
- package/dist/shared/ccjk.L7yC58_i.mjs +0 -225
- package/dist/shared/ccjk.MwtjAULc.mjs +0 -1447
- package/dist/shared/ccjk.OJKHVSOb.mjs +0 -2005
- package/dist/shared/ccjk.OTnevPNE.mjs +0 -225
- package/dist/shared/ccjk.RyizuzOI.mjs +0 -21
- package/dist/shared/ccjk.T_cX87dY.mjs +0 -15
- package/dist/shared/ccjk.bQ7Dh1g4.mjs +0 -249
- package/dist/shared/ccjk.gDEDGD_t.mjs +0 -38
- package/dist/shared/ccjk.hoqrwWdN.mjs +0 -333
- package/dist/shared/ccjk.i_vn-9C3.mjs +0 -317
- package/dist/shared/ccjk.lG3ccFjm.mjs +0 -885
- package/dist/shared/ccjk.wLJHO0Af.mjs +0 -244
- package/dist/shared/ccjk.y-a_1vK4.mjs +0 -5127
- package/dist/templates/agents/README.md +0 -78
- package/dist/templates/agents/fullstack-developer.json +0 -70
- package/dist/templates/agents/go-expert.json +0 -69
- package/dist/templates/agents/index.json +0 -64
- package/dist/templates/agents/python-expert.json +0 -69
- package/dist/templates/agents/react-specialist.json +0 -69
- package/dist/templates/agents/testing-automation-expert.json +0 -70
- package/dist/templates/agents/typescript-architect.json +0 -69
- package/dist/templates/claude-code/common/settings.json +0 -109
- package/dist/templates/common/error-prevention.md +0 -267
- package/dist/templates/common/karpathy-baseline.md +0 -83
- package/dist/templates/common/output-styles/zh-CN/carmack-mode.md +0 -381
- package/dist/templates/common/output-styles/zh-CN/codex-rigor-mode.md +0 -114
- package/dist/templates/common/output-styles/zh-CN/dhh-mode.md +0 -265
- package/dist/templates/common/output-styles/zh-CN/evan-you-mode.md +0 -539
- package/dist/templates/common/output-styles/zh-CN/jobs-mode.md +0 -369
- package/dist/templates/common/output-styles/zh-CN/linus-mode.md +0 -135
- package/dist/templates/common/output-styles/zh-CN/uncle-bob-mode.md +0 -221
- package/dist/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +0 -628
- package/dist/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +0 -628
- package/dist/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +0 -187
- package/dist/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +0 -191
- package/dist/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +0 -249
- package/dist/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +0 -277
- package/dist/templates/common/workflow/essential/en/agents/get-current-datetime.md +0 -29
- package/dist/templates/common/workflow/essential/en/agents/init-architect.md +0 -115
- package/dist/templates/common/workflow/essential/en/agents/ui-ux-designer.md +0 -91
- package/dist/templates/common/workflow/essential/en/feat.md +0 -92
- package/dist/templates/common/workflow/essential/en/goal.md +0 -147
- package/dist/templates/common/workflow/essential/en/init-project.md +0 -53
- package/dist/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +0 -29
- package/dist/templates/common/workflow/essential/zh-CN/agents/init-architect.md +0 -115
- package/dist/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +0 -91
- package/dist/templates/common/workflow/essential/zh-CN/feat.md +0 -315
- package/dist/templates/common/workflow/essential/zh-CN/goal.md +0 -146
- package/dist/templates/common/workflow/essential/zh-CN/init-project.md +0 -53
- package/dist/templates/common/workflow/git/en/git-cleanBranches.md +0 -102
- package/dist/templates/common/workflow/git/en/git-commit.md +0 -205
- package/dist/templates/common/workflow/git/en/git-rollback.md +0 -90
- package/dist/templates/common/workflow/git/en/git-worktree.md +0 -276
- package/dist/templates/common/workflow/git/zh-CN/git-cleanBranches.md +0 -102
- package/dist/templates/common/workflow/git/zh-CN/git-commit.md +0 -205
- package/dist/templates/common/workflow/git/zh-CN/git-rollback.md +0 -90
- package/dist/templates/common/workflow/git/zh-CN/git-worktree.md +0 -276
- package/dist/templates/common/workflow/interview/en/interview.md +0 -67
- package/dist/templates/common/workflow/interview/zh-CN/interview.md +0 -67
- package/dist/templates/common/workflow/linearMethod/en/linear-method.md +0 -651
- package/dist/templates/common/workflow/linearMethod/zh-CN/linear-method.md +0 -752
- package/dist/templates/common/workflow/refactoringMaster/en/refactoring-master.md +0 -516
- package/dist/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +0 -812
- package/dist/templates/common/workflow/sixStep/en/workflow.md +0 -83
- package/dist/templates/common/workflow/sixStep/zh-CN/workflow.md +0 -359
- package/dist/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +0 -364
- package/dist/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +0 -366
- package/dist/templates/hooks/README.md +0 -212
- package/dist/templates/hooks/git-workflow-hooks.md +0 -551
- package/dist/templates/hooks/post-test/coverage.json +0 -21
- package/dist/templates/hooks/post-test/summary.json +0 -21
- package/dist/templates/hooks/post-test-coverage.md +0 -434
- package/dist/templates/hooks/pre-commit/eslint.json +0 -22
- package/dist/templates/hooks/pre-commit/prettier.json +0 -22
- package/dist/templates/hooks/pre-commit-black.md +0 -274
- package/dist/templates/hooks/pre-commit-eslint.md +0 -153
- package/dist/templates/hooks/pre-commit-gofmt.md +0 -284
- package/dist/templates/hooks/pre-commit-prettier.md +0 -212
- package/dist/templates/hooks/pre-commit-type-check.md +0 -377
- package/dist/templates/skills/ccjk-init.md +0 -154
- package/dist/templates/skills/ccjk-mcp-setup.md +0 -205
- package/dist/templates/skills/ccjk-troubleshoot.md +0 -228
- package/dist/templates/skills/django-patterns.md +0 -1016
- package/dist/templates/skills/git-workflow.md +0 -748
- package/dist/templates/skills/go-idioms.md +0 -963
- package/dist/templates/skills/index.json +0 -132
- package/dist/templates/skills/nextjs-optimization.md +0 -694
- package/dist/templates/skills/python-pep8.md +0 -852
- package/dist/templates/skills/react-patterns.md +0 -686
- package/dist/templates/skills/rust-patterns.md +0 -1057
- package/dist/templates/skills/security-best-practices.md +0 -1413
- package/dist/templates/skills/testing-best-practices.md +0 -1315
- package/dist/templates/skills/ts-best-practices.md +0 -354
- package/templates/agents/README.md +0 -78
- package/templates/agents/fullstack-developer.json +0 -70
- package/templates/agents/go-expert.json +0 -69
- package/templates/agents/index.json +0 -64
- package/templates/agents/python-expert.json +0 -69
- package/templates/agents/react-specialist.json +0 -69
- package/templates/agents/testing-automation-expert.json +0 -70
- package/templates/agents/typescript-architect.json +0 -69
- package/templates/claude-code/common/settings.json +0 -109
- package/templates/common/error-prevention.md +0 -267
- package/templates/common/karpathy-baseline.md +0 -83
- package/templates/common/output-styles/zh-CN/carmack-mode.md +0 -381
- package/templates/common/output-styles/zh-CN/codex-rigor-mode.md +0 -114
- package/templates/common/output-styles/zh-CN/dhh-mode.md +0 -265
- package/templates/common/output-styles/zh-CN/evan-you-mode.md +0 -539
- package/templates/common/output-styles/zh-CN/jobs-mode.md +0 -369
- package/templates/common/output-styles/zh-CN/linus-mode.md +0 -135
- package/templates/common/output-styles/zh-CN/uncle-bob-mode.md +0 -221
- package/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +0 -628
- package/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +0 -628
- package/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +0 -187
- package/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +0 -191
- package/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +0 -249
- package/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +0 -277
- package/templates/common/workflow/essential/en/agents/get-current-datetime.md +0 -29
- package/templates/common/workflow/essential/en/agents/init-architect.md +0 -115
- package/templates/common/workflow/essential/en/agents/ui-ux-designer.md +0 -91
- package/templates/common/workflow/essential/en/feat.md +0 -92
- package/templates/common/workflow/essential/en/goal.md +0 -147
- package/templates/common/workflow/essential/en/init-project.md +0 -53
- package/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +0 -29
- package/templates/common/workflow/essential/zh-CN/agents/init-architect.md +0 -115
- package/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +0 -91
- package/templates/common/workflow/essential/zh-CN/feat.md +0 -315
- package/templates/common/workflow/essential/zh-CN/goal.md +0 -146
- package/templates/common/workflow/essential/zh-CN/init-project.md +0 -53
- package/templates/common/workflow/git/en/git-cleanBranches.md +0 -102
- package/templates/common/workflow/git/en/git-commit.md +0 -205
- package/templates/common/workflow/git/en/git-rollback.md +0 -90
- package/templates/common/workflow/git/en/git-worktree.md +0 -276
- package/templates/common/workflow/git/zh-CN/git-cleanBranches.md +0 -102
- package/templates/common/workflow/git/zh-CN/git-commit.md +0 -205
- package/templates/common/workflow/git/zh-CN/git-rollback.md +0 -90
- package/templates/common/workflow/git/zh-CN/git-worktree.md +0 -276
- package/templates/common/workflow/interview/en/interview.md +0 -67
- package/templates/common/workflow/interview/zh-CN/interview.md +0 -67
- package/templates/common/workflow/linearMethod/en/linear-method.md +0 -651
- package/templates/common/workflow/linearMethod/zh-CN/linear-method.md +0 -752
- package/templates/common/workflow/refactoringMaster/en/refactoring-master.md +0 -516
- package/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +0 -812
- package/templates/common/workflow/sixStep/en/workflow.md +0 -83
- package/templates/common/workflow/sixStep/zh-CN/workflow.md +0 -359
- package/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +0 -364
- package/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +0 -366
- package/templates/hooks/README.md +0 -212
- package/templates/hooks/git-workflow-hooks.md +0 -551
- package/templates/hooks/post-test/coverage.json +0 -21
- package/templates/hooks/post-test/summary.json +0 -21
- package/templates/hooks/post-test-coverage.md +0 -434
- package/templates/hooks/pre-commit/eslint.json +0 -22
- package/templates/hooks/pre-commit/prettier.json +0 -22
- package/templates/hooks/pre-commit-black.md +0 -274
- package/templates/hooks/pre-commit-eslint.md +0 -153
- package/templates/hooks/pre-commit-gofmt.md +0 -284
- package/templates/hooks/pre-commit-prettier.md +0 -212
- package/templates/hooks/pre-commit-type-check.md +0 -377
- package/templates/skills/basic.hbs +0 -72
- package/templates/skills/ccjk-init.md +0 -154
- package/templates/skills/ccjk-mcp-setup.md +0 -205
- package/templates/skills/ccjk-troubleshoot.md +0 -228
- package/templates/skills/code-refactor.hbs +0 -133
- package/templates/skills/code-review.hbs +0 -141
- package/templates/skills/django-patterns.md +0 -1016
- package/templates/skills/git-workflow.md +0 -748
- package/templates/skills/go-idioms.md +0 -963
- package/templates/skills/index.json +0 -132
- package/templates/skills/nextjs-optimization.md +0 -694
- package/templates/skills/python-pep8.md +0 -852
- package/templates/skills/react-patterns.md +0 -686
- package/templates/skills/rust-patterns.md +0 -1057
- package/templates/skills/security-best-practices.md +0 -1413
- package/templates/skills/testing-best-practices.md +0 -1315
- package/templates/skills/ts-best-practices.md +0 -354
- package/templates/skills/type-fix.hbs +0 -132
package/dist/index.mjs
DELETED
|
@@ -1,3732 +0,0 @@
|
|
|
1
|
-
export { P as ProjectAnalyzer, T as TemplatesClient, d as analyzeDependencies, a as analyzeProject, h as batchAnalyze, b as createTemplatesClient, e as detectProject, f as detectProjectType, g as getTemplatesClient } from './shared/ccjk.CoCHVXl3.mjs';
|
|
2
|
-
import { a as createCloudClient } from './shared/ccjk.OJKHVSOb.mjs';
|
|
3
|
-
export { C as CachedCloudClient, b as CloudCache, d as CloudClient, F as FallbackCloudClient, R as RetryableCloudClient, T as TelemetryReporter, c as createCompleteCloudClient, g as getTelemetry, i as initializeTelemetry, r as retryUtils, s as stopTelemetry, t as telemetryUtils, e as trackEvent, w as withRetry } from './shared/ccjk.OJKHVSOb.mjs';
|
|
4
|
-
import { T as ToolRegistry } from './shared/ccjk.lG3ccFjm.mjs';
|
|
5
|
-
export { A as AiderTool, B as BaseCodeTool, C as ClaudeCodeTool, b as ClavueTool, c as ClineTool, d as CodexTool, e as ContinueTool, f as CursorTool, a as getRegistry, g as getRuntimeCapabilityDescriptor } from './shared/ccjk.lG3ccFjm.mjs';
|
|
6
|
-
import { CLOUD_ENDPOINTS } from './chunks/constants.mjs';
|
|
7
|
-
export { a as CloudError, b as CloudErrorCode, C as CloudErrorFactory, f as formatErrorForLogging, g as getRetryDelay, h as handleCloudError, i as isAuthError, c as isRateLimitError, d as isRetryableError, e as isRetryableErrorCode } from './shared/ccjk.DMV3x5Sd.mjs';
|
|
8
|
-
import { e as extractString } from './shared/ccjk.C2jHOZVP.mjs';
|
|
9
|
-
export { a as extractDisplayName, i as i18nHelpers, n as normalizeRecommendation, b as normalizeRecommendations } from './shared/ccjk.C2jHOZVP.mjs';
|
|
10
|
-
import a from './chunks/index5.mjs';
|
|
11
|
-
import { g as getRuntimeVersion } from './shared/ccjk.gDEDGD_t.mjs';
|
|
12
|
-
import { execSync } from 'node:child_process';
|
|
13
|
-
import { existsSync, readdirSync, readFileSync, statSync, promises, createReadStream } from 'node:fs';
|
|
14
|
-
import * as os from 'node:os';
|
|
15
|
-
import { homedir } from 'node:os';
|
|
16
|
-
import { j as join$1 } from './shared/ccjk.bQ7Dh1g4.mjs';
|
|
17
|
-
import { b as buildCommand, c as commandExists, a as escapeArgument, e as executeCommand, d as executeCommandParallel, f as executeCommandSequence, g as executeCommandStream, h as getCommandPath, i as getCommandVersion, p as parseVersion } from './shared/ccjk.BnsY5WxD.mjs';
|
|
18
|
-
export { k as config } from './chunks/config.mjs';
|
|
19
|
-
import * as path from 'node:path';
|
|
20
|
-
export { a as loggerUtils } from './shared/ccjk.8oaxX4iR.mjs';
|
|
21
|
-
export { p as platform } from './chunks/platform.mjs';
|
|
22
|
-
import { Transform } from 'node:stream';
|
|
23
|
-
import { pipeline } from 'node:stream/promises';
|
|
24
|
-
import './chunks/index10.mjs';
|
|
25
|
-
import 'tinyglobby';
|
|
26
|
-
import './shared/ccjk.BBtCGd_g.mjs';
|
|
27
|
-
import 'node:crypto';
|
|
28
|
-
import 'node:url';
|
|
29
|
-
import 'node:util';
|
|
30
|
-
import './chunks/index2.mjs';
|
|
31
|
-
import 'node:process';
|
|
32
|
-
import './shared/ccjk.BAGoDD49.mjs';
|
|
33
|
-
import './shared/ccjk.RyizuzOI.mjs';
|
|
34
|
-
import './chunks/index6.mjs';
|
|
35
|
-
import 'node:readline';
|
|
36
|
-
import 'stream';
|
|
37
|
-
import 'node:tty';
|
|
38
|
-
import 'node:async_hooks';
|
|
39
|
-
import './shared/ccjk.Cjgrln_h.mjs';
|
|
40
|
-
import 'tty';
|
|
41
|
-
import 'fs';
|
|
42
|
-
import 'child_process';
|
|
43
|
-
import 'buffer';
|
|
44
|
-
import 'string_decoder';
|
|
45
|
-
import './chunks/claude-config.mjs';
|
|
46
|
-
import './shared/ccjk.DDL-4C-k.mjs';
|
|
47
|
-
import './chunks/ccjk-config.mjs';
|
|
48
|
-
import './chunks/index3.mjs';
|
|
49
|
-
import './chunks/fs-operations.mjs';
|
|
50
|
-
import 'node:fs/promises';
|
|
51
|
-
import './chunks/json-config.mjs';
|
|
52
|
-
import './chunks/main.mjs';
|
|
53
|
-
import 'module';
|
|
54
|
-
|
|
55
|
-
async function getCloudRecommendations(analysis) {
|
|
56
|
-
try {
|
|
57
|
-
const client = createCloudClient();
|
|
58
|
-
const response = await client.analyzeProject({
|
|
59
|
-
projectRoot: analysis.rootPath || process.cwd(),
|
|
60
|
-
dependencies: analysis.dependencies?.direct.reduce((acc, d) => {
|
|
61
|
-
acc[d.name] = d.version || "*";
|
|
62
|
-
return acc;
|
|
63
|
-
}, {})
|
|
64
|
-
});
|
|
65
|
-
return (response.recommendations || []).map((rec) => {
|
|
66
|
-
const config = rec.config;
|
|
67
|
-
return {
|
|
68
|
-
name: extractString(rec.name, rec.id || "Unknown Agent"),
|
|
69
|
-
description: extractString(rec.description, "No description available"),
|
|
70
|
-
skills: config?.skills || [],
|
|
71
|
-
mcpServers: config?.mcpServers || [],
|
|
72
|
-
persona: config?.persona,
|
|
73
|
-
capabilities: config?.capabilities || [],
|
|
74
|
-
confidence: rec.relevanceScore || 0.8,
|
|
75
|
-
reason: "Recommended by CCJK Cloud"
|
|
76
|
-
};
|
|
77
|
-
});
|
|
78
|
-
} catch (error) {
|
|
79
|
-
console.warn("Failed to get cloud recommendations:", error);
|
|
80
|
-
return [];
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
async function getCloudSkillRecommendations(analysis) {
|
|
84
|
-
try {
|
|
85
|
-
const client = createCloudClient();
|
|
86
|
-
const _response = await client.analyzeProject({
|
|
87
|
-
projectRoot: analysis.rootPath || process.cwd(),
|
|
88
|
-
dependencies: analysis.dependencies?.direct.reduce((acc, d) => {
|
|
89
|
-
acc[d.name] = d.version || "*";
|
|
90
|
-
return acc;
|
|
91
|
-
}, {})
|
|
92
|
-
});
|
|
93
|
-
return [];
|
|
94
|
-
} catch (error) {
|
|
95
|
-
console.warn("Failed to get cloud skill recommendations:", error);
|
|
96
|
-
return [];
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
async function getCloudMcpRecommendations(analysis) {
|
|
100
|
-
try {
|
|
101
|
-
const client = createCloudClient();
|
|
102
|
-
const _response = await client.analyzeProject({
|
|
103
|
-
projectRoot: analysis.rootPath || process.cwd(),
|
|
104
|
-
dependencies: analysis.dependencies?.direct.reduce((acc, d) => {
|
|
105
|
-
acc[d.name] = d.version || "*";
|
|
106
|
-
return acc;
|
|
107
|
-
}, {})
|
|
108
|
-
});
|
|
109
|
-
return [];
|
|
110
|
-
} catch (error) {
|
|
111
|
-
console.warn("Failed to get cloud MCP recommendations:", error);
|
|
112
|
-
return [];
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function convertConfig(config) {
|
|
117
|
-
if (!config || typeof config !== "object")
|
|
118
|
-
return void 0;
|
|
119
|
-
const obj = config;
|
|
120
|
-
if ("command" in obj || "npmPackage" in obj) {
|
|
121
|
-
return {
|
|
122
|
-
type: typeof obj.type === "string" ? obj.type : void 0,
|
|
123
|
-
command: typeof obj.command === "string" ? obj.command : void 0,
|
|
124
|
-
args: Array.isArray(obj.args) ? obj.args.filter((a) => typeof a === "string") : void 0,
|
|
125
|
-
env: typeof obj.env === "object" && obj.env ? obj.env : void 0,
|
|
126
|
-
npmPackage: typeof obj.npmPackage === "string" ? obj.npmPackage : void 0,
|
|
127
|
-
installCommand: typeof obj.installCommand === "string" ? obj.installCommand : void 0
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
if ("enabled" in obj || "triggers" in obj) {
|
|
131
|
-
return {
|
|
132
|
-
enabled: typeof obj.enabled === "boolean" ? obj.enabled : void 0,
|
|
133
|
-
priority: typeof obj.priority === "number" ? obj.priority : void 0,
|
|
134
|
-
triggers: Array.isArray(obj.triggers) ? obj.triggers.filter((t) => typeof t === "string") : void 0,
|
|
135
|
-
parameters: typeof obj.parameters === "object" && obj.parameters ? obj.parameters : void 0
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
if ("persona" in obj || "capabilities" in obj) {
|
|
139
|
-
return {
|
|
140
|
-
persona: typeof obj.persona === "string" ? obj.persona : void 0,
|
|
141
|
-
capabilities: Array.isArray(obj.capabilities) ? obj.capabilities.filter((c) => typeof c === "string") : void 0,
|
|
142
|
-
skills: Array.isArray(obj.skills) ? obj.skills.filter((s) => typeof s === "string") : void 0,
|
|
143
|
-
mcpServers: Array.isArray(obj.mcpServers) ? obj.mcpServers.filter((m) => typeof m === "string") : void 0,
|
|
144
|
-
temperature: typeof obj.temperature === "number" ? obj.temperature : void 0,
|
|
145
|
-
maxTokens: typeof obj.maxTokens === "number" ? obj.maxTokens : void 0
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
if ("when" in obj) {
|
|
149
|
-
return {
|
|
150
|
-
command: typeof obj.command === "string" ? obj.command : void 0,
|
|
151
|
-
args: Array.isArray(obj.args) ? obj.args.filter((a) => typeof a === "string") : void 0,
|
|
152
|
-
when: typeof obj.when === "string" ? obj.when : void 0,
|
|
153
|
-
enabled: typeof obj.enabled === "boolean" ? obj.enabled : void 0
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
if ("steps" in obj) {
|
|
157
|
-
return {
|
|
158
|
-
steps: Array.isArray(obj.steps) ? obj.steps.filter((s) => typeof s === "string") : void 0,
|
|
159
|
-
triggers: Array.isArray(obj.triggers) ? obj.triggers.filter((t) => typeof t === "string") : void 0,
|
|
160
|
-
conditions: typeof obj.conditions === "object" && obj.conditions ? obj.conditions : void 0
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
return void 0;
|
|
164
|
-
}
|
|
165
|
-
function convertParameterDefault(value) {
|
|
166
|
-
if (value === null || value === void 0)
|
|
167
|
-
return null;
|
|
168
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
|
|
169
|
-
return value;
|
|
170
|
-
if (Array.isArray(value)) {
|
|
171
|
-
if (value.every((v) => typeof v === "string"))
|
|
172
|
-
return value;
|
|
173
|
-
if (value.every((v) => typeof v === "number"))
|
|
174
|
-
return value;
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
if (typeof value === "object") {
|
|
178
|
-
const obj = value;
|
|
179
|
-
const converted = {};
|
|
180
|
-
for (const [k, v] of Object.entries(obj)) {
|
|
181
|
-
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean")
|
|
182
|
-
converted[k] = v;
|
|
183
|
-
}
|
|
184
|
-
return converted;
|
|
185
|
-
}
|
|
186
|
-
return null;
|
|
187
|
-
}
|
|
188
|
-
function convertRecommendation(raw, _preferredLang = "en") {
|
|
189
|
-
return {
|
|
190
|
-
id: raw.id,
|
|
191
|
-
name: typeof raw.name === "string" ? { en: raw.name } : raw.name,
|
|
192
|
-
description: typeof raw.description === "string" ? { en: raw.description } : raw.description,
|
|
193
|
-
category: raw.category,
|
|
194
|
-
relevanceScore: raw.relevanceScore,
|
|
195
|
-
installCommand: raw.installCommand,
|
|
196
|
-
config: convertConfig(raw.config),
|
|
197
|
-
tags: raw.tags,
|
|
198
|
-
dependencies: raw.dependencies
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
function convertTemplateParameter(raw) {
|
|
202
|
-
return {
|
|
203
|
-
name: raw.name,
|
|
204
|
-
type: raw.type,
|
|
205
|
-
required: raw.required,
|
|
206
|
-
default: convertParameterDefault(raw.default),
|
|
207
|
-
description: typeof raw.description === "string" ? { en: raw.description } : raw.description
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
function convertTemplate(raw, _preferredLang = "en") {
|
|
211
|
-
return {
|
|
212
|
-
id: raw.id,
|
|
213
|
-
type: raw.type,
|
|
214
|
-
name: typeof raw.name === "string" ? { en: raw.name } : raw.name,
|
|
215
|
-
description: typeof raw.description === "string" ? { en: raw.description } : raw.description,
|
|
216
|
-
content: raw.content,
|
|
217
|
-
version: raw.version,
|
|
218
|
-
author: raw.author,
|
|
219
|
-
tags: raw.tags,
|
|
220
|
-
parameters: raw.parameters ? raw.parameters.map(convertTemplateParameter) : void 0,
|
|
221
|
-
createdAt: raw.createdAt,
|
|
222
|
-
updatedAt: raw.updatedAt
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
function convertProjectAnalysisResponse(raw, preferredLang = "en") {
|
|
226
|
-
return {
|
|
227
|
-
requestId: raw.requestId,
|
|
228
|
-
recommendations: raw.recommendations.map((r) => convertRecommendation(r, preferredLang)),
|
|
229
|
-
projectType: raw.projectType,
|
|
230
|
-
frameworks: raw.frameworks
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
function convertBatchTemplateResponse(raw, preferredLang = "en") {
|
|
234
|
-
const templates = {};
|
|
235
|
-
for (const [id, template] of Object.entries(raw.templates)) {
|
|
236
|
-
templates[id] = convertTemplate(template, preferredLang);
|
|
237
|
-
}
|
|
238
|
-
return {
|
|
239
|
-
requestId: raw.requestId,
|
|
240
|
-
templates,
|
|
241
|
-
notFound: raw.notFound
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
function validateProjectAnalysisRequest(request) {
|
|
245
|
-
const errors = [];
|
|
246
|
-
if (!request.projectRoot || typeof request.projectRoot !== "string")
|
|
247
|
-
errors.push("projectRoot is required and must be a string");
|
|
248
|
-
if (request.dependencies && typeof request.dependencies !== "object")
|
|
249
|
-
errors.push("dependencies must be an object");
|
|
250
|
-
if (request.devDependencies && typeof request.devDependencies !== "object")
|
|
251
|
-
errors.push("devDependencies must be an object");
|
|
252
|
-
if (request.language && !["en", "zh-CN"].includes(request.language))
|
|
253
|
-
errors.push('language must be "en" or "zh-CN"');
|
|
254
|
-
return {
|
|
255
|
-
valid: errors.length === 0,
|
|
256
|
-
errors
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
function validateBatchTemplateRequest(request) {
|
|
260
|
-
const errors = [];
|
|
261
|
-
if (!Array.isArray(request.ids))
|
|
262
|
-
errors.push("ids must be an array");
|
|
263
|
-
else if (request.ids.length === 0)
|
|
264
|
-
errors.push("ids array cannot be empty");
|
|
265
|
-
else if (!request.ids.every((id) => typeof id === "string"))
|
|
266
|
-
errors.push("all ids must be strings");
|
|
267
|
-
if (request.language && !["en", "zh-CN"].includes(request.language))
|
|
268
|
-
errors.push('language must be "en" or "zh-CN"');
|
|
269
|
-
return {
|
|
270
|
-
valid: errors.length === 0,
|
|
271
|
-
errors
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
function validateUsageReport(report) {
|
|
275
|
-
const errors = [];
|
|
276
|
-
if (!report.reportId || typeof report.reportId !== "string")
|
|
277
|
-
errors.push("reportId is required and must be a string");
|
|
278
|
-
if (!report.metricType || typeof report.metricType !== "string")
|
|
279
|
-
errors.push("metricType is required and must be a string");
|
|
280
|
-
if (!report.timestamp || typeof report.timestamp !== "string")
|
|
281
|
-
errors.push("timestamp is required and must be a string");
|
|
282
|
-
if (!report.ccjkVersion || typeof report.ccjkVersion !== "string")
|
|
283
|
-
errors.push("ccjkVersion is required and must be a string");
|
|
284
|
-
if (!report.nodeVersion || typeof report.nodeVersion !== "string")
|
|
285
|
-
errors.push("nodeVersion is required and must be a string");
|
|
286
|
-
if (!report.platform || typeof report.platform !== "string")
|
|
287
|
-
errors.push("platform is required and must be a string");
|
|
288
|
-
if (report.deviceId !== void 0 && typeof report.deviceId !== "string")
|
|
289
|
-
errors.push("deviceId must be a string when provided");
|
|
290
|
-
if (report.clientVersion !== void 0 && typeof report.clientVersion !== "string")
|
|
291
|
-
errors.push("clientVersion must be a string when provided");
|
|
292
|
-
return {
|
|
293
|
-
valid: errors.length === 0,
|
|
294
|
-
errors
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
function isRecommendationConfig(value) {
|
|
298
|
-
return convertConfig(value) !== void 0;
|
|
299
|
-
}
|
|
300
|
-
function isTelemetryEventData(value) {
|
|
301
|
-
if (!value || typeof value !== "object")
|
|
302
|
-
return false;
|
|
303
|
-
const obj = value;
|
|
304
|
-
if (typeof obj.timestamp !== "number" && typeof obj.timestamp !== "string")
|
|
305
|
-
return false;
|
|
306
|
-
return true;
|
|
307
|
-
}
|
|
308
|
-
function isTemplateParameterValue(value) {
|
|
309
|
-
if (value === null || value === void 0)
|
|
310
|
-
return value === null;
|
|
311
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
|
|
312
|
-
return true;
|
|
313
|
-
if (Array.isArray(value)) {
|
|
314
|
-
if (value.length === 0)
|
|
315
|
-
return true;
|
|
316
|
-
const allStrings = value.every((v) => typeof v === "string");
|
|
317
|
-
const allNumbers = value.every((v) => typeof v === "number");
|
|
318
|
-
return allStrings || allNumbers;
|
|
319
|
-
}
|
|
320
|
-
if (typeof value === "object") {
|
|
321
|
-
return Object.values(value).every(
|
|
322
|
-
(v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean"
|
|
323
|
-
);
|
|
324
|
-
}
|
|
325
|
-
return false;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
const API_BASE_URL$2 = `${CLOUD_ENDPOINTS.MAIN.BASE_URL}${CLOUD_ENDPOINTS.MAIN.API_VERSION}`;
|
|
329
|
-
var RatingsApiErrorCode = /* @__PURE__ */ ((RatingsApiErrorCode2) => {
|
|
330
|
-
RatingsApiErrorCode2["DUPLICATE_RATING"] = "DUPLICATE_RATING";
|
|
331
|
-
RatingsApiErrorCode2["INVALID_RATING_VALUE"] = "INVALID_RATING_VALUE";
|
|
332
|
-
RatingsApiErrorCode2["SKILL_NOT_FOUND"] = "SKILL_NOT_FOUND";
|
|
333
|
-
RatingsApiErrorCode2["UNAUTHORIZED"] = "UNAUTHORIZED";
|
|
334
|
-
RatingsApiErrorCode2["NETWORK_ERROR"] = "NETWORK_ERROR";
|
|
335
|
-
RatingsApiErrorCode2["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
|
|
336
|
-
return RatingsApiErrorCode2;
|
|
337
|
-
})(RatingsApiErrorCode || {});
|
|
338
|
-
class RatingsApiError extends Error {
|
|
339
|
-
constructor(message, code, statusCode, details) {
|
|
340
|
-
super(message);
|
|
341
|
-
this.code = code;
|
|
342
|
-
this.statusCode = statusCode;
|
|
343
|
-
this.details = details;
|
|
344
|
-
this.name = "RatingsApiError";
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
function validateRating(rating) {
|
|
348
|
-
if (!Number.isInteger(rating) || rating < 1 || rating > 5) {
|
|
349
|
-
throw new RatingsApiError(
|
|
350
|
-
`Invalid rating value: ${rating}. Rating must be an integer between 1 and 5.`,
|
|
351
|
-
"INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
function buildQueryString(params) {
|
|
356
|
-
const searchParams = new URLSearchParams();
|
|
357
|
-
for (const [key, value] of Object.entries(params)) {
|
|
358
|
-
if (value !== void 0) {
|
|
359
|
-
searchParams.append(key, String(value));
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
const queryString = searchParams.toString();
|
|
363
|
-
return queryString ? `?${queryString}` : "";
|
|
364
|
-
}
|
|
365
|
-
async function handleResponse(response, context) {
|
|
366
|
-
if (!response.ok) {
|
|
367
|
-
let errorData = {};
|
|
368
|
-
try {
|
|
369
|
-
errorData = await response.json();
|
|
370
|
-
} catch {
|
|
371
|
-
}
|
|
372
|
-
const errorMessage = errorData.message || errorData.error || `${context} failed`;
|
|
373
|
-
const errorCode = mapHttpStatusToErrorCode(response.status, errorData.code);
|
|
374
|
-
throw new RatingsApiError(
|
|
375
|
-
errorMessage,
|
|
376
|
-
errorCode,
|
|
377
|
-
response.status,
|
|
378
|
-
errorData
|
|
379
|
-
);
|
|
380
|
-
}
|
|
381
|
-
try {
|
|
382
|
-
const data = await response.json();
|
|
383
|
-
if (data.success === false) {
|
|
384
|
-
throw new RatingsApiError(
|
|
385
|
-
data.error || `${context} failed`,
|
|
386
|
-
"UNKNOWN_ERROR" /* UNKNOWN_ERROR */,
|
|
387
|
-
response.status
|
|
388
|
-
);
|
|
389
|
-
}
|
|
390
|
-
return data.data;
|
|
391
|
-
} catch (error) {
|
|
392
|
-
if (error instanceof RatingsApiError) {
|
|
393
|
-
throw error;
|
|
394
|
-
}
|
|
395
|
-
throw new RatingsApiError(
|
|
396
|
-
`Failed to parse response for ${context}`,
|
|
397
|
-
"UNKNOWN_ERROR" /* UNKNOWN_ERROR */,
|
|
398
|
-
response.status
|
|
399
|
-
);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
function mapHttpStatusToErrorCode(status, serverCode) {
|
|
403
|
-
if (serverCode === "DUPLICATE_RATING") {
|
|
404
|
-
return "DUPLICATE_RATING" /* DUPLICATE_RATING */;
|
|
405
|
-
}
|
|
406
|
-
switch (status) {
|
|
407
|
-
case 401:
|
|
408
|
-
return "UNAUTHORIZED" /* UNAUTHORIZED */;
|
|
409
|
-
case 404:
|
|
410
|
-
return "SKILL_NOT_FOUND" /* SKILL_NOT_FOUND */;
|
|
411
|
-
case 409:
|
|
412
|
-
return "DUPLICATE_RATING" /* DUPLICATE_RATING */;
|
|
413
|
-
case 422:
|
|
414
|
-
return "INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */;
|
|
415
|
-
default:
|
|
416
|
-
return "UNKNOWN_ERROR" /* UNKNOWN_ERROR */;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
async function getSkillRatings(skillId, params = {}) {
|
|
420
|
-
if (!skillId || typeof skillId !== "string") {
|
|
421
|
-
throw new RatingsApiError(
|
|
422
|
-
"Skill ID is required and must be a string",
|
|
423
|
-
"INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */
|
|
424
|
-
);
|
|
425
|
-
}
|
|
426
|
-
const queryString = buildQueryString({
|
|
427
|
-
page: params.page,
|
|
428
|
-
limit: params.limit,
|
|
429
|
-
sort: params.sort
|
|
430
|
-
});
|
|
431
|
-
const url = `${API_BASE_URL$2}/skills/${encodeURIComponent(skillId)}/ratings${queryString}`;
|
|
432
|
-
try {
|
|
433
|
-
const response = await fetch(url, {
|
|
434
|
-
method: "GET",
|
|
435
|
-
headers: {
|
|
436
|
-
"Content-Type": "application/json",
|
|
437
|
-
"Accept": "application/json"
|
|
438
|
-
}
|
|
439
|
-
});
|
|
440
|
-
return await handleResponse(response, "Get skill ratings");
|
|
441
|
-
} catch (error) {
|
|
442
|
-
if (error instanceof RatingsApiError) {
|
|
443
|
-
throw error;
|
|
444
|
-
}
|
|
445
|
-
throw new RatingsApiError(
|
|
446
|
-
`Network error while fetching ratings: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
447
|
-
"NETWORK_ERROR" /* NETWORK_ERROR */
|
|
448
|
-
);
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
async function createRating(skillId, data, token) {
|
|
452
|
-
if (!skillId || typeof skillId !== "string") {
|
|
453
|
-
throw new RatingsApiError(
|
|
454
|
-
"Skill ID is required and must be a string",
|
|
455
|
-
"INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */
|
|
456
|
-
);
|
|
457
|
-
}
|
|
458
|
-
if (!token || typeof token !== "string") {
|
|
459
|
-
throw new RatingsApiError(
|
|
460
|
-
"Authentication token is required",
|
|
461
|
-
"UNAUTHORIZED" /* UNAUTHORIZED */
|
|
462
|
-
);
|
|
463
|
-
}
|
|
464
|
-
if (!data.userId || typeof data.userId !== "string") {
|
|
465
|
-
throw new RatingsApiError(
|
|
466
|
-
"User ID is required and must be a string",
|
|
467
|
-
"INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */
|
|
468
|
-
);
|
|
469
|
-
}
|
|
470
|
-
validateRating(data.rating);
|
|
471
|
-
const url = `${API_BASE_URL$2}/skills/${encodeURIComponent(skillId)}/ratings`;
|
|
472
|
-
const requestBody = {
|
|
473
|
-
userId: data.userId,
|
|
474
|
-
rating: data.rating,
|
|
475
|
-
...data.review !== void 0 && { review: data.review }
|
|
476
|
-
};
|
|
477
|
-
try {
|
|
478
|
-
const response = await fetch(url, {
|
|
479
|
-
method: "POST",
|
|
480
|
-
headers: {
|
|
481
|
-
"Content-Type": "application/json",
|
|
482
|
-
"Accept": "application/json",
|
|
483
|
-
"Authorization": `Bearer ${token}`
|
|
484
|
-
},
|
|
485
|
-
body: JSON.stringify(requestBody)
|
|
486
|
-
});
|
|
487
|
-
return await handleResponse(response, "Create rating");
|
|
488
|
-
} catch (error) {
|
|
489
|
-
if (error instanceof RatingsApiError) {
|
|
490
|
-
throw error;
|
|
491
|
-
}
|
|
492
|
-
throw new RatingsApiError(
|
|
493
|
-
`Network error while creating rating: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
494
|
-
"NETWORK_ERROR" /* NETWORK_ERROR */
|
|
495
|
-
);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
function isDuplicateRatingError(error) {
|
|
499
|
-
return error instanceof RatingsApiError && error.code === "DUPLICATE_RATING" /* DUPLICATE_RATING */;
|
|
500
|
-
}
|
|
501
|
-
function isUnauthorizedError(error) {
|
|
502
|
-
return error instanceof RatingsApiError && error.code === "UNAUTHORIZED" /* UNAUTHORIZED */;
|
|
503
|
-
}
|
|
504
|
-
function isSkillNotFoundError(error) {
|
|
505
|
-
return error instanceof RatingsApiError && error.code === "SKILL_NOT_FOUND" /* SKILL_NOT_FOUND */;
|
|
506
|
-
}
|
|
507
|
-
const ratingsApi = {
|
|
508
|
-
getSkillRatings,
|
|
509
|
-
createRating,
|
|
510
|
-
isDuplicateRatingError,
|
|
511
|
-
isUnauthorizedError,
|
|
512
|
-
isSkillNotFoundError
|
|
513
|
-
};
|
|
514
|
-
|
|
515
|
-
const API_BASE_URL$1 = `${CLOUD_ENDPOINTS.MAIN.BASE_URL}${CLOUD_ENDPOINTS.MAIN.API_VERSION}`;
|
|
516
|
-
const DEFAULT_CACHE_TTL = 5 * 60 * 1e3;
|
|
517
|
-
class SkillsMarketplaceApiError extends Error {
|
|
518
|
-
/** HTTP status code */
|
|
519
|
-
status;
|
|
520
|
-
/** Error code from API response */
|
|
521
|
-
code;
|
|
522
|
-
/** Original response data */
|
|
523
|
-
data;
|
|
524
|
-
constructor(message, status, code, data) {
|
|
525
|
-
super(message);
|
|
526
|
-
this.name = "SkillsMarketplaceApiError";
|
|
527
|
-
this.status = status;
|
|
528
|
-
this.code = code;
|
|
529
|
-
this.data = data;
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
class ResponseCache {
|
|
533
|
-
cache = /* @__PURE__ */ new Map();
|
|
534
|
-
/**
|
|
535
|
-
* Get cached data if valid
|
|
536
|
-
* @param key - Cache key
|
|
537
|
-
* @returns Cached data or undefined if not found/expired
|
|
538
|
-
*/
|
|
539
|
-
get(key) {
|
|
540
|
-
const entry = this.cache.get(key);
|
|
541
|
-
if (!entry) {
|
|
542
|
-
return void 0;
|
|
543
|
-
}
|
|
544
|
-
const now = Date.now();
|
|
545
|
-
if (now - entry.timestamp > entry.ttl) {
|
|
546
|
-
this.cache.delete(key);
|
|
547
|
-
return void 0;
|
|
548
|
-
}
|
|
549
|
-
return entry.data;
|
|
550
|
-
}
|
|
551
|
-
/**
|
|
552
|
-
* Set cache entry
|
|
553
|
-
* @param key - Cache key
|
|
554
|
-
* @param data - Data to cache
|
|
555
|
-
* @param ttl - Time to live in milliseconds
|
|
556
|
-
*/
|
|
557
|
-
set(key, data, ttl) {
|
|
558
|
-
this.cache.set(key, {
|
|
559
|
-
data,
|
|
560
|
-
timestamp: Date.now(),
|
|
561
|
-
ttl
|
|
562
|
-
});
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* Clear all cache entries
|
|
566
|
-
*/
|
|
567
|
-
clear() {
|
|
568
|
-
this.cache.clear();
|
|
569
|
-
}
|
|
570
|
-
/**
|
|
571
|
-
* Delete a specific cache entry
|
|
572
|
-
* @param key - Cache key to delete
|
|
573
|
-
*/
|
|
574
|
-
delete(key) {
|
|
575
|
-
this.cache.delete(key);
|
|
576
|
-
}
|
|
577
|
-
/**
|
|
578
|
-
* Get cache size
|
|
579
|
-
* @returns Number of cached entries
|
|
580
|
-
*/
|
|
581
|
-
get size() {
|
|
582
|
-
return this.cache.size;
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
const responseCache = new ResponseCache();
|
|
586
|
-
function generateCacheKey(endpoint, params) {
|
|
587
|
-
const sortedParams = params ? Object.keys(params).sort().reduce(
|
|
588
|
-
(acc, key) => {
|
|
589
|
-
if (params[key] !== void 0 && params[key] !== null) {
|
|
590
|
-
acc[key] = params[key];
|
|
591
|
-
}
|
|
592
|
-
return acc;
|
|
593
|
-
},
|
|
594
|
-
{}
|
|
595
|
-
) : {};
|
|
596
|
-
return `${endpoint}:${JSON.stringify(sortedParams)}`;
|
|
597
|
-
}
|
|
598
|
-
function buildUrl$1(endpoint, params) {
|
|
599
|
-
const url = new URL(`${API_BASE_URL$1}${endpoint}`);
|
|
600
|
-
if (params) {
|
|
601
|
-
Object.entries(params).forEach(([key, value]) => {
|
|
602
|
-
if (value !== void 0 && value !== null) {
|
|
603
|
-
url.searchParams.append(key, String(value));
|
|
604
|
-
}
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
return url.toString();
|
|
608
|
-
}
|
|
609
|
-
async function fetchApi(endpoint, params, options = {}) {
|
|
610
|
-
const { signal, cacheTtl = DEFAULT_CACHE_TTL, forceRefresh = false } = options;
|
|
611
|
-
if (cacheTtl > 0 && !forceRefresh) {
|
|
612
|
-
const cacheKey = generateCacheKey(endpoint, params);
|
|
613
|
-
const cached = responseCache.get(cacheKey);
|
|
614
|
-
if (cached !== void 0) {
|
|
615
|
-
return cached;
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
const url = buildUrl$1(endpoint, params);
|
|
619
|
-
try {
|
|
620
|
-
const response = await fetch(url, {
|
|
621
|
-
method: "GET",
|
|
622
|
-
headers: {
|
|
623
|
-
"Accept": "application/json",
|
|
624
|
-
"Content-Type": "application/json"
|
|
625
|
-
},
|
|
626
|
-
signal
|
|
627
|
-
});
|
|
628
|
-
if (!response.ok) {
|
|
629
|
-
let errorData;
|
|
630
|
-
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
631
|
-
let errorCode;
|
|
632
|
-
try {
|
|
633
|
-
errorData = await response.json();
|
|
634
|
-
if (typeof errorData === "object" && errorData !== null) {
|
|
635
|
-
const err = errorData;
|
|
636
|
-
if (typeof err.message === "string") {
|
|
637
|
-
errorMessage = err.message;
|
|
638
|
-
}
|
|
639
|
-
if (typeof err.code === "string") {
|
|
640
|
-
errorCode = err.code;
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
} catch {
|
|
644
|
-
}
|
|
645
|
-
throw new SkillsMarketplaceApiError(errorMessage, response.status, errorCode, errorData);
|
|
646
|
-
}
|
|
647
|
-
const data = await response.json();
|
|
648
|
-
if (cacheTtl > 0) {
|
|
649
|
-
const cacheKey = generateCacheKey(endpoint, params);
|
|
650
|
-
responseCache.set(cacheKey, data, cacheTtl);
|
|
651
|
-
}
|
|
652
|
-
return data;
|
|
653
|
-
} catch (error) {
|
|
654
|
-
if (error instanceof SkillsMarketplaceApiError) {
|
|
655
|
-
throw error;
|
|
656
|
-
}
|
|
657
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
658
|
-
throw new SkillsMarketplaceApiError("Request was cancelled", 0, "ABORT_ERROR");
|
|
659
|
-
}
|
|
660
|
-
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
661
|
-
throw new SkillsMarketplaceApiError(
|
|
662
|
-
"Network error: Unable to connect to the API",
|
|
663
|
-
0,
|
|
664
|
-
"NETWORK_ERROR"
|
|
665
|
-
);
|
|
666
|
-
}
|
|
667
|
-
throw new SkillsMarketplaceApiError(
|
|
668
|
-
error instanceof Error ? error.message : "Unknown error occurred",
|
|
669
|
-
0,
|
|
670
|
-
"UNKNOWN_ERROR"
|
|
671
|
-
);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
async function getMarketplace(params = {}, options = {}) {
|
|
675
|
-
return fetchApi("/skills/marketplace", params, options);
|
|
676
|
-
}
|
|
677
|
-
async function searchSkills(params, options = {}) {
|
|
678
|
-
if (!params.q || params.q.trim() === "") {
|
|
679
|
-
throw new SkillsMarketplaceApiError(
|
|
680
|
-
"Search query (q) is required",
|
|
681
|
-
400,
|
|
682
|
-
"INVALID_PARAMS"
|
|
683
|
-
);
|
|
684
|
-
}
|
|
685
|
-
return fetchApi("/skills/search", params, options);
|
|
686
|
-
}
|
|
687
|
-
async function getSearchSuggestions(params, options = {}) {
|
|
688
|
-
if (!params.q || params.q.trim() === "") {
|
|
689
|
-
throw new SkillsMarketplaceApiError(
|
|
690
|
-
"Search query (q) is required",
|
|
691
|
-
400,
|
|
692
|
-
"INVALID_PARAMS"
|
|
693
|
-
);
|
|
694
|
-
}
|
|
695
|
-
const suggestionOptions = {
|
|
696
|
-
...options,
|
|
697
|
-
cacheTtl: options.cacheTtl ?? 60 * 1e3
|
|
698
|
-
};
|
|
699
|
-
return fetchApi(
|
|
700
|
-
"/skills/search/suggestions",
|
|
701
|
-
params,
|
|
702
|
-
suggestionOptions
|
|
703
|
-
);
|
|
704
|
-
}
|
|
705
|
-
async function getTrendingKeywords(params = {}, options = {}) {
|
|
706
|
-
const trendingOptions = {
|
|
707
|
-
...options,
|
|
708
|
-
cacheTtl: options.cacheTtl ?? 10 * 60 * 1e3
|
|
709
|
-
};
|
|
710
|
-
return fetchApi(
|
|
711
|
-
"/skills/search/trending",
|
|
712
|
-
params,
|
|
713
|
-
trendingOptions
|
|
714
|
-
);
|
|
715
|
-
}
|
|
716
|
-
function clearCache() {
|
|
717
|
-
responseCache.clear();
|
|
718
|
-
}
|
|
719
|
-
function getCacheSize() {
|
|
720
|
-
return responseCache.size;
|
|
721
|
-
}
|
|
722
|
-
function createAbortController() {
|
|
723
|
-
return new AbortController();
|
|
724
|
-
}
|
|
725
|
-
const skillsMarketplaceApi = {
|
|
726
|
-
getMarketplace,
|
|
727
|
-
searchSkills,
|
|
728
|
-
getSearchSuggestions,
|
|
729
|
-
getTrendingKeywords,
|
|
730
|
-
clearCache,
|
|
731
|
-
getCacheSize,
|
|
732
|
-
createAbortController
|
|
733
|
-
};
|
|
734
|
-
|
|
735
|
-
const API_BASE_URL = `${CLOUD_ENDPOINTS.MAIN.BASE_URL}${CLOUD_ENDPOINTS.MAIN.API_VERSION}`;
|
|
736
|
-
function buildUrl(endpoint, params) {
|
|
737
|
-
const url = new URL(`${API_BASE_URL}${endpoint}`);
|
|
738
|
-
if (params) {
|
|
739
|
-
Object.entries(params).forEach(([key, value]) => {
|
|
740
|
-
if (value !== void 0 && value !== null) {
|
|
741
|
-
url.searchParams.append(key, String(value));
|
|
742
|
-
}
|
|
743
|
-
});
|
|
744
|
-
}
|
|
745
|
-
return url.toString();
|
|
746
|
-
}
|
|
747
|
-
async function authenticatedRequest(method, endpoint, options, body) {
|
|
748
|
-
const { token, signal, timeout = 3e4 } = options;
|
|
749
|
-
const url = buildUrl(endpoint);
|
|
750
|
-
const controller = new AbortController();
|
|
751
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
752
|
-
const requestSignal = signal || controller.signal;
|
|
753
|
-
try {
|
|
754
|
-
const response = await fetch(url, {
|
|
755
|
-
method,
|
|
756
|
-
headers: {
|
|
757
|
-
"Accept": "application/json",
|
|
758
|
-
"Content-Type": "application/json",
|
|
759
|
-
"Authorization": `Bearer ${token}`
|
|
760
|
-
},
|
|
761
|
-
body: body ? JSON.stringify(body) : void 0,
|
|
762
|
-
signal: requestSignal
|
|
763
|
-
});
|
|
764
|
-
clearTimeout(timeoutId);
|
|
765
|
-
if (!response.ok) {
|
|
766
|
-
let errorData;
|
|
767
|
-
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
768
|
-
let errorCode;
|
|
769
|
-
try {
|
|
770
|
-
errorData = await response.json();
|
|
771
|
-
if (typeof errorData === "object" && errorData !== null) {
|
|
772
|
-
const err = errorData;
|
|
773
|
-
if (typeof err.error === "string") {
|
|
774
|
-
errorMessage = err.error;
|
|
775
|
-
}
|
|
776
|
-
if (typeof err.code === "string") {
|
|
777
|
-
errorCode = err.code;
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
} catch {
|
|
781
|
-
}
|
|
782
|
-
throw new SkillsMarketplaceApiError(errorMessage, response.status, errorCode, errorData);
|
|
783
|
-
}
|
|
784
|
-
const apiResponse = await response.json();
|
|
785
|
-
if (!apiResponse.success) {
|
|
786
|
-
throw new SkillsMarketplaceApiError(
|
|
787
|
-
apiResponse.error || "Request failed",
|
|
788
|
-
response.status,
|
|
789
|
-
apiResponse.code
|
|
790
|
-
);
|
|
791
|
-
}
|
|
792
|
-
if (!apiResponse.data) {
|
|
793
|
-
throw new SkillsMarketplaceApiError(
|
|
794
|
-
"No data in response",
|
|
795
|
-
response.status,
|
|
796
|
-
"NO_DATA"
|
|
797
|
-
);
|
|
798
|
-
}
|
|
799
|
-
return apiResponse.data;
|
|
800
|
-
} catch (error) {
|
|
801
|
-
clearTimeout(timeoutId);
|
|
802
|
-
if (error instanceof SkillsMarketplaceApiError) {
|
|
803
|
-
throw error;
|
|
804
|
-
}
|
|
805
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
806
|
-
throw new SkillsMarketplaceApiError("Request was cancelled", 0, "ABORT_ERROR");
|
|
807
|
-
}
|
|
808
|
-
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
809
|
-
throw new SkillsMarketplaceApiError(
|
|
810
|
-
"Network error: Unable to connect to the API",
|
|
811
|
-
0,
|
|
812
|
-
"NETWORK_ERROR"
|
|
813
|
-
);
|
|
814
|
-
}
|
|
815
|
-
throw new SkillsMarketplaceApiError(
|
|
816
|
-
error instanceof Error ? error.message : "Unknown error occurred",
|
|
817
|
-
0,
|
|
818
|
-
"UNKNOWN_ERROR"
|
|
819
|
-
);
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
async function getUserSkills(userId, options) {
|
|
823
|
-
if (!userId || userId.trim() === "") {
|
|
824
|
-
throw new SkillsMarketplaceApiError(
|
|
825
|
-
"User ID is required",
|
|
826
|
-
400,
|
|
827
|
-
"INVALID_PARAMS"
|
|
828
|
-
);
|
|
829
|
-
}
|
|
830
|
-
return authenticatedRequest(
|
|
831
|
-
"GET",
|
|
832
|
-
`/users/${userId}/skills`,
|
|
833
|
-
options
|
|
834
|
-
);
|
|
835
|
-
}
|
|
836
|
-
async function installSkill(userId, request, options) {
|
|
837
|
-
if (!userId || userId.trim() === "") {
|
|
838
|
-
throw new SkillsMarketplaceApiError(
|
|
839
|
-
"User ID is required",
|
|
840
|
-
400,
|
|
841
|
-
"INVALID_PARAMS"
|
|
842
|
-
);
|
|
843
|
-
}
|
|
844
|
-
if (!request.skillId || request.skillId.trim() === "") {
|
|
845
|
-
throw new SkillsMarketplaceApiError(
|
|
846
|
-
"Skill ID is required",
|
|
847
|
-
400,
|
|
848
|
-
"INVALID_PARAMS"
|
|
849
|
-
);
|
|
850
|
-
}
|
|
851
|
-
return authenticatedRequest(
|
|
852
|
-
"POST",
|
|
853
|
-
`/users/${userId}/skills`,
|
|
854
|
-
options,
|
|
855
|
-
request
|
|
856
|
-
);
|
|
857
|
-
}
|
|
858
|
-
async function uninstallSkill(userId, skillId, options) {
|
|
859
|
-
if (!userId || userId.trim() === "") {
|
|
860
|
-
throw new SkillsMarketplaceApiError(
|
|
861
|
-
"User ID is required",
|
|
862
|
-
400,
|
|
863
|
-
"INVALID_PARAMS"
|
|
864
|
-
);
|
|
865
|
-
}
|
|
866
|
-
if (!skillId || skillId.trim() === "") {
|
|
867
|
-
throw new SkillsMarketplaceApiError(
|
|
868
|
-
"Skill ID is required",
|
|
869
|
-
400,
|
|
870
|
-
"INVALID_PARAMS"
|
|
871
|
-
);
|
|
872
|
-
}
|
|
873
|
-
return authenticatedRequest(
|
|
874
|
-
"DELETE",
|
|
875
|
-
`/users/${userId}/skills/${skillId}`,
|
|
876
|
-
options
|
|
877
|
-
);
|
|
878
|
-
}
|
|
879
|
-
async function updateSkill(userId, skillId, request, options) {
|
|
880
|
-
if (!userId || userId.trim() === "") {
|
|
881
|
-
throw new SkillsMarketplaceApiError(
|
|
882
|
-
"User ID is required",
|
|
883
|
-
400,
|
|
884
|
-
"INVALID_PARAMS"
|
|
885
|
-
);
|
|
886
|
-
}
|
|
887
|
-
if (!skillId || skillId.trim() === "") {
|
|
888
|
-
throw new SkillsMarketplaceApiError(
|
|
889
|
-
"Skill ID is required",
|
|
890
|
-
400,
|
|
891
|
-
"INVALID_PARAMS"
|
|
892
|
-
);
|
|
893
|
-
}
|
|
894
|
-
if (!request.isEnabled && !request.config) {
|
|
895
|
-
throw new SkillsMarketplaceApiError(
|
|
896
|
-
"At least one of isEnabled or config must be provided",
|
|
897
|
-
400,
|
|
898
|
-
"INVALID_PARAMS"
|
|
899
|
-
);
|
|
900
|
-
}
|
|
901
|
-
return authenticatedRequest(
|
|
902
|
-
"PATCH",
|
|
903
|
-
`/users/${userId}/skills/${skillId}`,
|
|
904
|
-
options,
|
|
905
|
-
request
|
|
906
|
-
);
|
|
907
|
-
}
|
|
908
|
-
async function getRecommendations(userId, params = {}, options) {
|
|
909
|
-
if (!userId || userId.trim() === "") {
|
|
910
|
-
throw new SkillsMarketplaceApiError(
|
|
911
|
-
"User ID is required",
|
|
912
|
-
400,
|
|
913
|
-
"INVALID_PARAMS"
|
|
914
|
-
);
|
|
915
|
-
}
|
|
916
|
-
const endpoint = `/users/${userId}/recommendations`;
|
|
917
|
-
const url = buildUrl(endpoint, params);
|
|
918
|
-
const { token, signal, timeout = 3e4 } = options;
|
|
919
|
-
const controller = new AbortController();
|
|
920
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
921
|
-
const requestSignal = signal || controller.signal;
|
|
922
|
-
try {
|
|
923
|
-
const response = await fetch(url, {
|
|
924
|
-
method: "GET",
|
|
925
|
-
headers: {
|
|
926
|
-
"Accept": "application/json",
|
|
927
|
-
"Content-Type": "application/json",
|
|
928
|
-
"Authorization": `Bearer ${token}`
|
|
929
|
-
},
|
|
930
|
-
signal: requestSignal
|
|
931
|
-
});
|
|
932
|
-
clearTimeout(timeoutId);
|
|
933
|
-
if (!response.ok) {
|
|
934
|
-
let errorData;
|
|
935
|
-
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
936
|
-
let errorCode;
|
|
937
|
-
try {
|
|
938
|
-
errorData = await response.json();
|
|
939
|
-
if (typeof errorData === "object" && errorData !== null) {
|
|
940
|
-
const err = errorData;
|
|
941
|
-
if (typeof err.error === "string") {
|
|
942
|
-
errorMessage = err.error;
|
|
943
|
-
}
|
|
944
|
-
if (typeof err.code === "string") {
|
|
945
|
-
errorCode = err.code;
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
} catch {
|
|
949
|
-
}
|
|
950
|
-
throw new SkillsMarketplaceApiError(errorMessage, response.status, errorCode, errorData);
|
|
951
|
-
}
|
|
952
|
-
const apiResponse = await response.json();
|
|
953
|
-
if (!apiResponse.success || !apiResponse.data) {
|
|
954
|
-
throw new SkillsMarketplaceApiError(
|
|
955
|
-
apiResponse.error || "Request failed",
|
|
956
|
-
response.status,
|
|
957
|
-
apiResponse.code
|
|
958
|
-
);
|
|
959
|
-
}
|
|
960
|
-
return apiResponse.data;
|
|
961
|
-
} catch (error) {
|
|
962
|
-
clearTimeout(timeoutId);
|
|
963
|
-
if (error instanceof SkillsMarketplaceApiError) {
|
|
964
|
-
throw error;
|
|
965
|
-
}
|
|
966
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
967
|
-
throw new SkillsMarketplaceApiError("Request was cancelled", 0, "ABORT_ERROR");
|
|
968
|
-
}
|
|
969
|
-
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
970
|
-
throw new SkillsMarketplaceApiError(
|
|
971
|
-
"Network error: Unable to connect to the API",
|
|
972
|
-
0,
|
|
973
|
-
"NETWORK_ERROR"
|
|
974
|
-
);
|
|
975
|
-
}
|
|
976
|
-
throw new SkillsMarketplaceApiError(
|
|
977
|
-
error instanceof Error ? error.message : "Unknown error occurred",
|
|
978
|
-
0,
|
|
979
|
-
"UNKNOWN_ERROR"
|
|
980
|
-
);
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
async function getUserQuota(userId, options) {
|
|
984
|
-
if (!userId || userId.trim() === "") {
|
|
985
|
-
throw new SkillsMarketplaceApiError(
|
|
986
|
-
"User ID is required",
|
|
987
|
-
400,
|
|
988
|
-
"INVALID_PARAMS"
|
|
989
|
-
);
|
|
990
|
-
}
|
|
991
|
-
return authenticatedRequest(
|
|
992
|
-
"GET",
|
|
993
|
-
`/users/${userId}/quota`,
|
|
994
|
-
options
|
|
995
|
-
);
|
|
996
|
-
}
|
|
997
|
-
function canInstallMore(quota) {
|
|
998
|
-
return quota.remaining > 0;
|
|
999
|
-
}
|
|
1000
|
-
function getQuotaUsagePercentage(quota) {
|
|
1001
|
-
if (quota.limit === 0) {
|
|
1002
|
-
return 0;
|
|
1003
|
-
}
|
|
1004
|
-
return Math.round(quota.used / quota.limit * 100);
|
|
1005
|
-
}
|
|
1006
|
-
function isSkillInstalled(skills, skillId) {
|
|
1007
|
-
return skills.some((skill) => skill.skillId === skillId);
|
|
1008
|
-
}
|
|
1009
|
-
function getEnabledSkills(skills) {
|
|
1010
|
-
return skills.filter((skill) => skill.isEnabled);
|
|
1011
|
-
}
|
|
1012
|
-
function getDisabledSkills(skills) {
|
|
1013
|
-
return skills.filter((skill) => !skill.isEnabled);
|
|
1014
|
-
}
|
|
1015
|
-
function sortByUsage(skills, order = "desc") {
|
|
1016
|
-
return [...skills].sort((a, b) => {
|
|
1017
|
-
return order === "desc" ? b.usageCount - a.usageCount : a.usageCount - b.usageCount;
|
|
1018
|
-
});
|
|
1019
|
-
}
|
|
1020
|
-
function sortByLastUsed(skills, order = "desc") {
|
|
1021
|
-
return [...skills].sort((a, b) => {
|
|
1022
|
-
const aTime = a.lastUsedAt ? new Date(a.lastUsedAt).getTime() : 0;
|
|
1023
|
-
const bTime = b.lastUsedAt ? new Date(b.lastUsedAt).getTime() : 0;
|
|
1024
|
-
return order === "desc" ? bTime - aTime : aTime - bTime;
|
|
1025
|
-
});
|
|
1026
|
-
}
|
|
1027
|
-
const userSkillsApi = {
|
|
1028
|
-
getUserSkills,
|
|
1029
|
-
installSkill,
|
|
1030
|
-
uninstallSkill,
|
|
1031
|
-
updateSkill,
|
|
1032
|
-
getRecommendations,
|
|
1033
|
-
getUserQuota,
|
|
1034
|
-
// Utility functions
|
|
1035
|
-
canInstallMore,
|
|
1036
|
-
getQuotaUsagePercentage,
|
|
1037
|
-
isSkillInstalled,
|
|
1038
|
-
getEnabledSkills,
|
|
1039
|
-
getDisabledSkills,
|
|
1040
|
-
sortByUsage,
|
|
1041
|
-
sortByLastUsed
|
|
1042
|
-
};
|
|
1043
|
-
|
|
1044
|
-
class ToolFactory {
|
|
1045
|
-
registry;
|
|
1046
|
-
constructor(registry) {
|
|
1047
|
-
this.registry = registry || ToolRegistry.getInstance();
|
|
1048
|
-
}
|
|
1049
|
-
/**
|
|
1050
|
-
* Create a tool instance by name
|
|
1051
|
-
*/
|
|
1052
|
-
createTool(name, config) {
|
|
1053
|
-
const tool = this.registry.getTool(name);
|
|
1054
|
-
if (!tool) {
|
|
1055
|
-
throw new Error(`Tool '${name}' not found in registry. Available tools: ${this.registry.getToolNames().join(", ")}`);
|
|
1056
|
-
}
|
|
1057
|
-
if (config) {
|
|
1058
|
-
tool.configure({ name, ...config }).catch((err) => {
|
|
1059
|
-
console.warn(`Failed to configure tool '${name}':`, err);
|
|
1060
|
-
});
|
|
1061
|
-
}
|
|
1062
|
-
return tool;
|
|
1063
|
-
}
|
|
1064
|
-
/**
|
|
1065
|
-
* Create multiple tool instances
|
|
1066
|
-
*/
|
|
1067
|
-
createTools(names) {
|
|
1068
|
-
return names.map((name) => this.createTool(name));
|
|
1069
|
-
}
|
|
1070
|
-
/**
|
|
1071
|
-
* Create all registered tools
|
|
1072
|
-
*/
|
|
1073
|
-
createAllTools() {
|
|
1074
|
-
const names = this.registry.getToolNames();
|
|
1075
|
-
return this.createTools(names);
|
|
1076
|
-
}
|
|
1077
|
-
/**
|
|
1078
|
-
* Check if a tool can be created
|
|
1079
|
-
*/
|
|
1080
|
-
canCreateTool(name) {
|
|
1081
|
-
return this.registry.hasTool(name);
|
|
1082
|
-
}
|
|
1083
|
-
/**
|
|
1084
|
-
* Get available tool names
|
|
1085
|
-
*/
|
|
1086
|
-
getAvailableTools() {
|
|
1087
|
-
return this.registry.getToolNames();
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
function createTool(name, config) {
|
|
1091
|
-
const factory = new ToolFactory();
|
|
1092
|
-
return factory.createTool(name, config);
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
function unique(arr) {
|
|
1096
|
-
return [...new Set(arr)];
|
|
1097
|
-
}
|
|
1098
|
-
function uniqueBy(arr, key) {
|
|
1099
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1100
|
-
return arr.filter((item) => {
|
|
1101
|
-
const value = typeof key === "function" ? key(item) : item[key];
|
|
1102
|
-
if (seen.has(value)) {
|
|
1103
|
-
return false;
|
|
1104
|
-
}
|
|
1105
|
-
seen.add(value);
|
|
1106
|
-
return true;
|
|
1107
|
-
});
|
|
1108
|
-
}
|
|
1109
|
-
function flatten$1(arr, depth = Infinity) {
|
|
1110
|
-
if (depth === 0)
|
|
1111
|
-
return arr;
|
|
1112
|
-
return arr.reduce((acc, val) => {
|
|
1113
|
-
if (Array.isArray(val)) {
|
|
1114
|
-
acc.push(...flatten$1(val, depth - 1));
|
|
1115
|
-
} else {
|
|
1116
|
-
acc.push(val);
|
|
1117
|
-
}
|
|
1118
|
-
return acc;
|
|
1119
|
-
}, []);
|
|
1120
|
-
}
|
|
1121
|
-
function chunk(arr, size) {
|
|
1122
|
-
const chunks = [];
|
|
1123
|
-
for (let i = 0; i < arr.length; i += size) {
|
|
1124
|
-
chunks.push(arr.slice(i, i + size));
|
|
1125
|
-
}
|
|
1126
|
-
return chunks;
|
|
1127
|
-
}
|
|
1128
|
-
function shuffle(arr) {
|
|
1129
|
-
const result = [...arr];
|
|
1130
|
-
for (let i = result.length - 1; i > 0; i--) {
|
|
1131
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
1132
|
-
[result[i], result[j]] = [result[j], result[i]];
|
|
1133
|
-
}
|
|
1134
|
-
return result;
|
|
1135
|
-
}
|
|
1136
|
-
function sample(arr) {
|
|
1137
|
-
return arr[Math.floor(Math.random() * arr.length)];
|
|
1138
|
-
}
|
|
1139
|
-
function sampleSize(arr, size) {
|
|
1140
|
-
const shuffled = shuffle(arr);
|
|
1141
|
-
return shuffled.slice(0, Math.min(size, arr.length));
|
|
1142
|
-
}
|
|
1143
|
-
function partition(arr, predicate) {
|
|
1144
|
-
const truthy = [];
|
|
1145
|
-
const falsy = [];
|
|
1146
|
-
for (const item of arr) {
|
|
1147
|
-
if (predicate(item)) {
|
|
1148
|
-
truthy.push(item);
|
|
1149
|
-
} else {
|
|
1150
|
-
falsy.push(item);
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
return [truthy, falsy];
|
|
1154
|
-
}
|
|
1155
|
-
function intersection(...arrays) {
|
|
1156
|
-
if (arrays.length === 0)
|
|
1157
|
-
return [];
|
|
1158
|
-
if (arrays.length === 1)
|
|
1159
|
-
return arrays[0];
|
|
1160
|
-
const [first, ...rest] = arrays;
|
|
1161
|
-
return first.filter((item) => rest.every((arr) => arr.includes(item)));
|
|
1162
|
-
}
|
|
1163
|
-
function union(...arrays) {
|
|
1164
|
-
return unique(flatten$1(arrays, 1));
|
|
1165
|
-
}
|
|
1166
|
-
function difference(arr, ...others) {
|
|
1167
|
-
const otherItems = new Set(flatten$1(others, 1));
|
|
1168
|
-
return arr.filter((item) => !otherItems.has(item));
|
|
1169
|
-
}
|
|
1170
|
-
function zip(...arrays) {
|
|
1171
|
-
const maxLength = Math.max(...arrays.map((arr) => arr.length));
|
|
1172
|
-
const result = [];
|
|
1173
|
-
for (let i = 0; i < maxLength; i++) {
|
|
1174
|
-
result.push(arrays.map((arr) => arr[i]));
|
|
1175
|
-
}
|
|
1176
|
-
return result;
|
|
1177
|
-
}
|
|
1178
|
-
function unzip(arr) {
|
|
1179
|
-
return zip(...arr);
|
|
1180
|
-
}
|
|
1181
|
-
function groupConsecutive(arr, predicate) {
|
|
1182
|
-
if (arr.length === 0)
|
|
1183
|
-
return [];
|
|
1184
|
-
const groups = [[arr[0]]];
|
|
1185
|
-
for (let i = 1; i < arr.length; i++) {
|
|
1186
|
-
const lastGroup = groups[groups.length - 1];
|
|
1187
|
-
const lastItem = lastGroup[lastGroup.length - 1];
|
|
1188
|
-
if (predicate(lastItem, arr[i])) {
|
|
1189
|
-
lastGroup.push(arr[i]);
|
|
1190
|
-
} else {
|
|
1191
|
-
groups.push([arr[i]]);
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
return groups;
|
|
1195
|
-
}
|
|
1196
|
-
function take(arr, n) {
|
|
1197
|
-
return arr.slice(0, n);
|
|
1198
|
-
}
|
|
1199
|
-
function takeLast(arr, n) {
|
|
1200
|
-
return arr.slice(-n);
|
|
1201
|
-
}
|
|
1202
|
-
function drop(arr, n) {
|
|
1203
|
-
return arr.slice(n);
|
|
1204
|
-
}
|
|
1205
|
-
function dropLast(arr, n) {
|
|
1206
|
-
return arr.slice(0, -n);
|
|
1207
|
-
}
|
|
1208
|
-
function takeWhile(arr, predicate) {
|
|
1209
|
-
const result = [];
|
|
1210
|
-
for (const item of arr) {
|
|
1211
|
-
if (!predicate(item))
|
|
1212
|
-
break;
|
|
1213
|
-
result.push(item);
|
|
1214
|
-
}
|
|
1215
|
-
return result;
|
|
1216
|
-
}
|
|
1217
|
-
function dropWhile(arr, predicate) {
|
|
1218
|
-
let dropping = true;
|
|
1219
|
-
return arr.filter((item) => {
|
|
1220
|
-
if (dropping && predicate(item)) {
|
|
1221
|
-
return false;
|
|
1222
|
-
}
|
|
1223
|
-
dropping = false;
|
|
1224
|
-
return true;
|
|
1225
|
-
});
|
|
1226
|
-
}
|
|
1227
|
-
function findIndex(arr, predicate) {
|
|
1228
|
-
return arr.findIndex(predicate);
|
|
1229
|
-
}
|
|
1230
|
-
function findLastIndex(arr, predicate) {
|
|
1231
|
-
for (let i = arr.length - 1; i >= 0; i--) {
|
|
1232
|
-
if (predicate(arr[i])) {
|
|
1233
|
-
return i;
|
|
1234
|
-
}
|
|
1235
|
-
}
|
|
1236
|
-
return -1;
|
|
1237
|
-
}
|
|
1238
|
-
function count(arr, item) {
|
|
1239
|
-
return arr.filter((x) => x === item).length;
|
|
1240
|
-
}
|
|
1241
|
-
function countBy(arr, predicate) {
|
|
1242
|
-
return arr.filter(predicate).length;
|
|
1243
|
-
}
|
|
1244
|
-
function sum(arr) {
|
|
1245
|
-
return arr.reduce((acc, val) => acc + val, 0);
|
|
1246
|
-
}
|
|
1247
|
-
function sumBy(arr, selector) {
|
|
1248
|
-
return arr.reduce((acc, item) => {
|
|
1249
|
-
const value = typeof selector === "function" ? selector(item) : item[selector];
|
|
1250
|
-
return acc + (typeof value === "number" ? value : 0);
|
|
1251
|
-
}, 0);
|
|
1252
|
-
}
|
|
1253
|
-
function average(arr) {
|
|
1254
|
-
return arr.length === 0 ? 0 : sum(arr) / arr.length;
|
|
1255
|
-
}
|
|
1256
|
-
function min(arr) {
|
|
1257
|
-
return arr.length === 0 ? void 0 : Math.min(...arr);
|
|
1258
|
-
}
|
|
1259
|
-
function max(arr) {
|
|
1260
|
-
return arr.length === 0 ? void 0 : Math.max(...arr);
|
|
1261
|
-
}
|
|
1262
|
-
function minBy(arr, selector) {
|
|
1263
|
-
if (arr.length === 0)
|
|
1264
|
-
return void 0;
|
|
1265
|
-
return arr.reduce((min2, item) => {
|
|
1266
|
-
const minValue = typeof selector === "function" ? selector(min2) : min2[selector];
|
|
1267
|
-
const itemValue = typeof selector === "function" ? selector(item) : item[selector];
|
|
1268
|
-
return itemValue < minValue ? item : min2;
|
|
1269
|
-
});
|
|
1270
|
-
}
|
|
1271
|
-
function maxBy(arr, selector) {
|
|
1272
|
-
if (arr.length === 0)
|
|
1273
|
-
return void 0;
|
|
1274
|
-
return arr.reduce((max2, item) => {
|
|
1275
|
-
const maxValue = typeof selector === "function" ? selector(max2) : max2[selector];
|
|
1276
|
-
const itemValue = typeof selector === "function" ? selector(item) : item[selector];
|
|
1277
|
-
return itemValue > maxValue ? item : max2;
|
|
1278
|
-
});
|
|
1279
|
-
}
|
|
1280
|
-
function sortBy(arr, selector, order = "asc") {
|
|
1281
|
-
const sorted = [...arr].sort((a, b) => {
|
|
1282
|
-
const aValue = typeof selector === "function" ? selector(a) : a[selector];
|
|
1283
|
-
const bValue = typeof selector === "function" ? selector(b) : b[selector];
|
|
1284
|
-
if (aValue < bValue)
|
|
1285
|
-
return order === "asc" ? -1 : 1;
|
|
1286
|
-
if (aValue > bValue)
|
|
1287
|
-
return order === "asc" ? 1 : -1;
|
|
1288
|
-
return 0;
|
|
1289
|
-
});
|
|
1290
|
-
return sorted;
|
|
1291
|
-
}
|
|
1292
|
-
function isEmpty$1(arr) {
|
|
1293
|
-
return arr.length === 0;
|
|
1294
|
-
}
|
|
1295
|
-
function compact$1(arr) {
|
|
1296
|
-
return arr.filter((item) => !!item);
|
|
1297
|
-
}
|
|
1298
|
-
function range(start, end, step = 1) {
|
|
1299
|
-
if (end === void 0) {
|
|
1300
|
-
end = start;
|
|
1301
|
-
start = 0;
|
|
1302
|
-
}
|
|
1303
|
-
const result = [];
|
|
1304
|
-
for (let i = start; i < end; i += step) {
|
|
1305
|
-
result.push(i);
|
|
1306
|
-
}
|
|
1307
|
-
return result;
|
|
1308
|
-
}
|
|
1309
|
-
function rotate(arr, n) {
|
|
1310
|
-
const len = arr.length;
|
|
1311
|
-
if (len === 0)
|
|
1312
|
-
return arr;
|
|
1313
|
-
n = (n % len + len) % len;
|
|
1314
|
-
return [...arr.slice(n), ...arr.slice(0, n)];
|
|
1315
|
-
}
|
|
1316
|
-
function isEqual$1(arr1, arr2) {
|
|
1317
|
-
if (arr1.length !== arr2.length)
|
|
1318
|
-
return false;
|
|
1319
|
-
return arr1.every((item, index) => item === arr2[index]);
|
|
1320
|
-
}
|
|
1321
|
-
|
|
1322
|
-
const index$6 = {
|
|
1323
|
-
__proto__: null,
|
|
1324
|
-
average: average,
|
|
1325
|
-
chunk: chunk,
|
|
1326
|
-
compact: compact$1,
|
|
1327
|
-
count: count,
|
|
1328
|
-
countBy: countBy,
|
|
1329
|
-
difference: difference,
|
|
1330
|
-
drop: drop,
|
|
1331
|
-
dropLast: dropLast,
|
|
1332
|
-
dropWhile: dropWhile,
|
|
1333
|
-
findIndex: findIndex,
|
|
1334
|
-
findLastIndex: findLastIndex,
|
|
1335
|
-
flatten: flatten$1,
|
|
1336
|
-
groupConsecutive: groupConsecutive,
|
|
1337
|
-
intersection: intersection,
|
|
1338
|
-
isEmpty: isEmpty$1,
|
|
1339
|
-
isEqual: isEqual$1,
|
|
1340
|
-
max: max,
|
|
1341
|
-
maxBy: maxBy,
|
|
1342
|
-
min: min,
|
|
1343
|
-
minBy: minBy,
|
|
1344
|
-
partition: partition,
|
|
1345
|
-
range: range,
|
|
1346
|
-
rotate: rotate,
|
|
1347
|
-
sample: sample,
|
|
1348
|
-
sampleSize: sampleSize,
|
|
1349
|
-
shuffle: shuffle,
|
|
1350
|
-
sortBy: sortBy,
|
|
1351
|
-
sum: sum,
|
|
1352
|
-
sumBy: sumBy,
|
|
1353
|
-
take: take,
|
|
1354
|
-
takeLast: takeLast,
|
|
1355
|
-
takeWhile: takeWhile,
|
|
1356
|
-
union: union,
|
|
1357
|
-
unique: unique,
|
|
1358
|
-
uniqueBy: uniqueBy,
|
|
1359
|
-
unzip: unzip,
|
|
1360
|
-
zip: zip
|
|
1361
|
-
};
|
|
1362
|
-
|
|
1363
|
-
function sleep(ms) {
|
|
1364
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1365
|
-
}
|
|
1366
|
-
async function retry(fn, options = {}) {
|
|
1367
|
-
const {
|
|
1368
|
-
maxAttempts = 3,
|
|
1369
|
-
delay = 1e3,
|
|
1370
|
-
backoff = 2,
|
|
1371
|
-
onRetry
|
|
1372
|
-
} = options;
|
|
1373
|
-
let lastError;
|
|
1374
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1375
|
-
try {
|
|
1376
|
-
return await fn();
|
|
1377
|
-
} catch (error) {
|
|
1378
|
-
lastError = error;
|
|
1379
|
-
if (attempt < maxAttempts) {
|
|
1380
|
-
if (onRetry) {
|
|
1381
|
-
onRetry(lastError, attempt);
|
|
1382
|
-
}
|
|
1383
|
-
const waitTime = delay * backoff ** (attempt - 1);
|
|
1384
|
-
await sleep(waitTime);
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
throw lastError;
|
|
1389
|
-
}
|
|
1390
|
-
async function timeout(promise, ms, errorMessage = "Operation timed out") {
|
|
1391
|
-
let timeoutId;
|
|
1392
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
1393
|
-
timeoutId = setTimeout(() => reject(new Error(errorMessage)), ms);
|
|
1394
|
-
});
|
|
1395
|
-
try {
|
|
1396
|
-
return await Promise.race([promise, timeoutPromise]);
|
|
1397
|
-
} finally {
|
|
1398
|
-
clearTimeout(timeoutId);
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
function debounce(fn, delay) {
|
|
1402
|
-
let timeoutId = null;
|
|
1403
|
-
let pendingPromise = null;
|
|
1404
|
-
return (...args) => {
|
|
1405
|
-
if (timeoutId) {
|
|
1406
|
-
clearTimeout(timeoutId);
|
|
1407
|
-
}
|
|
1408
|
-
if (!pendingPromise) {
|
|
1409
|
-
pendingPromise = new Promise((resolve, reject) => {
|
|
1410
|
-
timeoutId = setTimeout(async () => {
|
|
1411
|
-
try {
|
|
1412
|
-
const result = await fn(...args);
|
|
1413
|
-
resolve(result);
|
|
1414
|
-
} catch (error) {
|
|
1415
|
-
reject(error);
|
|
1416
|
-
} finally {
|
|
1417
|
-
pendingPromise = null;
|
|
1418
|
-
timeoutId = null;
|
|
1419
|
-
}
|
|
1420
|
-
}, delay);
|
|
1421
|
-
});
|
|
1422
|
-
}
|
|
1423
|
-
return pendingPromise;
|
|
1424
|
-
};
|
|
1425
|
-
}
|
|
1426
|
-
function throttle(fn, delay) {
|
|
1427
|
-
let lastCall = 0;
|
|
1428
|
-
let pendingPromise = null;
|
|
1429
|
-
return (...args) => {
|
|
1430
|
-
const now = Date.now();
|
|
1431
|
-
if (now - lastCall >= delay) {
|
|
1432
|
-
lastCall = now;
|
|
1433
|
-
pendingPromise = fn(...args);
|
|
1434
|
-
return pendingPromise;
|
|
1435
|
-
}
|
|
1436
|
-
if (!pendingPromise) {
|
|
1437
|
-
pendingPromise = new Promise((resolve, reject) => {
|
|
1438
|
-
setTimeout(async () => {
|
|
1439
|
-
lastCall = Date.now();
|
|
1440
|
-
try {
|
|
1441
|
-
const result = await fn(...args);
|
|
1442
|
-
resolve(result);
|
|
1443
|
-
} catch (error) {
|
|
1444
|
-
reject(error);
|
|
1445
|
-
} finally {
|
|
1446
|
-
pendingPromise = null;
|
|
1447
|
-
}
|
|
1448
|
-
}, delay - (now - lastCall));
|
|
1449
|
-
});
|
|
1450
|
-
}
|
|
1451
|
-
return pendingPromise;
|
|
1452
|
-
};
|
|
1453
|
-
}
|
|
1454
|
-
async function parallelLimit(tasks, limit) {
|
|
1455
|
-
const results = [];
|
|
1456
|
-
const executing = [];
|
|
1457
|
-
for (const [index, task] of tasks.entries()) {
|
|
1458
|
-
const promise = task().then((result) => {
|
|
1459
|
-
results[index] = result;
|
|
1460
|
-
});
|
|
1461
|
-
executing.push(promise);
|
|
1462
|
-
if (executing.length >= limit) {
|
|
1463
|
-
await Promise.race(executing);
|
|
1464
|
-
executing.splice(
|
|
1465
|
-
executing.findIndex((p) => p === promise),
|
|
1466
|
-
1
|
|
1467
|
-
);
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
|
-
await Promise.all(executing);
|
|
1471
|
-
return results;
|
|
1472
|
-
}
|
|
1473
|
-
async function sequence(tasks) {
|
|
1474
|
-
const results = [];
|
|
1475
|
-
for (const task of tasks) {
|
|
1476
|
-
results.push(await task());
|
|
1477
|
-
}
|
|
1478
|
-
return results;
|
|
1479
|
-
}
|
|
1480
|
-
async function allSettled(promises) {
|
|
1481
|
-
return Promise.allSettled(promises);
|
|
1482
|
-
}
|
|
1483
|
-
async function raceWithTimeout(promises, ms) {
|
|
1484
|
-
return timeout(Promise.race(promises), ms);
|
|
1485
|
-
}
|
|
1486
|
-
function memoize(fn, options = {}) {
|
|
1487
|
-
const cache = /* @__PURE__ */ new Map();
|
|
1488
|
-
const { keyGenerator = (...args) => JSON.stringify(args), ttl } = options;
|
|
1489
|
-
return (async (...args) => {
|
|
1490
|
-
const key = keyGenerator(...args);
|
|
1491
|
-
const cached = cache.get(key);
|
|
1492
|
-
if (cached) {
|
|
1493
|
-
if (!ttl || Date.now() - cached.timestamp < ttl) {
|
|
1494
|
-
return cached.value;
|
|
1495
|
-
}
|
|
1496
|
-
cache.delete(key);
|
|
1497
|
-
}
|
|
1498
|
-
const value = await fn(...args);
|
|
1499
|
-
cache.set(key, { value, timestamp: Date.now() });
|
|
1500
|
-
return value;
|
|
1501
|
-
});
|
|
1502
|
-
}
|
|
1503
|
-
function defer() {
|
|
1504
|
-
let resolve;
|
|
1505
|
-
let reject;
|
|
1506
|
-
const promise = new Promise((res, rej) => {
|
|
1507
|
-
resolve = res;
|
|
1508
|
-
reject = rej;
|
|
1509
|
-
});
|
|
1510
|
-
return { promise, resolve, reject };
|
|
1511
|
-
}
|
|
1512
|
-
async function waitFor(condition, options = {}) {
|
|
1513
|
-
const {
|
|
1514
|
-
timeout: timeoutMs = 5e3,
|
|
1515
|
-
interval = 100,
|
|
1516
|
-
timeoutMessage = "Condition not met within timeout"
|
|
1517
|
-
} = options;
|
|
1518
|
-
const startTime = Date.now();
|
|
1519
|
-
while (true) {
|
|
1520
|
-
const result = await condition();
|
|
1521
|
-
if (result)
|
|
1522
|
-
return;
|
|
1523
|
-
if (Date.now() - startTime >= timeoutMs) {
|
|
1524
|
-
throw new Error(timeoutMessage);
|
|
1525
|
-
}
|
|
1526
|
-
await sleep(interval);
|
|
1527
|
-
}
|
|
1528
|
-
}
|
|
1529
|
-
class Mutex {
|
|
1530
|
-
locked = false;
|
|
1531
|
-
queue = [];
|
|
1532
|
-
async acquire() {
|
|
1533
|
-
if (!this.locked) {
|
|
1534
|
-
this.locked = true;
|
|
1535
|
-
return;
|
|
1536
|
-
}
|
|
1537
|
-
return new Promise((resolve) => {
|
|
1538
|
-
this.queue.push(resolve);
|
|
1539
|
-
});
|
|
1540
|
-
}
|
|
1541
|
-
release() {
|
|
1542
|
-
if (this.queue.length > 0) {
|
|
1543
|
-
const resolve = this.queue.shift();
|
|
1544
|
-
resolve();
|
|
1545
|
-
} else {
|
|
1546
|
-
this.locked = false;
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
async runExclusive(fn) {
|
|
1550
|
-
await this.acquire();
|
|
1551
|
-
try {
|
|
1552
|
-
return await fn();
|
|
1553
|
-
} finally {
|
|
1554
|
-
this.release();
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
class Semaphore {
|
|
1559
|
-
permits;
|
|
1560
|
-
queue = [];
|
|
1561
|
-
constructor(permits) {
|
|
1562
|
-
this.permits = permits;
|
|
1563
|
-
}
|
|
1564
|
-
async acquire() {
|
|
1565
|
-
if (this.permits > 0) {
|
|
1566
|
-
this.permits--;
|
|
1567
|
-
return;
|
|
1568
|
-
}
|
|
1569
|
-
return new Promise((resolve) => {
|
|
1570
|
-
this.queue.push(resolve);
|
|
1571
|
-
});
|
|
1572
|
-
}
|
|
1573
|
-
release() {
|
|
1574
|
-
if (this.queue.length > 0) {
|
|
1575
|
-
const resolve = this.queue.shift();
|
|
1576
|
-
resolve();
|
|
1577
|
-
} else {
|
|
1578
|
-
this.permits++;
|
|
1579
|
-
}
|
|
1580
|
-
}
|
|
1581
|
-
async runExclusive(fn) {
|
|
1582
|
-
await this.acquire();
|
|
1583
|
-
try {
|
|
1584
|
-
return await fn();
|
|
1585
|
-
} finally {
|
|
1586
|
-
this.release();
|
|
1587
|
-
}
|
|
1588
|
-
}
|
|
1589
|
-
}
|
|
1590
|
-
async function batch(items, batchSize, processor) {
|
|
1591
|
-
const results = [];
|
|
1592
|
-
for (let i = 0; i < items.length; i += batchSize) {
|
|
1593
|
-
const batch2 = items.slice(i, i + batchSize);
|
|
1594
|
-
const batchResults = await processor(batch2);
|
|
1595
|
-
results.push(...batchResults);
|
|
1596
|
-
}
|
|
1597
|
-
return results;
|
|
1598
|
-
}
|
|
1599
|
-
async function poll(fn, options = {}) {
|
|
1600
|
-
const { interval = 1e3, timeout: timeoutMs = 3e4, validate } = options;
|
|
1601
|
-
const startTime = Date.now();
|
|
1602
|
-
while (true) {
|
|
1603
|
-
const result = await fn();
|
|
1604
|
-
if (!validate || validate(result)) {
|
|
1605
|
-
return result;
|
|
1606
|
-
}
|
|
1607
|
-
if (Date.now() - startTime >= timeoutMs) {
|
|
1608
|
-
throw new Error("Polling timeout exceeded");
|
|
1609
|
-
}
|
|
1610
|
-
await sleep(interval);
|
|
1611
|
-
}
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
const index$5 = {
|
|
1615
|
-
__proto__: null,
|
|
1616
|
-
Mutex: Mutex,
|
|
1617
|
-
Semaphore: Semaphore,
|
|
1618
|
-
allSettled: allSettled,
|
|
1619
|
-
batch: batch,
|
|
1620
|
-
debounce: debounce,
|
|
1621
|
-
defer: defer,
|
|
1622
|
-
memoize: memoize,
|
|
1623
|
-
parallelLimit: parallelLimit,
|
|
1624
|
-
poll: poll,
|
|
1625
|
-
raceWithTimeout: raceWithTimeout,
|
|
1626
|
-
retry: retry,
|
|
1627
|
-
sequence: sequence,
|
|
1628
|
-
sleep: sleep,
|
|
1629
|
-
throttle: throttle,
|
|
1630
|
-
timeout: timeout,
|
|
1631
|
-
waitFor: waitFor
|
|
1632
|
-
};
|
|
1633
|
-
|
|
1634
|
-
const CLAUDE_DIR = join$1(homedir(), ".claude");
|
|
1635
|
-
const COMMANDS_DIR = join$1(CLAUDE_DIR, "commands", "ccjk");
|
|
1636
|
-
const SKILLS_DIR = join$1(CLAUDE_DIR, "skills");
|
|
1637
|
-
const SUPERPOWERS_DIR = join$1(CLAUDE_DIR, "superpowers");
|
|
1638
|
-
function scanCommands() {
|
|
1639
|
-
const capabilities = [];
|
|
1640
|
-
if (!existsSync(COMMANDS_DIR)) {
|
|
1641
|
-
return capabilities;
|
|
1642
|
-
}
|
|
1643
|
-
try {
|
|
1644
|
-
const files = readdirSync(COMMANDS_DIR);
|
|
1645
|
-
for (const file of files) {
|
|
1646
|
-
if (!file.endsWith(".md"))
|
|
1647
|
-
continue;
|
|
1648
|
-
const filePath = join$1(COMMANDS_DIR, file);
|
|
1649
|
-
const commandId = file.replace(".md", "");
|
|
1650
|
-
try {
|
|
1651
|
-
const content = readFileSync(filePath, "utf-8");
|
|
1652
|
-
const nameMatch = content.match(/^#\s([^\n]+)$/m);
|
|
1653
|
-
const descMatch = content.match(/^>\s([^\n]+)$/m);
|
|
1654
|
-
capabilities.push({
|
|
1655
|
-
id: commandId,
|
|
1656
|
-
name: nameMatch?.[1] || commandId,
|
|
1657
|
-
type: "command",
|
|
1658
|
-
status: "active",
|
|
1659
|
-
priority: 10,
|
|
1660
|
-
description: descMatch?.[1] || "CCJK command",
|
|
1661
|
-
triggers: [`/ccjk:${commandId}`],
|
|
1662
|
-
path: filePath
|
|
1663
|
-
});
|
|
1664
|
-
} catch (error) {
|
|
1665
|
-
capabilities.push({
|
|
1666
|
-
id: commandId,
|
|
1667
|
-
name: commandId,
|
|
1668
|
-
type: "command",
|
|
1669
|
-
status: "error",
|
|
1670
|
-
priority: 0,
|
|
1671
|
-
description: "Failed to load command",
|
|
1672
|
-
error: error instanceof Error ? error.message : "Unknown error",
|
|
1673
|
-
path: filePath
|
|
1674
|
-
});
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
} catch {
|
|
1678
|
-
}
|
|
1679
|
-
return capabilities;
|
|
1680
|
-
}
|
|
1681
|
-
function scanSkills() {
|
|
1682
|
-
const capabilities = [];
|
|
1683
|
-
if (!existsSync(SKILLS_DIR)) {
|
|
1684
|
-
return capabilities;
|
|
1685
|
-
}
|
|
1686
|
-
try {
|
|
1687
|
-
const files = readdirSync(SKILLS_DIR);
|
|
1688
|
-
for (const file of files) {
|
|
1689
|
-
if (!file.endsWith(".md"))
|
|
1690
|
-
continue;
|
|
1691
|
-
const filePath = join$1(SKILLS_DIR, file);
|
|
1692
|
-
const skillId = file.replace(".md", "");
|
|
1693
|
-
try {
|
|
1694
|
-
const content = readFileSync(filePath, "utf-8");
|
|
1695
|
-
const nameMatch = content.match(/^#\s([^\n]+)$/m);
|
|
1696
|
-
const descMatch = content.match(/^>\s([^\n]+)$/m);
|
|
1697
|
-
capabilities.push({
|
|
1698
|
-
id: skillId,
|
|
1699
|
-
name: nameMatch?.[1] || skillId,
|
|
1700
|
-
type: "skill",
|
|
1701
|
-
status: "active",
|
|
1702
|
-
priority: 8,
|
|
1703
|
-
description: descMatch?.[1] || "Custom skill",
|
|
1704
|
-
triggers: [`/${skillId}`],
|
|
1705
|
-
path: filePath
|
|
1706
|
-
});
|
|
1707
|
-
} catch (error) {
|
|
1708
|
-
capabilities.push({
|
|
1709
|
-
id: skillId,
|
|
1710
|
-
name: skillId,
|
|
1711
|
-
type: "skill",
|
|
1712
|
-
status: "error",
|
|
1713
|
-
priority: 0,
|
|
1714
|
-
description: "Failed to load skill",
|
|
1715
|
-
error: error instanceof Error ? error.message : "Unknown error",
|
|
1716
|
-
path: filePath
|
|
1717
|
-
});
|
|
1718
|
-
}
|
|
1719
|
-
}
|
|
1720
|
-
} catch {
|
|
1721
|
-
}
|
|
1722
|
-
return capabilities;
|
|
1723
|
-
}
|
|
1724
|
-
function scanSuperpowers() {
|
|
1725
|
-
const capabilities = [];
|
|
1726
|
-
if (!existsSync(SUPERPOWERS_DIR)) {
|
|
1727
|
-
return capabilities;
|
|
1728
|
-
}
|
|
1729
|
-
try {
|
|
1730
|
-
const entries = readdirSync(SUPERPOWERS_DIR);
|
|
1731
|
-
for (const entry of entries) {
|
|
1732
|
-
const entryPath = join$1(SUPERPOWERS_DIR, entry);
|
|
1733
|
-
try {
|
|
1734
|
-
const stat = statSync(entryPath);
|
|
1735
|
-
if (!stat.isDirectory())
|
|
1736
|
-
continue;
|
|
1737
|
-
const files = readdirSync(entryPath);
|
|
1738
|
-
const mdFiles = files.filter((f) => f.endsWith(".md"));
|
|
1739
|
-
if (mdFiles.length === 0)
|
|
1740
|
-
continue;
|
|
1741
|
-
const status = mdFiles.length > 0 ? "active" : "inactive";
|
|
1742
|
-
capabilities.push({
|
|
1743
|
-
id: entry,
|
|
1744
|
-
name: entry,
|
|
1745
|
-
type: "superpower",
|
|
1746
|
-
status,
|
|
1747
|
-
priority: 9,
|
|
1748
|
-
description: `Superpower with ${mdFiles.length} skill(s)`,
|
|
1749
|
-
path: entryPath
|
|
1750
|
-
});
|
|
1751
|
-
} catch (error) {
|
|
1752
|
-
capabilities.push({
|
|
1753
|
-
id: entry,
|
|
1754
|
-
name: entry,
|
|
1755
|
-
type: "superpower",
|
|
1756
|
-
status: "error",
|
|
1757
|
-
priority: 0,
|
|
1758
|
-
description: "Failed to load superpower",
|
|
1759
|
-
error: error instanceof Error ? error.message : "Unknown error",
|
|
1760
|
-
path: entryPath
|
|
1761
|
-
});
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
} catch {
|
|
1765
|
-
}
|
|
1766
|
-
return capabilities;
|
|
1767
|
-
}
|
|
1768
|
-
function scanMCPServices() {
|
|
1769
|
-
const capabilities = [];
|
|
1770
|
-
const configPath = join$1(CLAUDE_DIR, "claude_desktop_config.json");
|
|
1771
|
-
if (!existsSync(configPath)) {
|
|
1772
|
-
return capabilities;
|
|
1773
|
-
}
|
|
1774
|
-
try {
|
|
1775
|
-
const content = readFileSync(configPath, "utf-8");
|
|
1776
|
-
const config = JSON.parse(content);
|
|
1777
|
-
if (config.mcpServers && typeof config.mcpServers === "object") {
|
|
1778
|
-
for (const [serviceName, serviceConfig] of Object.entries(config.mcpServers)) {
|
|
1779
|
-
const status = serviceConfig && typeof serviceConfig === "object" ? "active" : "inactive";
|
|
1780
|
-
capabilities.push({
|
|
1781
|
-
id: serviceName,
|
|
1782
|
-
name: serviceName,
|
|
1783
|
-
type: "mcp",
|
|
1784
|
-
status,
|
|
1785
|
-
priority: 7,
|
|
1786
|
-
description: "MCP service",
|
|
1787
|
-
path: configPath
|
|
1788
|
-
});
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
} catch {
|
|
1792
|
-
}
|
|
1793
|
-
return capabilities;
|
|
1794
|
-
}
|
|
1795
|
-
function scanAgents() {
|
|
1796
|
-
const capabilities = [];
|
|
1797
|
-
try {
|
|
1798
|
-
execSync("which agent-browser", { stdio: "ignore" });
|
|
1799
|
-
capabilities.push({
|
|
1800
|
-
id: "agent-browser",
|
|
1801
|
-
name: "Agent Browser",
|
|
1802
|
-
type: "agent",
|
|
1803
|
-
status: "active",
|
|
1804
|
-
priority: 10,
|
|
1805
|
-
description: "Zero-config browser automation",
|
|
1806
|
-
triggers: ["agent-browser"]
|
|
1807
|
-
});
|
|
1808
|
-
} catch {
|
|
1809
|
-
}
|
|
1810
|
-
return capabilities;
|
|
1811
|
-
}
|
|
1812
|
-
function scanCapabilities() {
|
|
1813
|
-
const commands = scanCommands();
|
|
1814
|
-
const skills = scanSkills();
|
|
1815
|
-
const agents = scanAgents();
|
|
1816
|
-
const mcpServices = scanMCPServices();
|
|
1817
|
-
const superpowers = scanSuperpowers();
|
|
1818
|
-
const allCapabilities = [
|
|
1819
|
-
...commands,
|
|
1820
|
-
...skills,
|
|
1821
|
-
...agents,
|
|
1822
|
-
...mcpServices,
|
|
1823
|
-
...superpowers
|
|
1824
|
-
];
|
|
1825
|
-
const activeCount = allCapabilities.filter((c) => c.status === "active").length;
|
|
1826
|
-
const errorCount = allCapabilities.filter((c) => c.status === "error").length;
|
|
1827
|
-
return {
|
|
1828
|
-
commands,
|
|
1829
|
-
skills,
|
|
1830
|
-
agents,
|
|
1831
|
-
mcpServices,
|
|
1832
|
-
superpowers,
|
|
1833
|
-
total: allCapabilities.length,
|
|
1834
|
-
activeCount,
|
|
1835
|
-
errorCount
|
|
1836
|
-
};
|
|
1837
|
-
}
|
|
1838
|
-
function getCapability(id) {
|
|
1839
|
-
const result = scanCapabilities();
|
|
1840
|
-
const allCapabilities = [
|
|
1841
|
-
...result.commands,
|
|
1842
|
-
...result.skills,
|
|
1843
|
-
...result.agents,
|
|
1844
|
-
...result.mcpServices,
|
|
1845
|
-
...result.superpowers
|
|
1846
|
-
];
|
|
1847
|
-
return allCapabilities.find((c) => c.id === id);
|
|
1848
|
-
}
|
|
1849
|
-
function getCapabilitiesByType(type) {
|
|
1850
|
-
const result = scanCapabilities();
|
|
1851
|
-
switch (type) {
|
|
1852
|
-
case "command":
|
|
1853
|
-
return result.commands;
|
|
1854
|
-
case "skill":
|
|
1855
|
-
return result.skills;
|
|
1856
|
-
case "agent":
|
|
1857
|
-
return result.agents;
|
|
1858
|
-
case "mcp":
|
|
1859
|
-
return result.mcpServices;
|
|
1860
|
-
case "superpower":
|
|
1861
|
-
return result.superpowers;
|
|
1862
|
-
default:
|
|
1863
|
-
return [];
|
|
1864
|
-
}
|
|
1865
|
-
}
|
|
1866
|
-
|
|
1867
|
-
const BOX_CHARS = {
|
|
1868
|
-
topLeft: "\u256D",
|
|
1869
|
-
topRight: "\u256E",
|
|
1870
|
-
bottomLeft: "\u2570",
|
|
1871
|
-
bottomRight: "\u256F",
|
|
1872
|
-
horizontal: "\u2500",
|
|
1873
|
-
vertical: "\u2502"
|
|
1874
|
-
};
|
|
1875
|
-
function createBorderLine(width, type) {
|
|
1876
|
-
const left = type === "top" ? BOX_CHARS.topLeft : type === "bottom" ? BOX_CHARS.bottomLeft : BOX_CHARS.vertical;
|
|
1877
|
-
const right = type === "top" ? BOX_CHARS.topRight : type === "bottom" ? BOX_CHARS.bottomRight : BOX_CHARS.vertical;
|
|
1878
|
-
const fill = type === "middle" ? " " : BOX_CHARS.horizontal;
|
|
1879
|
-
return `${left}${fill.repeat(width - 2)}${right}`;
|
|
1880
|
-
}
|
|
1881
|
-
function centerText(text, width) {
|
|
1882
|
-
const plainText = text.replace(/\x1B\[[0-9;]*m/g, "");
|
|
1883
|
-
const padding = Math.max(0, width - plainText.length - 2);
|
|
1884
|
-
const leftPad = Math.floor(padding / 2);
|
|
1885
|
-
const rightPad = padding - leftPad;
|
|
1886
|
-
return `${BOX_CHARS.vertical}${" ".repeat(leftPad)}${text}${" ".repeat(rightPad)}${BOX_CHARS.vertical}`;
|
|
1887
|
-
}
|
|
1888
|
-
function leftText(text, width) {
|
|
1889
|
-
const plainText = text.replace(/\x1B\[[0-9;]*m/g, "");
|
|
1890
|
-
const padding = Math.max(0, width - plainText.length - 2);
|
|
1891
|
-
return `${BOX_CHARS.vertical} ${text}${" ".repeat(padding - 1)}${BOX_CHARS.vertical}`;
|
|
1892
|
-
}
|
|
1893
|
-
function getVersion() {
|
|
1894
|
-
return getRuntimeVersion();
|
|
1895
|
-
}
|
|
1896
|
-
function generateWelcome(scanResult, options = {}) {
|
|
1897
|
-
const {
|
|
1898
|
-
showVersion = true,
|
|
1899
|
-
showStats = true,
|
|
1900
|
-
showRecommendations = true,
|
|
1901
|
-
compact = false
|
|
1902
|
-
} = options;
|
|
1903
|
-
const lines = [];
|
|
1904
|
-
const width = compact ? 50 : 70;
|
|
1905
|
-
lines.push(createBorderLine(width, "top"));
|
|
1906
|
-
if (showVersion) {
|
|
1907
|
-
const version = getVersion();
|
|
1908
|
-
const title = a.bold.cyan(`\u{1F389} CCJK v${version} - Claude Code JinKu`);
|
|
1909
|
-
lines.push(centerText(title, width));
|
|
1910
|
-
} else {
|
|
1911
|
-
const title = a.bold.cyan("\u{1F389} CCJK - Claude Code JinKu");
|
|
1912
|
-
lines.push(centerText(title, width));
|
|
1913
|
-
}
|
|
1914
|
-
if (showStats && scanResult.total > 0) {
|
|
1915
|
-
lines.push(leftText("", width));
|
|
1916
|
-
lines.push(leftText(a.bold("\u2728 Available Capabilities:"), width));
|
|
1917
|
-
if (scanResult.skills.length > 0) {
|
|
1918
|
-
const activeSkills = scanResult.skills.filter((c) => c.status === "active");
|
|
1919
|
-
if (activeSkills.length > 0) {
|
|
1920
|
-
lines.push(leftText("", width));
|
|
1921
|
-
lines.push(leftText(a.bold.green(" \u{1F4DA} Skills:"), width));
|
|
1922
|
-
activeSkills.slice(0, 5).forEach((skill) => {
|
|
1923
|
-
const trigger = skill.triggers?.[0] || `/${skill.id}`;
|
|
1924
|
-
lines.push(leftText(` ${a.cyan(trigger.padEnd(20))} ${a.dim(skill.description)}`, width));
|
|
1925
|
-
});
|
|
1926
|
-
if (activeSkills.length > 5) {
|
|
1927
|
-
lines.push(leftText(` ${a.dim(`... and ${activeSkills.length - 5} more`)}`, width));
|
|
1928
|
-
}
|
|
1929
|
-
}
|
|
1930
|
-
}
|
|
1931
|
-
if (scanResult.mcpServices.length > 0) {
|
|
1932
|
-
const activeMcp = scanResult.mcpServices.filter((c) => c.status === "active");
|
|
1933
|
-
if (activeMcp.length > 0) {
|
|
1934
|
-
lines.push(leftText("", width));
|
|
1935
|
-
lines.push(leftText(a.bold.green(" \u{1F50C} MCP Services:"), width));
|
|
1936
|
-
activeMcp.slice(0, 5).forEach((mcp) => {
|
|
1937
|
-
lines.push(leftText(` ${a.cyan(mcp.name.padEnd(20))} ${a.dim(mcp.description)}`, width));
|
|
1938
|
-
});
|
|
1939
|
-
if (activeMcp.length > 5) {
|
|
1940
|
-
lines.push(leftText(` ${a.dim(`... and ${activeMcp.length - 5} more`)}`, width));
|
|
1941
|
-
}
|
|
1942
|
-
}
|
|
1943
|
-
}
|
|
1944
|
-
if (scanResult.agents.length > 0) {
|
|
1945
|
-
const activeAgents = scanResult.agents.filter((c) => c.status === "active");
|
|
1946
|
-
if (activeAgents.length > 0) {
|
|
1947
|
-
lines.push(leftText("", width));
|
|
1948
|
-
lines.push(leftText(a.bold.green(" \u{1F916} Agents:"), width));
|
|
1949
|
-
activeAgents.forEach((agent) => {
|
|
1950
|
-
const trigger = agent.triggers?.[0] || agent.id;
|
|
1951
|
-
lines.push(leftText(` ${a.cyan(trigger.padEnd(20))} ${a.dim(agent.description)}`, width));
|
|
1952
|
-
});
|
|
1953
|
-
}
|
|
1954
|
-
}
|
|
1955
|
-
if (scanResult.superpowers.length > 0) {
|
|
1956
|
-
const activeSuperpowers = scanResult.superpowers.filter((c) => c.status === "active");
|
|
1957
|
-
if (activeSuperpowers.length > 0) {
|
|
1958
|
-
lines.push(leftText("", width));
|
|
1959
|
-
lines.push(leftText(a.bold.green(" \u26A1 Superpowers:"), width));
|
|
1960
|
-
activeSuperpowers.slice(0, 3).forEach((sp) => {
|
|
1961
|
-
lines.push(leftText(` ${a.cyan(sp.name.padEnd(20))} ${a.dim(sp.description)}`, width));
|
|
1962
|
-
});
|
|
1963
|
-
if (activeSuperpowers.length > 3) {
|
|
1964
|
-
lines.push(leftText(` ${a.dim(`... and ${activeSuperpowers.length - 3} more`)}`, width));
|
|
1965
|
-
}
|
|
1966
|
-
}
|
|
1967
|
-
}
|
|
1968
|
-
if (scanResult.commands.length > 0) {
|
|
1969
|
-
const activeCommands = scanResult.commands.filter((c) => c.status === "active").length;
|
|
1970
|
-
lines.push(leftText("", width));
|
|
1971
|
-
lines.push(leftText(` ${a.green("\u2022")} ${activeCommands} CCJK Command(s) available`, width));
|
|
1972
|
-
}
|
|
1973
|
-
if (scanResult.errorCount > 0) {
|
|
1974
|
-
lines.push(leftText("", width));
|
|
1975
|
-
lines.push(leftText(` ${a.red("\u26A0")} ${scanResult.errorCount} capability error(s) detected`, width));
|
|
1976
|
-
}
|
|
1977
|
-
}
|
|
1978
|
-
if (showRecommendations && !compact) {
|
|
1979
|
-
lines.push(leftText("", width));
|
|
1980
|
-
lines.push(leftText(a.bold("\u{1F4A1} Quick Tips:"), width));
|
|
1981
|
-
lines.push(leftText(` ${a.green("/ccjk:status")} - View detailed capability status`, width));
|
|
1982
|
-
lines.push(leftText(` ${a.green("/ccjk:help")} - Get help and documentation`, width));
|
|
1983
|
-
const activeSkills = scanResult.skills.filter((c) => c.status === "active");
|
|
1984
|
-
if (activeSkills.length > 0 && activeSkills[0].triggers?.[0]) {
|
|
1985
|
-
lines.push(leftText(` ${a.green(activeSkills[0].triggers[0])} - Try this skill`, width));
|
|
1986
|
-
}
|
|
1987
|
-
}
|
|
1988
|
-
lines.push(createBorderLine(width, "bottom"));
|
|
1989
|
-
return lines.join("\n");
|
|
1990
|
-
}
|
|
1991
|
-
function generateCompactWelcome(scanResult) {
|
|
1992
|
-
const parts = [];
|
|
1993
|
-
if (scanResult.commands.length > 0) {
|
|
1994
|
-
parts.push(`${scanResult.commands.filter((c) => c.status === "active").length} commands`);
|
|
1995
|
-
}
|
|
1996
|
-
if (scanResult.skills.length > 0) {
|
|
1997
|
-
parts.push(`${scanResult.skills.filter((c) => c.status === "active").length} skills`);
|
|
1998
|
-
}
|
|
1999
|
-
if (scanResult.superpowers.length > 0) {
|
|
2000
|
-
parts.push(`${scanResult.superpowers.filter((c) => c.status === "active").length} superpowers`);
|
|
2001
|
-
}
|
|
2002
|
-
const summary = parts.join(", ");
|
|
2003
|
-
return a.dim(`CCJK loaded: ${summary || "no capabilities"}`);
|
|
2004
|
-
}
|
|
2005
|
-
function generateRecommendations(scanResult) {
|
|
2006
|
-
const recommendations = [];
|
|
2007
|
-
if (scanResult.total === 0) {
|
|
2008
|
-
recommendations.push("Run `npx ccjk` to install CCJK capabilities");
|
|
2009
|
-
return recommendations;
|
|
2010
|
-
}
|
|
2011
|
-
if (scanResult.agents.length === 0) {
|
|
2012
|
-
recommendations.push("Install Agent Browser for zero-config browser automation");
|
|
2013
|
-
}
|
|
2014
|
-
if (scanResult.superpowers.length === 0) {
|
|
2015
|
-
recommendations.push("Install Superpowers for advanced AI workflows");
|
|
2016
|
-
}
|
|
2017
|
-
if (scanResult.errorCount > 0) {
|
|
2018
|
-
recommendations.push(`Fix ${scanResult.errorCount} capability error(s) - run /ccjk:status for details`);
|
|
2019
|
-
}
|
|
2020
|
-
return recommendations;
|
|
2021
|
-
}
|
|
2022
|
-
|
|
2023
|
-
const index$4 = {
|
|
2024
|
-
__proto__: null,
|
|
2025
|
-
buildCommand: buildCommand,
|
|
2026
|
-
commandExists: commandExists,
|
|
2027
|
-
escapeArgument: escapeArgument,
|
|
2028
|
-
executeCommand: executeCommand,
|
|
2029
|
-
executeCommandParallel: executeCommandParallel,
|
|
2030
|
-
executeCommandSequence: executeCommandSequence,
|
|
2031
|
-
executeCommandStream: executeCommandStream,
|
|
2032
|
-
getCommandPath: getCommandPath,
|
|
2033
|
-
getCommandVersion: getCommandVersion,
|
|
2034
|
-
parseVersion: parseVersion
|
|
2035
|
-
};
|
|
2036
|
-
|
|
2037
|
-
class ConfigManager {
|
|
2038
|
-
constructor(namespace, options = {}) {
|
|
2039
|
-
this.namespace = namespace;
|
|
2040
|
-
this.options = {
|
|
2041
|
-
configDir: options.configDir || this.getDefaultConfigDir(),
|
|
2042
|
-
fileName: options.fileName || `${namespace}.json`,
|
|
2043
|
-
createIfMissing: options.createIfMissing ?? true,
|
|
2044
|
-
validate: options.validate || (() => true)
|
|
2045
|
-
};
|
|
2046
|
-
this.configPath = path.join(this.options.configDir, this.options.fileName);
|
|
2047
|
-
}
|
|
2048
|
-
configPath;
|
|
2049
|
-
options;
|
|
2050
|
-
cache;
|
|
2051
|
-
/**
|
|
2052
|
-
* Get the default configuration directory
|
|
2053
|
-
*/
|
|
2054
|
-
getDefaultConfigDir() {
|
|
2055
|
-
return path.join(os.homedir(), ".ccjk");
|
|
2056
|
-
}
|
|
2057
|
-
/**
|
|
2058
|
-
* Load configuration from file
|
|
2059
|
-
*/
|
|
2060
|
-
async load() {
|
|
2061
|
-
try {
|
|
2062
|
-
const data = await promises.readFile(this.configPath, "utf-8");
|
|
2063
|
-
const config = JSON.parse(data);
|
|
2064
|
-
if (!this.options.validate(config)) {
|
|
2065
|
-
throw new Error("Configuration validation failed");
|
|
2066
|
-
}
|
|
2067
|
-
this.cache = config;
|
|
2068
|
-
return config;
|
|
2069
|
-
} catch (error) {
|
|
2070
|
-
if (error.code === "ENOENT") {
|
|
2071
|
-
return null;
|
|
2072
|
-
}
|
|
2073
|
-
throw error;
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
|
-
/**
|
|
2077
|
-
* Save configuration to file
|
|
2078
|
-
*/
|
|
2079
|
-
async save(config) {
|
|
2080
|
-
if (!this.options.validate(config)) {
|
|
2081
|
-
throw new Error("Configuration validation failed");
|
|
2082
|
-
}
|
|
2083
|
-
await promises.mkdir(this.options.configDir, { recursive: true });
|
|
2084
|
-
await promises.writeFile(this.configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
2085
|
-
this.cache = config;
|
|
2086
|
-
}
|
|
2087
|
-
/**
|
|
2088
|
-
* Update configuration (merge with existing)
|
|
2089
|
-
*/
|
|
2090
|
-
async update(updates) {
|
|
2091
|
-
const current = await this.load() || {};
|
|
2092
|
-
const updated = { ...current, ...updates };
|
|
2093
|
-
await this.save(updated);
|
|
2094
|
-
return updated;
|
|
2095
|
-
}
|
|
2096
|
-
/**
|
|
2097
|
-
* Delete configuration file
|
|
2098
|
-
*/
|
|
2099
|
-
async delete() {
|
|
2100
|
-
try {
|
|
2101
|
-
await promises.unlink(this.configPath);
|
|
2102
|
-
this.cache = void 0;
|
|
2103
|
-
} catch (error) {
|
|
2104
|
-
if (error.code !== "ENOENT") {
|
|
2105
|
-
throw error;
|
|
2106
|
-
}
|
|
2107
|
-
}
|
|
2108
|
-
}
|
|
2109
|
-
/**
|
|
2110
|
-
* Check if configuration file exists
|
|
2111
|
-
*/
|
|
2112
|
-
async exists() {
|
|
2113
|
-
try {
|
|
2114
|
-
await promises.access(this.configPath);
|
|
2115
|
-
return true;
|
|
2116
|
-
} catch {
|
|
2117
|
-
return false;
|
|
2118
|
-
}
|
|
2119
|
-
}
|
|
2120
|
-
/**
|
|
2121
|
-
* Get configuration path
|
|
2122
|
-
*/
|
|
2123
|
-
getPath() {
|
|
2124
|
-
return this.configPath;
|
|
2125
|
-
}
|
|
2126
|
-
/**
|
|
2127
|
-
* Get cached configuration (without file I/O)
|
|
2128
|
-
*/
|
|
2129
|
-
getCached() {
|
|
2130
|
-
return this.cache;
|
|
2131
|
-
}
|
|
2132
|
-
/**
|
|
2133
|
-
* Clear cache
|
|
2134
|
-
*/
|
|
2135
|
-
clearCache() {
|
|
2136
|
-
this.cache = void 0;
|
|
2137
|
-
}
|
|
2138
|
-
}
|
|
2139
|
-
function createConfigManager(namespace, options) {
|
|
2140
|
-
return new ConfigManager(namespace, options);
|
|
2141
|
-
}
|
|
2142
|
-
|
|
2143
|
-
class ConfigValidator {
|
|
2144
|
-
constructor(rules) {
|
|
2145
|
-
this.rules = rules;
|
|
2146
|
-
}
|
|
2147
|
-
/**
|
|
2148
|
-
* Validate a configuration object
|
|
2149
|
-
*/
|
|
2150
|
-
validate(config) {
|
|
2151
|
-
const errors = [];
|
|
2152
|
-
for (const rule of this.rules) {
|
|
2153
|
-
const value = config[rule.field];
|
|
2154
|
-
if (rule.required && (value === void 0 || value === null)) {
|
|
2155
|
-
errors.push({
|
|
2156
|
-
field: String(rule.field),
|
|
2157
|
-
message: rule.message || `Field '${String(rule.field)}' is required`
|
|
2158
|
-
});
|
|
2159
|
-
continue;
|
|
2160
|
-
}
|
|
2161
|
-
if (value === void 0 || value === null) {
|
|
2162
|
-
continue;
|
|
2163
|
-
}
|
|
2164
|
-
if (rule.type) {
|
|
2165
|
-
const actualType = Array.isArray(value) ? "array" : typeof value;
|
|
2166
|
-
if (actualType !== rule.type) {
|
|
2167
|
-
errors.push({
|
|
2168
|
-
field: String(rule.field),
|
|
2169
|
-
message: rule.message || `Field '${String(rule.field)}' must be of type ${rule.type}`
|
|
2170
|
-
});
|
|
2171
|
-
continue;
|
|
2172
|
-
}
|
|
2173
|
-
}
|
|
2174
|
-
if (rule.validator && !rule.validator(value)) {
|
|
2175
|
-
errors.push({
|
|
2176
|
-
field: String(rule.field),
|
|
2177
|
-
message: rule.message || `Field '${String(rule.field)}' validation failed`
|
|
2178
|
-
});
|
|
2179
|
-
}
|
|
2180
|
-
}
|
|
2181
|
-
return {
|
|
2182
|
-
valid: errors.length === 0,
|
|
2183
|
-
errors
|
|
2184
|
-
};
|
|
2185
|
-
}
|
|
2186
|
-
/**
|
|
2187
|
-
* Validate and throw on error
|
|
2188
|
-
*/
|
|
2189
|
-
validateOrThrow(config) {
|
|
2190
|
-
const result = this.validate(config);
|
|
2191
|
-
if (!result.valid) {
|
|
2192
|
-
const errorMessages = result.errors.map((e) => `${e.field}: ${e.message}`).join(", ");
|
|
2193
|
-
throw new Error(`Configuration validation failed: ${errorMessages}`);
|
|
2194
|
-
}
|
|
2195
|
-
}
|
|
2196
|
-
}
|
|
2197
|
-
function createValidator(rules) {
|
|
2198
|
-
return new ConfigValidator(rules);
|
|
2199
|
-
}
|
|
2200
|
-
const validators = {
|
|
2201
|
-
/**
|
|
2202
|
-
* Validate string is not empty
|
|
2203
|
-
*/
|
|
2204
|
-
notEmpty: (value) => {
|
|
2205
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
2206
|
-
},
|
|
2207
|
-
/**
|
|
2208
|
-
* Validate string matches pattern
|
|
2209
|
-
*/
|
|
2210
|
-
pattern: (regex) => (value) => {
|
|
2211
|
-
return typeof value === "string" && regex.test(value);
|
|
2212
|
-
},
|
|
2213
|
-
/**
|
|
2214
|
-
* Validate number is in range
|
|
2215
|
-
*/
|
|
2216
|
-
range: (min, max) => (value) => {
|
|
2217
|
-
return typeof value === "number" && value >= min && value <= max;
|
|
2218
|
-
},
|
|
2219
|
-
/**
|
|
2220
|
-
* Validate string length
|
|
2221
|
-
*/
|
|
2222
|
-
length: (min, max) => (value) => {
|
|
2223
|
-
if (typeof value !== "string")
|
|
2224
|
-
return false;
|
|
2225
|
-
if (max !== void 0) {
|
|
2226
|
-
return value.length >= min && value.length <= max;
|
|
2227
|
-
}
|
|
2228
|
-
return value.length >= min;
|
|
2229
|
-
},
|
|
2230
|
-
/**
|
|
2231
|
-
* Validate value is one of allowed values
|
|
2232
|
-
*/
|
|
2233
|
-
oneOf: (allowed) => (value) => {
|
|
2234
|
-
return allowed.includes(value);
|
|
2235
|
-
},
|
|
2236
|
-
/**
|
|
2237
|
-
* Validate email format
|
|
2238
|
-
*/
|
|
2239
|
-
email: (value) => {
|
|
2240
|
-
const emailRegex = /^[^\s@]+@[^\s@][^\s.@]*\.[^\s@]+$/;
|
|
2241
|
-
return typeof value === "string" && emailRegex.test(value);
|
|
2242
|
-
},
|
|
2243
|
-
/**
|
|
2244
|
-
* Validate URL format
|
|
2245
|
-
*/
|
|
2246
|
-
url: (value) => {
|
|
2247
|
-
try {
|
|
2248
|
-
new URL(value);
|
|
2249
|
-
return true;
|
|
2250
|
-
} catch {
|
|
2251
|
-
return false;
|
|
2252
|
-
}
|
|
2253
|
-
},
|
|
2254
|
-
/**
|
|
2255
|
-
* Validate object has required keys
|
|
2256
|
-
*/
|
|
2257
|
-
hasKeys: (keys) => (value) => {
|
|
2258
|
-
if (typeof value !== "object" || value === null)
|
|
2259
|
-
return false;
|
|
2260
|
-
return keys.every((key) => key in value);
|
|
2261
|
-
},
|
|
2262
|
-
/**
|
|
2263
|
-
* Validate array is not empty
|
|
2264
|
-
*/
|
|
2265
|
-
notEmptyArray: (value) => {
|
|
2266
|
-
return Array.isArray(value) && value.length > 0;
|
|
2267
|
-
}
|
|
2268
|
-
};
|
|
2269
|
-
|
|
2270
|
-
class BaseError extends Error {
|
|
2271
|
-
constructor(message, code, statusCode, details) {
|
|
2272
|
-
super(message);
|
|
2273
|
-
this.code = code;
|
|
2274
|
-
this.statusCode = statusCode;
|
|
2275
|
-
this.details = details;
|
|
2276
|
-
this.name = this.constructor.name;
|
|
2277
|
-
Error.captureStackTrace(this, this.constructor);
|
|
2278
|
-
}
|
|
2279
|
-
toJSON() {
|
|
2280
|
-
return {
|
|
2281
|
-
name: this.name,
|
|
2282
|
-
message: this.message,
|
|
2283
|
-
code: this.code,
|
|
2284
|
-
statusCode: this.statusCode,
|
|
2285
|
-
details: this.details,
|
|
2286
|
-
stack: this.stack
|
|
2287
|
-
};
|
|
2288
|
-
}
|
|
2289
|
-
}
|
|
2290
|
-
class ValidationError extends BaseError {
|
|
2291
|
-
constructor(message, details) {
|
|
2292
|
-
super(message, "VALIDATION_ERROR", 400, details);
|
|
2293
|
-
}
|
|
2294
|
-
}
|
|
2295
|
-
class NotFoundError extends BaseError {
|
|
2296
|
-
constructor(message, details) {
|
|
2297
|
-
super(message, "NOT_FOUND", 404, details);
|
|
2298
|
-
}
|
|
2299
|
-
}
|
|
2300
|
-
class UnauthorizedError extends BaseError {
|
|
2301
|
-
constructor(message, details) {
|
|
2302
|
-
super(message, "UNAUTHORIZED", 401, details);
|
|
2303
|
-
}
|
|
2304
|
-
}
|
|
2305
|
-
class ForbiddenError extends BaseError {
|
|
2306
|
-
constructor(message, details) {
|
|
2307
|
-
super(message, "FORBIDDEN", 403, details);
|
|
2308
|
-
}
|
|
2309
|
-
}
|
|
2310
|
-
class ConflictError extends BaseError {
|
|
2311
|
-
constructor(message, details) {
|
|
2312
|
-
super(message, "CONFLICT", 409, details);
|
|
2313
|
-
}
|
|
2314
|
-
}
|
|
2315
|
-
class TimeoutError extends BaseError {
|
|
2316
|
-
constructor(message, details) {
|
|
2317
|
-
super(message, "TIMEOUT", 408, details);
|
|
2318
|
-
}
|
|
2319
|
-
}
|
|
2320
|
-
class InternalError extends BaseError {
|
|
2321
|
-
constructor(message, details) {
|
|
2322
|
-
super(message, "INTERNAL_ERROR", 500, details);
|
|
2323
|
-
}
|
|
2324
|
-
}
|
|
2325
|
-
class ConfigurationError extends BaseError {
|
|
2326
|
-
constructor(message, details) {
|
|
2327
|
-
super(message, "CONFIGURATION_ERROR", 500, details);
|
|
2328
|
-
}
|
|
2329
|
-
}
|
|
2330
|
-
class NetworkError extends BaseError {
|
|
2331
|
-
constructor(message, details) {
|
|
2332
|
-
super(message, "NETWORK_ERROR", 503, details);
|
|
2333
|
-
}
|
|
2334
|
-
}
|
|
2335
|
-
function isErrorType(error, errorClass) {
|
|
2336
|
-
return error instanceof errorClass;
|
|
2337
|
-
}
|
|
2338
|
-
function getErrorMessage(error) {
|
|
2339
|
-
if (error instanceof Error) {
|
|
2340
|
-
return error.message;
|
|
2341
|
-
}
|
|
2342
|
-
if (typeof error === "string") {
|
|
2343
|
-
return error;
|
|
2344
|
-
}
|
|
2345
|
-
return "An unknown error occurred";
|
|
2346
|
-
}
|
|
2347
|
-
function getErrorStack(error) {
|
|
2348
|
-
if (error instanceof Error) {
|
|
2349
|
-
return error.stack;
|
|
2350
|
-
}
|
|
2351
|
-
return void 0;
|
|
2352
|
-
}
|
|
2353
|
-
function formatError(error) {
|
|
2354
|
-
if (error instanceof BaseError) {
|
|
2355
|
-
return {
|
|
2356
|
-
message: error.message,
|
|
2357
|
-
name: error.name,
|
|
2358
|
-
code: error.code,
|
|
2359
|
-
statusCode: error.statusCode,
|
|
2360
|
-
stack: error.stack,
|
|
2361
|
-
details: error.details
|
|
2362
|
-
};
|
|
2363
|
-
}
|
|
2364
|
-
if (error instanceof Error) {
|
|
2365
|
-
return {
|
|
2366
|
-
message: error.message,
|
|
2367
|
-
name: error.name,
|
|
2368
|
-
stack: error.stack
|
|
2369
|
-
};
|
|
2370
|
-
}
|
|
2371
|
-
return {
|
|
2372
|
-
message: String(error)
|
|
2373
|
-
};
|
|
2374
|
-
}
|
|
2375
|
-
function wrapError(error, message, code) {
|
|
2376
|
-
const originalMessage = getErrorMessage(error);
|
|
2377
|
-
const fullMessage = `${message}: ${originalMessage}`;
|
|
2378
|
-
if (error instanceof BaseError) {
|
|
2379
|
-
return new BaseError(
|
|
2380
|
-
fullMessage,
|
|
2381
|
-
code || error.code,
|
|
2382
|
-
error.statusCode,
|
|
2383
|
-
error.details
|
|
2384
|
-
);
|
|
2385
|
-
}
|
|
2386
|
-
return new BaseError(fullMessage, code);
|
|
2387
|
-
}
|
|
2388
|
-
function tryCatch(fn) {
|
|
2389
|
-
try {
|
|
2390
|
-
const data = fn();
|
|
2391
|
-
return { success: true, data };
|
|
2392
|
-
} catch (error) {
|
|
2393
|
-
return {
|
|
2394
|
-
success: false,
|
|
2395
|
-
error: error instanceof Error ? error : new Error(String(error))
|
|
2396
|
-
};
|
|
2397
|
-
}
|
|
2398
|
-
}
|
|
2399
|
-
async function tryCatchAsync(fn) {
|
|
2400
|
-
try {
|
|
2401
|
-
const data = await fn();
|
|
2402
|
-
return { success: true, data };
|
|
2403
|
-
} catch (error) {
|
|
2404
|
-
return {
|
|
2405
|
-
success: false,
|
|
2406
|
-
error: error instanceof Error ? error : new Error(String(error))
|
|
2407
|
-
};
|
|
2408
|
-
}
|
|
2409
|
-
}
|
|
2410
|
-
function assert$1(condition, message, ErrorClass = Error) {
|
|
2411
|
-
if (!condition) {
|
|
2412
|
-
throw new ErrorClass(message);
|
|
2413
|
-
}
|
|
2414
|
-
}
|
|
2415
|
-
function createErrorHandler(handlers, defaultHandler) {
|
|
2416
|
-
return (error) => {
|
|
2417
|
-
if (error instanceof BaseError && error.code && handlers[error.code]) {
|
|
2418
|
-
handlers[error.code](error);
|
|
2419
|
-
} else if (error instanceof Error && handlers[error.name]) {
|
|
2420
|
-
handlers[error.name](error);
|
|
2421
|
-
} else if (defaultHandler) {
|
|
2422
|
-
defaultHandler(error instanceof Error ? error : new Error(String(error)));
|
|
2423
|
-
} else {
|
|
2424
|
-
throw error;
|
|
2425
|
-
}
|
|
2426
|
-
};
|
|
2427
|
-
}
|
|
2428
|
-
class AggregateError extends BaseError {
|
|
2429
|
-
constructor(errors, message = "Multiple errors occurred") {
|
|
2430
|
-
super(message, "AGGREGATE_ERROR", 500, { errors });
|
|
2431
|
-
this.errors = errors;
|
|
2432
|
-
}
|
|
2433
|
-
static fromErrors(errors) {
|
|
2434
|
-
const message = `${errors.length} error(s) occurred: ${errors.map((e) => e.message).join(", ")}`;
|
|
2435
|
-
return new AggregateError(errors, message);
|
|
2436
|
-
}
|
|
2437
|
-
}
|
|
2438
|
-
async function retryWithErrorHandling(fn, options = {}) {
|
|
2439
|
-
const {
|
|
2440
|
-
maxAttempts = 3,
|
|
2441
|
-
delay = 1e3,
|
|
2442
|
-
shouldRetry = () => true,
|
|
2443
|
-
onError
|
|
2444
|
-
} = options;
|
|
2445
|
-
let lastError;
|
|
2446
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
2447
|
-
try {
|
|
2448
|
-
return await fn();
|
|
2449
|
-
} catch (error) {
|
|
2450
|
-
lastError = error instanceof Error ? error : new Error(String(error));
|
|
2451
|
-
if (onError) {
|
|
2452
|
-
onError(lastError, attempt);
|
|
2453
|
-
}
|
|
2454
|
-
if (attempt < maxAttempts && shouldRetry(lastError)) {
|
|
2455
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
2456
|
-
} else {
|
|
2457
|
-
throw lastError;
|
|
2458
|
-
}
|
|
2459
|
-
}
|
|
2460
|
-
}
|
|
2461
|
-
throw lastError;
|
|
2462
|
-
}
|
|
2463
|
-
|
|
2464
|
-
const index$3 = {
|
|
2465
|
-
__proto__: null,
|
|
2466
|
-
AggregateError: AggregateError,
|
|
2467
|
-
BaseError: BaseError,
|
|
2468
|
-
ConfigurationError: ConfigurationError,
|
|
2469
|
-
ConflictError: ConflictError,
|
|
2470
|
-
ForbiddenError: ForbiddenError,
|
|
2471
|
-
InternalError: InternalError,
|
|
2472
|
-
NetworkError: NetworkError,
|
|
2473
|
-
NotFoundError: NotFoundError,
|
|
2474
|
-
TimeoutError: TimeoutError,
|
|
2475
|
-
UnauthorizedError: UnauthorizedError,
|
|
2476
|
-
ValidationError: ValidationError,
|
|
2477
|
-
assert: assert$1,
|
|
2478
|
-
createErrorHandler: createErrorHandler,
|
|
2479
|
-
formatError: formatError,
|
|
2480
|
-
getErrorMessage: getErrorMessage,
|
|
2481
|
-
getErrorStack: getErrorStack,
|
|
2482
|
-
isErrorType: isErrorType,
|
|
2483
|
-
retryWithErrorHandling: retryWithErrorHandling,
|
|
2484
|
-
tryCatch: tryCatch,
|
|
2485
|
-
tryCatchAsync: tryCatchAsync,
|
|
2486
|
-
wrapError: wrapError
|
|
2487
|
-
};
|
|
2488
|
-
|
|
2489
|
-
async function exists(filePath) {
|
|
2490
|
-
try {
|
|
2491
|
-
await promises.access(filePath);
|
|
2492
|
-
return true;
|
|
2493
|
-
} catch {
|
|
2494
|
-
return false;
|
|
2495
|
-
}
|
|
2496
|
-
}
|
|
2497
|
-
async function isFile(filePath) {
|
|
2498
|
-
try {
|
|
2499
|
-
const stats = await promises.stat(filePath);
|
|
2500
|
-
return stats.isFile();
|
|
2501
|
-
} catch {
|
|
2502
|
-
return false;
|
|
2503
|
-
}
|
|
2504
|
-
}
|
|
2505
|
-
async function isDirectory(filePath) {
|
|
2506
|
-
try {
|
|
2507
|
-
const stats = await promises.stat(filePath);
|
|
2508
|
-
return stats.isDirectory();
|
|
2509
|
-
} catch {
|
|
2510
|
-
return false;
|
|
2511
|
-
}
|
|
2512
|
-
}
|
|
2513
|
-
async function ensureDir(dirPath) {
|
|
2514
|
-
await promises.mkdir(dirPath, { recursive: true });
|
|
2515
|
-
}
|
|
2516
|
-
async function readFile(filePath, encoding = "utf-8") {
|
|
2517
|
-
return promises.readFile(filePath, encoding);
|
|
2518
|
-
}
|
|
2519
|
-
async function writeFile(filePath, content, encoding = "utf-8") {
|
|
2520
|
-
await ensureDir(path.dirname(filePath));
|
|
2521
|
-
await promises.writeFile(filePath, content, encoding);
|
|
2522
|
-
}
|
|
2523
|
-
async function appendFile(filePath, content, encoding = "utf-8") {
|
|
2524
|
-
await ensureDir(path.dirname(filePath));
|
|
2525
|
-
await promises.appendFile(filePath, content, encoding);
|
|
2526
|
-
}
|
|
2527
|
-
async function readJSON(filePath) {
|
|
2528
|
-
const content = await readFile(filePath);
|
|
2529
|
-
return JSON.parse(content);
|
|
2530
|
-
}
|
|
2531
|
-
async function writeJSON(filePath, data, pretty = true) {
|
|
2532
|
-
const content = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
2533
|
-
await writeFile(filePath, content);
|
|
2534
|
-
}
|
|
2535
|
-
async function copyFile(src, dest) {
|
|
2536
|
-
await ensureDir(path.dirname(dest));
|
|
2537
|
-
await promises.copyFile(src, dest);
|
|
2538
|
-
}
|
|
2539
|
-
async function moveFile(src, dest) {
|
|
2540
|
-
await ensureDir(path.dirname(dest));
|
|
2541
|
-
await promises.rename(src, dest);
|
|
2542
|
-
}
|
|
2543
|
-
async function deleteFile(filePath) {
|
|
2544
|
-
try {
|
|
2545
|
-
await promises.unlink(filePath);
|
|
2546
|
-
} catch (error) {
|
|
2547
|
-
if (error.code !== "ENOENT") {
|
|
2548
|
-
throw error;
|
|
2549
|
-
}
|
|
2550
|
-
}
|
|
2551
|
-
}
|
|
2552
|
-
async function deleteDir(dirPath) {
|
|
2553
|
-
try {
|
|
2554
|
-
await promises.rm(dirPath, { recursive: true, force: true });
|
|
2555
|
-
} catch (error) {
|
|
2556
|
-
if (error.code !== "ENOENT") {
|
|
2557
|
-
throw error;
|
|
2558
|
-
}
|
|
2559
|
-
}
|
|
2560
|
-
}
|
|
2561
|
-
async function listFiles(dirPath, recursive = false) {
|
|
2562
|
-
const entries = await promises.readdir(dirPath, { withFileTypes: true });
|
|
2563
|
-
const files = [];
|
|
2564
|
-
for (const entry of entries) {
|
|
2565
|
-
const fullPath = path.join(dirPath, entry.name);
|
|
2566
|
-
if (entry.isFile()) {
|
|
2567
|
-
files.push(fullPath);
|
|
2568
|
-
} else if (entry.isDirectory() && recursive) {
|
|
2569
|
-
const subFiles = await listFiles(fullPath, true);
|
|
2570
|
-
files.push(...subFiles);
|
|
2571
|
-
}
|
|
2572
|
-
}
|
|
2573
|
-
return files;
|
|
2574
|
-
}
|
|
2575
|
-
async function listDirs(dirPath) {
|
|
2576
|
-
const entries = await promises.readdir(dirPath, { withFileTypes: true });
|
|
2577
|
-
const dirs = [];
|
|
2578
|
-
for (const entry of entries) {
|
|
2579
|
-
if (entry.isDirectory()) {
|
|
2580
|
-
dirs.push(path.join(dirPath, entry.name));
|
|
2581
|
-
}
|
|
2582
|
-
}
|
|
2583
|
-
return dirs;
|
|
2584
|
-
}
|
|
2585
|
-
async function getFileSize$1(filePath) {
|
|
2586
|
-
const stats = await promises.stat(filePath);
|
|
2587
|
-
return stats.size;
|
|
2588
|
-
}
|
|
2589
|
-
async function getModifiedTime(filePath) {
|
|
2590
|
-
const stats = await promises.stat(filePath);
|
|
2591
|
-
return stats.mtime;
|
|
2592
|
-
}
|
|
2593
|
-
async function getCreatedTime(filePath) {
|
|
2594
|
-
const stats = await promises.stat(filePath);
|
|
2595
|
-
return stats.birthtime;
|
|
2596
|
-
}
|
|
2597
|
-
async function isReadable(filePath) {
|
|
2598
|
-
try {
|
|
2599
|
-
await promises.access(filePath, promises.constants.R_OK);
|
|
2600
|
-
return true;
|
|
2601
|
-
} catch {
|
|
2602
|
-
return false;
|
|
2603
|
-
}
|
|
2604
|
-
}
|
|
2605
|
-
async function isWritable(filePath) {
|
|
2606
|
-
try {
|
|
2607
|
-
await promises.access(filePath, promises.constants.W_OK);
|
|
2608
|
-
return true;
|
|
2609
|
-
} catch {
|
|
2610
|
-
return false;
|
|
2611
|
-
}
|
|
2612
|
-
}
|
|
2613
|
-
async function isExecutable(filePath) {
|
|
2614
|
-
try {
|
|
2615
|
-
await promises.access(filePath, promises.constants.X_OK);
|
|
2616
|
-
return true;
|
|
2617
|
-
} catch {
|
|
2618
|
-
return false;
|
|
2619
|
-
}
|
|
2620
|
-
}
|
|
2621
|
-
async function findFiles(dirPath, pattern, recursive = true) {
|
|
2622
|
-
const allFiles = await listFiles(dirPath, recursive);
|
|
2623
|
-
const regex = typeof pattern === "string" ? new RegExp(pattern) : pattern;
|
|
2624
|
-
return allFiles.filter((file) => regex.test(file));
|
|
2625
|
-
}
|
|
2626
|
-
async function getDirSize(dirPath) {
|
|
2627
|
-
const files = await listFiles(dirPath, true);
|
|
2628
|
-
let totalSize = 0;
|
|
2629
|
-
for (const file of files) {
|
|
2630
|
-
try {
|
|
2631
|
-
totalSize += await getFileSize$1(file);
|
|
2632
|
-
} catch {
|
|
2633
|
-
}
|
|
2634
|
-
}
|
|
2635
|
-
return totalSize;
|
|
2636
|
-
}
|
|
2637
|
-
async function copyDir(src, dest) {
|
|
2638
|
-
await ensureDir(dest);
|
|
2639
|
-
const entries = await promises.readdir(src, { withFileTypes: true });
|
|
2640
|
-
for (const entry of entries) {
|
|
2641
|
-
const srcPath = path.join(src, entry.name);
|
|
2642
|
-
const destPath = path.join(dest, entry.name);
|
|
2643
|
-
if (entry.isDirectory()) {
|
|
2644
|
-
await copyDir(srcPath, destPath);
|
|
2645
|
-
} else {
|
|
2646
|
-
await copyFile(srcPath, destPath);
|
|
2647
|
-
}
|
|
2648
|
-
}
|
|
2649
|
-
}
|
|
2650
|
-
async function emptyDir(dirPath) {
|
|
2651
|
-
if (!await exists(dirPath)) {
|
|
2652
|
-
return;
|
|
2653
|
-
}
|
|
2654
|
-
const entries = await promises.readdir(dirPath);
|
|
2655
|
-
for (const entry of entries) {
|
|
2656
|
-
const fullPath = path.join(dirPath, entry);
|
|
2657
|
-
const stat = await promises.stat(fullPath);
|
|
2658
|
-
if (stat.isDirectory()) {
|
|
2659
|
-
await deleteDir(fullPath);
|
|
2660
|
-
} else {
|
|
2661
|
-
await deleteFile(fullPath);
|
|
2662
|
-
}
|
|
2663
|
-
}
|
|
2664
|
-
}
|
|
2665
|
-
|
|
2666
|
-
const index$2 = {
|
|
2667
|
-
__proto__: null,
|
|
2668
|
-
appendFile: appendFile,
|
|
2669
|
-
copyDir: copyDir,
|
|
2670
|
-
copyFile: copyFile,
|
|
2671
|
-
deleteDir: deleteDir,
|
|
2672
|
-
deleteFile: deleteFile,
|
|
2673
|
-
emptyDir: emptyDir,
|
|
2674
|
-
ensureDir: ensureDir,
|
|
2675
|
-
exists: exists,
|
|
2676
|
-
findFiles: findFiles,
|
|
2677
|
-
getCreatedTime: getCreatedTime,
|
|
2678
|
-
getDirSize: getDirSize,
|
|
2679
|
-
getFileSize: getFileSize$1,
|
|
2680
|
-
getModifiedTime: getModifiedTime,
|
|
2681
|
-
isDirectory: isDirectory,
|
|
2682
|
-
isExecutable: isExecutable,
|
|
2683
|
-
isFile: isFile,
|
|
2684
|
-
isReadable: isReadable,
|
|
2685
|
-
isWritable: isWritable,
|
|
2686
|
-
listDirs: listDirs,
|
|
2687
|
-
listFiles: listFiles,
|
|
2688
|
-
moveFile: moveFile,
|
|
2689
|
-
readFile: readFile,
|
|
2690
|
-
readJSON: readJSON,
|
|
2691
|
-
writeFile: writeFile,
|
|
2692
|
-
writeJSON: writeJSON
|
|
2693
|
-
};
|
|
2694
|
-
|
|
2695
|
-
const LOG_LEVELS = {
|
|
2696
|
-
debug: 0,
|
|
2697
|
-
info: 1,
|
|
2698
|
-
warn: 2,
|
|
2699
|
-
error: 3
|
|
2700
|
-
};
|
|
2701
|
-
const COLORS = {
|
|
2702
|
-
reset: "\x1B[0m",
|
|
2703
|
-
debug: "\x1B[36m",
|
|
2704
|
-
// Cyan
|
|
2705
|
-
info: "\x1B[32m",
|
|
2706
|
-
// Green
|
|
2707
|
-
warn: "\x1B[33m",
|
|
2708
|
-
// Yellow
|
|
2709
|
-
error: "\x1B[31m"
|
|
2710
|
-
// Red
|
|
2711
|
-
};
|
|
2712
|
-
class Logger {
|
|
2713
|
-
level;
|
|
2714
|
-
prefix;
|
|
2715
|
-
timestamp;
|
|
2716
|
-
colors;
|
|
2717
|
-
constructor(options = {}) {
|
|
2718
|
-
this.level = options.level || "info";
|
|
2719
|
-
this.prefix = options.prefix || "";
|
|
2720
|
-
this.timestamp = options.timestamp ?? true;
|
|
2721
|
-
this.colors = options.colors ?? true;
|
|
2722
|
-
}
|
|
2723
|
-
shouldLog(level) {
|
|
2724
|
-
return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
|
|
2725
|
-
}
|
|
2726
|
-
formatMessage(level, message, ...args) {
|
|
2727
|
-
const parts = [];
|
|
2728
|
-
if (this.timestamp) {
|
|
2729
|
-
parts.push(`[${(/* @__PURE__ */ new Date()).toISOString()}]`);
|
|
2730
|
-
}
|
|
2731
|
-
if (this.prefix) {
|
|
2732
|
-
parts.push(`[${this.prefix}]`);
|
|
2733
|
-
}
|
|
2734
|
-
parts.push(`[${level.toUpperCase()}]`);
|
|
2735
|
-
parts.push(message);
|
|
2736
|
-
let formatted = parts.join(" ");
|
|
2737
|
-
if (args.length > 0) {
|
|
2738
|
-
formatted += ` ${args.map((arg) => this.stringify(arg)).join(" ")}`;
|
|
2739
|
-
}
|
|
2740
|
-
if (this.colors && process.stdout.isTTY) {
|
|
2741
|
-
return `${COLORS[level]}${formatted}${COLORS.reset}`;
|
|
2742
|
-
}
|
|
2743
|
-
return formatted;
|
|
2744
|
-
}
|
|
2745
|
-
stringify(value) {
|
|
2746
|
-
if (typeof value === "string") {
|
|
2747
|
-
return value;
|
|
2748
|
-
}
|
|
2749
|
-
if (value instanceof Error) {
|
|
2750
|
-
return value.stack || value.message;
|
|
2751
|
-
}
|
|
2752
|
-
try {
|
|
2753
|
-
return JSON.stringify(value, null, 2);
|
|
2754
|
-
} catch {
|
|
2755
|
-
return String(value);
|
|
2756
|
-
}
|
|
2757
|
-
}
|
|
2758
|
-
debug(message, ...args) {
|
|
2759
|
-
if (this.shouldLog("debug")) {
|
|
2760
|
-
console.debug(this.formatMessage("debug", message, ...args));
|
|
2761
|
-
}
|
|
2762
|
-
}
|
|
2763
|
-
info(message, ...args) {
|
|
2764
|
-
if (this.shouldLog("info")) {
|
|
2765
|
-
console.info(this.formatMessage("info", message, ...args));
|
|
2766
|
-
}
|
|
2767
|
-
}
|
|
2768
|
-
warn(message, ...args) {
|
|
2769
|
-
if (this.shouldLog("warn")) {
|
|
2770
|
-
console.warn(this.formatMessage("warn", message, ...args));
|
|
2771
|
-
}
|
|
2772
|
-
}
|
|
2773
|
-
error(message, ...args) {
|
|
2774
|
-
if (this.shouldLog("error")) {
|
|
2775
|
-
console.error(this.formatMessage("error", message, ...args));
|
|
2776
|
-
}
|
|
2777
|
-
}
|
|
2778
|
-
setLevel(level) {
|
|
2779
|
-
this.level = level;
|
|
2780
|
-
}
|
|
2781
|
-
getLevel() {
|
|
2782
|
-
return this.level;
|
|
2783
|
-
}
|
|
2784
|
-
}
|
|
2785
|
-
function createLogger(options) {
|
|
2786
|
-
return new Logger(options);
|
|
2787
|
-
}
|
|
2788
|
-
const logger = createLogger();
|
|
2789
|
-
|
|
2790
|
-
function deepClone(obj) {
|
|
2791
|
-
if (obj === null || typeof obj !== "object") {
|
|
2792
|
-
return obj;
|
|
2793
|
-
}
|
|
2794
|
-
if (obj instanceof Date) {
|
|
2795
|
-
return new Date(obj.getTime());
|
|
2796
|
-
}
|
|
2797
|
-
if (Array.isArray(obj)) {
|
|
2798
|
-
return obj.map((item) => deepClone(item));
|
|
2799
|
-
}
|
|
2800
|
-
if (obj instanceof Object) {
|
|
2801
|
-
const clonedObj = {};
|
|
2802
|
-
for (const key in obj) {
|
|
2803
|
-
if (obj.hasOwnProperty(key)) {
|
|
2804
|
-
clonedObj[key] = deepClone(obj[key]);
|
|
2805
|
-
}
|
|
2806
|
-
}
|
|
2807
|
-
return clonedObj;
|
|
2808
|
-
}
|
|
2809
|
-
return obj;
|
|
2810
|
-
}
|
|
2811
|
-
function deepMerge(target, source) {
|
|
2812
|
-
const output = { ...target };
|
|
2813
|
-
for (const key in source) {
|
|
2814
|
-
if (source.hasOwnProperty(key)) {
|
|
2815
|
-
const sourceValue = source[key];
|
|
2816
|
-
const targetValue = output[key];
|
|
2817
|
-
if (isObject$1(sourceValue) && isObject$1(targetValue)) {
|
|
2818
|
-
output[key] = deepMerge(targetValue, sourceValue);
|
|
2819
|
-
} else {
|
|
2820
|
-
output[key] = sourceValue;
|
|
2821
|
-
}
|
|
2822
|
-
}
|
|
2823
|
-
}
|
|
2824
|
-
return output;
|
|
2825
|
-
}
|
|
2826
|
-
function isObject$1(value) {
|
|
2827
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2828
|
-
}
|
|
2829
|
-
function get(obj, path, defaultValue) {
|
|
2830
|
-
const keys2 = path.split(".");
|
|
2831
|
-
let result = obj;
|
|
2832
|
-
for (const key of keys2) {
|
|
2833
|
-
if (result === null || result === void 0) {
|
|
2834
|
-
return defaultValue;
|
|
2835
|
-
}
|
|
2836
|
-
result = result[key];
|
|
2837
|
-
}
|
|
2838
|
-
return result !== void 0 ? result : defaultValue;
|
|
2839
|
-
}
|
|
2840
|
-
function set(obj, path, value) {
|
|
2841
|
-
const keys2 = path.split(".");
|
|
2842
|
-
const lastKey = keys2.pop();
|
|
2843
|
-
let current = obj;
|
|
2844
|
-
for (const key of keys2) {
|
|
2845
|
-
if (!(key in current) || typeof current[key] !== "object") {
|
|
2846
|
-
current[key] = {};
|
|
2847
|
-
}
|
|
2848
|
-
current = current[key];
|
|
2849
|
-
}
|
|
2850
|
-
current[lastKey] = value;
|
|
2851
|
-
}
|
|
2852
|
-
function has(obj, path) {
|
|
2853
|
-
const keys2 = path.split(".");
|
|
2854
|
-
let current = obj;
|
|
2855
|
-
for (const key of keys2) {
|
|
2856
|
-
if (current === null || current === void 0 || !(key in current)) {
|
|
2857
|
-
return false;
|
|
2858
|
-
}
|
|
2859
|
-
current = current[key];
|
|
2860
|
-
}
|
|
2861
|
-
return true;
|
|
2862
|
-
}
|
|
2863
|
-
function unset(obj, path) {
|
|
2864
|
-
const keys2 = path.split(".");
|
|
2865
|
-
const lastKey = keys2.pop();
|
|
2866
|
-
let current = obj;
|
|
2867
|
-
for (const key of keys2) {
|
|
2868
|
-
if (current === null || current === void 0 || !(key in current)) {
|
|
2869
|
-
return false;
|
|
2870
|
-
}
|
|
2871
|
-
current = current[key];
|
|
2872
|
-
}
|
|
2873
|
-
if (lastKey in current) {
|
|
2874
|
-
delete current[lastKey];
|
|
2875
|
-
return true;
|
|
2876
|
-
}
|
|
2877
|
-
return false;
|
|
2878
|
-
}
|
|
2879
|
-
function keys(obj, prefix = "") {
|
|
2880
|
-
const result = [];
|
|
2881
|
-
for (const key in obj) {
|
|
2882
|
-
if (obj.hasOwnProperty(key)) {
|
|
2883
|
-
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
2884
|
-
result.push(fullKey);
|
|
2885
|
-
if (isObject$1(obj[key])) {
|
|
2886
|
-
result.push(...keys(obj[key], fullKey));
|
|
2887
|
-
}
|
|
2888
|
-
}
|
|
2889
|
-
}
|
|
2890
|
-
return result;
|
|
2891
|
-
}
|
|
2892
|
-
function values(obj) {
|
|
2893
|
-
return Object.values(obj);
|
|
2894
|
-
}
|
|
2895
|
-
function entries(obj) {
|
|
2896
|
-
return Object.entries(obj);
|
|
2897
|
-
}
|
|
2898
|
-
function pick(obj, keys2) {
|
|
2899
|
-
const result = {};
|
|
2900
|
-
for (const key of keys2) {
|
|
2901
|
-
if (key in obj) {
|
|
2902
|
-
result[key] = obj[key];
|
|
2903
|
-
}
|
|
2904
|
-
}
|
|
2905
|
-
return result;
|
|
2906
|
-
}
|
|
2907
|
-
function omit(obj, keys2) {
|
|
2908
|
-
const result = { ...obj };
|
|
2909
|
-
for (const key of keys2) {
|
|
2910
|
-
delete result[key];
|
|
2911
|
-
}
|
|
2912
|
-
return result;
|
|
2913
|
-
}
|
|
2914
|
-
function filter(obj, predicate) {
|
|
2915
|
-
const result = {};
|
|
2916
|
-
for (const [key, value] of entries(obj)) {
|
|
2917
|
-
if (predicate(value, key)) {
|
|
2918
|
-
result[key] = value;
|
|
2919
|
-
}
|
|
2920
|
-
}
|
|
2921
|
-
return result;
|
|
2922
|
-
}
|
|
2923
|
-
function map(obj, mapper) {
|
|
2924
|
-
const result = {};
|
|
2925
|
-
for (const [key, value] of entries(obj)) {
|
|
2926
|
-
result[key] = mapper(value, key);
|
|
2927
|
-
}
|
|
2928
|
-
return result;
|
|
2929
|
-
}
|
|
2930
|
-
function isEmpty(obj) {
|
|
2931
|
-
return Object.keys(obj).length === 0;
|
|
2932
|
-
}
|
|
2933
|
-
function flatten(obj, prefix = "", separator = ".") {
|
|
2934
|
-
const result = {};
|
|
2935
|
-
for (const key in obj) {
|
|
2936
|
-
if (obj.hasOwnProperty(key)) {
|
|
2937
|
-
const fullKey = prefix ? `${prefix}${separator}${key}` : key;
|
|
2938
|
-
if (isObject$1(obj[key]) && !Array.isArray(obj[key])) {
|
|
2939
|
-
Object.assign(result, flatten(obj[key], fullKey, separator));
|
|
2940
|
-
} else {
|
|
2941
|
-
result[fullKey] = obj[key];
|
|
2942
|
-
}
|
|
2943
|
-
}
|
|
2944
|
-
}
|
|
2945
|
-
return result;
|
|
2946
|
-
}
|
|
2947
|
-
function unflatten(obj, separator = ".") {
|
|
2948
|
-
const result = {};
|
|
2949
|
-
for (const [key, value] of entries(obj)) {
|
|
2950
|
-
set(result, key.replace(new RegExp(separator, "g"), "."), value);
|
|
2951
|
-
}
|
|
2952
|
-
return result;
|
|
2953
|
-
}
|
|
2954
|
-
function invert(obj) {
|
|
2955
|
-
const result = {};
|
|
2956
|
-
for (const [key, value] of entries(obj)) {
|
|
2957
|
-
result[value] = key;
|
|
2958
|
-
}
|
|
2959
|
-
return result;
|
|
2960
|
-
}
|
|
2961
|
-
function groupBy(arr, key) {
|
|
2962
|
-
const result = {};
|
|
2963
|
-
for (const item of arr) {
|
|
2964
|
-
const groupKey = typeof key === "function" ? key(item) : String(item[key]);
|
|
2965
|
-
if (!result[groupKey]) {
|
|
2966
|
-
result[groupKey] = [];
|
|
2967
|
-
}
|
|
2968
|
-
result[groupKey].push(item);
|
|
2969
|
-
}
|
|
2970
|
-
return result;
|
|
2971
|
-
}
|
|
2972
|
-
function keyBy(arr, key) {
|
|
2973
|
-
const result = {};
|
|
2974
|
-
for (const item of arr) {
|
|
2975
|
-
const itemKey = typeof key === "function" ? key(item) : String(item[key]);
|
|
2976
|
-
result[itemKey] = item;
|
|
2977
|
-
}
|
|
2978
|
-
return result;
|
|
2979
|
-
}
|
|
2980
|
-
function isEqual(obj1, obj2) {
|
|
2981
|
-
if (obj1 === obj2)
|
|
2982
|
-
return true;
|
|
2983
|
-
if (typeof obj1 !== "object" || typeof obj2 !== "object" || obj1 === null || obj2 === null) {
|
|
2984
|
-
return false;
|
|
2985
|
-
}
|
|
2986
|
-
const keys1 = Object.keys(obj1);
|
|
2987
|
-
const keys2 = Object.keys(obj2);
|
|
2988
|
-
if (keys1.length !== keys2.length)
|
|
2989
|
-
return false;
|
|
2990
|
-
for (const key of keys1) {
|
|
2991
|
-
if (!keys2.includes(key) || !isEqual(obj1[key], obj2[key])) {
|
|
2992
|
-
return false;
|
|
2993
|
-
}
|
|
2994
|
-
}
|
|
2995
|
-
return true;
|
|
2996
|
-
}
|
|
2997
|
-
function compact(obj) {
|
|
2998
|
-
const result = {};
|
|
2999
|
-
for (const [key, value] of entries(obj)) {
|
|
3000
|
-
if (value !== null && value !== void 0) {
|
|
3001
|
-
result[key] = value;
|
|
3002
|
-
}
|
|
3003
|
-
}
|
|
3004
|
-
return result;
|
|
3005
|
-
}
|
|
3006
|
-
function deepFreeze(obj) {
|
|
3007
|
-
Object.freeze(obj);
|
|
3008
|
-
for (const key in obj) {
|
|
3009
|
-
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
3010
|
-
const value = obj[key];
|
|
3011
|
-
if (typeof value === "object" && value !== null) {
|
|
3012
|
-
deepFreeze(value);
|
|
3013
|
-
}
|
|
3014
|
-
}
|
|
3015
|
-
}
|
|
3016
|
-
return obj;
|
|
3017
|
-
}
|
|
3018
|
-
function merge(...objects) {
|
|
3019
|
-
return objects.reduce((acc, obj) => ({ ...acc, ...obj }), {});
|
|
3020
|
-
}
|
|
3021
|
-
function size(obj) {
|
|
3022
|
-
return Object.keys(obj).length;
|
|
3023
|
-
}
|
|
3024
|
-
|
|
3025
|
-
const index$1 = {
|
|
3026
|
-
__proto__: null,
|
|
3027
|
-
compact: compact,
|
|
3028
|
-
deepClone: deepClone,
|
|
3029
|
-
deepFreeze: deepFreeze,
|
|
3030
|
-
deepMerge: deepMerge,
|
|
3031
|
-
entries: entries,
|
|
3032
|
-
filter: filter,
|
|
3033
|
-
flatten: flatten,
|
|
3034
|
-
get: get,
|
|
3035
|
-
groupBy: groupBy,
|
|
3036
|
-
has: has,
|
|
3037
|
-
invert: invert,
|
|
3038
|
-
isEmpty: isEmpty,
|
|
3039
|
-
isEqual: isEqual,
|
|
3040
|
-
keyBy: keyBy,
|
|
3041
|
-
keys: keys,
|
|
3042
|
-
map: map,
|
|
3043
|
-
merge: merge,
|
|
3044
|
-
omit: omit,
|
|
3045
|
-
pick: pick,
|
|
3046
|
-
set: set,
|
|
3047
|
-
size: size,
|
|
3048
|
-
unflatten: unflatten,
|
|
3049
|
-
unset: unset,
|
|
3050
|
-
values: values
|
|
3051
|
-
};
|
|
3052
|
-
|
|
3053
|
-
function getPlatform() {
|
|
3054
|
-
const platform = os.platform();
|
|
3055
|
-
if (platform === "darwin" || platform === "linux" || platform === "win32") {
|
|
3056
|
-
return platform;
|
|
3057
|
-
}
|
|
3058
|
-
return "unknown";
|
|
3059
|
-
}
|
|
3060
|
-
function getArchitecture() {
|
|
3061
|
-
const arch = os.arch();
|
|
3062
|
-
if (arch === "x64" || arch === "arm64" || arch === "ia32") {
|
|
3063
|
-
return arch;
|
|
3064
|
-
}
|
|
3065
|
-
return "unknown";
|
|
3066
|
-
}
|
|
3067
|
-
function isMacOS() {
|
|
3068
|
-
return getPlatform() === "darwin";
|
|
3069
|
-
}
|
|
3070
|
-
function isLinux() {
|
|
3071
|
-
return getPlatform() === "linux";
|
|
3072
|
-
}
|
|
3073
|
-
function isWindows() {
|
|
3074
|
-
return getPlatform() === "win32";
|
|
3075
|
-
}
|
|
3076
|
-
function isUnix() {
|
|
3077
|
-
return isMacOS() || isLinux();
|
|
3078
|
-
}
|
|
3079
|
-
function getPlatformInfo() {
|
|
3080
|
-
return {
|
|
3081
|
-
platform: getPlatform(),
|
|
3082
|
-
architecture: getArchitecture(),
|
|
3083
|
-
release: os.release(),
|
|
3084
|
-
hostname: os.hostname(),
|
|
3085
|
-
homedir: os.homedir(),
|
|
3086
|
-
tmpdir: os.tmpdir(),
|
|
3087
|
-
cpus: os.cpus().length,
|
|
3088
|
-
totalMemory: os.totalmem(),
|
|
3089
|
-
freeMemory: os.freemem()
|
|
3090
|
-
};
|
|
3091
|
-
}
|
|
3092
|
-
|
|
3093
|
-
function getHomeDir() {
|
|
3094
|
-
return os.homedir();
|
|
3095
|
-
}
|
|
3096
|
-
function getConfigDir(appName) {
|
|
3097
|
-
const home = getHomeDir();
|
|
3098
|
-
if (isWindows()) {
|
|
3099
|
-
const appData = process.env.APPDATA || path.join(home, "AppData", "Roaming");
|
|
3100
|
-
return appName ? path.join(appData, appName) : appData;
|
|
3101
|
-
}
|
|
3102
|
-
if (isMacOS()) {
|
|
3103
|
-
const configDir2 = path.join(home, "Library", "Application Support");
|
|
3104
|
-
return appName ? path.join(configDir2, appName) : configDir2;
|
|
3105
|
-
}
|
|
3106
|
-
const configDir = process.env.XDG_CONFIG_HOME || path.join(home, ".config");
|
|
3107
|
-
return appName ? path.join(configDir, appName) : configDir;
|
|
3108
|
-
}
|
|
3109
|
-
function getDataDir(appName) {
|
|
3110
|
-
const home = getHomeDir();
|
|
3111
|
-
if (isWindows()) {
|
|
3112
|
-
const localAppData = process.env.LOCALAPPDATA || path.join(home, "AppData", "Local");
|
|
3113
|
-
return appName ? path.join(localAppData, appName) : localAppData;
|
|
3114
|
-
}
|
|
3115
|
-
if (isMacOS()) {
|
|
3116
|
-
const dataDir2 = path.join(home, "Library", "Application Support");
|
|
3117
|
-
return appName ? path.join(dataDir2, appName) : dataDir2;
|
|
3118
|
-
}
|
|
3119
|
-
const dataDir = process.env.XDG_DATA_HOME || path.join(home, ".local", "share");
|
|
3120
|
-
return appName ? path.join(dataDir, appName) : dataDir;
|
|
3121
|
-
}
|
|
3122
|
-
function getCacheDir(appName) {
|
|
3123
|
-
const home = getHomeDir();
|
|
3124
|
-
if (isWindows()) {
|
|
3125
|
-
const temp = os.tmpdir();
|
|
3126
|
-
return appName ? path.join(temp, appName) : temp;
|
|
3127
|
-
}
|
|
3128
|
-
if (isMacOS()) {
|
|
3129
|
-
const cacheDir2 = path.join(home, "Library", "Caches");
|
|
3130
|
-
return appName ? path.join(cacheDir2, appName) : cacheDir2;
|
|
3131
|
-
}
|
|
3132
|
-
const cacheDir = process.env.XDG_CACHE_HOME || path.join(home, ".cache");
|
|
3133
|
-
return appName ? path.join(cacheDir, appName) : cacheDir;
|
|
3134
|
-
}
|
|
3135
|
-
function getTempDir(appName) {
|
|
3136
|
-
const temp = os.tmpdir();
|
|
3137
|
-
return appName ? path.join(temp, appName) : temp;
|
|
3138
|
-
}
|
|
3139
|
-
|
|
3140
|
-
const DEFAULT_CHUNK_SIZE = 1024 * 1024;
|
|
3141
|
-
async function processLargeFile(filePath, processor, options = {}) {
|
|
3142
|
-
const { chunkSize = DEFAULT_CHUNK_SIZE, encoding = "utf8" } = options;
|
|
3143
|
-
return new Promise((resolve, reject) => {
|
|
3144
|
-
const stream = createReadStream(filePath, { encoding });
|
|
3145
|
-
const chunks = [];
|
|
3146
|
-
let chunkIndex = 0;
|
|
3147
|
-
stream.on("data", (chunk) => {
|
|
3148
|
-
const buffer = typeof chunk === "string" ? Buffer.from(chunk, encoding) : chunk;
|
|
3149
|
-
chunks.push(buffer);
|
|
3150
|
-
if (chunks.length * chunkSize >= chunkSize) {
|
|
3151
|
-
const combined = Buffer.concat(chunks);
|
|
3152
|
-
processor(combined, chunkIndex++);
|
|
3153
|
-
chunks.length = 0;
|
|
3154
|
-
}
|
|
3155
|
-
});
|
|
3156
|
-
stream.on("end", () => {
|
|
3157
|
-
if (chunks.length > 0) {
|
|
3158
|
-
const combined = Buffer.concat(chunks);
|
|
3159
|
-
processor(combined, chunkIndex);
|
|
3160
|
-
}
|
|
3161
|
-
resolve();
|
|
3162
|
-
});
|
|
3163
|
-
stream.on("error", reject);
|
|
3164
|
-
});
|
|
3165
|
-
}
|
|
3166
|
-
async function streamJSON(filePath, _options = {}) {
|
|
3167
|
-
const chunks = [];
|
|
3168
|
-
await pipeline(
|
|
3169
|
-
createReadStream(filePath, { encoding: "utf8" }),
|
|
3170
|
-
new Transform({
|
|
3171
|
-
transform(chunk, _, callback) {
|
|
3172
|
-
chunks.push(chunk);
|
|
3173
|
-
callback();
|
|
3174
|
-
}
|
|
3175
|
-
})
|
|
3176
|
-
);
|
|
3177
|
-
const content = Buffer.concat(chunks).toString("utf8");
|
|
3178
|
-
return JSON.parse(content);
|
|
3179
|
-
}
|
|
3180
|
-
async function streamWriteJSON(filePath, data, _options = {}) {
|
|
3181
|
-
await promises.writeFile(filePath, JSON.stringify(data, null, 2), "utf8");
|
|
3182
|
-
}
|
|
3183
|
-
async function processLineByLine(filePath, processor) {
|
|
3184
|
-
const readline = await import('node:readline');
|
|
3185
|
-
const rl = readline.createInterface({
|
|
3186
|
-
input: createReadStream(filePath, { encoding: "utf8" }),
|
|
3187
|
-
crlfDelay: Number.MAX_VALUE
|
|
3188
|
-
// Treat \r\n as single character
|
|
3189
|
-
});
|
|
3190
|
-
let index = 0;
|
|
3191
|
-
for await (const line of rl) {
|
|
3192
|
-
await Promise.resolve(processor(line, index++));
|
|
3193
|
-
}
|
|
3194
|
-
rl.close();
|
|
3195
|
-
}
|
|
3196
|
-
async function getFileSize(filePath) {
|
|
3197
|
-
try {
|
|
3198
|
-
const stats = await promises.stat(filePath);
|
|
3199
|
-
return stats.size;
|
|
3200
|
-
} catch {
|
|
3201
|
-
return 0;
|
|
3202
|
-
}
|
|
3203
|
-
}
|
|
3204
|
-
async function countLines(filePath) {
|
|
3205
|
-
let count = 0;
|
|
3206
|
-
await processLineByLine(filePath, () => {
|
|
3207
|
-
count++;
|
|
3208
|
-
});
|
|
3209
|
-
return count;
|
|
3210
|
-
}
|
|
3211
|
-
async function batchProcessFiles(filePaths, processor, concurrency = 3) {
|
|
3212
|
-
const results = /* @__PURE__ */ new Map();
|
|
3213
|
-
const queue = [...filePaths];
|
|
3214
|
-
const processing = /* @__PURE__ */ new Set();
|
|
3215
|
-
const processNext = async () => {
|
|
3216
|
-
while (queue.length > 0 && processing.size < concurrency) {
|
|
3217
|
-
const file = queue.shift();
|
|
3218
|
-
processing.add(file);
|
|
3219
|
-
try {
|
|
3220
|
-
const result = await processor(file);
|
|
3221
|
-
results.set(file, result);
|
|
3222
|
-
} catch (_error) {
|
|
3223
|
-
results.set(file, null);
|
|
3224
|
-
} finally {
|
|
3225
|
-
processing.delete(file);
|
|
3226
|
-
}
|
|
3227
|
-
}
|
|
3228
|
-
};
|
|
3229
|
-
const workers = Array.from({ length: Math.min(concurrency, queue.length) });
|
|
3230
|
-
for (let i = 0; i < workers.length; i++) {
|
|
3231
|
-
processNext().then(() => {
|
|
3232
|
-
});
|
|
3233
|
-
}
|
|
3234
|
-
await Promise.all(workers);
|
|
3235
|
-
return results;
|
|
3236
|
-
}
|
|
3237
|
-
async function isLargeFile(filePath, threshold = 1024 * 1024) {
|
|
3238
|
-
return await getFileSize(filePath) > threshold;
|
|
3239
|
-
}
|
|
3240
|
-
async function getFileInfo(filePath, options = {}) {
|
|
3241
|
-
const size = await getFileSize(filePath);
|
|
3242
|
-
const isLarge = size > (options.chunkSize || DEFAULT_CHUNK_SIZE);
|
|
3243
|
-
const lines = isLarge ? await countLines(filePath) : 0;
|
|
3244
|
-
return {
|
|
3245
|
-
path: filePath,
|
|
3246
|
-
size,
|
|
3247
|
-
lines,
|
|
3248
|
-
isLarge,
|
|
3249
|
-
encoding: options.encoding || null
|
|
3250
|
-
};
|
|
3251
|
-
}
|
|
3252
|
-
|
|
3253
|
-
function capitalize(str) {
|
|
3254
|
-
if (!str)
|
|
3255
|
-
return str;
|
|
3256
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
3257
|
-
}
|
|
3258
|
-
function camelCase(str) {
|
|
3259
|
-
return str.replace(/^\w|[A-Z]|\b\w/g, (letter, index) => index === 0 ? letter.toLowerCase() : letter.toUpperCase()).replace(/\s+/g, "").replace(/[-_]/g, "");
|
|
3260
|
-
}
|
|
3261
|
-
function pascalCase(str) {
|
|
3262
|
-
return str.replace(/^\w|[A-Z]|\b\w/g, (letter) => letter.toUpperCase()).replace(/\s+/g, "").replace(/[-_]/g, "");
|
|
3263
|
-
}
|
|
3264
|
-
function snakeCase(str) {
|
|
3265
|
-
return str.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/\s+/g, "_").replace(/-/g, "_").replace(/^_/, "");
|
|
3266
|
-
}
|
|
3267
|
-
function kebabCase(str) {
|
|
3268
|
-
return str.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/\s+/g, "-").replace(/_/g, "-").replace(/^-/, "");
|
|
3269
|
-
}
|
|
3270
|
-
function constantCase(str) {
|
|
3271
|
-
return snakeCase(str).toUpperCase();
|
|
3272
|
-
}
|
|
3273
|
-
function truncate(str, length, suffix = "...") {
|
|
3274
|
-
if (str.length <= length)
|
|
3275
|
-
return str;
|
|
3276
|
-
return str.slice(0, length - suffix.length) + suffix;
|
|
3277
|
-
}
|
|
3278
|
-
function pad(str, length, char = " ", direction = "right") {
|
|
3279
|
-
if (str.length >= length)
|
|
3280
|
-
return str;
|
|
3281
|
-
const padLength = length - str.length;
|
|
3282
|
-
if (direction === "left") {
|
|
3283
|
-
return char.repeat(padLength) + str;
|
|
3284
|
-
} else if (direction === "right") {
|
|
3285
|
-
return str + char.repeat(padLength);
|
|
3286
|
-
} else {
|
|
3287
|
-
const leftPad = Math.floor(padLength / 2);
|
|
3288
|
-
const rightPad = padLength - leftPad;
|
|
3289
|
-
return char.repeat(leftPad) + str + char.repeat(rightPad);
|
|
3290
|
-
}
|
|
3291
|
-
}
|
|
3292
|
-
function trim(str) {
|
|
3293
|
-
return str.trim();
|
|
3294
|
-
}
|
|
3295
|
-
function trimStart(str) {
|
|
3296
|
-
return str.trimStart();
|
|
3297
|
-
}
|
|
3298
|
-
function trimEnd(str) {
|
|
3299
|
-
return str.trimEnd();
|
|
3300
|
-
}
|
|
3301
|
-
function split(str, delimiter) {
|
|
3302
|
-
return str.split(delimiter);
|
|
3303
|
-
}
|
|
3304
|
-
function join(arr, separator = "") {
|
|
3305
|
-
return arr.join(separator);
|
|
3306
|
-
}
|
|
3307
|
-
function replaceAll(str, search, replacement) {
|
|
3308
|
-
if (typeof search === "string") {
|
|
3309
|
-
return str.split(search).join(replacement);
|
|
3310
|
-
}
|
|
3311
|
-
return str.replace(new RegExp(search, "g"), replacement);
|
|
3312
|
-
}
|
|
3313
|
-
function startsWith(str, prefix) {
|
|
3314
|
-
return str.startsWith(prefix);
|
|
3315
|
-
}
|
|
3316
|
-
function endsWith(str, suffix) {
|
|
3317
|
-
return str.endsWith(suffix);
|
|
3318
|
-
}
|
|
3319
|
-
function contains(str, substring) {
|
|
3320
|
-
return str.includes(substring);
|
|
3321
|
-
}
|
|
3322
|
-
function countOccurrences(str, substring) {
|
|
3323
|
-
return str.split(substring).length - 1;
|
|
3324
|
-
}
|
|
3325
|
-
function reverse(str) {
|
|
3326
|
-
return str.split("").reverse().join("");
|
|
3327
|
-
}
|
|
3328
|
-
function removeWhitespace(str) {
|
|
3329
|
-
return str.replace(/\s+/g, "");
|
|
3330
|
-
}
|
|
3331
|
-
function normalizeWhitespace(str) {
|
|
3332
|
-
return str.replace(/\s+/g, " ").trim();
|
|
3333
|
-
}
|
|
3334
|
-
function words(str) {
|
|
3335
|
-
return str.match(/\b\w+\b/g) || [];
|
|
3336
|
-
}
|
|
3337
|
-
function wordCount(str) {
|
|
3338
|
-
return words(str).length;
|
|
3339
|
-
}
|
|
3340
|
-
function titleCase(str) {
|
|
3341
|
-
return str.toLowerCase().split(" ").map((word) => capitalize(word)).join(" ");
|
|
3342
|
-
}
|
|
3343
|
-
function sentenceCase(str) {
|
|
3344
|
-
return capitalize(str.toLowerCase());
|
|
3345
|
-
}
|
|
3346
|
-
function escapeHTML(str) {
|
|
3347
|
-
const htmlEscapes = {
|
|
3348
|
-
"&": "&",
|
|
3349
|
-
"<": "<",
|
|
3350
|
-
">": ">",
|
|
3351
|
-
'"': """,
|
|
3352
|
-
"'": "'"
|
|
3353
|
-
};
|
|
3354
|
-
return str.replace(/[&<>"']/g, (char) => htmlEscapes[char]);
|
|
3355
|
-
}
|
|
3356
|
-
function unescapeHTML(str) {
|
|
3357
|
-
const htmlUnescapes = {
|
|
3358
|
-
"&": "&",
|
|
3359
|
-
"<": "<",
|
|
3360
|
-
">": ">",
|
|
3361
|
-
""": '"',
|
|
3362
|
-
"'": "'"
|
|
3363
|
-
};
|
|
3364
|
-
return str.replace(/&(?:amp|lt|gt|quot|#39);/g, (entity) => htmlUnescapes[entity]);
|
|
3365
|
-
}
|
|
3366
|
-
function escapeRegExp(str) {
|
|
3367
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3368
|
-
}
|
|
3369
|
-
function randomString(length, charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") {
|
|
3370
|
-
let result = "";
|
|
3371
|
-
for (let i = 0; i < length; i++) {
|
|
3372
|
-
result += charset.charAt(Math.floor(Math.random() * charset.length));
|
|
3373
|
-
}
|
|
3374
|
-
return result;
|
|
3375
|
-
}
|
|
3376
|
-
function uuid() {
|
|
3377
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
3378
|
-
const r = Math.random() * 16 | 0;
|
|
3379
|
-
const v = c === "x" ? r : r & 3 | 8;
|
|
3380
|
-
return v.toString(16);
|
|
3381
|
-
});
|
|
3382
|
-
}
|
|
3383
|
-
function slugify(str) {
|
|
3384
|
-
return str.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
3385
|
-
}
|
|
3386
|
-
function extractNumbers(str) {
|
|
3387
|
-
const matches = str.match(/-?\d+\.?\d*/g);
|
|
3388
|
-
return matches ? matches.map(Number) : [];
|
|
3389
|
-
}
|
|
3390
|
-
function template(str, values) {
|
|
3391
|
-
return str.replace(/\{(\w+)\}/g, (match, key) => {
|
|
3392
|
-
return values[key] !== void 0 ? String(values[key]) : match;
|
|
3393
|
-
});
|
|
3394
|
-
}
|
|
3395
|
-
function repeat(str, count) {
|
|
3396
|
-
return str.repeat(count);
|
|
3397
|
-
}
|
|
3398
|
-
function isBlank(str) {
|
|
3399
|
-
return !str || str.trim().length === 0;
|
|
3400
|
-
}
|
|
3401
|
-
function ensureSuffix(str, suffix) {
|
|
3402
|
-
return endsWith(str, suffix) ? str : str + suffix;
|
|
3403
|
-
}
|
|
3404
|
-
function ensurePrefix(str, prefix) {
|
|
3405
|
-
return startsWith(str, prefix) ? str : prefix + str;
|
|
3406
|
-
}
|
|
3407
|
-
function removePrefix(str, prefix) {
|
|
3408
|
-
return startsWith(str, prefix) ? str.slice(prefix.length) : str;
|
|
3409
|
-
}
|
|
3410
|
-
function removeSuffix(str, suffix) {
|
|
3411
|
-
return endsWith(str, suffix) ? str.slice(0, -suffix.length) : str;
|
|
3412
|
-
}
|
|
3413
|
-
|
|
3414
|
-
const index = {
|
|
3415
|
-
__proto__: null,
|
|
3416
|
-
camelCase: camelCase,
|
|
3417
|
-
capitalize: capitalize,
|
|
3418
|
-
constantCase: constantCase,
|
|
3419
|
-
contains: contains,
|
|
3420
|
-
countOccurrences: countOccurrences,
|
|
3421
|
-
endsWith: endsWith,
|
|
3422
|
-
ensurePrefix: ensurePrefix,
|
|
3423
|
-
ensureSuffix: ensureSuffix,
|
|
3424
|
-
escapeHTML: escapeHTML,
|
|
3425
|
-
escapeRegExp: escapeRegExp,
|
|
3426
|
-
extractNumbers: extractNumbers,
|
|
3427
|
-
isBlank: isBlank,
|
|
3428
|
-
join: join,
|
|
3429
|
-
kebabCase: kebabCase,
|
|
3430
|
-
normalizeWhitespace: normalizeWhitespace,
|
|
3431
|
-
pad: pad,
|
|
3432
|
-
pascalCase: pascalCase,
|
|
3433
|
-
randomString: randomString,
|
|
3434
|
-
removePrefix: removePrefix,
|
|
3435
|
-
removeSuffix: removeSuffix,
|
|
3436
|
-
removeWhitespace: removeWhitespace,
|
|
3437
|
-
repeat: repeat,
|
|
3438
|
-
replaceAll: replaceAll,
|
|
3439
|
-
reverse: reverse,
|
|
3440
|
-
sentenceCase: sentenceCase,
|
|
3441
|
-
slugify: slugify,
|
|
3442
|
-
snakeCase: snakeCase,
|
|
3443
|
-
split: split,
|
|
3444
|
-
startsWith: startsWith,
|
|
3445
|
-
template: template,
|
|
3446
|
-
titleCase: titleCase,
|
|
3447
|
-
trim: trim,
|
|
3448
|
-
trimEnd: trimEnd,
|
|
3449
|
-
trimStart: trimStart,
|
|
3450
|
-
truncate: truncate,
|
|
3451
|
-
unescapeHTML: unescapeHTML,
|
|
3452
|
-
uuid: uuid,
|
|
3453
|
-
wordCount: wordCount,
|
|
3454
|
-
words: words
|
|
3455
|
-
};
|
|
3456
|
-
|
|
3457
|
-
function validateArrayAccess(array, index) {
|
|
3458
|
-
if (!Array.isArray(array)) {
|
|
3459
|
-
return { valid: false, error: "Input is not an array" };
|
|
3460
|
-
}
|
|
3461
|
-
if (index < 0 || index >= array.length) {
|
|
3462
|
-
return { valid: false, error: `Index ${index} out of bounds for array of length ${array.length}` };
|
|
3463
|
-
}
|
|
3464
|
-
return { valid: true };
|
|
3465
|
-
}
|
|
3466
|
-
function safeArrayAccess(array, index, defaultValue) {
|
|
3467
|
-
const validation = validateArrayAccess(array, index);
|
|
3468
|
-
if (!validation.valid) {
|
|
3469
|
-
return defaultValue;
|
|
3470
|
-
}
|
|
3471
|
-
return array[index];
|
|
3472
|
-
}
|
|
3473
|
-
function validateObjectKeyAccess(obj, key) {
|
|
3474
|
-
if (!obj || typeof obj !== "object") {
|
|
3475
|
-
return { valid: false, error: "Input is not an object" };
|
|
3476
|
-
}
|
|
3477
|
-
if (!(key in obj)) {
|
|
3478
|
-
return { valid: false, error: `Key "${key}" not found in object` };
|
|
3479
|
-
}
|
|
3480
|
-
return { valid: true };
|
|
3481
|
-
}
|
|
3482
|
-
function safeObjectAccess(obj, key, defaultValue) {
|
|
3483
|
-
if (!obj || typeof obj !== "object") {
|
|
3484
|
-
return defaultValue;
|
|
3485
|
-
}
|
|
3486
|
-
return key in obj ? obj[key] : defaultValue;
|
|
3487
|
-
}
|
|
3488
|
-
function isValidEnvVarName(name) {
|
|
3489
|
-
if (!name || typeof name !== "string") {
|
|
3490
|
-
return { valid: false, error: "Environment variable name must be a non-empty string" };
|
|
3491
|
-
}
|
|
3492
|
-
if (!/^[A-Z_][A-Z0-9_]*$/.test(name)) {
|
|
3493
|
-
return {
|
|
3494
|
-
valid: false,
|
|
3495
|
-
error: "Environment variable name must start with letter or underscore and contain only uppercase letters, numbers, and underscores"
|
|
3496
|
-
};
|
|
3497
|
-
}
|
|
3498
|
-
return { valid: true };
|
|
3499
|
-
}
|
|
3500
|
-
function sanitizeEnvValue(value) {
|
|
3501
|
-
if (!value || typeof value !== "string") {
|
|
3502
|
-
return "";
|
|
3503
|
-
}
|
|
3504
|
-
return value.replace(/[\n\r\0]/g, "");
|
|
3505
|
-
}
|
|
3506
|
-
function isValidUrl(url) {
|
|
3507
|
-
if (!url || typeof url !== "string") {
|
|
3508
|
-
return { valid: false, error: "URL must be a non-empty string" };
|
|
3509
|
-
}
|
|
3510
|
-
if (url.length > 2048) {
|
|
3511
|
-
return { valid: false, error: "URL is too long (max 2048 characters)" };
|
|
3512
|
-
}
|
|
3513
|
-
try {
|
|
3514
|
-
const parsed = new URL(url);
|
|
3515
|
-
if (!["http:", "https:"].includes(parsed.protocol)) {
|
|
3516
|
-
return { valid: false, error: "URL must use http:// or https://" };
|
|
3517
|
-
}
|
|
3518
|
-
if (!parsed.hostname) {
|
|
3519
|
-
return { valid: false, error: "URL must have a valid hostname" };
|
|
3520
|
-
}
|
|
3521
|
-
return { valid: true };
|
|
3522
|
-
} catch {
|
|
3523
|
-
return { valid: false, error: "Invalid URL format" };
|
|
3524
|
-
}
|
|
3525
|
-
}
|
|
3526
|
-
function isValidFilePath(path) {
|
|
3527
|
-
if (!path || typeof path !== "string") {
|
|
3528
|
-
return { valid: false, error: "Path must be a non-empty string" };
|
|
3529
|
-
}
|
|
3530
|
-
if (path.includes("..")) {
|
|
3531
|
-
return { valid: false, error: "Path contains directory traversal characters (..)" };
|
|
3532
|
-
}
|
|
3533
|
-
if (path.includes("\0")) {
|
|
3534
|
-
return { valid: false, error: "Path contains null bytes" };
|
|
3535
|
-
}
|
|
3536
|
-
return { valid: true };
|
|
3537
|
-
}
|
|
3538
|
-
function isValidPathEntry(entry) {
|
|
3539
|
-
if (!entry || typeof entry !== "string") {
|
|
3540
|
-
return { valid: false, error: "Path entry must be a non-empty string" };
|
|
3541
|
-
}
|
|
3542
|
-
if (entry.includes("..") || entry.includes("/") || entry.includes("\\")) {
|
|
3543
|
-
return { valid: false, error: "Path entry contains invalid characters" };
|
|
3544
|
-
}
|
|
3545
|
-
if (entry.includes("\0")) {
|
|
3546
|
-
return { valid: false, error: "Path entry contains null bytes" };
|
|
3547
|
-
}
|
|
3548
|
-
return { valid: true };
|
|
3549
|
-
}
|
|
3550
|
-
function validateUserInput(input, options = {}) {
|
|
3551
|
-
if (!input || typeof input !== "string") {
|
|
3552
|
-
return { valid: false, error: "Input must be a non-empty string" };
|
|
3553
|
-
}
|
|
3554
|
-
const trimmed = input.trim();
|
|
3555
|
-
if (trimmed.length === 0) {
|
|
3556
|
-
return { valid: false, error: "Input cannot be empty" };
|
|
3557
|
-
}
|
|
3558
|
-
const { minLength = 1, maxLength = 1e3, pattern, allowedChars } = options;
|
|
3559
|
-
if (trimmed.length < minLength) {
|
|
3560
|
-
return { valid: false, error: `Input must be at least ${minLength} characters` };
|
|
3561
|
-
}
|
|
3562
|
-
if (trimmed.length > maxLength) {
|
|
3563
|
-
return { valid: false, error: `Input must not exceed ${maxLength} characters` };
|
|
3564
|
-
}
|
|
3565
|
-
if (pattern && !pattern.test(trimmed)) {
|
|
3566
|
-
return { valid: false, error: "Input contains invalid characters" };
|
|
3567
|
-
}
|
|
3568
|
-
if (allowedChars) {
|
|
3569
|
-
const allowedSet = new Set(allowedChars);
|
|
3570
|
-
for (const char of trimmed) {
|
|
3571
|
-
if (!allowedSet.has(char)) {
|
|
3572
|
-
return { valid: false, error: `Input contains disallowed character: ${char}` };
|
|
3573
|
-
}
|
|
3574
|
-
}
|
|
3575
|
-
}
|
|
3576
|
-
return { valid: true };
|
|
3577
|
-
}
|
|
3578
|
-
function sanitizeUserInput(input, maxLength = 1e3) {
|
|
3579
|
-
if (!input || typeof input !== "string") {
|
|
3580
|
-
return "";
|
|
3581
|
-
}
|
|
3582
|
-
return input.trim().slice(0, maxLength);
|
|
3583
|
-
}
|
|
3584
|
-
function isValidApiKey(apiKey) {
|
|
3585
|
-
if (!apiKey || typeof apiKey !== "string") {
|
|
3586
|
-
return { valid: false, error: "API key must be a non-empty string" };
|
|
3587
|
-
}
|
|
3588
|
-
if (apiKey.length < 10) {
|
|
3589
|
-
return { valid: false, error: "API key is too short" };
|
|
3590
|
-
}
|
|
3591
|
-
if (apiKey.length > 500) {
|
|
3592
|
-
return { valid: false, error: "API key is too long" };
|
|
3593
|
-
}
|
|
3594
|
-
if (/\s/.test(apiKey)) {
|
|
3595
|
-
return { valid: false, error: "API key contains whitespace" };
|
|
3596
|
-
}
|
|
3597
|
-
return { valid: true };
|
|
3598
|
-
}
|
|
3599
|
-
function formatApiKeyDisplay(apiKey) {
|
|
3600
|
-
if (!apiKey || typeof apiKey !== "string" || apiKey.length < 12) {
|
|
3601
|
-
return "***";
|
|
3602
|
-
}
|
|
3603
|
-
return `${apiKey.substring(0, 8)}...${apiKey.substring(apiKey.length - 4)}`;
|
|
3604
|
-
}
|
|
3605
|
-
function validateConfigStructure(config, schema) {
|
|
3606
|
-
if (!config || typeof config !== "object") {
|
|
3607
|
-
return { valid: false, error: "Config must be an object" };
|
|
3608
|
-
}
|
|
3609
|
-
const configObj = config;
|
|
3610
|
-
for (const [key, expectedType] of Object.entries(schema)) {
|
|
3611
|
-
if (!(key in configObj)) {
|
|
3612
|
-
return { valid: false, error: `Missing required field: ${key}` };
|
|
3613
|
-
}
|
|
3614
|
-
const value = configObj[key];
|
|
3615
|
-
const actualType = Array.isArray(value) ? "array" : typeof value;
|
|
3616
|
-
if (actualType !== expectedType) {
|
|
3617
|
-
return {
|
|
3618
|
-
valid: false,
|
|
3619
|
-
error: `Field "${key}" has wrong type. Expected ${expectedType}, got ${actualType}`
|
|
3620
|
-
};
|
|
3621
|
-
}
|
|
3622
|
-
}
|
|
3623
|
-
return { valid: true };
|
|
3624
|
-
}
|
|
3625
|
-
function validateArray(array, validator) {
|
|
3626
|
-
if (!Array.isArray(array)) {
|
|
3627
|
-
return { valid: false, error: "Input is not an array" };
|
|
3628
|
-
}
|
|
3629
|
-
for (let i = 0; i < array.length; i++) {
|
|
3630
|
-
const result = validator(array[i]);
|
|
3631
|
-
if (!result.valid) {
|
|
3632
|
-
return { valid: false, error: `Item at index ${i}: ${result.error}` };
|
|
3633
|
-
}
|
|
3634
|
-
}
|
|
3635
|
-
return { valid: true };
|
|
3636
|
-
}
|
|
3637
|
-
function isValidEnumValue(value, allowedValues) {
|
|
3638
|
-
if (!allowedValues.includes(value)) {
|
|
3639
|
-
return {
|
|
3640
|
-
valid: false,
|
|
3641
|
-
error: `Invalid value. Must be one of: ${allowedValues.join(", ")}`
|
|
3642
|
-
};
|
|
3643
|
-
}
|
|
3644
|
-
return { valid: true };
|
|
3645
|
-
}
|
|
3646
|
-
function isValidPort(port) {
|
|
3647
|
-
if (typeof port !== "number" && typeof port !== "string") {
|
|
3648
|
-
return { valid: false, error: "Port must be a number or string" };
|
|
3649
|
-
}
|
|
3650
|
-
const portNum = typeof port === "string" ? Number.parseInt(port, 10) : port;
|
|
3651
|
-
if (!Number.isInteger(portNum) || portNum < 1 || portNum > 65535) {
|
|
3652
|
-
return { valid: false, error: "Port must be between 1 and 65535" };
|
|
3653
|
-
}
|
|
3654
|
-
return { valid: true };
|
|
3655
|
-
}
|
|
3656
|
-
function isValidHostname(hostname) {
|
|
3657
|
-
if (!hostname || typeof hostname !== "string") {
|
|
3658
|
-
return { valid: false, error: "Hostname must be a non-empty string" };
|
|
3659
|
-
}
|
|
3660
|
-
if (hostname.length > 253) {
|
|
3661
|
-
return { valid: false, error: "Hostname is too long (max 253 characters)" };
|
|
3662
|
-
}
|
|
3663
|
-
if (!/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i.test(hostname)) {
|
|
3664
|
-
return { valid: false, error: "Invalid hostname format" };
|
|
3665
|
-
}
|
|
3666
|
-
return { valid: true };
|
|
3667
|
-
}
|
|
3668
|
-
|
|
3669
|
-
const validation = {
|
|
3670
|
-
__proto__: null,
|
|
3671
|
-
formatApiKeyDisplay: formatApiKeyDisplay,
|
|
3672
|
-
isValidApiKey: isValidApiKey,
|
|
3673
|
-
isValidEnumValue: isValidEnumValue,
|
|
3674
|
-
isValidEnvVarName: isValidEnvVarName,
|
|
3675
|
-
isValidFilePath: isValidFilePath,
|
|
3676
|
-
isValidHostname: isValidHostname,
|
|
3677
|
-
isValidPathEntry: isValidPathEntry,
|
|
3678
|
-
isValidPort: isValidPort,
|
|
3679
|
-
isValidUrl: isValidUrl,
|
|
3680
|
-
safeArrayAccess: safeArrayAccess,
|
|
3681
|
-
safeObjectAccess: safeObjectAccess,
|
|
3682
|
-
sanitizeEnvValue: sanitizeEnvValue,
|
|
3683
|
-
sanitizeUserInput: sanitizeUserInput,
|
|
3684
|
-
validateArray: validateArray,
|
|
3685
|
-
validateArrayAccess: validateArrayAccess,
|
|
3686
|
-
validateConfigStructure: validateConfigStructure,
|
|
3687
|
-
validateObjectKeyAccess: validateObjectKeyAccess,
|
|
3688
|
-
validateUserInput: validateUserInput
|
|
3689
|
-
};
|
|
3690
|
-
|
|
3691
|
-
function isDefined(value) {
|
|
3692
|
-
return value !== null && value !== void 0;
|
|
3693
|
-
}
|
|
3694
|
-
function isString(value) {
|
|
3695
|
-
return typeof value === "string";
|
|
3696
|
-
}
|
|
3697
|
-
function isNumber(value) {
|
|
3698
|
-
return typeof value === "number" && !isNaN(value);
|
|
3699
|
-
}
|
|
3700
|
-
function isBoolean(value) {
|
|
3701
|
-
return typeof value === "boolean";
|
|
3702
|
-
}
|
|
3703
|
-
function isObject(value) {
|
|
3704
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3705
|
-
}
|
|
3706
|
-
function isArray(value) {
|
|
3707
|
-
return Array.isArray(value);
|
|
3708
|
-
}
|
|
3709
|
-
function isEmail(value) {
|
|
3710
|
-
const emailRegex = /^[^\s@]+@[^\s@][^\s.@]*\.[^\s@]+$/;
|
|
3711
|
-
return emailRegex.test(value);
|
|
3712
|
-
}
|
|
3713
|
-
function isURL(value) {
|
|
3714
|
-
try {
|
|
3715
|
-
new URL(value);
|
|
3716
|
-
return true;
|
|
3717
|
-
} catch {
|
|
3718
|
-
return false;
|
|
3719
|
-
}
|
|
3720
|
-
}
|
|
3721
|
-
function assertDefined(value, message) {
|
|
3722
|
-
if (!isDefined(value)) {
|
|
3723
|
-
throw new Error(message || "Value is null or undefined");
|
|
3724
|
-
}
|
|
3725
|
-
}
|
|
3726
|
-
function assert(condition, message) {
|
|
3727
|
-
if (!condition) {
|
|
3728
|
-
throw new Error(message || "Assertion failed");
|
|
3729
|
-
}
|
|
3730
|
-
}
|
|
3731
|
-
|
|
3732
|
-
export { BaseError, ConfigManager, ConfigValidator, ConfigurationError, InternalError, Logger, Mutex, NotFoundError, RatingsApiError, RatingsApiErrorCode, Semaphore, TimeoutError, ToolFactory, ToolRegistry, UnauthorizedError, ValidationError, index$6 as array, assert, assertDefined, index$5 as async, batchProcessFiles, camelCase, canInstallMore, capitalize, chunk, index$4 as command, commandExists, convertBatchTemplateResponse, convertConfig, convertParameterDefault, convertProjectAnalysisResponse, convertRecommendation, convertTemplate, convertTemplateParameter, copyFile, countLines, createCloudClient, createConfigManager, createLogger, createRating, createTool, createValidator, debounce, deepClone, deepMerge, deleteDir, deleteFile, difference, ensureDir, index$3 as error, executeCommand, executeCommandStream, exists, extractString, flatten, flatten$1 as flattenArray, formatError, index$2 as fs, generateCompactWelcome, generateRecommendations, generateWelcome, get, getArchitecture, getCacheDir, getCapabilitiesByType, getCapability, getCloudMcpRecommendations, getCloudRecommendations, getCloudSkillRecommendations, getCommandPath, getCommandVersion, getConfigDir, getDataDir, getDisabledSkills, getEnabledSkills, getErrorMessage, getFileInfo, getFileSize, getHomeDir, getPlatform, getPlatformInfo, getQuotaUsagePercentage, getRecommendations, getSkillRatings, getTempDir, getUserQuota, getUserSkills, has, installSkill, intersection, isArray, isBoolean, isDefined, isDirectory, isDuplicateRatingError, isEmail, isFile, isLargeFile, isLinux, isMacOS, isNumber, isObject, isRecommendationConfig, isSkillInstalled, isSkillNotFoundError, isString, isTelemetryEventData, isTemplateParameterValue, isURL, isUnauthorizedError, isUnix, isWindows, kebabCase, listDirs, listFiles, logger, moveFile, index$1 as object, omit, parallelLimit, partition, pascalCase, pick, processLargeFile, processLineByLine, ratingsApi, readFile, readJSON, retry, scanCapabilities, sequence, set, shuffle, skillsMarketplaceApi, sleep, slugify, snakeCase, sortByLastUsed, sortByUsage, streamJSON, streamWriteJSON, index as string, template, throttle, timeout, truncate, tryCatch, tryCatchAsync, unflatten, uninstallSkill, union, unique, updateSkill, userSkillsApi, validateBatchTemplateRequest, validateProjectAnalysisRequest, validateUsageReport, validation, validators, waitFor, wrapError, writeFile, writeJSON };
|