cc-viewer 1.7.23 → 1.8.1
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/README.md +20 -0
- package/cli.js +92 -11
- package/concepts/ar/GlobalSettings.md +2 -2
- package/concepts/ar/ToolsFirst.md +1 -1
- package/concepts/da/GlobalSettings.md +2 -2
- package/concepts/da/ToolsFirst.md +1 -1
- package/concepts/de/GlobalSettings.md +2 -2
- package/concepts/de/ToolsFirst.md +1 -1
- package/concepts/en/GlobalSettings.md +2 -2
- package/concepts/en/ToolsFirst.md +1 -1
- package/concepts/es/GlobalSettings.md +2 -2
- package/concepts/es/ToolsFirst.md +1 -1
- package/concepts/fr/GlobalSettings.md +2 -2
- package/concepts/fr/ToolsFirst.md +1 -1
- package/concepts/it/GlobalSettings.md +2 -2
- package/concepts/it/ToolsFirst.md +1 -1
- package/concepts/ja/GlobalSettings.md +2 -2
- package/concepts/ja/ToolsFirst.md +1 -1
- package/concepts/ko/GlobalSettings.md +2 -2
- package/concepts/ko/ToolsFirst.md +1 -1
- package/concepts/no/GlobalSettings.md +2 -2
- package/concepts/no/ToolsFirst.md +1 -1
- package/concepts/pl/GlobalSettings.md +2 -2
- package/concepts/pl/ToolsFirst.md +1 -1
- package/concepts/pt-BR/GlobalSettings.md +2 -2
- package/concepts/pt-BR/ToolsFirst.md +1 -1
- package/concepts/ru/GlobalSettings.md +2 -2
- package/concepts/ru/ToolsFirst.md +1 -1
- package/concepts/th/GlobalSettings.md +2 -2
- package/concepts/th/ToolsFirst.md +1 -1
- package/concepts/tr/GlobalSettings.md +2 -2
- package/concepts/tr/ToolsFirst.md +1 -1
- package/concepts/uk/GlobalSettings.md +2 -2
- package/concepts/uk/ToolsFirst.md +1 -1
- package/concepts/zh/GlobalSettings.md +2 -2
- package/concepts/zh/ToolsFirst.md +1 -1
- package/concepts/zh-TW/GlobalSettings.md +2 -2
- package/concepts/zh-TW/ToolsFirst.md +1 -1
- package/dist/assets/App-CqQJDjfT.js +2 -0
- package/dist/assets/App-ssYfrjwF.css +1 -0
- package/dist/assets/{MdxEditorPanel-e5DlfcqJ.js → MdxEditorPanel-DXwb5tSD.js} +1 -1
- package/dist/assets/{Mobile-B8xwCLgr.js → Mobile-DOjKURO3.js} +1 -1
- package/dist/assets/{ProxyStatsModal-_w677xPM.js → ProxyStatsModal-BEnxiRXF.js} +1 -1
- package/dist/assets/index-CH_N7vvX.js +2 -0
- package/dist/assets/seqResourceLoaders-BJhO6zhW.js +2 -0
- package/dist/assets/seqResourceLoaders-DI0G5nu1.css +41 -0
- package/dist/index.html +1 -1
- package/findcc.js +17 -8
- package/node_modules/@ccv/core/package.json +13 -0
- package/{server/lib → node_modules/@ccv/core/src}/approval-modal-prefs.js +1 -1
- package/node_modules/@ccv/core/src/clearCheckpoint.js +7 -0
- package/{src/utils → node_modules/@ccv/core/src}/contentFilter.js +207 -141
- package/{server/lib → node_modules/@ccv/core/src}/context-rules.js +2 -2
- package/{server/lib → node_modules/@ccv/core/src}/delta-reconstructor.js +60 -4
- package/{server/lib → node_modules/@ccv/core/src}/error-report.js +5 -4
- package/{server/lib → node_modules/@ccv/core/src}/session-boundary.js +3 -3
- package/{src/utils → node_modules/@ccv/core/src}/teammateDetector.js +9 -0
- package/{server/lib → node_modules/@ccv/core/src}/tools-xml-formatter.js +3 -3
- package/{server/lib → node_modules/@ccv/core/src}/v2-transcript-normalizer.js +1 -1
- package/{server/lib → node_modules/@ccv/core/src}/voice-pack-events.js +2 -2
- package/package.json +11 -97
- package/server/_paths.js +28 -7
- package/server/i18n.js +60 -0
- package/server/interceptor.js +36 -11
- package/server/lib/adapters/dingtalk-adapter.js +2 -2
- package/server/lib/adapters/discord-adapter.js +2 -2
- package/server/lib/adapters/feishu-adapter.js +2 -2
- package/server/lib/adapters/wecom-adapter.js +2 -2
- package/server/lib/approval-policy.js +29 -0
- package/server/lib/{ask-store.js → ask/ask-store.js} +3 -3
- package/server/lib/{perm-bridge.js → ask/perm-bridge.js} +5 -5
- package/server/lib/builtin-model-prompts.js +198 -0
- package/server/lib/chat-queue.js +341 -0
- package/server/lib/cli-inject.js +1 -1
- package/server/lib/context-watcher.js +3 -3
- package/server/lib/create_system_prompt.js +0 -9
- package/server/lib/enrich-plan-input.js +1 -1
- package/server/lib/ensure-hooks.js +2 -2
- package/server/lib/file-access-policy.js +6 -1
- package/server/lib/file-api.js +17 -1
- package/server/lib/{dingtalk-bridge.js → im/dingtalk-bridge.js} +1 -1
- package/server/lib/{im-append-system.js → im/im-append-system.js} +5 -13
- package/server/lib/{im-bridge-core.js → im/im-bridge-core.js} +12 -6
- package/server/lib/{im-config.js → im/im-config.js} +1 -1
- package/server/lib/im/im-deny.js +4 -0
- package/server/lib/{im-lang.js → im/im-lang.js} +1 -1
- package/server/lib/{im-lock.js → im/im-lock.js} +2 -2
- package/server/lib/{im-process-manager.js → im/im-process-manager.js} +1 -1
- package/server/lib/{im-senders.js → im/im-senders.js} +1 -1
- package/server/lib/{im-skills.js → im/im-skills.js} +2 -2
- package/server/lib/interceptor-core.js +8 -5
- package/server/lib/kv-cache-analyzer.js +6 -5
- package/server/lib/launch-config.js +329 -0
- package/server/lib/log-file-utils.js +21 -0
- package/server/lib/log-management.js +6 -17
- package/server/lib/log-stream.js +1 -1
- package/server/lib/log-watcher.js +1 -1
- package/server/lib/model-system-prompts.js +18 -2
- package/server/lib/prefs-store.js +2 -2
- package/server/lib/project-prefs.js +6 -6
- package/server/lib/project-state.js +15 -0
- package/server/lib/{proxy-retry.js → proxy/proxy-retry.js} +2 -2
- package/server/lib/{proxy-stats.js → proxy/proxy-stats.js} +3 -3
- package/server/lib/sdk-adapter.js +6 -74
- package/server/lib/sdk-manager.js +383 -278
- package/server/lib/skills-api.js +1 -1
- package/server/lib/spawn-model-resolver.js +21 -6
- package/server/lib/stats-worker.js +2 -2
- package/server/lib/system-prompt-files.js +53 -15
- package/server/lib/system-prompt-render.js +23 -7
- package/server/lib/system-prompt-snapshots.js +452 -0
- package/server/lib/updater.js +63 -3
- package/server/lib/user-prompt-extract.js +5 -5
- package/server/lib/v2/adapter.js +3 -3
- package/server/lib/v2/conversation-store.js +1 -1
- package/server/lib/v2/convert.js +3 -3
- package/server/lib/v2/jsonl-read.js +1 -1
- package/server/lib/v2/live-feed.js +3 -3
- package/server/lib/v2/meta-rows.js +3 -3
- package/server/lib/v2/replay.js +1 -1
- package/server/lib/v2/session-list.js +1 -1
- package/server/lib/v2/session-owner.js +1 -1
- package/server/lib/v2/v2-writer.js +26 -1
- package/server/lib/v2/verify.js +1 -1
- package/server/lib/voice-pack-manager.js +4 -5
- package/server/lib/wire-compress.js +1 -1
- package/server/proxy.js +5 -5
- package/server/pty-manager.js +285 -184
- package/server/routes/ask-perm.js +1 -1
- package/server/routes/dingtalk.js +3 -3
- package/server/routes/events.js +2 -2
- package/server/routes/expert.js +74 -13
- package/server/routes/im.js +5 -5
- package/server/routes/preferences.js +3 -3
- package/server/routes/workspaces.js +1 -1
- package/server/server.js +207 -58
- package/server/system-prompt-templates/systemPromptModel.md +0 -8
- package/server/system-prompt-templates/systemPromptVariables.ar.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.da.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.de.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.es.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.fr.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.it.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.ja.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.ko.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.no.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.pl.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.pt-BR.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.ru.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.th.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.tr.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.uk.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.zh-TW.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.zh.md +0 -7
- package/ultraAgents/README.md +3 -0
- package/ultraAgents/test-analysis-expert.json +45 -0
- package/dist/assets/App-BWajJyJh.css +0 -1
- package/dist/assets/App-CusqoEAB.js +0 -2
- package/dist/assets/index-D6FmFsIz.js +0 -2
- package/dist/assets/seqResourceLoaders-3K77Znll.js +0 -2
- package/dist/assets/seqResourceLoaders-BgD_Rwvc.css +0 -41
- package/src/utils/apiUrl.js +0 -26
- package/src/utils/askFallback.js +0 -21
- package/src/utils/askOptionDesc.js +0 -55
- package/src/utils/askPortalMatcher.js +0 -54
- package/src/utils/autoApproveOptions.js +0 -27
- package/src/utils/avatarAnimationPostPass.js +0 -49
- package/src/utils/builtinPresets.js +0 -18
- package/src/utils/clearCheckpoint.js +0 -7
- package/src/utils/commandValidator.js +0 -45
- package/src/utils/contextRaw.js +0 -18
- package/src/utils/contextSidebarNavigation.js +0 -16
- package/src/utils/contextTurns.js +0 -117
- package/src/utils/displayScaleHelper.js +0 -47
- package/src/utils/effectiveModel.js +0 -17
- package/src/utils/entry-slim.js +0 -563
- package/src/utils/entryCache.js +0 -144
- package/src/utils/errorReport.js +0 -6
- package/src/utils/fileExpandedPathsStorage.js +0 -70
- package/src/utils/fileIcons.jsx +0 -36
- package/src/utils/fileOpen.js +0 -37
- package/src/utils/formatters.js +0 -48
- package/src/utils/gitApi.js +0 -50
- package/src/utils/gitTreeBuilder.js +0 -19
- package/src/utils/helpers.js +0 -854
- package/src/utils/identityHeal.js +0 -108
- package/src/utils/imConnState.js +0 -59
- package/src/utils/imOrigin.js +0 -24
- package/src/utils/imTr.js +0 -7
- package/src/utils/imageCompress.js +0 -83
- package/src/utils/imageDownscale.js +0 -28
- package/src/utils/imageResize.js +0 -112
- package/src/utils/ingestPipeline.js +0 -47
- package/src/utils/isProxyMode.js +0 -11
- package/src/utils/lazyWithReload.js +0 -53
- package/src/utils/markdown.js +0 -30
- package/src/utils/markdownIncremental.js +0 -39
- package/src/utils/markdownProfiler.js +0 -113
- package/src/utils/mdExtensionDetect.js +0 -64
- package/src/utils/memoryLinkParser.js +0 -44
- package/src/utils/modalMask.js +0 -15
- package/src/utils/modelSuggestions.js +0 -48
- package/src/utils/monotime.js +0 -6
- package/src/utils/pinnedMenu.js +0 -55
- package/src/utils/presetShortcuts.js +0 -14
- package/src/utils/projectAlias.js +0 -135
- package/src/utils/promptClassifier.js +0 -112
- package/src/utils/promptDetect.js +0 -196
- package/src/utils/promptNav.js +0 -60
- package/src/utils/ptyChunkBuilder.js +0 -251
- package/src/utils/quickMenuHoverIntent.js +0 -35
- package/src/utils/rateLimitParser.js +0 -119
- package/src/utils/readResultPool.js +0 -106
- package/src/utils/refreshCachedItemProp.js +0 -30
- package/src/utils/resizeCalc.js +0 -21
- package/src/utils/resolveLocalized.js +0 -17
- package/src/utils/searchApi.js +0 -47
- package/src/utils/searchReplace.js +0 -51
- package/src/utils/seqResourceLoaders.js +0 -79
- package/src/utils/sessionManager.js +0 -482
- package/src/utils/sessionMerge.js +0 -239
- package/src/utils/skillModalController.js +0 -111
- package/src/utils/skillsParser.js +0 -116
- package/src/utils/slashCommandLabels.js +0 -80
- package/src/utils/splitDragCalc.js +0 -73
- package/src/utils/stickyBottomController.js +0 -643
- package/src/utils/svgSanitize.js +0 -48
- package/src/utils/systemTags.js +0 -47
- package/src/utils/tClaude.js +0 -20
- package/src/utils/teamModalBuilder.js +0 -351
- package/src/utils/teamSessionParser.js +0 -190
- package/src/utils/teammateAvatars.js +0 -194
- package/src/utils/termDiag.js +0 -114
- package/src/utils/terminalClipboard.js +0 -117
- package/src/utils/terminalWriteQueue.js +0 -398
- package/src/utils/thinkingMerge.js +0 -49
- package/src/utils/toolCatalog.js +0 -30
- package/src/utils/toolResultBuilder.js +0 -411
- package/src/utils/toolResultClassifier.js +0 -16
- package/src/utils/toolResultCore.js +0 -194
- package/src/utils/toolsDiff.js +0 -44
- package/src/utils/toolsXmlFormatter.js +0 -3
- package/src/utils/ultraplanController.js +0 -109
- package/src/utils/ultraplanExperts.js +0 -86
- package/src/utils/ultraplanTemplates.js +0 -154
- package/src/utils/userImageRefs.js +0 -49
- package/src/utils/v3Assembler.js +0 -125
- package/src/utils/v3Rows.js +0 -49
- package/src/utils/voicePackPlayer.js +0 -233
- package/src/utils/webSearchGrouping.js +0 -111
- package/src/utils/workflowFormat.js +0 -52
- package/src/utils/workflowRuns.js +0 -118
- package/src/utils/workflowStore.js +0 -94
- /package/{src/utils → node_modules/@ccv/core/src}/requestType.js +0 -0
- /package/server/lib/{ask-bridge.js → ask/ask-bridge.js} +0 -0
- /package/server/lib/{ask-constants.js → ask/ask-constants.js} +0 -0
- /package/server/lib/{ask-reaper.js → ask/ask-reaper.js} +0 -0
- /package/server/lib/{dingtalk-config.js → im/dingtalk-config.js} +0 -0
- /package/server/lib/{im-log-watcher.js → im/im-log-watcher.js} +0 -0
- /package/server/lib/{proxy-env.js → proxy/proxy-env.js} +0 -0
- /package/server/lib/{proxy-errors.js → proxy/proxy-errors.js} +0 -0
package/server/lib/skills-api.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Skill 动态装卸 API —— 扫描并移动 `.claude/skills/` 和 `.claude/skills-skip/` 之间的 skill 文件夹。
|
|
2
|
-
// 纯 Node 实现,无 React / 浏览器 依赖,方便 test/skills-api.test.js 直接 import。
|
|
2
|
+
// 纯 Node 实现,无 React / 浏览器 依赖,方便 packages/app/test/skills-api.test.js 直接 import。
|
|
3
3
|
|
|
4
4
|
import { existsSync, readdirSync, readFileSync, lstatSync, mkdirSync, renameSync, cpSync, rmSync, realpathSync } from 'node:fs';
|
|
5
5
|
import { join, basename, sep, normalize, isAbsolute } from 'node:path';
|
|
@@ -9,12 +9,21 @@
|
|
|
9
9
|
//
|
|
10
10
|
// Signal priority (best-effort heuristic — the shell-env vs settings.json-env ordering is
|
|
11
11
|
// a repo convention, not documented Claude Code semantics; a mismatch merely means "no
|
|
12
|
-
// injection" or "same-family entry", both harmless)
|
|
13
|
-
//
|
|
14
|
-
//
|
|
12
|
+
// injection" or "same-family entry", both harmless).
|
|
13
|
+
// Base model, most spawn-specific first:
|
|
14
|
+
// 1. the MERGED --settings launch object (opts.launchSettings — pty-manager folds the
|
|
15
|
+
// user's/launcher's --settings into the injected one): env.CLAUDE_MODEL >
|
|
16
|
+
// env.ANTHROPIC_MODEL. Wrappers like cfuse deliver the real model EXCLUSIVELY
|
|
17
|
+
// inside this blob, and claude applies a settings env block over the inherited
|
|
18
|
+
// shell env — so this outranks process env.
|
|
15
19
|
// 2. env CLAUDE_MODEL > env ANTHROPIC_MODEL (shell exports inherited by the spawn)
|
|
16
|
-
// 3.
|
|
20
|
+
// 3. launchSettings top-level `model` (below the inherited env vars, mirroring
|
|
21
|
+
// Claude Code's own env-over-settings precedence)
|
|
22
|
+
// 4. settings.json `env.ANTHROPIC_MODEL` > settings.json top-level `model`
|
|
17
23
|
// (the env block outranks the top-level field, mirroring how Claude Code applies it)
|
|
24
|
+
// Then the active third-party proxy profile for the spawned workspace rewrites the base
|
|
25
|
+
// via family mapping (resolveProfileModel — the model the ccv proxy will actually
|
|
26
|
+
// route to).
|
|
18
27
|
// Known limitation: a `--model` flag passed through extraArgs is not consulted.
|
|
19
28
|
//
|
|
20
29
|
// Pure disk reads — deliberately NOT importing server/interceptor.js: its module-level
|
|
@@ -79,7 +88,10 @@ function readActiveProfile(spawnDir, logDir) {
|
|
|
79
88
|
*
|
|
80
89
|
* @param {string} spawnDir workspace being launched (absolute path)
|
|
81
90
|
* @param {Object} [env] environment (default process.env)
|
|
82
|
-
* @param {{ logDir?: string, configDir?: string }} [opts]
|
|
91
|
+
* @param {{ logDir?: string, configDir?: string, launchSettings?: Object|null }} [opts]
|
|
92
|
+
* logDir/configDir: test seams for the data roots;
|
|
93
|
+
* launchSettings: the merged --settings object this spawn will run with
|
|
94
|
+
* (highest-priority base-model signal — see header)
|
|
83
95
|
* @returns {string|null}
|
|
84
96
|
*/
|
|
85
97
|
export function resolveSpawnModel(spawnDir, env = process.env, opts = {}) {
|
|
@@ -87,7 +99,10 @@ export function resolveSpawnModel(spawnDir, env = process.env, opts = {}) {
|
|
|
87
99
|
const configDir = opts.configDir || getClaudeConfigDir();
|
|
88
100
|
|
|
89
101
|
// Base model: what claude itself is configured to request.
|
|
90
|
-
|
|
102
|
+
const launch = (opts.launchSettings && typeof opts.launchSettings === 'object') ? opts.launchSettings : null;
|
|
103
|
+
let base = nonEmpty(launch?.env?.CLAUDE_MODEL) || nonEmpty(launch?.env?.ANTHROPIC_MODEL)
|
|
104
|
+
|| nonEmpty(env?.CLAUDE_MODEL) || nonEmpty(env?.ANTHROPIC_MODEL)
|
|
105
|
+
|| nonEmpty(launch?.model);
|
|
91
106
|
if (!base) {
|
|
92
107
|
const settings = readJson(join(configDir, 'settings.json'));
|
|
93
108
|
base = nonEmpty(settings?.env?.ANTHROPIC_MODEL) || nonEmpty(settings?.model);
|
|
@@ -10,12 +10,12 @@ import { join, basename } from 'node:path';
|
|
|
10
10
|
import { readJsonlTolerant, listSessionIds } from './v2/replay.js';
|
|
11
11
|
import { dirSizeSync } from './v2/layout.js';
|
|
12
12
|
import { isDiscardableSession } from './v2/session-select.js';
|
|
13
|
-
import { reportSwallowed } from '
|
|
13
|
+
import { reportSwallowed } from '@ccv/core/error-report';
|
|
14
14
|
import {
|
|
15
15
|
INTER_SESSION_TYPES, isSystemText, extractUserTexts, isSuggestionMode,
|
|
16
16
|
collectPromptsFromEvents, sortEpochFiles,
|
|
17
17
|
} from './user-prompt-extract.js';
|
|
18
|
-
import { aggregateRecords, mergeProxyFileCache, parseDailyFileName } from './proxy-stats.js';
|
|
18
|
+
import { aggregateRecords, mergeProxyFileCache, parseDailyFileName } from './proxy/proxy-stats.js';
|
|
19
19
|
|
|
20
20
|
// Prompt/preview extraction moved to the shared server/lib/user-prompt-extract.js
|
|
21
21
|
// (also feeds the V2Writer prompts.jsonl cache and the log-list read side).
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readFileSync, writeFileSync, rmSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { MODEL_PROMPT_DIR, matchModelPrompt } from './model-system-prompts.js';
|
|
4
|
+
import { isBuiltinDisabled, matchBuiltinModelPrompt, materializeBuiltinPrompt } from './builtin-model-prompts.js';
|
|
5
|
+
import { isNonEmptyFile } from './file-api.js';
|
|
6
|
+
import { reportSwallowed } from '@ccv/core/error-report';
|
|
7
|
+
|
|
8
|
+
// isNonEmptyFile lives in file-api.js (shared leaf, cycle break:
|
|
9
|
+
// model-system-prompts.js must not import this module). Re-exported here so
|
|
10
|
+
// existing consumers (routes/expert.js) keep their module path.
|
|
11
|
+
export { isNonEmptyFile } from './file-api.js';
|
|
4
12
|
|
|
5
13
|
// 启动目录里检查的「全大写 sentinel」文件名:多词约定用下划线连接
|
|
6
14
|
// (对齐 CLAUDE.md / GitHub CODE_OF_CONDUCT.md 等惯例)。
|
|
@@ -14,17 +22,12 @@ export const DISABLE_AUTO_SYSTEM_PROMPT_ENV = 'CCV_DISABLE_AUTO_SYSTEM_PROMPT';
|
|
|
14
22
|
|
|
15
23
|
// 文件需存在、是普通文件且非空(size>0)才算数:空文件会把 system prompt 抹空,跳过更安全。
|
|
16
24
|
// 坏符号链接 / 不存在 / 目录 → statSync 抛错或 isFile()=false → 返回 false。
|
|
17
|
-
export
|
|
18
|
-
try {
|
|
19
|
-
const st = statSync(p);
|
|
20
|
-
return st.isFile() && st.size > 0;
|
|
21
|
-
} catch {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
+
// (implementation: file-api.js — see the re-export above)
|
|
25
26
|
|
|
26
27
|
// args 里是否已含某个 flag(同时匹配 `--x` 与 `--x=value` 两种写法,检测更稳)。
|
|
27
|
-
|
|
28
|
+
// Exported for pty-manager's pin path: a manually-passed flag suppresses the matching
|
|
29
|
+
// pinned entry with the same semantics as the fresh-build path.
|
|
30
|
+
export function hasArg(args, ...names) {
|
|
28
31
|
if (!Array.isArray(args)) return false;
|
|
29
32
|
return args.some(a =>
|
|
30
33
|
typeof a === 'string' && names.some(n => a === n || a.startsWith(n + '='))
|
|
@@ -41,22 +44,28 @@ function hasArg(args, ...names) {
|
|
|
41
44
|
*
|
|
42
45
|
* 模型定制(opts.modelId 提供时):先在 <projectDir>/system_prompt/(工作区)与
|
|
43
46
|
* opts.globalModelDir(全局)里做模糊匹配;命中的条目「整体取代」上面两份默认 sentinel
|
|
44
|
-
* ——即便手动 flag 抑制了注入也不再回看默认文件(条目已取而代之)
|
|
45
|
-
*
|
|
47
|
+
* ——即便手动 flag 抑制了注入也不再回看默认文件(条目已取而代之)。未命中则进入内置层:
|
|
48
|
+
* 随包 presets(builtin-model-prompts.js)按同语义再匹配一次,命中且未被墓碑禁用时把
|
|
49
|
+
* preset 文本物化为临时文件注入;命中被禁用(builtinDisabled)或未命中才回落 sentinel。
|
|
46
50
|
*
|
|
47
51
|
* Decide whether to inject system-prompt file flags based on sentinel files in
|
|
48
52
|
* the launch directory. When opts.modelId is given, model-specific entries in
|
|
49
53
|
* the workspace/global system_prompt folders are matched first; a match fully
|
|
50
|
-
* supersedes the Default sentinels.
|
|
54
|
+
* supersedes the Default sentinels. Without a file match, shipped built-in presets
|
|
55
|
+
* act as the fallback layer (tombstone-disabled ones are skipped). Reads fs/env;
|
|
56
|
+
* writes materialized built-in temp files; the built-in layer never throws — any
|
|
57
|
+
* failure falls back to the sentinel logic via reportSwallowed.
|
|
51
58
|
*
|
|
52
59
|
* @param {string} projectDir 启动目录(绝对路径)
|
|
53
60
|
* @param {string[]} [existingArgs] 已有的 claude 参数(用于「手动优先」判断)
|
|
54
61
|
* @param {Object} [env] 环境变量(默认 process.env)
|
|
55
62
|
* @param {{ modelId?: string|null, globalModelDir?: string|null }} [opts]
|
|
56
|
-
* @returns {{ args: string[], loaded: string[], model: string|null, suppressed?: 'env'|'manual-flag'
|
|
63
|
+
* @returns {{ args: string[], loaded: string[], model: string|null, suppressed?: 'env'|'manual-flag',
|
|
64
|
+
* builtinDisabled?: string }}
|
|
57
65
|
* args: 待追加参数;loaded: 实际加载的文件(终端提示);model: 命中的条目名(未命中为 null);
|
|
58
66
|
* suppressed: 注入被有意跳过的原因(env 开关 / 手动同义 flag 抑制了已命中的模型条目)——
|
|
59
67
|
* 调用方(pty-manager)据此不再打「no matching entry」误导性告警。
|
|
68
|
+
* builtinDisabled 仅在内置层命中但被墓碑禁用时出现(增量字段,否则不存在)。
|
|
60
69
|
*/
|
|
61
70
|
export function buildSystemPromptFileArgs(projectDir, existingArgs = [], env = process.env, opts = {}) {
|
|
62
71
|
const out = { args: [], loaded: [], model: null };
|
|
@@ -80,8 +89,37 @@ export function buildSystemPromptFileArgs(projectDir, existingArgs = [], env = p
|
|
|
80
89
|
}
|
|
81
90
|
return out; // 命中即返回:默认 sentinel 不再参与(含手动 flag 抑制注入的情况)。
|
|
82
91
|
}
|
|
92
|
+
// 用户文件未命中 → 内置层(随包 presets):同语义匹配 + 墓碑检查;命中即物化注入并
|
|
93
|
+
// 提前返回(同样取代 sentinel)。整层 try-catch:任何失败(preset 缺失/tmp 不可写)经
|
|
94
|
+
// reportSwallowed 回落 sentinel——内置不可用绝不应连默认注入都拖垮。
|
|
95
|
+
// No file match → built-in fallback layer (shipped presets, tombstone-aware).
|
|
96
|
+
try {
|
|
97
|
+
const builtin = matchBuiltinModelPrompt(opts.modelId);
|
|
98
|
+
if (builtin) {
|
|
99
|
+
const flagPair = builtin.mode === 'override'
|
|
100
|
+
? ['--system-prompt', '--system-prompt-file']
|
|
101
|
+
: ['--append-system-prompt', '--append-system-prompt-file'];
|
|
102
|
+
if (hasArg(existingArgs, ...flagPair)) {
|
|
103
|
+
out.suppressed = 'manual-flag'; // 与文件命中同语义:有意跳过,非「无条目」
|
|
104
|
+
return out; // 手动抑制也提前返回(不物化、不回看 sentinel)
|
|
105
|
+
}
|
|
106
|
+
const workspaceModelDir = join(projectDir, MODEL_PROMPT_DIR);
|
|
107
|
+
if (isBuiltinDisabled(builtin.name, workspaceModelDir, opts.globalModelDir)) {
|
|
108
|
+
out.builtinDisabled = builtin.name; // 供 launch-config 区分「被禁用」与「无条目」
|
|
109
|
+
// 落回 sentinel(不 return)
|
|
110
|
+
} else {
|
|
111
|
+
const path = materializeBuiltinPrompt(builtin.id, builtin.text);
|
|
112
|
+
out.args.push(flagPair[1], path);
|
|
113
|
+
out.loaded.push(`builtin:${builtin.name}`); // 稳定标签,不打印 tmp 丑路径
|
|
114
|
+
out.model = builtin.name;
|
|
115
|
+
return out;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} catch (err) {
|
|
119
|
+
reportSwallowed('system-prompt-files.builtin', err);
|
|
120
|
+
}
|
|
83
121
|
// No matching entry: fall through to the default sentinels. Diagnostics for
|
|
84
|
-
// this case live in the caller (pty-manager)
|
|
122
|
+
// this case live in the caller (launch-config/pty-manager).
|
|
85
123
|
}
|
|
86
124
|
|
|
87
125
|
// 整段替换:CC_SYSTEM.md → --system-prompt-file (用户已传 --system-prompt[-file] 则跳过)
|
|
@@ -39,25 +39,36 @@ export function renderedPromptDir(pid = process.pid) {
|
|
|
39
39
|
* modelId: resolved model id from the last launch — becomes ${model.name} (the [1m]
|
|
40
40
|
* context-window suffix is stripped: it is a claude-code UI notation, not a model name);
|
|
41
41
|
* variablesFactory: test seam replacing createSystemPromptVariables.
|
|
42
|
-
* @returns {{ args: string[], loaded: string[], model: string|null }}
|
|
43
|
-
* whose content was rendered point at the temp copy
|
|
42
|
+
* @returns {{ args: string[], loaded: string[], model: string|null, entries: Array }}
|
|
43
|
+
* same shape; file paths whose content was rendered point at the temp copy
|
|
44
|
+
* instead. `entries` records the FINAL content of every injected file —
|
|
45
|
+
* [{flag, basename, content}] for successfully read files (rendered text when
|
|
46
|
+
* rendered, raw text when passed through — the launch-time bytes are what a
|
|
47
|
+
* later `-c`/`-r` pin must reuse, not whatever the source file says by then),
|
|
48
|
+
* or {flag, basename, content: null, unavailable: true} when the file could
|
|
49
|
+
* not be read/rendered (the arg falls back to the raw path; snapshot writers
|
|
50
|
+
* skip unavailable entries). Consumers that don't care can ignore the field.
|
|
44
51
|
*/
|
|
45
52
|
export function renderSystemPromptFileArgs(sysPrompt, opts = {}) {
|
|
46
53
|
// Defensive: null / non-object → safe default, so the caller always gets a valid
|
|
47
54
|
// spread target and the "loaded" notice guard (sysPrompt.loaded.length) can't throw.
|
|
48
|
-
if (!sysPrompt || typeof sysPrompt !== 'object') return { args: [], loaded: [], model: null };
|
|
55
|
+
if (!sysPrompt || typeof sysPrompt !== 'object') return { args: [], loaded: [], model: null, entries: [] };
|
|
49
56
|
const args = Array.isArray(sysPrompt.args) ? sysPrompt.args : [];
|
|
50
|
-
if (args.length === 0) return sysPrompt;
|
|
57
|
+
if (args.length === 0) return { entries: [], ...sysPrompt };
|
|
51
58
|
|
|
52
59
|
let variables = null; // lazy: collected once, and only if some file actually has placeholders
|
|
53
60
|
const out = [...args];
|
|
61
|
+
const entries = [];
|
|
54
62
|
for (let i = 0; i + 1 < out.length; i += 2) {
|
|
55
63
|
const flag = out[i];
|
|
56
64
|
if (flag !== '--system-prompt-file' && flag !== '--append-system-prompt-file') continue;
|
|
57
65
|
const path = out[i + 1];
|
|
58
66
|
try {
|
|
59
67
|
const text = readFileSync(path, 'utf-8');
|
|
60
|
-
if (!TEMPLATE_VARIABLE_RE.test(text))
|
|
68
|
+
if (!TEMPLATE_VARIABLE_RE.test(text)) {
|
|
69
|
+
entries.push({ flag, basename: basename(path), content: text }); // pass-through: pin the launch-time bytes
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
61
72
|
if (!variables) {
|
|
62
73
|
const factory = opts.variablesFactory || createSystemPromptVariables;
|
|
63
74
|
const overrides = {};
|
|
@@ -65,15 +76,20 @@ export function renderSystemPromptFileArgs(sysPrompt, opts = {}) {
|
|
|
65
76
|
variables = factory(overrides, { cwd: opts.cwd });
|
|
66
77
|
}
|
|
67
78
|
const rendered = createSystemPrompt(text, { variables, missingVariableMode: 'keep' });
|
|
68
|
-
if (rendered === text)
|
|
79
|
+
if (rendered === text) { // every placeholder unknown → nothing changed, keep raw path
|
|
80
|
+
entries.push({ flag, basename: basename(path), content: text });
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
69
83
|
const dir = renderedPromptDir();
|
|
70
84
|
mkdirSync(dir, { recursive: true });
|
|
71
85
|
const target = join(dir, basename(path));
|
|
72
86
|
writeFileSync(target, rendered, 'utf-8');
|
|
73
87
|
out[i + 1] = target;
|
|
88
|
+
entries.push({ flag, basename: basename(path), content: rendered });
|
|
74
89
|
} catch (e) {
|
|
90
|
+
entries.push({ flag, basename: basename(path), content: null, unavailable: true });
|
|
75
91
|
console.warn(`[CC Viewer] system-prompt template render failed for ${path} (injecting the raw file):`, e?.message || e);
|
|
76
92
|
}
|
|
77
93
|
}
|
|
78
|
-
return { ...sysPrompt, args: out };
|
|
94
|
+
return { ...sysPrompt, args: out, entries };
|
|
79
95
|
}
|