@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.
@@ -736,8 +736,8 @@ function getClientVersion() {
736
736
  if (cached)
737
737
  return cached;
738
738
  try {
739
- if ("4.2.27") {
740
- cached = "4.2.27";
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.27",
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.27".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
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.27",
138900
+ version: "4.2.29",
138890
138901
  versionBase: getVersionBase(),
138891
- buildTime: "2026-08-13T08:38:48.650Z",
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=37609006F3D6B41264756E2164756E21
143240
+ //# debugId=ADEDB9641343B30B64756E2164756E21
143230
143241
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@costrict/csc",
3
- "version": "4.2.27",
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/install-cosknow.mjs"
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/install-cosknow.mjs",
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
- }