@curdx/flow 3.0.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -82
- package/LICENSE +1 -1
- package/README.md +28 -129
- package/dist/index.mjs +1165 -0
- package/package.json +33 -44
- package/.claude-plugin/marketplace.json +0 -48
- package/.claude-plugin/plugin.json +0 -52
- package/agent-preamble/preamble.md +0 -314
- package/agents/flow-adversary.md +0 -203
- package/agents/flow-architect.md +0 -198
- package/agents/flow-brownfield-analyst.md +0 -143
- package/agents/flow-debugger.md +0 -321
- package/agents/flow-edge-hunter.md +0 -289
- package/agents/flow-executor.md +0 -269
- package/agents/flow-orchestrator.md +0 -145
- package/agents/flow-planner.md +0 -247
- package/agents/flow-product-designer.md +0 -159
- package/agents/flow-qa-engineer.md +0 -282
- package/agents/flow-researcher.md +0 -166
- package/agents/flow-reviewer.md +0 -304
- package/agents/flow-security-auditor.md +0 -401
- package/agents/flow-triage-analyst.md +0 -272
- package/agents/flow-ui-researcher.md +0 -230
- package/agents/flow-ux-designer.md +0 -221
- package/agents/flow-verifier.md +0 -350
- package/bin/curdx-flow +0 -5
- package/bin/curdx-flow-state +0 -104
- package/bin/curdx-flow.js +0 -54
- package/cli/README.md +0 -104
- package/cli/doctor-workflow.js +0 -483
- package/cli/doctor.js +0 -73
- package/cli/help.js +0 -59
- package/cli/install-bundled-mcps.js +0 -37
- package/cli/install-companions.js +0 -19
- package/cli/install-context7-config.js +0 -80
- package/cli/install-curdx-plugin.js +0 -96
- package/cli/install-language.js +0 -35
- package/cli/install-next-steps.js +0 -29
- package/cli/install-options.js +0 -9
- package/cli/install-paths.js +0 -52
- package/cli/install-recommended-plugins.js +0 -104
- package/cli/install-required-plugins.js +0 -57
- package/cli/install-self-update.js +0 -62
- package/cli/install-workflow.js +0 -209
- package/cli/install.js +0 -101
- package/cli/lib/claude-commands.js +0 -41
- package/cli/lib/claude-ops.js +0 -47
- package/cli/lib/claude.js +0 -183
- package/cli/lib/config.js +0 -24
- package/cli/lib/doctor-claude-settings.js +0 -1186
- package/cli/lib/doctor-report.js +0 -978
- package/cli/lib/doctor-runtime-environment.js +0 -196
- package/cli/lib/frontmatter.js +0 -44
- package/cli/lib/json-schema.js +0 -57
- package/cli/lib/logging.js +0 -25
- package/cli/lib/process.js +0 -60
- package/cli/lib/prompts.js +0 -135
- package/cli/lib/runtime.js +0 -107
- package/cli/lib/semver.js +0 -109
- package/cli/lib/version.js +0 -12
- package/cli/protocols-body.md +0 -22
- package/cli/protocols.js +0 -162
- package/cli/registry.js +0 -123
- package/cli/router.js +0 -49
- package/cli/uninstall-actions.js +0 -360
- package/cli/uninstall-workflow.js +0 -146
- package/cli/uninstall.js +0 -42
- package/cli/upgrade-workflow.js +0 -80
- package/cli/upgrade.js +0 -91
- package/cli/utils.js +0 -40
- package/gates/adversarial-review-gate.md +0 -219
- package/gates/coverage-audit-gate.md +0 -182
- package/gates/devex-gate.md +0 -254
- package/gates/edge-case-gate.md +0 -194
- package/gates/karpathy-gate.md +0 -130
- package/gates/security-gate.md +0 -218
- package/gates/tdd-gate.md +0 -182
- package/gates/test-quality-gate.md +0 -59
- package/gates/verification-gate.md +0 -179
- package/hooks/hooks.json +0 -130
- package/hooks/scripts/common.sh +0 -237
- package/hooks/scripts/config-change-guard.sh +0 -94
- package/hooks/scripts/flow-context-watch.sh +0 -94
- package/hooks/scripts/inject-karpathy.sh +0 -53
- package/hooks/scripts/quick-mode-guard.sh +0 -69
- package/hooks/scripts/session-start.sh +0 -94
- package/hooks/scripts/session-title.sh +0 -87
- package/hooks/scripts/stop-watcher.sh +0 -231
- package/hooks/scripts/subagent-artifact-guard.sh +0 -92
- package/hooks/scripts/subagent-statusline.sh +0 -111
- package/hooks/scripts/task-lifecycle-guard.sh +0 -106
- package/hooks/scripts/teammate-idle-guard.sh +0 -83
- package/knowledge/artifact-output-discipline.md +0 -24
- package/knowledge/artifact-summary-contracts.md +0 -50
- package/knowledge/atomic-commits.md +0 -262
- package/knowledge/claude-code-runtime-contracts.md +0 -240
- package/knowledge/epic-decomposition.md +0 -307
- package/knowledge/execution-strategies.md +0 -303
- package/knowledge/karpathy-guidelines.md +0 -219
- package/knowledge/planning-reviews.md +0 -211
- package/knowledge/poc-first-workflow.md +0 -223
- package/knowledge/review-feedback-intake.md +0 -57
- package/knowledge/spec-driven-development.md +0 -180
- package/knowledge/systematic-debugging.md +0 -378
- package/knowledge/two-stage-review.md +0 -249
- package/knowledge/wave-execution.md +0 -403
- package/monitors/monitors.json +0 -8
- package/monitors/scripts/flow-state-monitor.sh +0 -102
- package/output-styles/curdx-evidence-first.md +0 -34
- package/output-styles/curdx-fast-mode.md +0 -42
- package/output-styles/curdx-spec-mode.md +0 -46
- package/schemas/agent-frontmatter.schema.json +0 -66
- package/schemas/config.schema.json +0 -134
- package/schemas/gate-frontmatter.schema.json +0 -30
- package/schemas/hooks.schema.json +0 -115
- package/schemas/output-style-frontmatter.schema.json +0 -22
- package/schemas/plugin-manifest.schema.json +0 -436
- package/schemas/plugin-settings.schema.json +0 -29
- package/schemas/skill-frontmatter.schema.json +0 -177
- package/schemas/spec-frontmatter.schema.json +0 -42
- package/schemas/spec-state.schema.json +0 -165
- package/settings.json +0 -8
- package/skills/brownfield-index/SKILL.md +0 -53
- package/skills/brownfield-index/references/applicability.md +0 -12
- package/skills/brownfield-index/references/handoff.md +0 -8
- package/skills/brownfield-index/references/index-contract.md +0 -10
- package/skills/browser-qa/SKILL.md +0 -39
- package/skills/browser-qa/references/handoff.md +0 -6
- package/skills/browser-qa/references/prerequisites.md +0 -10
- package/skills/browser-qa/references/qa-contract.md +0 -20
- package/skills/cancel/SKILL.md +0 -41
- package/skills/cancel/references/destructive-mode.md +0 -17
- package/skills/cancel/references/reporting.md +0 -18
- package/skills/cancel/references/state-recovery.md +0 -30
- package/skills/cancel/references/target-resolution.md +0 -7
- package/skills/debug/SKILL.md +0 -45
- package/skills/debug/references/context-gathering.md +0 -11
- package/skills/debug/references/failure-guard.md +0 -25
- package/skills/debug/references/intake.md +0 -12
- package/skills/debug/references/phase-workflow.md +0 -34
- package/skills/debug/references/reporting.md +0 -20
- package/skills/epic/SKILL.md +0 -39
- package/skills/epic/references/epic-artifacts.md +0 -20
- package/skills/epic/references/epic-intake.md +0 -9
- package/skills/epic/references/slice-handoff.md +0 -16
- package/skills/fast/SKILL.md +0 -62
- package/skills/fast/references/applicability.md +0 -25
- package/skills/fast/references/clarification.md +0 -20
- package/skills/fast/references/execution-contract.md +0 -56
- package/skills/help/SKILL.md +0 -55
- package/skills/help/references/dispatch.md +0 -20
- package/skills/help/references/overview.md +0 -39
- package/skills/help/references/troubleshoot.md +0 -47
- package/skills/help/references/workflow.md +0 -37
- package/skills/implement/SKILL.md +0 -104
- package/skills/implement/references/error-recovery.md +0 -36
- package/skills/implement/references/linear-execution.md +0 -43
- package/skills/implement/references/native-task-sync.md +0 -107
- package/skills/implement/references/preflight.md +0 -43
- package/skills/implement/references/progress-contract.md +0 -36
- package/skills/implement/references/state-init.md +0 -36
- package/skills/implement/references/stop-hook-execution.md +0 -50
- package/skills/implement/references/strategy-router.md +0 -38
- package/skills/implement/references/subagent-execution.md +0 -57
- package/skills/implement/references/wave-execution.md +0 -180
- package/skills/init/SKILL.md +0 -49
- package/skills/init/references/gitignore-and-health.md +0 -26
- package/skills/init/references/next-steps.md +0 -22
- package/skills/init/references/preflight.md +0 -15
- package/skills/init/references/scaffold-contract.md +0 -27
- package/skills/review/SKILL.md +0 -82
- package/skills/review/references/optional-passes.md +0 -48
- package/skills/review/references/preflight.md +0 -38
- package/skills/review/references/report-contract.md +0 -49
- package/skills/review/references/reporting.md +0 -20
- package/skills/review/references/stage-execution.md +0 -32
- package/skills/security-audit/SKILL.md +0 -47
- package/skills/security-audit/references/audit-contract.md +0 -21
- package/skills/security-audit/references/gate-handoff.md +0 -8
- package/skills/security-audit/references/scope-and-depth.md +0 -9
- package/skills/spec/SKILL.md +0 -100
- package/skills/spec/references/artifact-landing.md +0 -31
- package/skills/spec/references/phase-execution.md +0 -50
- package/skills/spec/references/planning-review.md +0 -31
- package/skills/spec/references/preflight-and-routing.md +0 -46
- package/skills/spec/references/reporting.md +0 -21
- package/skills/start/SKILL.md +0 -84
- package/skills/start/references/branch-routing.md +0 -51
- package/skills/start/references/mode-semantics.md +0 -12
- package/skills/start/references/preflight.md +0 -13
- package/skills/start/references/reporting.md +0 -20
- package/skills/start/references/state-seeding.md +0 -44
- package/skills/start/references/workflow-handoff.md +0 -26
- package/skills/status/SKILL.md +0 -41
- package/skills/status/references/gather-contract.md +0 -30
- package/skills/status/references/health-rules.md +0 -27
- package/skills/status/references/output-contract.md +0 -25
- package/skills/status/references/preflight.md +0 -10
- package/skills/status/references/recovery-hints.md +0 -18
- package/skills/ui-sketch/SKILL.md +0 -39
- package/skills/ui-sketch/references/brief-intake.md +0 -10
- package/skills/ui-sketch/references/iteration-handoff.md +0 -5
- package/skills/ui-sketch/references/variant-contract.md +0 -15
- package/skills/verify/SKILL.md +0 -56
- package/skills/verify/references/evidence-workflow.md +0 -39
- package/skills/verify/references/output-contract.md +0 -23
- package/skills/verify/references/preflight.md +0 -11
- package/skills/verify/references/report-handoff.md +0 -35
- package/skills/verify/references/strict-mode.md +0 -12
- package/templates/CONTEXT.md.tmpl +0 -53
- package/templates/PROJECT.md.tmpl +0 -59
- package/templates/ROADMAP.md.tmpl +0 -50
- package/templates/STATE.md.tmpl +0 -49
- package/templates/config.json.tmpl +0 -51
- package/templates/design.md.tmpl +0 -83
- package/templates/progress.md.tmpl +0 -77
- package/templates/requirements.md.tmpl +0 -76
- package/templates/research.md.tmpl +0 -83
- package/templates/tasks.md.tmpl +0 -107
package/cli/uninstall-actions.js
DELETED
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
import { existsSync, lstatSync, unlinkSync, rmSync, readlinkSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
|
-
|
|
5
|
-
import { REQUIRED_PLUGINS, RECOMMENDED_PLUGINS, BUNDLED_MCPS } from "./registry.js";
|
|
6
|
-
import { readConfig, writeConfig } from "./lib/config.js";
|
|
7
|
-
import {
|
|
8
|
-
removeMcp,
|
|
9
|
-
removePluginMarketplace,
|
|
10
|
-
uninstallPlugin,
|
|
11
|
-
} from "./lib/claude-ops.js";
|
|
12
|
-
import {
|
|
13
|
-
confirm,
|
|
14
|
-
color,
|
|
15
|
-
listPlugins,
|
|
16
|
-
log,
|
|
17
|
-
resultLastLine,
|
|
18
|
-
resultOutput,
|
|
19
|
-
} from "./utils.js";
|
|
20
|
-
import { reconcileLegacyContext7InstallState } from "./install-context7-config.js";
|
|
21
|
-
import {
|
|
22
|
-
UNINSTALL_STEP_COUNT,
|
|
23
|
-
getInstalledTargets,
|
|
24
|
-
getManagedMarketplaceIds,
|
|
25
|
-
selectRecommendedPluginsToRemove,
|
|
26
|
-
shouldKeepBundledMcps,
|
|
27
|
-
shouldKeepRequiredPlugins,
|
|
28
|
-
} from "./uninstall-workflow.js";
|
|
29
|
-
|
|
30
|
-
const HOME = homedir();
|
|
31
|
-
|
|
32
|
-
const RECOMMENDED = RECOMMENDED_PLUGINS.map(toUninstallTarget);
|
|
33
|
-
const REQUIRED = REQUIRED_PLUGINS.map(toUninstallTarget);
|
|
34
|
-
|
|
35
|
-
// Symlinks created by install.js (only cleaned with --purge)
|
|
36
|
-
const MANAGED_SYMLINKS = [
|
|
37
|
-
join(HOME, ".local", "bin", "bun"),
|
|
38
|
-
join(HOME, ".local", "bin", "uv"),
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
export async function uninstallCurdxFlowPlugin(
|
|
42
|
-
{
|
|
43
|
-
listPluginsImpl = listPlugins,
|
|
44
|
-
uninstallPluginImpl = uninstallPlugin,
|
|
45
|
-
logImpl = log,
|
|
46
|
-
resultOutputImpl = resultOutput,
|
|
47
|
-
} = {}
|
|
48
|
-
) {
|
|
49
|
-
logImpl.blank();
|
|
50
|
-
logImpl.step(1, UNINSTALL_STEP_COUNT, "Uninstalling curdx-flow plugin...");
|
|
51
|
-
const curdx = listPluginsImpl().find((plugin) => plugin.name === "curdx-flow");
|
|
52
|
-
if (!curdx) {
|
|
53
|
-
logImpl.info("curdx-flow not installed, skipping");
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const result = await uninstallPluginImpl({
|
|
58
|
-
scope: "user",
|
|
59
|
-
uninstallSpec: "curdx-flow@curdx-flow-marketplace",
|
|
60
|
-
});
|
|
61
|
-
if (result.code === 0) {
|
|
62
|
-
logImpl.ok("curdx-flow uninstalled");
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
logImpl.err(`Uninstall failed: ${resultOutputImpl(result)}`);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export async function maybeUninstallRecommendedPlugins(
|
|
70
|
-
{ yes, keepRecommended },
|
|
71
|
-
{
|
|
72
|
-
getInstalledTargetsImpl = getInstalledTargets,
|
|
73
|
-
selectRecommendedPluginsToRemoveImpl = selectRecommendedPluginsToRemove,
|
|
74
|
-
uninstallNamedPluginImpl = uninstallNamedPlugin,
|
|
75
|
-
logImpl = log,
|
|
76
|
-
} = {}
|
|
77
|
-
) {
|
|
78
|
-
logImpl.blank();
|
|
79
|
-
logImpl.step(2, UNINSTALL_STEP_COUNT, "Recommended plugins");
|
|
80
|
-
if (keepRecommended) {
|
|
81
|
-
logImpl.info("Keeping recommended plugins (--keep-recommended)");
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const present = getInstalledTargetsImpl(RECOMMENDED);
|
|
86
|
-
if (present.length === 0) {
|
|
87
|
-
logImpl.info("No installed recommended plugins");
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const selected = await selectRecommendedPluginsToRemoveImpl({ yes, present });
|
|
92
|
-
for (const name of selected) {
|
|
93
|
-
const entry = present.find((plugin) => plugin.name === name);
|
|
94
|
-
if (!entry) continue;
|
|
95
|
-
await uninstallNamedPluginImpl(entry);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export async function uninstallNamedPlugin(
|
|
100
|
-
entry,
|
|
101
|
-
{
|
|
102
|
-
uninstallPluginImpl = uninstallPlugin,
|
|
103
|
-
resultLastLineImpl = resultLastLine,
|
|
104
|
-
} = {}
|
|
105
|
-
) {
|
|
106
|
-
log.blank();
|
|
107
|
-
console.log(` ${color.cyan("▸")} Uninstalling ${color.bold(entry.name)}...`);
|
|
108
|
-
const result = await uninstallPluginImpl(entry);
|
|
109
|
-
if (result.code === 0) {
|
|
110
|
-
console.log(` ${color.green("✓")} ${entry.name} uninstalled`);
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
console.log(
|
|
115
|
-
` ${color.red("✗")} ${entry.name} uninstall failed: ${resultLastLineImpl(result)}`
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export async function maybeRemoveBundledMcps(
|
|
120
|
-
{ yes, keepRecommended },
|
|
121
|
-
{
|
|
122
|
-
shouldKeepBundledMcpsImpl = shouldKeepBundledMcps,
|
|
123
|
-
confirmImpl = confirm,
|
|
124
|
-
removeMcpImpl = removeMcp,
|
|
125
|
-
logImpl = log,
|
|
126
|
-
} = {}
|
|
127
|
-
) {
|
|
128
|
-
logImpl.blank();
|
|
129
|
-
logImpl.info("Required user-level MCP servers (sequential-thinking)");
|
|
130
|
-
if (shouldKeepBundledMcpsImpl({ yes, keepRecommended })) {
|
|
131
|
-
logImpl.info(
|
|
132
|
-
color.dim("--yes or --keep-recommended: keeping user-level MCPs (remove manually with `claude mcp remove <name>`)")
|
|
133
|
-
);
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const removeMcps = await confirmImpl(
|
|
138
|
-
`Remove user-level MCPs registered by install (${BUNDLED_MCPS.map((mcp) => mcp.name).join(", ")})? ${color.dim("(keeps them if other tools depend on them)")}`,
|
|
139
|
-
false
|
|
140
|
-
);
|
|
141
|
-
if (!removeMcps) {
|
|
142
|
-
logImpl.info("Keeping user-level MCPs");
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
for (const mcp of BUNDLED_MCPS) {
|
|
147
|
-
const result = await removeMcpImpl({ name: mcp.name });
|
|
148
|
-
if (result.code === 0) {
|
|
149
|
-
logImpl.ok(` ${mcp.name.padEnd(22)} removed`);
|
|
150
|
-
} else {
|
|
151
|
-
logImpl.info(` ${mcp.name.padEnd(22)} ${color.dim("not present or already removed")}`);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export async function maybeUninstallRequiredPlugins(
|
|
157
|
-
{ yes },
|
|
158
|
-
{
|
|
159
|
-
shouldKeepRequiredPluginsImpl = shouldKeepRequiredPlugins,
|
|
160
|
-
confirmImpl = confirm,
|
|
161
|
-
uninstallPluginImpl = uninstallPlugin,
|
|
162
|
-
logImpl = log,
|
|
163
|
-
} = {}
|
|
164
|
-
) {
|
|
165
|
-
logImpl.blank();
|
|
166
|
-
logImpl.info("Required companion plugins");
|
|
167
|
-
if (shouldKeepRequiredPluginsImpl({ yes })) {
|
|
168
|
-
logImpl.info(
|
|
169
|
-
color.dim("--yes mode: keeping required companion plugins (use --purge to remove them)")
|
|
170
|
-
);
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const removeRequired = await confirmImpl(
|
|
175
|
-
`Remove required companion plugins (${REQUIRED.map((plugin) => plugin.name).join(", ")})? ${color.dim("(keeps shared tools available if other workflows depend on them)")}`,
|
|
176
|
-
false
|
|
177
|
-
);
|
|
178
|
-
if (!removeRequired) {
|
|
179
|
-
logImpl.info("Keeping required companion plugins");
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
for (const plugin of REQUIRED) {
|
|
184
|
-
const result = await uninstallPluginImpl(plugin);
|
|
185
|
-
if (result.code === 0) {
|
|
186
|
-
logImpl.ok(` ${plugin.name.padEnd(22)} uninstalled`);
|
|
187
|
-
} else {
|
|
188
|
-
logImpl.info(` ${plugin.name.padEnd(22)} ${color.dim("not present or already removed")}`);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
export async function maybePurgeRuntimeArtifacts(
|
|
194
|
-
{ purge },
|
|
195
|
-
{
|
|
196
|
-
purgeManagedMarketplacesImpl = purgeManagedMarketplaces,
|
|
197
|
-
removeManagedSymlinksImpl = removeManagedSymlinks,
|
|
198
|
-
readConfigImpl = readConfig,
|
|
199
|
-
writeConfigImpl = writeConfig,
|
|
200
|
-
removeMcpImpl = removeMcp,
|
|
201
|
-
readUserMcpConfigImpl,
|
|
202
|
-
logImpl = log,
|
|
203
|
-
} = {}
|
|
204
|
-
) {
|
|
205
|
-
logImpl.blank();
|
|
206
|
-
logImpl.step(3, UNINSTALL_STEP_COUNT, "Runtime symlinks and marketplaces");
|
|
207
|
-
if (!purge) {
|
|
208
|
-
logImpl.info(
|
|
209
|
-
color.dim("Keeping ~/.local/bin/bun, ~/.local/bin/uv (use --purge to remove)")
|
|
210
|
-
);
|
|
211
|
-
logImpl.info(
|
|
212
|
-
color.dim("Reason: these bun/uv binaries may be used by other tools — confirm before deleting")
|
|
213
|
-
);
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
await purgeManagedMarketplacesImpl();
|
|
218
|
-
removeManagedSymlinksImpl();
|
|
219
|
-
await purgeLegacyContext7InstallState({
|
|
220
|
-
readConfigImpl,
|
|
221
|
-
writeConfigImpl,
|
|
222
|
-
removeMcpImpl,
|
|
223
|
-
readUserMcpConfigImpl,
|
|
224
|
-
logImpl,
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
export async function maybeRemoveProjectState(
|
|
229
|
-
{ yes },
|
|
230
|
-
{
|
|
231
|
-
cwd = process.cwd(),
|
|
232
|
-
confirmImpl = confirm,
|
|
233
|
-
existsSyncImpl = existsSync,
|
|
234
|
-
rmSyncImpl = rmSync,
|
|
235
|
-
logImpl = log,
|
|
236
|
-
} = {}
|
|
237
|
-
) {
|
|
238
|
-
logImpl.blank();
|
|
239
|
-
logImpl.step(4, UNINSTALL_STEP_COUNT, "Project state directory");
|
|
240
|
-
const flowDir = join(cwd, ".flow");
|
|
241
|
-
if (!existsSyncImpl(flowDir)) {
|
|
242
|
-
logImpl.info(".flow/ does not exist, skipping");
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
if (yes) {
|
|
247
|
-
logImpl.info(
|
|
248
|
-
color.dim("--yes mode: keeping .flow/ (contains specs & decisions — confirm by hand before deleting)")
|
|
249
|
-
);
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const ok = await confirmImpl(
|
|
254
|
-
`${color.red("DANGER:")} delete the ${color.bold(".flow/")} directory of the current project? ${color.dim("(includes all specs / decisions, not recoverable)")}`,
|
|
255
|
-
false
|
|
256
|
-
);
|
|
257
|
-
if (!ok) {
|
|
258
|
-
logImpl.info("Keeping .flow/");
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
try {
|
|
263
|
-
rmSyncImpl(flowDir, { recursive: true, force: true });
|
|
264
|
-
logImpl.ok(`Removed ${flowDir}`);
|
|
265
|
-
} catch (err) {
|
|
266
|
-
logImpl.err(`Removal failed: ${err.message}`);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
async function purgeManagedMarketplaces(
|
|
271
|
-
{
|
|
272
|
-
getManagedMarketplaceIdsImpl = getManagedMarketplaceIds,
|
|
273
|
-
removePluginMarketplaceImpl = removePluginMarketplace,
|
|
274
|
-
logImpl = log,
|
|
275
|
-
} = {}
|
|
276
|
-
) {
|
|
277
|
-
const marketplaceIds = getManagedMarketplaceIdsImpl(RECOMMENDED.concat(REQUIRED));
|
|
278
|
-
|
|
279
|
-
for (const marketplaceId of marketplaceIds) {
|
|
280
|
-
const result = await removePluginMarketplaceImpl(marketplaceId);
|
|
281
|
-
if (result.code === 0) {
|
|
282
|
-
logImpl.ok(`Removed marketplace ${marketplaceId}`);
|
|
283
|
-
} else if (!result.stderr.includes("not found")) {
|
|
284
|
-
logImpl.warn(`Failed to remove marketplace ${marketplaceId}: ${resultLastLine(result)}`);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
function removeManagedSymlinks(
|
|
290
|
-
{
|
|
291
|
-
existsSyncImpl = existsSync,
|
|
292
|
-
isBrokenSymlinkImpl = isBrokenSymlink,
|
|
293
|
-
lstatSyncImpl = lstatSync,
|
|
294
|
-
readlinkSyncImpl = readlinkSync,
|
|
295
|
-
unlinkSyncImpl = unlinkSync,
|
|
296
|
-
logImpl = log,
|
|
297
|
-
} = {}
|
|
298
|
-
) {
|
|
299
|
-
for (const link of MANAGED_SYMLINKS) {
|
|
300
|
-
if (!existsSyncImpl(link) && !isBrokenSymlinkImpl(link)) {
|
|
301
|
-
continue;
|
|
302
|
-
}
|
|
303
|
-
try {
|
|
304
|
-
const stat = lstatSyncImpl(link);
|
|
305
|
-
if (!stat.isSymbolicLink()) {
|
|
306
|
-
logImpl.warn(
|
|
307
|
-
`${link} is not a symlink (likely a real file placed by the user), skipping`
|
|
308
|
-
);
|
|
309
|
-
continue;
|
|
310
|
-
}
|
|
311
|
-
const target = readlinkSyncImpl(link);
|
|
312
|
-
unlinkSyncImpl(link);
|
|
313
|
-
logImpl.ok(`Removed symlink ${link} ${color.dim(`(was → ${target})`)}`);
|
|
314
|
-
} catch (err) {
|
|
315
|
-
logImpl.warn(`Failed to remove ${link}: ${err.message}`);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
async function purgeLegacyContext7InstallState(
|
|
321
|
-
{
|
|
322
|
-
readConfigImpl = readConfig,
|
|
323
|
-
writeConfigImpl = writeConfig,
|
|
324
|
-
removeMcpImpl = removeMcp,
|
|
325
|
-
readUserMcpConfigImpl,
|
|
326
|
-
logImpl = log,
|
|
327
|
-
} = {}
|
|
328
|
-
) {
|
|
329
|
-
const config = readConfigImpl();
|
|
330
|
-
const language = config?.language === "zh" ? "zh" : "en";
|
|
331
|
-
await reconcileLegacyContext7InstallState(
|
|
332
|
-
{ name: "context7-plugin" },
|
|
333
|
-
language,
|
|
334
|
-
config,
|
|
335
|
-
{
|
|
336
|
-
writeConfigImpl,
|
|
337
|
-
removeMcpImpl,
|
|
338
|
-
readUserMcpConfigImpl,
|
|
339
|
-
logImpl,
|
|
340
|
-
}
|
|
341
|
-
);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
function toUninstallTarget(entry) {
|
|
345
|
-
return {
|
|
346
|
-
name: entry.name,
|
|
347
|
-
uninstallSpec: entry.uninstallSpec,
|
|
348
|
-
uninstallArgs: entry.uninstallArgs || [],
|
|
349
|
-
marketplaceId: entry.marketplaceId,
|
|
350
|
-
scope: entry.scope,
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
function isBrokenSymlink(pathname) {
|
|
355
|
-
try {
|
|
356
|
-
return lstatSync(pathname).isSymbolicLink();
|
|
357
|
-
} catch {
|
|
358
|
-
return false;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { GLOBAL_CLAUDE_MD, removeGlobalProtocols } from "./protocols.js";
|
|
2
|
-
import {
|
|
3
|
-
claudeVersion,
|
|
4
|
-
color,
|
|
5
|
-
confirm,
|
|
6
|
-
listPlugins,
|
|
7
|
-
log,
|
|
8
|
-
multiSelect,
|
|
9
|
-
} from "./utils.js";
|
|
10
|
-
|
|
11
|
-
export const UNINSTALL_STEP_COUNT = 4;
|
|
12
|
-
|
|
13
|
-
export function createUninstallContext(args = []) {
|
|
14
|
-
return {
|
|
15
|
-
yes: args.includes("--yes") || args.includes("-y"),
|
|
16
|
-
purge: args.includes("--purge"),
|
|
17
|
-
keepRecommended: args.includes("--keep-recommended"),
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function ensureClaudeCliAvailableForUninstall(
|
|
22
|
-
{ claudeVersionImpl = claudeVersion, logImpl = log, exitImpl = process.exit } = {}
|
|
23
|
-
) {
|
|
24
|
-
const version = claudeVersionImpl();
|
|
25
|
-
if (!version) {
|
|
26
|
-
logImpl.err("claude CLI not found, cannot uninstall plugin.");
|
|
27
|
-
exitImpl(1);
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return version;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export async function confirmUninstallStep(
|
|
35
|
-
{ yes },
|
|
36
|
-
{ confirmImpl = confirm, logImpl = log } = {}
|
|
37
|
-
) {
|
|
38
|
-
if (yes) {
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const confirmed = await confirmImpl(
|
|
43
|
-
`This will uninstall the ${color.bold("curdx-flow")} plugin. Continue?`,
|
|
44
|
-
false
|
|
45
|
-
);
|
|
46
|
-
if (!confirmed) {
|
|
47
|
-
logImpl.info("Cancelled");
|
|
48
|
-
}
|
|
49
|
-
return confirmed;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function getInstalledTargets(entries, { listPluginsImpl = listPlugins } = {}) {
|
|
53
|
-
const installedNames = new Set(listPluginsImpl().map((plugin) => plugin.name));
|
|
54
|
-
return entries.filter((entry) => installedNames.has(entry.name));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export async function selectRecommendedPluginsToRemove(
|
|
58
|
-
{ yes, present },
|
|
59
|
-
{ multiSelectImpl = multiSelect, logImpl = log } = {}
|
|
60
|
-
) {
|
|
61
|
-
if (present.length === 0) {
|
|
62
|
-
return [];
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (yes) {
|
|
66
|
-
logImpl.info(
|
|
67
|
-
color.dim("--yes mode: keeping recommended plugins (use --purge to remove them)")
|
|
68
|
-
);
|
|
69
|
-
return [];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const choices = present.map((entry) => ({
|
|
73
|
-
label: color.bold(entry.name),
|
|
74
|
-
value: entry.name,
|
|
75
|
-
hint: "",
|
|
76
|
-
}));
|
|
77
|
-
|
|
78
|
-
return multiSelectImpl(
|
|
79
|
-
"Which recommended plugins to also uninstall? (default: none)",
|
|
80
|
-
choices,
|
|
81
|
-
[]
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export function shouldKeepBundledMcps({ yes, keepRecommended }) {
|
|
86
|
-
if (!yes && !keepRecommended) {
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export function shouldKeepRequiredPlugins({ yes }) {
|
|
94
|
-
return yes;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function getManagedMarketplaceIds(entries) {
|
|
98
|
-
return [
|
|
99
|
-
...new Set(
|
|
100
|
-
entries
|
|
101
|
-
.map((entry) => entry.marketplaceId)
|
|
102
|
-
.filter((id) => id && id !== "claude-plugins-official")
|
|
103
|
-
),
|
|
104
|
-
];
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function removeProtocolsStep(
|
|
108
|
-
{ logImpl = log, removeGlobalProtocolsImpl = removeGlobalProtocols } = {}
|
|
109
|
-
) {
|
|
110
|
-
logImpl.blank();
|
|
111
|
-
console.log(color.dim("Removing global protocols from ~/.claude/CLAUDE.md..."));
|
|
112
|
-
|
|
113
|
-
try {
|
|
114
|
-
const result = removeGlobalProtocolsImpl();
|
|
115
|
-
if (result.action === "removed") {
|
|
116
|
-
logImpl.ok(`Global protocols removed ${color.dim(`(${GLOBAL_CLAUDE_MD})`)}`);
|
|
117
|
-
} else if (result.action === "not-present") {
|
|
118
|
-
logImpl.info("Global protocols not present, skipping");
|
|
119
|
-
} else {
|
|
120
|
-
logImpl.info("~/.claude/CLAUDE.md does not exist, skipping");
|
|
121
|
-
}
|
|
122
|
-
} catch (err) {
|
|
123
|
-
logImpl.warn(`Protocol removal failed: ${err.message}`);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export function printUninstallSummary({ purge }, { logImpl = log } = {}) {
|
|
128
|
-
logImpl.blank();
|
|
129
|
-
console.log(color.bold("✅ Uninstall complete"));
|
|
130
|
-
if (purge) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
console.log(
|
|
135
|
-
color.dim(
|
|
136
|
-
`\nArtifacts kept:\n` +
|
|
137
|
-
` - ~/.local/bin/bun, ~/.local/bin/uv (symlinks; use --purge to remove)\n` +
|
|
138
|
-
` - bun/uv binaries themselves (~/.bun/bin/bun, ~/.local/bin/uv real installs)\n` +
|
|
139
|
-
` - claude-mem data (~/.claude-mem/)\n` +
|
|
140
|
-
` - claude marketplace cache`
|
|
141
|
-
)
|
|
142
|
-
);
|
|
143
|
-
console.log(
|
|
144
|
-
color.dim(`\nFully purge: ${color.cyan("curdx-flow uninstall --purge")}`)
|
|
145
|
-
);
|
|
146
|
-
}
|
package/cli/uninstall.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* uninstall command — remove curdx-flow plugin (and optionally recommended plugins / artifacts).
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { log } from "./utils.js";
|
|
6
|
-
import {
|
|
7
|
-
createUninstallContext,
|
|
8
|
-
ensureClaudeCliAvailableForUninstall,
|
|
9
|
-
printUninstallSummary,
|
|
10
|
-
removeProtocolsStep,
|
|
11
|
-
confirmUninstallStep,
|
|
12
|
-
} from "./uninstall-workflow.js";
|
|
13
|
-
import {
|
|
14
|
-
maybePurgeRuntimeArtifacts,
|
|
15
|
-
maybeRemoveBundledMcps,
|
|
16
|
-
maybeRemoveProjectState,
|
|
17
|
-
maybeUninstallRecommendedPlugins,
|
|
18
|
-
maybeUninstallRequiredPlugins,
|
|
19
|
-
uninstallCurdxFlowPlugin,
|
|
20
|
-
} from "./uninstall-actions.js";
|
|
21
|
-
|
|
22
|
-
export async function uninstall(args = []) {
|
|
23
|
-
const context = createUninstallContext(args);
|
|
24
|
-
|
|
25
|
-
log.title("🗑️ CurdX-Flow Uninstaller");
|
|
26
|
-
|
|
27
|
-
ensureClaudeCliAvailableForUninstall();
|
|
28
|
-
|
|
29
|
-
if (!(await confirmUninstallStep(context))) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
await uninstallCurdxFlowPlugin();
|
|
34
|
-
await maybeUninstallRecommendedPlugins(context);
|
|
35
|
-
await maybeRemoveBundledMcps(context);
|
|
36
|
-
await maybeUninstallRequiredPlugins(context);
|
|
37
|
-
await maybePurgeRuntimeArtifacts(context);
|
|
38
|
-
removeProtocolsStep();
|
|
39
|
-
await maybeRemoveProjectState(context);
|
|
40
|
-
|
|
41
|
-
printUninstallSummary(context);
|
|
42
|
-
}
|
package/cli/upgrade-workflow.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { claudeVersion, color, listPlugins, log, resultLastLine } from "./utils.js";
|
|
2
|
-
|
|
3
|
-
export const UPGRADE_STEP_COUNT = 3;
|
|
4
|
-
|
|
5
|
-
export function ensureClaudeCliAvailableForUpgrade(
|
|
6
|
-
{ claudeVersionImpl = claudeVersion, logImpl = log, exitImpl = process.exit } = {}
|
|
7
|
-
) {
|
|
8
|
-
const version = claudeVersionImpl();
|
|
9
|
-
if (!version) {
|
|
10
|
-
logImpl.err("claude CLI not found");
|
|
11
|
-
exitImpl(1);
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
return version;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function getInstalledPluginNames({ listPluginsImpl = listPlugins } = {}) {
|
|
19
|
-
return new Set(listPluginsImpl().map((plugin) => plugin.name));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function getPluginNameFromSpec(spec) {
|
|
23
|
-
return String(spec).split("@")[0];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function classifyPluginUpdateResult(result) {
|
|
27
|
-
if (result.code !== 0) {
|
|
28
|
-
return {
|
|
29
|
-
status: "failed",
|
|
30
|
-
message: resultLastLine(result),
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (!result.stdout.includes("updated from")) {
|
|
35
|
-
return {
|
|
36
|
-
status: "unchanged",
|
|
37
|
-
message: "already up to date",
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const match = result.stdout.match(/updated from (\S+) to (\S+)/);
|
|
42
|
-
if (!match) {
|
|
43
|
-
return {
|
|
44
|
-
status: "updated",
|
|
45
|
-
message: "updated",
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return {
|
|
50
|
-
status: "updated",
|
|
51
|
-
from: match[1],
|
|
52
|
-
to: match[2],
|
|
53
|
-
message: color.dim(`${match[1]} → ${match[2]}`),
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export async function refreshMarketplaces(
|
|
58
|
-
marketplaceIds,
|
|
59
|
-
{ updatePluginMarketplaceImpl, logImpl = log } = {}
|
|
60
|
-
) {
|
|
61
|
-
logImpl.step(1, UPGRADE_STEP_COUNT, "Refreshing marketplaces...");
|
|
62
|
-
|
|
63
|
-
for (const marketplaceId of marketplaceIds) {
|
|
64
|
-
const result = await updatePluginMarketplaceImpl(marketplaceId);
|
|
65
|
-
if (result.code === 0) {
|
|
66
|
-
logImpl.ok(` ${marketplaceId}`);
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (!result.stderr.includes("not found")) {
|
|
71
|
-
logImpl.warn(` ${marketplaceId}: ${resultLastLine(result)}`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export function printUpgradeSummary({ logImpl = log } = {}) {
|
|
77
|
-
logImpl.blank();
|
|
78
|
-
logImpl.ok("Upgrade complete");
|
|
79
|
-
console.log(color.dim(" Some changes require a Claude Code restart to take effect"));
|
|
80
|
-
}
|
package/cli/upgrade.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* upgrade command — update curdx-flow + recommended plugins to latest.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { log, readConfig } from "./utils.js";
|
|
6
|
-
import { reconcileLegacyContext7InstallState } from "./install-context7-config.js";
|
|
7
|
-
import {
|
|
8
|
-
PLUGINS_TO_UPDATE,
|
|
9
|
-
MARKETPLACES_TO_REFRESH,
|
|
10
|
-
} from "./registry.js";
|
|
11
|
-
import {
|
|
12
|
-
updatePlugin,
|
|
13
|
-
updatePluginMarketplace,
|
|
14
|
-
} from "./lib/claude-ops.js";
|
|
15
|
-
import {
|
|
16
|
-
classifyPluginUpdateResult,
|
|
17
|
-
ensureClaudeCliAvailableForUpgrade,
|
|
18
|
-
getInstalledPluginNames,
|
|
19
|
-
getPluginNameFromSpec,
|
|
20
|
-
printUpgradeSummary,
|
|
21
|
-
refreshMarketplaces,
|
|
22
|
-
UPGRADE_STEP_COUNT,
|
|
23
|
-
} from "./upgrade-workflow.js";
|
|
24
|
-
|
|
25
|
-
export async function upgrade(
|
|
26
|
-
args = [],
|
|
27
|
-
{
|
|
28
|
-
updatePluginImpl = updatePlugin,
|
|
29
|
-
updatePluginMarketplaceImpl = updatePluginMarketplace,
|
|
30
|
-
ensureClaudeCliAvailableForUpgradeImpl = ensureClaudeCliAvailableForUpgrade,
|
|
31
|
-
getInstalledPluginNamesImpl = getInstalledPluginNames,
|
|
32
|
-
readConfigImpl = readConfig,
|
|
33
|
-
reconcileLegacyContext7InstallStateImpl = reconcileLegacyContext7InstallState,
|
|
34
|
-
logImpl = log,
|
|
35
|
-
} = {}
|
|
36
|
-
) {
|
|
37
|
-
logImpl.title("⬆️ CurdX-Flow upgrade");
|
|
38
|
-
|
|
39
|
-
ensureClaudeCliAvailableForUpgradeImpl({ logImpl });
|
|
40
|
-
|
|
41
|
-
// Refresh marketplaces first (derived from cli/registry.js)
|
|
42
|
-
await refreshMarketplaces(MARKETPLACES_TO_REFRESH, {
|
|
43
|
-
updatePluginMarketplaceImpl,
|
|
44
|
-
logImpl,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// Update each plugin
|
|
48
|
-
logImpl.blank();
|
|
49
|
-
logImpl.step(2, UPGRADE_STEP_COUNT, "Updating installed plugins...");
|
|
50
|
-
const installedNames = getInstalledPluginNamesImpl();
|
|
51
|
-
|
|
52
|
-
for (const spec of PLUGINS_TO_UPDATE) {
|
|
53
|
-
const pluginName = getPluginNameFromSpec(spec);
|
|
54
|
-
if (!installedNames.has(pluginName)) {
|
|
55
|
-
logImpl.info(` ${pluginName.padEnd(22)} not installed, skipping`);
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const result = await updatePluginImpl(spec);
|
|
60
|
-
const status = classifyPluginUpdateResult(result);
|
|
61
|
-
|
|
62
|
-
if (status.status === "updated") {
|
|
63
|
-
logImpl.ok(` ${pluginName.padEnd(22)} ${status.message}`);
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (status.status === "unchanged") {
|
|
68
|
-
logImpl.info(` ${pluginName.padEnd(22)} ${status.message}`);
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
logImpl.warn(` ${pluginName.padEnd(22)} ${status.message}`);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
logImpl.blank();
|
|
76
|
-
logImpl.step(3, UPGRADE_STEP_COUNT, "Reconciling legacy Context7 state...");
|
|
77
|
-
if (installedNames.has("context7-plugin")) {
|
|
78
|
-
const config = readConfigImpl();
|
|
79
|
-
const language = config?.language === "zh" ? "zh" : "en";
|
|
80
|
-
await reconcileLegacyContext7InstallStateImpl(
|
|
81
|
-
{ name: "context7-plugin" },
|
|
82
|
-
language,
|
|
83
|
-
config,
|
|
84
|
-
{ logImpl }
|
|
85
|
-
);
|
|
86
|
-
} else {
|
|
87
|
-
logImpl.info(" context7-plugin not installed, skipping");
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
printUpgradeSummary({ logImpl });
|
|
91
|
-
}
|