@costrict/csc 4.2.27 → 4.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +89893 -87853
- package/dist/services/rawDump/batchWorker.js +21 -10
- package/package.json +3 -3
- package/scripts/cleanup-cosknow.mjs +150 -0
- package/scripts/install-cosknow.mjs +0 -34
|
@@ -736,8 +736,8 @@ function getClientVersion() {
|
|
|
736
736
|
if (cached)
|
|
737
737
|
return cached;
|
|
738
738
|
try {
|
|
739
|
-
if ("4.2.
|
|
740
|
-
cached = "4.2.
|
|
739
|
+
if ("4.2.29") {
|
|
740
|
+
cached = "4.2.29";
|
|
741
741
|
return cached;
|
|
742
742
|
}
|
|
743
743
|
} catch {}
|
|
@@ -5600,6 +5600,7 @@ var init_cli = __esm(() => {
|
|
|
5600
5600
|
"cli.option.appendSystemPrompt": "Append a system prompt to the default system prompt",
|
|
5601
5601
|
"cli.option.appendSystemPromptFile": "Read system prompt from a file and append to the default system prompt",
|
|
5602
5602
|
"cli.option.assistant": "Force assistant mode (Agent SDK daemon use)",
|
|
5603
|
+
"cli.option.authProvider": "Authenticate fetches with the current CoStrict login. Only 'costrict' is supported; a URL served by your own CoStrict deployment is detected automatically.",
|
|
5603
5604
|
"cli.option.authToken": "Bearer token for authentication",
|
|
5604
5605
|
"cli.option.available": "Include available plugins from marketplaces",
|
|
5605
5606
|
"cli.option.bare": "Minimal mode: skip hooks, LSP, plugin sync, attribution, auto-memory, background prefetches, keychain reads, and CLAUDE.md auto-discovery. Sets CLAUDE_CODE_SIMPLE=1. Anthropic auth is strictly ANTHROPIC_API_KEY or apiKeyHelper via --settings (OAuth and keychain are never read). 3P providers (Bedrock/Vertex/Foundry) use their own credentials. Skills still resolve via /skill-name. Explicitly provide context via: --system-prompt[-file], --append-system-prompt[-file], --add-dir (CLAUDE.md dirs), --mcp-config, --settings, --agents, --plugin-dir.",
|
|
@@ -5826,6 +5827,8 @@ Set it to the space-separated scopes the refresh token was issued with
|
|
|
5826
5827
|
"cli.plugins.invalidMarketplaceSource": "Invalid marketplace source format. Try: owner/repo, https://..., or ./path",
|
|
5827
5828
|
"cli.plugins.invalidScope": "Invalid scope '{scope}'. Use: user, project, or local",
|
|
5828
5829
|
"cli.plugins.sparseNotSupported": "--sparse is only supported for github and git marketplace sources (got: {source})",
|
|
5830
|
+
"cli.plugins.invalidAuthProvider": "Invalid auth provider '{provider}'. Only 'costrict' is supported.",
|
|
5831
|
+
"cli.plugins.authProviderNotSupported": "--auth-provider is only supported for url marketplace sources (got: {source})",
|
|
5829
5832
|
"cli.plugins.addingMarketplace": "Adding marketplace...",
|
|
5830
5833
|
"cli.plugins.marketplaceAlreadyOnDisk": "Marketplace '{name}' already on disk \u2014 declared in {scope} settings",
|
|
5831
5834
|
"cli.plugins.marketplaceAdded": "Successfully added marketplace: {name} (declared in {scope} settings)",
|
|
@@ -10148,6 +10151,7 @@ var init_cli2 = __esm(() => {
|
|
|
10148
10151
|
"cli.option.appendSystemPrompt": "\u5411\u9ED8\u8BA4\u7CFB\u7EDF\u63D0\u793A\u8BCD\u8FFD\u52A0\u5185\u5BB9",
|
|
10149
10152
|
"cli.option.appendSystemPromptFile": "\u4ECE\u6587\u4EF6\u8BFB\u53D6\u7CFB\u7EDF\u63D0\u793A\u8BCD\u5E76\u8FFD\u52A0\u5230\u9ED8\u8BA4\u7CFB\u7EDF\u63D0\u793A\u8BCD",
|
|
10150
10153
|
"cli.option.assistant": "\u5F3A\u5236\u4F7F\u7528 assistant \u6A21\u5F0F\uFF08Agent SDK daemon \u4F7F\u7528\uFF09",
|
|
10154
|
+
"cli.option.authProvider": "\u4F7F\u7528\u5F53\u524D CoStrict \u767B\u5F55\u6001\u8BA4\u8BC1\u5E02\u573A\u62C9\u53D6\u3002\u4EC5\u652F\u6301 'costrict'\uFF1B\u7531\u672C\u673A CoStrict \u90E8\u7F72\u63D0\u4F9B\u7684 URL \u4F1A\u81EA\u52A8\u8BC6\u522B\u3002",
|
|
10151
10155
|
"cli.option.authToken": "\u7528\u4E8E\u8BA4\u8BC1\u7684 Bearer token",
|
|
10152
10156
|
"cli.option.available": "\u5305\u542B\u5E02\u573A\u4E2D\u53EF\u7528\u7684\u63D2\u4EF6",
|
|
10153
10157
|
"cli.option.bare": "\u7CBE\u7B80\u6A21\u5F0F\uFF1A\u8DF3\u8FC7 hooks\u3001LSP\u3001\u63D2\u4EF6\u540C\u6B65\u3001attribution\u3001\u81EA\u52A8\u8BB0\u5FC6\u3001\u540E\u53F0\u9884\u53D6\u3001keychain \u8BFB\u53D6\u548C CLAUDE.md \u81EA\u52A8\u53D1\u73B0\u3002\u8BBE\u7F6E CLAUDE_CODE_SIMPLE=1\u3002\u8BA4\u8BC1\u4E25\u683C\u4F7F\u7528 ANTHROPIC_API_KEY \u6216\u901A\u8FC7 --settings \u7684 apiKeyHelper\uFF08OAuth \u548C keychain \u4E0D\u4F1A\u88AB\u8BFB\u53D6\uFF09\u3002\u7B2C\u4E09\u65B9 provider\uFF08Bedrock/Vertex/Foundry\uFF09\u4F7F\u7528\u5404\u81EA\u7684\u51ED\u8BC1\u3002\u6280\u80FD\u4ECD\u901A\u8FC7 /skill-name \u89E3\u6790\u3002\u53EF\u901A\u8FC7\u4EE5\u4E0B\u65B9\u5F0F\u663E\u5F0F\u63D0\u4F9B\u4E0A\u4E0B\u6587\uFF1A--system-prompt[-file]\u3001--append-system-prompt[-file]\u3001--add-dir\uFF08CLAUDE.md \u76EE\u5F55\uFF09\u3001--mcp-config\u3001--settings\u3001--agents\u3001--plugin-dir\u3002",
|
|
@@ -10374,6 +10378,8 @@ detached \u5F15\u64CE\u6CA1\u6709\u7528\u4E8E\u4EA4\u4E92\u8F93\u5165\u7684\u7EC
|
|
|
10374
10378
|
"cli.plugins.invalidMarketplaceSource": "\u65E0\u6548\u7684\u5E02\u573A\u6E90\u683C\u5F0F\u3002\u8BF7\u4F7F\u7528: owner/repo, https://..., \u6216 ./path",
|
|
10375
10379
|
"cli.plugins.invalidScope": "\u65E0\u6548\u7684\u4F5C\u7528\u57DF '{scope}'\u3002\u8BF7\u4F7F\u7528: user, project \u6216 local",
|
|
10376
10380
|
"cli.plugins.sparseNotSupported": "--sparse \u4EC5\u652F\u6301 github \u548C git \u5E02\u573A\u6E90\uFF08\u5F97\u5230\u7684\u662F: {source}\uFF09",
|
|
10381
|
+
"cli.plugins.invalidAuthProvider": "\u65E0\u6548\u7684\u8BA4\u8BC1\u63D0\u4F9B\u65B9 '{provider}'\u3002\u4EC5\u652F\u6301 'costrict'\u3002",
|
|
10382
|
+
"cli.plugins.authProviderNotSupported": "--auth-provider \u4EC5\u652F\u6301 url \u7C7B\u578B\u7684\u5E02\u573A\u6E90\uFF08\u5F97\u5230\u7684\u662F: {source}\uFF09",
|
|
10377
10383
|
"cli.plugins.addingMarketplace": "\u6B63\u5728\u6DFB\u52A0\u5E02\u573A...",
|
|
10378
10384
|
"cli.plugins.marketplaceAlreadyOnDisk": "\u5E02\u573A '{name}' \u5DF2\u5B58\u5728\u4E8E\u78C1\u76D8\u4E0A \u2014 \u5DF2\u5728 {scope} \u8BBE\u7F6E\u4E2D\u58F0\u660E",
|
|
10379
10385
|
"cli.plugins.marketplaceAdded": "\u6210\u529F\u6DFB\u52A0\u5E02\u573A: {name}\uFF08\u5DF2\u5728 {scope} \u8BBE\u7F6E\u4E2D\u58F0\u660E\uFF09",
|
|
@@ -87604,7 +87610,7 @@ function isBlockedOfficialName(name) {
|
|
|
87604
87610
|
}
|
|
87605
87611
|
return BLOCKED_OFFICIAL_NAME_PATTERN.test(name);
|
|
87606
87612
|
}
|
|
87607
|
-
var ALLOWED_OFFICIAL_MARKETPLACE_NAMES, NO_AUTO_UPDATE_OFFICIAL_MARKETPLACES, AUTO_UPDATE_THIRD_PARTY_MARKETPLACES, BLOCKED_OFFICIAL_NAME_PATTERN, NON_ASCII_PATTERN, RelativePath, RelativeJSONPath, McpbPath, RelativeMarkdownPath, RelativeCommandPath, MarketplaceNameSchema, PluginAuthorSchema, PluginManifestMetadataSchema, PluginHooksSchema, PluginManifestHooksSchema, CommandMetadataSchema, PluginManifestCommandsSchema, PluginManifestAgentsSchema, PluginManifestSkillsSchema, PluginManifestOutputStylesSchema, nonEmptyString, fileExtension, PluginManifestMcpServerSchema, PluginUserConfigOptionSchema, PluginManifestUserConfigSchema, PluginManifestChannelsSchema, LspServerConfigSchema, PluginManifestLspServerSchema, NpmPackageNameSchema, PluginManifestSettingsSchema, PluginManifestSchema, MarketplaceSourceSchema, gitSha, PluginSourceSchema, SettingsMarketplacePluginSchema, PluginMarketplaceEntrySchema, PluginMarketplaceSchema, PluginIdSchema, DEP_REF_REGEX, DependencyRefSchema, SettingsPluginEntrySchema, InstalledPluginSchema, InstalledPluginsFileSchemaV1, PluginScopeSchema, PluginInstallationEntrySchema, InstalledPluginsFileSchemaV2, InstalledPluginsFileSchema, KnownMarketplaceSchema, KnownMarketplacesFileSchema;
|
|
87613
|
+
var ALLOWED_OFFICIAL_MARKETPLACE_NAMES, NO_AUTO_UPDATE_OFFICIAL_MARKETPLACES, AUTO_UPDATE_THIRD_PARTY_MARKETPLACES, BLOCKED_OFFICIAL_NAME_PATTERN, NON_ASCII_PATTERN, RelativePath, RelativeJSONPath, McpbPath, RelativeMarkdownPath, RelativeCommandPath, MarketplaceNameSchema, PluginAuthorSchema, PluginManifestMetadataSchema, PluginHooksSchema, PluginManifestHooksSchema, CommandMetadataSchema, PluginManifestCommandsSchema, PluginManifestAgentsSchema, PluginManifestSkillsSchema, PluginManifestOutputStylesSchema, nonEmptyString, fileExtension, PluginManifestMcpServerSchema, PluginUserConfigOptionSchema, PluginManifestUserConfigSchema, PluginManifestChannelsSchema, LspServerConfigSchema, PluginManifestLspServerSchema, NpmPackageNameSchema, PluginManifestSettingsSchema, PluginManifestSchema, MarketplaceSourceSchema, gitSha, CoStrictAuthProviderSchema, PluginSourceSchema, SettingsMarketplacePluginSchema, PluginMarketplaceEntrySchema, PluginMarketplaceSchema, PluginIdSchema, DEP_REF_REGEX, DependencyRefSchema, SettingsPluginEntrySchema, InstalledPluginSchema, InstalledPluginsFileSchemaV1, PluginScopeSchema, PluginInstallationEntrySchema, InstalledPluginsFileSchemaV2, InstalledPluginsFileSchema, KnownMarketplaceSchema, KnownMarketplacesFileSchema;
|
|
87608
87614
|
var init_schemas3 = __esm(() => {
|
|
87609
87615
|
init_v4();
|
|
87610
87616
|
init_hooks();
|
|
@@ -87811,6 +87817,7 @@ var init_schemas3 = __esm(() => {
|
|
|
87811
87817
|
exports_external.object({
|
|
87812
87818
|
source: exports_external.literal("url"),
|
|
87813
87819
|
url: exports_external.string().url().describe("Direct URL to marketplace.json file"),
|
|
87820
|
+
authProvider: exports_external.literal("costrict").optional().describe("Inject the current CoStrict OAuth token when fetching"),
|
|
87814
87821
|
headers: exports_external.record(exports_external.string(), exports_external.string()).optional().describe("Custom HTTP headers (e.g., for authentication)")
|
|
87815
87822
|
}),
|
|
87816
87823
|
exports_external.object({
|
|
@@ -87857,6 +87864,7 @@ var init_schemas3 = __esm(() => {
|
|
|
87857
87864
|
}).describe("Inline marketplace manifest defined directly in settings.json. " + "The reconciler writes a synthetic marketplace.json to the cache; " + "diffMarketplaces detects edits via isEqual on the stored source " + "(the plugins array is inside this object, so edits surface as sourceChanged).")
|
|
87858
87865
|
]));
|
|
87859
87866
|
gitSha = lazySchema(() => exports_external.string().length(40).regex(/^[a-f0-9]{40}$/, "Must be a full 40-character lowercase git commit SHA"));
|
|
87867
|
+
CoStrictAuthProviderSchema = lazySchema(() => exports_external.literal("costrict").optional().describe("Fetch this source with the current CoStrict identity (private sources only)"));
|
|
87860
87868
|
PluginSourceSchema = lazySchema(() => exports_external.union([
|
|
87861
87869
|
RelativePath().describe("Path to the plugin root, relative to the marketplace root (the directory containing .claude-plugin/, not .claude-plugin/ itself)"),
|
|
87862
87870
|
exports_external.object({
|
|
@@ -87875,7 +87883,8 @@ var init_schemas3 = __esm(() => {
|
|
|
87875
87883
|
source: exports_external.literal("url"),
|
|
87876
87884
|
url: exports_external.string().describe("Full git repository URL (https:// or git@)"),
|
|
87877
87885
|
ref: exports_external.string().optional().describe('Git branch or tag to use (e.g., "main", "v1.0.0"). Defaults to repository default branch.'),
|
|
87878
|
-
sha: gitSha().optional().describe("Specific commit SHA to use")
|
|
87886
|
+
sha: gitSha().optional().describe("Specific commit SHA to use"),
|
|
87887
|
+
authProvider: CoStrictAuthProviderSchema()
|
|
87879
87888
|
}),
|
|
87880
87889
|
exports_external.object({
|
|
87881
87890
|
source: exports_external.literal("github"),
|
|
@@ -87888,7 +87897,8 @@ var init_schemas3 = __esm(() => {
|
|
|
87888
87897
|
url: exports_external.string().describe("Git repository: GitHub owner/repo shorthand, https://, or git@ URL"),
|
|
87889
87898
|
path: exports_external.string().min(1).describe('Subdirectory within the repo containing the plugin (e.g., "tools/claude-plugin"). ' + "Cloned sparsely using partial clone (--filter=tree:0) to minimize bandwidth for monorepos."),
|
|
87890
87899
|
ref: exports_external.string().optional().describe('Git branch or tag to use (e.g., "main", "v1.0.0"). Defaults to repository default branch.'),
|
|
87891
|
-
sha: gitSha().optional().describe("Specific commit SHA to use")
|
|
87900
|
+
sha: gitSha().optional().describe("Specific commit SHA to use"),
|
|
87901
|
+
authProvider: CoStrictAuthProviderSchema()
|
|
87892
87902
|
}).describe("Plugin located in a subdirectory of a larger repository (monorepo). " + "Only the specified subdirectory is materialized; the rest of the repo is not downloaded.")
|
|
87893
87903
|
]));
|
|
87894
87904
|
SettingsMarketplacePluginSchema = lazySchema(() => exports_external.object({
|
|
@@ -87907,6 +87917,7 @@ var init_schemas3 = __esm(() => {
|
|
|
87907
87917
|
message: 'Plugin name cannot contain spaces. Use kebab-case (e.g., "my-plugin")'
|
|
87908
87918
|
}).describe("Unique identifier matching the plugin name"),
|
|
87909
87919
|
source: PluginSourceSchema().describe("Where to fetch the plugin from"),
|
|
87920
|
+
authProvider: CoStrictAuthProviderSchema(),
|
|
87910
87921
|
category: exports_external.string().optional().describe('Category for organizing plugins (e.g., "productivity", "development")'),
|
|
87911
87922
|
tags: exports_external.array(exports_external.string()).optional().describe("Tags for searchability and discovery"),
|
|
87912
87923
|
strict: exports_external.boolean().optional().default(true).describe("Require the plugin manifest to be present in the plugin folder. If false, the marketplace entry provides the manifest.")
|
|
@@ -138559,7 +138570,7 @@ var init_user = __esm(() => {
|
|
|
138559
138570
|
deviceId,
|
|
138560
138571
|
sessionId: getSessionId(),
|
|
138561
138572
|
email: getEmail(),
|
|
138562
|
-
appVersion: "4.2.
|
|
138573
|
+
appVersion: "4.2.29",
|
|
138563
138574
|
platform: getHostPlatformForAnalytics(),
|
|
138564
138575
|
organizationUuid,
|
|
138565
138576
|
accountUuid,
|
|
@@ -138846,7 +138857,7 @@ var init_metadata = __esm(() => {
|
|
|
138846
138857
|
"sed"
|
|
138847
138858
|
]);
|
|
138848
138859
|
getVersionBase = memoize_default(() => {
|
|
138849
|
-
const match = "4.2.
|
|
138860
|
+
const match = "4.2.29".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
|
|
138850
138861
|
return match ? match[0] : undefined;
|
|
138851
138862
|
});
|
|
138852
138863
|
buildEnvContext = memoize_default(async () => {
|
|
@@ -138886,9 +138897,9 @@ var init_metadata = __esm(() => {
|
|
|
138886
138897
|
isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
|
|
138887
138898
|
isClaudeCodeAction: isEnvTruthy(process.env.CLAUDE_CODE_ACTION),
|
|
138888
138899
|
isClaudeAiAuth: isClaudeAISubscriber(),
|
|
138889
|
-
version: "4.2.
|
|
138900
|
+
version: "4.2.29",
|
|
138890
138901
|
versionBase: getVersionBase(),
|
|
138891
|
-
buildTime: "2026-08-
|
|
138902
|
+
buildTime: "2026-08-24T01:42:34.935Z",
|
|
138892
138903
|
deploymentEnvironment: env4.detectDeploymentEnvironment(),
|
|
138893
138904
|
...isEnvTruthy(process.env.GITHUB_ACTIONS) && {
|
|
138894
138905
|
githubEventName: process.env.GITHUB_EVENT_NAME,
|
|
@@ -143226,5 +143237,5 @@ export {
|
|
|
143226
143237
|
isParentHeartbeatValid
|
|
143227
143238
|
};
|
|
143228
143239
|
|
|
143229
|
-
//# debugId=
|
|
143240
|
+
//# debugId=ADEDB9641343B30B64756E2164756E21
|
|
143230
143241
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@costrict/csc",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.29",
|
|
4
4
|
"description": "costrict",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "costrict",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"scripts/postinstall.cjs",
|
|
37
37
|
"scripts/run-parallel.mjs",
|
|
38
38
|
"scripts/setup-chrome-mcp.mjs",
|
|
39
|
-
"scripts/
|
|
39
|
+
"scripts/cleanup-cosknow.mjs"
|
|
40
40
|
],
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "bun run build.ts",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"test": "bun test",
|
|
75
75
|
"check:unused": "knip-bun",
|
|
76
76
|
"health": "bun run scripts/health-check.ts",
|
|
77
|
-
"postinstall": "node scripts/run-parallel.mjs scripts/postinstall.cjs scripts/setup-chrome-mcp.mjs scripts/
|
|
77
|
+
"postinstall": "node scripts/run-parallel.mjs scripts/postinstall.cjs scripts/setup-chrome-mcp.mjs scripts/cleanup-cosknow.mjs",
|
|
78
78
|
"docs:dev": "npx mintlify dev",
|
|
79
79
|
"typecheck": "tsc --noEmit",
|
|
80
80
|
"rcs": "bun run scripts/rcs.ts",
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
+
import { readdir, rm } from 'node:fs/promises'
|
|
3
|
+
import { homedir } from 'node:os'
|
|
4
|
+
import { join } from 'node:path'
|
|
5
|
+
|
|
6
|
+
// 清理 csc postinstall 时期安装的 CosKnow kb 命令(v1 集成产物)。
|
|
7
|
+
// 现在不再自动安装 cosknow,此脚本负责把历史遗留的文件移除。
|
|
8
|
+
// 清理范围覆盖两个可能的 commands 目录:
|
|
9
|
+
// - ~/.claude/commands/ (v1 安装器当时的写入位置)
|
|
10
|
+
// - ~/.costrict/commands/ (品牌合规后的主配置目录)
|
|
11
|
+
// 每个目录内的删除范围:
|
|
12
|
+
// 1. .cosknow-manifest.json 中 files 列出的所有文件(权威依据)
|
|
13
|
+
// 2. 兜底:commands 目录下所有 kb-*.md(manifest 缺失或未列出时)
|
|
14
|
+
// 3. linter/kb-linter.js、prompts/ 子目录(v1 includeResources 复制产物)
|
|
15
|
+
// 4. .cosknow-manifest.json 本身
|
|
16
|
+
// 注意:不清理 ~/.costrict/cosknow/ 下的运行数据目录(statusline 等)。
|
|
17
|
+
// 任何失败都是非致命的:warn 后 exit 0,绝不影响 csc 安装/更新。
|
|
18
|
+
|
|
19
|
+
const MANIFEST_FILE = '.cosknow-manifest.json'
|
|
20
|
+
const TARGET_DIRS = [
|
|
21
|
+
join(homedir(), '.claude', 'commands'),
|
|
22
|
+
join(homedir(), '.costrict', 'commands'),
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
function log(msg) {
|
|
26
|
+
console.log(`[cosknow-cleanup] ${msg}`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function warn(msg) {
|
|
30
|
+
console.warn(`[cosknow-cleanup] ${msg}`)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 1. 按 manifest 删除
|
|
34
|
+
async function deleteFromManifest(commandsDir) {
|
|
35
|
+
const manifestPath = join(commandsDir, MANIFEST_FILE)
|
|
36
|
+
if (!existsSync(manifestPath)) {
|
|
37
|
+
return 0
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let manifest
|
|
41
|
+
try {
|
|
42
|
+
manifest = JSON.parse(readFileSync(manifestPath, 'utf8'))
|
|
43
|
+
} catch (e) {
|
|
44
|
+
warn(`invalid manifest at ${manifestPath}, skipping manifest-based cleanup: ${e.message}`)
|
|
45
|
+
return 0
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let deleted = 0
|
|
49
|
+
for (const filePath of manifest.files ?? []) {
|
|
50
|
+
if (existsSync(filePath)) {
|
|
51
|
+
try {
|
|
52
|
+
await rm(filePath)
|
|
53
|
+
deleted++
|
|
54
|
+
} catch (e) {
|
|
55
|
+
warn(`failed to remove ${filePath}: ${e.message}`)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return deleted
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 2. 兜底:删除 commands 目录下所有 kb-*.md
|
|
63
|
+
async function deleteKbCommands(commandsDir) {
|
|
64
|
+
let entries
|
|
65
|
+
try {
|
|
66
|
+
entries = await readdir(commandsDir)
|
|
67
|
+
} catch {
|
|
68
|
+
return 0 // commands 目录不存在,无需清理
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let deleted = 0
|
|
72
|
+
for (const entry of entries) {
|
|
73
|
+
if (!entry.startsWith('kb-') || !entry.endsWith('.md')) {
|
|
74
|
+
continue
|
|
75
|
+
}
|
|
76
|
+
const filePath = join(commandsDir, entry)
|
|
77
|
+
try {
|
|
78
|
+
await rm(filePath)
|
|
79
|
+
deleted++
|
|
80
|
+
} catch (e) {
|
|
81
|
+
warn(`failed to remove ${filePath}: ${e.message}`)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return deleted
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 3. 删除 v1 复制到 commands/ 下的资源文件
|
|
88
|
+
async function deleteResources(commandsDir) {
|
|
89
|
+
const linterPath = join(commandsDir, 'linter', 'kb-linter.js')
|
|
90
|
+
if (existsSync(linterPath)) {
|
|
91
|
+
try {
|
|
92
|
+
await rm(linterPath)
|
|
93
|
+
log(`removed ${linterPath}`)
|
|
94
|
+
} catch (e) {
|
|
95
|
+
warn(`failed to remove ${linterPath}: ${e.message}`)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 若 linter/ 目录是 cosknow 创建的(删掉 kb-linter.js 后为空),一并移除
|
|
100
|
+
const linterDir = join(commandsDir, 'linter')
|
|
101
|
+
if (existsSync(linterDir)) {
|
|
102
|
+
try {
|
|
103
|
+
const remaining = await readdir(linterDir)
|
|
104
|
+
if (remaining.length === 0) {
|
|
105
|
+
await rm(linterDir, { recursive: true, force: true })
|
|
106
|
+
log(`removed empty dir ${linterDir}`)
|
|
107
|
+
}
|
|
108
|
+
} catch (e) {
|
|
109
|
+
warn(`failed to inspect ${linterDir}: ${e.message}`)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const promptsDir = join(commandsDir, 'prompts')
|
|
114
|
+
if (existsSync(promptsDir)) {
|
|
115
|
+
try {
|
|
116
|
+
await rm(promptsDir, { recursive: true, force: true })
|
|
117
|
+
log(`removed ${promptsDir}`)
|
|
118
|
+
} catch (e) {
|
|
119
|
+
warn(`failed to remove ${promptsDir}: ${e.message}`)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 4. 删除 manifest 本身
|
|
125
|
+
async function deleteManifest(commandsDir) {
|
|
126
|
+
const manifestPath = join(commandsDir, MANIFEST_FILE)
|
|
127
|
+
if (existsSync(manifestPath)) {
|
|
128
|
+
try {
|
|
129
|
+
await rm(manifestPath)
|
|
130
|
+
log(`removed ${manifestPath}`)
|
|
131
|
+
} catch (e) {
|
|
132
|
+
warn(`failed to remove ${manifestPath}: ${e.message}`)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
let totalRemoved = 0
|
|
138
|
+
|
|
139
|
+
for (const commandsDir of TARGET_DIRS) {
|
|
140
|
+
totalRemoved += await deleteFromManifest(commandsDir)
|
|
141
|
+
totalRemoved += await deleteKbCommands(commandsDir)
|
|
142
|
+
await deleteResources(commandsDir)
|
|
143
|
+
await deleteManifest(commandsDir)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (totalRemoved > 0) {
|
|
147
|
+
log(`removed ${totalRemoved} CosKnow command file(s)`)
|
|
148
|
+
} else {
|
|
149
|
+
log('no CosKnow commands found, nothing to clean')
|
|
150
|
+
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { spawnSync, execSync } from 'node:child_process'
|
|
2
|
-
import { join } from 'node:path'
|
|
3
|
-
import { pathToFileURL } from 'node:url'
|
|
4
|
-
|
|
5
|
-
// 全局安装最新版
|
|
6
|
-
spawnSync('npm', ['install', '-g', '@costrict/cosknow@latest'], {
|
|
7
|
-
stdio: 'inherit',
|
|
8
|
-
shell: true,
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
// 获取全局 node_modules 路径
|
|
12
|
-
let globalPrefix
|
|
13
|
-
try {
|
|
14
|
-
globalPrefix = execSync('npm root -g', { encoding: 'utf8' }).trim()
|
|
15
|
-
} catch {
|
|
16
|
-
console.warn('[cosknow] cannot determine global npm root, skipping')
|
|
17
|
-
process.exit(0)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
let install
|
|
21
|
-
try {
|
|
22
|
-
const mod = await import(pathToFileURL(join(globalPrefix, '@costrict', 'cosknow', 'dist', 'index.js')).href)
|
|
23
|
-
install = mod.install
|
|
24
|
-
} catch {
|
|
25
|
-
console.warn('[cosknow] package not available, skipping command installation')
|
|
26
|
-
process.exit(0)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
await install({ target: 'claude-commands' })
|
|
31
|
-
console.log('[cosknow] commands installed to ~/.claude/commands/')
|
|
32
|
-
} catch (e) {
|
|
33
|
-
console.warn('[cosknow] install failed (non-fatal):', e.message)
|
|
34
|
-
}
|