From 196ff5ba21145ec77427d0d74484f21bb407df7c Mon Sep 17 00:00:00 2001 From: DoSun Date: Fri, 15 May 2026 09:10:07 +0800 Subject: [PATCH] feat: add task notification mode and skip review builtin option - Add TASK_NOTIFICATION_TAG to distinguish task notifications from regular prompts - Add SKIP_REVIEW_BUILTIN=1 env var to skip review builtin generation during dev/build for faster startup Co-Authored-By: claude-sonnet-4-6 --- build.ts | 22 ++++++++++------- scripts/dev.ts | 20 +++++++++------ src/cli/print.ts | 63 ++++++++++++++++++++++++++++++------------------ 3 files changed, 64 insertions(+), 41 deletions(-) diff --git a/build.ts b/build.ts index fceb03b98..5a2ad896e 100644 --- a/build.ts +++ b/build.ts @@ -8,15 +8,19 @@ const outdir = 'dist' const { rmSync } = await import('fs') rmSync(outdir, { recursive: true, force: true }) -// Step 1.5: Generate review builtin files -console.log('Generating review builtin files...') -const { spawnSync: genSpawnSync } = await import('child_process') -const genResult = genSpawnSync('bun', ['run', 'scripts/generate-review-builtin.ts'], { - stdio: 'inherit', - cwd: process.cwd(), -}) -if (genResult.status !== 0) { - console.warn('Warning: generate-review-builtin.ts failed, using existing files') +// Step 1.5: Generate review builtin files (skip with SKIP_REVIEW_BUILTIN=1) +if (process.env.SKIP_REVIEW_BUILTIN) { + console.log('Skipping review builtin generation (SKIP_REVIEW_BUILTIN is set)') +} else { + console.log('Generating review builtin files...') + const { spawnSync: genSpawnSync } = await import('child_process') + const genResult = genSpawnSync('bun', ['run', 'scripts/generate-review-builtin.ts'], { + stdio: 'inherit', + cwd: process.cwd(), + }) + if (genResult.status !== 0) { + console.warn('Warning: generate-review-builtin.ts failed, using existing files') + } } // Default features that match the official CLI build. diff --git a/scripts/dev.ts b/scripts/dev.ts index 18bf21547..39d258284 100644 --- a/scripts/dev.ts +++ b/scripts/dev.ts @@ -73,14 +73,18 @@ const inspectArgs = process.env.BUN_INSPECT // npm, etc.) and on all platforms. const bunCmd = process.execPath; -// Generate review builtin files before dev launch -console.log('[dev] Generating review builtin files...'); -const genResult = Bun.spawnSync(['bun', 'run', 'scripts/generate-review-builtin.ts'], { - stdio: ["inherit", "inherit", "inherit"], - cwd: projectRoot, -}); -if (!genResult.success) { - console.warn('[dev] Warning: generate-review-builtin.ts failed, using existing files'); +// Generate review builtin files before dev launch (skip with SKIP_REVIEW_BUILTIN=1) +if (process.env.SKIP_REVIEW_BUILTIN) { + console.log('[dev] Skipping review builtin generation (SKIP_REVIEW_BUILTIN is set)'); +} else { + console.log('[dev] Generating review builtin files...'); + const genResult = Bun.spawnSync(['bun', 'run', 'scripts/generate-review-builtin.ts'], { + stdio: ["inherit", "inherit", "inherit"], + cwd: projectRoot, + }); + if (!genResult.success) { + console.warn('[dev] Warning: generate-review-builtin.ts failed, using existing files'); + } } const args = [bunCmd, ...inspectArgs, "run", ...defineArgs, ...featureArgs, cliPath, ...process.argv.slice(2)]; diff --git a/src/cli/print.ts b/src/cli/print.ts index 412cd38c6..51ba7b830 100644 --- a/src/cli/print.ts +++ b/src/cli/print.ts @@ -161,7 +161,7 @@ import { DEFAULT_OUTPUT_STYLE_NAME, getAllOutputStyles, } from 'src/constants/outputStyles.js' -import { TEAMMATE_MESSAGE_TAG, TICK_TAG } from 'src/constants/xml.js' +import { TASK_NOTIFICATION_TAG, TEAMMATE_MESSAGE_TAG, TICK_TAG } from 'src/constants/xml.js' import { getSettings_DEPRECATED, getSettingsWithSources, @@ -4360,29 +4360,44 @@ function runHeadlessStreaming( trackReceivedMessageUuid(userMsg.uuid as UUID) } - enqueue({ - mode: 'prompt' as const, - // file_attachments rides the protobuf catchall from the web composer. - // Same-ref no-op when absent (no 'file_attachments' key). - value: await resolveAndPrepend( - userMsg, - (userMsg.message as { content: ContentBlockParam[] }).content, - ), - uuid: userMsg.uuid as `${string}-${string}-${string}-${string}-${string}`, - priority: (userMsg as { priority?: string }) - .priority as import('src/types/textInputTypes.js').QueuePriority, - }) - // Increment prompt count for attribution tracking and save snapshot - // The snapshot persists promptCount so it survives compaction - if (feature('COMMIT_ATTRIBUTION')) { - setAppState(prev => ({ - ...prev, - attribution: incrementPromptCount(prev.attribution, snapshot => { - void recordAttributionSnapshot(snapshot).catch(error => { - logForDebugging(`Attribution: Failed to save snapshot: ${error}`) - }) - }), - })) + const rawContent = typeof userMsg.content === 'string' ? userMsg.content : '' + const isTaskNotification = rawContent.trimStart().startsWith( + `<${TASK_NOTIFICATION_TAG}>`, + ) + + if (isTaskNotification) { + enqueue({ + mode: 'task-notification' as const, + value: rawContent, + uuid: userMsg.uuid as `${string}-${string}-${string}-${string}-${string}`, + priority: (userMsg as { priority?: string }) + .priority as import('src/types/textInputTypes.js').QueuePriority, + }) + } else { + enqueue({ + mode: 'prompt' as const, + // file_attachments rides the protobuf catchall from the web composer. + // Same-ref no-op when absent (no 'file_attachments' key). + value: await resolveAndPrepend( + userMsg, + (userMsg.message as { content: ContentBlockParam[] }).content, + ), + uuid: userMsg.uuid as `${string}-${string}-${string}-${string}-${string}`, + priority: (userMsg as { priority?: string }) + .priority as import('src/types/textInputTypes.js').QueuePriority, + }) + // Increment prompt count for attribution tracking and save snapshot + // The snapshot persists promptCount so it survives compaction + if (feature('COMMIT_ATTRIBUTION')) { + setAppState(prev => ({ + ...prev, + attribution: incrementPromptCount(prev.attribution, snapshot => { + void recordAttributionSnapshot(snapshot).catch(error => { + logForDebugging(`Attribution: Failed to save snapshot: ${error}`) + }) + }), + })) + } } void run() }