@promptbook/cli 0.113.0-4 → 0.113.0-8
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/apps/agents-server/src/app/admin/update/AdvancedOriginRepositoryPanel.tsx +76 -0
- package/apps/agents-server/src/app/admin/update/CurrentDeploymentCard.tsx +160 -0
- package/apps/agents-server/src/app/admin/update/PendingCommitsCard.tsx +86 -0
- package/apps/agents-server/src/app/admin/update/TargetEnvironmentCard.tsx +331 -0
- package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +20 -873
- package/apps/agents-server/src/app/admin/update/UpdateJobCard.tsx +329 -0
- package/apps/agents-server/src/app/admin/update/UpdateOverview.ts +74 -0
- package/apps/agents-server/src/app/admin/update/buildDeploymentTimeBehindLabel.ts +29 -0
- package/apps/agents-server/src/app/admin/update/formatHumanReadableTimestamp.ts +18 -0
- package/apps/agents-server/src/app/admin/update/getUpdateJobFailureMessage.ts +13 -0
- package/apps/agents-server/src/app/admin/update/getUpdateJobSuccessMessage.ts +13 -0
- package/apps/agents-server/src/app/admin/update/useUpdateClientState.ts +441 -0
- package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +13 -1
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/AgentCodePageClient.tsx +14 -559
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/AgentCodePageHeader.tsx +84 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/AgentCodePageSection.tsx +52 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/GeneratedCodePreview.tsx +138 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/GeneratedHarnessSection.tsx +98 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/SourceBookSection.tsx +66 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/TranspiledCodeErrorBanner.tsx +30 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/TranspiledCodeExportWarningBanner.tsx +62 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/Transpiler.ts +9 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/useAgentCodeExportState.ts +478 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/cloneMockedChatPreset.ts +17 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/confirmDeleteMockedChat.ts +16 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedMessage.ts +81 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedParticipant.ts +146 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedSettings.ts +19 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/createDuplicatedDraft.ts +66 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/findMockedChatById.ts +51 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/persistMockedChats.ts +51 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/useMockedChatsEditorState.ts +16 -426
- package/apps/agents-server/src/components/Homepage/buildFreeGraphBoxLayout.ts +446 -0
- package/apps/agents-server/src/components/Homepage/buildGraphLayoutNodes.ts +415 -157
- package/apps/agents-server/src/components/Homepage/useAgentsGraphCanvasState.ts +2 -1
- package/apps/agents-server/src/database/sqlite/$provideLocalSqliteSupabase.ts +3 -1541
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/LocalSqliteQueryBuilder.ts +623 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/LocalSqliteSupabaseClient.ts +64 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/ensureTable.ts +93 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteFilters.ts +202 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteMutationPayload.ts +131 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteRowOperations.ts +102 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteSql.ts +59 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteTableSchema.ts +329 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteTypes.ts +84 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteValueCodec.ts +63 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/normalizeSqliteError.ts +22 -0
- package/apps/agents-server/src/search/createDefaultServerSearchProviders/loadLocalOrganizationSearchDataset.ts +12 -1
- package/apps/agents-server/src/tools/send_email.ts +1 -2
- package/apps/agents-server/src/utils/agentOrganization/loadAgentOrganizationState.ts +13 -1
- package/apps/agents-server/src/utils/backup/createServerBackupZipStream.ts +7 -1382
- package/apps/agents-server/src/utils/backup/serverBackup/appendAgentBackupEntriesToZip.ts +27 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendConversationBackupEntriesToZip.ts +140 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendFileBackupEntriesToZip.ts +147 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendMessageBackupEntriesToZip.ts +65 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendMetadataBackupEntriesToZip.ts +39 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendSectionEntriesToZip.ts +92 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendUserBackupEntriesToZip.ts +80 -0
- package/apps/agents-server/src/utils/backup/serverBackup/createRedactedWalletBackupRecord.ts +34 -0
- package/apps/agents-server/src/utils/backup/serverBackup/createServerBackupManifest.ts +82 -0
- package/apps/agents-server/src/utils/backup/serverBackup/downloadBackupBinaryContent.ts +39 -0
- package/apps/agents-server/src/utils/backup/serverBackup/resolveFeedbackThreadMessages.ts +53 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupAttachments.ts +151 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupContext.ts +167 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupFilenames.ts +161 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupPreviews.ts +97 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupRowUtilities.ts +158 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupTypes.ts +59 -0
- package/apps/agents-server/src/utils/createLocalAgentSourceImporter.ts +159 -0
- package/apps/agents-server/src/utils/createMissingImportedAgentFallback.ts +60 -0
- package/apps/agents-server/src/utils/customDomainRouting.ts +157 -12
- package/apps/agents-server/src/utils/externalChatRunner/processExternalUserChatJob.ts +1 -1
- package/apps/agents-server/src/utils/importAgentWithFallback.ts +1 -58
- package/apps/agents-server/src/utils/localAgentRouteReferences.ts +167 -0
- package/apps/agents-server/src/utils/localChatRunner/processLocalUserChatJob.ts +1 -1
- package/apps/agents-server/src/utils/managementApi/managementApiAgents.ts +17 -3
- package/apps/agents-server/src/utils/messages/sendMessage.ts +5 -3
- package/apps/agents-server/src/utils/resolveAgentStateFromSource.ts +7 -1
- package/apps/agents-server/src/utils/resolveInheritedAgentSource.ts +54 -5
- package/apps/agents-server/src/utils/resolveServerAgentContext.ts +12 -1
- package/apps/agents-server/src/utils/resolveStoredAgentState.ts +2 -1
- package/apps/agents-server/src/utils/speech-to-text/SpeechToTextFailoverRecognition/SpeechToTextFailoverRecognitionProviderRuntime.ts +0 -1
- package/apps/agents-server/src/utils/speech-to-text/SpeechToTextFailoverRecognition.ts +34 -2
- package/apps/agents-server/src/utils/userChat/userChatMessageLifecycle.ts +39 -9
- package/apps/agents-server/tests/e2e/support/ChatHistoryNavigationSupport.ts +5 -0
- package/esm/index.es.js +875 -60
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/find-refactor-candidates/find-refactor-candidates.d.ts +7 -0
- package/esm/scripts/find-refactor-candidates/selectMostImportantRefactorCandidates.d.ts +12 -0
- package/esm/scripts/run-codex-prompts/common/resolveCoderAgent.d.ts +20 -0
- package/esm/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +5 -0
- package/esm/scripts/run-codex-prompts/ui/buildCoderRunAgentVisual.d.ts +29 -0
- package/esm/scripts/run-codex-prompts/ui/buildCoderRunUiFrame.d.ts +4 -0
- package/esm/src/avatars/renderAvatarVisualAsciiArt.d.ts +75 -0
- package/esm/src/book-components/Chat/Chat/insertDictationChunk.d.ts +1 -1
- package/esm/src/book-components/Chat/Chat/insertDictationChunk.test.d.ts +1 -0
- package/esm/src/book-components/Chat/Chat/learnDictationDictionary.test.d.ts +1 -0
- package/esm/src/book-components/Chat/Chat/refineFinalDictationChunk.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/common/createPositiveIntegerOptionParser.d.ts +10 -0
- package/esm/src/utils/ascii-art/$detectTerminalAnsiColorDepth.d.ts +15 -0
- package/esm/src/utils/ascii-art/convertImageDataToAsciiArt.d.ts +80 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/avatars/avatarAnimationScheduler.ts +2 -1
- package/src/avatars/renderAvatarVisualAsciiArt.ts +138 -0
- package/src/avatars/visuals/octopus3d3AvatarVisual.ts +6 -2
- package/src/avatars/visuals/octopus3d4AvatarVisual.ts +14 -18
- package/src/book-components/Chat/Chat/insertDictationChunk.ts +3 -3
- package/src/book-components/Chat/Chat/learnDictationDictionary.ts +1 -1
- package/src/book-components/Chat/Chat/useChatInputAreaDictation.ts +133 -26
- package/src/cli/cli-commands/agents-server/buildAgentsServer.ts +3 -1
- package/src/cli/cli-commands/coder/boilerplateTemplates.ts +14 -21
- package/src/cli/cli-commands/coder/find-refactor-candidates.ts +9 -2
- package/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.ts +1 -4
- package/src/cli/cli-commands/coder/run.ts +3 -27
- package/src/cli/cli-commands/common/createPositiveIntegerOptionParser.ts +31 -0
- package/src/commitments/TEAM/TEAM.ts +5 -5
- package/src/other/templates/getTemplatesPipelineCollection.ts +770 -1169
- package/src/utils/ascii-art/$detectTerminalAnsiColorDepth.ts +45 -0
- package/src/utils/ascii-art/convertImageDataToAsciiArt.ts +396 -0
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -0
- package/umd/index.umd.js +875 -60
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/find-refactor-candidates/find-refactor-candidates.d.ts +7 -0
- package/umd/scripts/find-refactor-candidates/selectMostImportantRefactorCandidates.d.ts +12 -0
- package/umd/scripts/run-codex-prompts/common/resolveCoderAgent.d.ts +20 -0
- package/umd/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +5 -0
- package/umd/scripts/run-codex-prompts/ui/buildCoderRunAgentVisual.d.ts +29 -0
- package/umd/scripts/run-codex-prompts/ui/buildCoderRunUiFrame.d.ts +4 -0
- package/umd/src/avatars/renderAvatarVisualAsciiArt.d.ts +75 -0
- package/umd/src/book-components/Chat/Chat/insertDictationChunk.d.ts +1 -1
- package/umd/src/book-components/Chat/Chat/insertDictationChunk.test.d.ts +1 -0
- package/umd/src/book-components/Chat/Chat/learnDictationDictionary.test.d.ts +1 -0
- package/umd/src/book-components/Chat/Chat/refineFinalDictationChunk.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/common/createPositiveIntegerOptionParser.d.ts +10 -0
- package/umd/src/utils/ascii-art/$detectTerminalAnsiColorDepth.d.ts +15 -0
- package/umd/src/utils/ascii-art/convertImageDataToAsciiArt.d.ts +80 -0
- package/umd/src/version.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/common/resolveAgentSystemMessage.d.ts +0 -6
- package/umd/scripts/run-codex-prompts/common/resolveAgentSystemMessage.d.ts +0 -6
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { AsciiArtColorDepth } from './convertImageDataToAsciiArt';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Detects the ANSI color depth supported by the current terminal.
|
|
5
|
+
*
|
|
6
|
+
* Prefers 24-bit true color when the environment advertises it (modern terminals such as
|
|
7
|
+
* Windows Terminal, ConEmu, VS Code, mintty, iTerm2, and WezTerm) and falls back to the
|
|
8
|
+
* portable 256-color palette otherwise.
|
|
9
|
+
*
|
|
10
|
+
* Note: `$` is used to indicate that this function is not a pure function - it reads the process environment
|
|
11
|
+
*
|
|
12
|
+
* @returns Color depth usable by `convertImageDataToAsciiArt`
|
|
13
|
+
*
|
|
14
|
+
* @private within the repository
|
|
15
|
+
*/
|
|
16
|
+
export function $detectTerminalAnsiColorDepth(): AsciiArtColorDepth {
|
|
17
|
+
if (typeof process === 'undefined' || !process.env) {
|
|
18
|
+
return 'ANSI_256';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const colorTerm = (process.env.COLORTERM || '').toLowerCase();
|
|
22
|
+
if (colorTerm.includes('truecolor') || colorTerm.includes('24bit')) {
|
|
23
|
+
return 'TRUE_COLOR';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (process.env.WT_SESSION !== undefined) {
|
|
27
|
+
return 'TRUE_COLOR'; // <- Note: Windows Terminal always supports true color but does not set COLORTERM
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (process.env.ConEmuANSI === 'ON') {
|
|
31
|
+
return 'TRUE_COLOR';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const termProgram = process.env.TERM_PROGRAM || '';
|
|
35
|
+
if (['vscode', 'iTerm.app', 'WezTerm', 'ghostty', 'Hyper'].includes(termProgram)) {
|
|
36
|
+
return 'TRUE_COLOR';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const term = (process.env.TERM || '').toLowerCase();
|
|
40
|
+
if (term.includes('truecolor') || term.includes('24bit') || term.includes('direct')) {
|
|
41
|
+
return 'TRUE_COLOR';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return 'ANSI_256';
|
|
45
|
+
}
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import { spaceTrim } from 'spacetrim';
|
|
2
|
+
import { UnexpectedError } from '../../errors/UnexpectedError';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Color depth of the ANSI escape codes emitted by the ASCII-art conversion.
|
|
6
|
+
*
|
|
7
|
+
* - `TRUE_COLOR` emits 24-bit `38;2;r;g;b` / `48;2;r;g;b` sequences
|
|
8
|
+
* - `ANSI_256` approximates colors on the 256-color ANSI cube for older terminals
|
|
9
|
+
*
|
|
10
|
+
* @private within the repository
|
|
11
|
+
*/
|
|
12
|
+
export type AsciiArtColorDepth = 'TRUE_COLOR' | 'ANSI_256';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Minimal structural subset of the DOM `ImageData` accepted by the ASCII-art conversion.
|
|
16
|
+
*
|
|
17
|
+
* Works with browser canvas `ImageData`, `@napi-rs/canvas` image data, or any raw RGBA buffer.
|
|
18
|
+
*
|
|
19
|
+
* @private within the repository
|
|
20
|
+
*/
|
|
21
|
+
export type AsciiArtImageData = {
|
|
22
|
+
/**
|
|
23
|
+
* Source image width in pixels.
|
|
24
|
+
*/
|
|
25
|
+
readonly width: number;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Source image height in pixels.
|
|
29
|
+
*/
|
|
30
|
+
readonly height: number;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Flat RGBA pixel buffer with 4 bytes per pixel.
|
|
34
|
+
*/
|
|
35
|
+
readonly data: ArrayLike<number>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Options for `convertImageDataToAsciiArt`.
|
|
40
|
+
*
|
|
41
|
+
* @private within the repository
|
|
42
|
+
*/
|
|
43
|
+
export type ConvertImageDataToAsciiArtOptions = {
|
|
44
|
+
/**
|
|
45
|
+
* Source pixels to convert.
|
|
46
|
+
*/
|
|
47
|
+
readonly imageData: AsciiArtImageData;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Output width in terminal character cells.
|
|
51
|
+
*/
|
|
52
|
+
readonly columns: number;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Output height in terminal character cells.
|
|
56
|
+
*
|
|
57
|
+
* Each character cell renders two vertically stacked pixels, so `rows = columns / 2`
|
|
58
|
+
* keeps a square image visually square in a common terminal font.
|
|
59
|
+
*/
|
|
60
|
+
readonly rows: number;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Color depth of the emitted ANSI escape codes.
|
|
64
|
+
*
|
|
65
|
+
* @default 'TRUE_COLOR'
|
|
66
|
+
*/
|
|
67
|
+
readonly colorDepth?: AsciiArtColorDepth;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Alpha channel value (0-255) below which an averaged half-cell is treated as fully transparent.
|
|
71
|
+
*
|
|
72
|
+
* @default 32
|
|
73
|
+
*/
|
|
74
|
+
readonly alphaThreshold?: number;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Default alpha channel value below which a half-cell is rendered as terminal background.
|
|
79
|
+
*
|
|
80
|
+
* @private within the repository
|
|
81
|
+
*/
|
|
82
|
+
const DEFAULT_ALPHA_THRESHOLD = 32;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Number of channels per pixel in an RGBA buffer.
|
|
86
|
+
*
|
|
87
|
+
* @private within the repository
|
|
88
|
+
*/
|
|
89
|
+
const RGBA_CHANNEL_COUNT = 4;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Upper half block character - foreground paints the top pixel, background paints the bottom pixel.
|
|
93
|
+
*
|
|
94
|
+
* @private within the repository
|
|
95
|
+
*/
|
|
96
|
+
const UPPER_HALF_BLOCK = '▀'; // <- ▀
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Lower half block character - foreground paints the bottom pixel while the top pixel stays transparent.
|
|
100
|
+
*
|
|
101
|
+
* @private within the repository
|
|
102
|
+
*/
|
|
103
|
+
const LOWER_HALF_BLOCK = '▄'; // <- ▄
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* ANSI escape sequence that resets all colors and attributes.
|
|
107
|
+
*
|
|
108
|
+
* @private within the repository
|
|
109
|
+
*/
|
|
110
|
+
const ANSI_RESET = '\u001b[0m';
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Maximum spread between RGB channels for a color to be treated as (nearly) achromatic gray.
|
|
114
|
+
*
|
|
115
|
+
* @private within the repository
|
|
116
|
+
*/
|
|
117
|
+
const ANSI_256_ACHROMATIC_CHANNEL_SPREAD = 12;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Gray level above which an achromatic color maps to the pure white color-cube entry.
|
|
121
|
+
*
|
|
122
|
+
* @private within the repository
|
|
123
|
+
*/
|
|
124
|
+
const ANSI_256_NEAR_WHITE_GRAY_LEVEL = 246;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Index of pure white inside the 6×6×6 ANSI color cube.
|
|
128
|
+
*
|
|
129
|
+
* @private within the repository
|
|
130
|
+
*/
|
|
131
|
+
const ANSI_256_WHITE_INDEX = 231;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Brightness of the lightest entry of the ANSI 256 grayscale ramp.
|
|
135
|
+
*
|
|
136
|
+
* @private within the repository
|
|
137
|
+
*/
|
|
138
|
+
const ANSI_256_GRAYSCALE_RAMP_MAX_LEVEL = 238;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Number of grayscale ramp steps above its first entry (ANSI indexes 232-255).
|
|
142
|
+
*
|
|
143
|
+
* @private within the repository
|
|
144
|
+
*/
|
|
145
|
+
const ANSI_256_GRAYSCALE_RAMP_INDEX_SPAN = 23;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Area-averaged color of one half of a character cell.
|
|
149
|
+
*
|
|
150
|
+
* @private helper of `convertImageDataToAsciiArt`
|
|
151
|
+
*/
|
|
152
|
+
type HalfCellColor = {
|
|
153
|
+
readonly red: number;
|
|
154
|
+
readonly green: number;
|
|
155
|
+
readonly blue: number;
|
|
156
|
+
readonly isOpaque: boolean;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Converts raw RGBA image pixels into colored ASCII art for ANSI terminals.
|
|
161
|
+
*
|
|
162
|
+
* This is the universal image-to-terminal technique used across the repository:
|
|
163
|
+
* every output character cell covers a rectangular region of source pixels which is
|
|
164
|
+
* split into a top and bottom half; each half is area-averaged and rendered with
|
|
165
|
+
* half-block characters (`▀` / `▄`) so one character shows two "pixels" vertically.
|
|
166
|
+
* Transparent halves keep the terminal background so non-rectangular images
|
|
167
|
+
* (for example rounded avatar cards) compose naturally into any terminal UI.
|
|
168
|
+
*
|
|
169
|
+
* @param options Source pixels, output grid size, and ANSI color depth.
|
|
170
|
+
* @returns One ANSI-colored string per output row, each ending with a color reset.
|
|
171
|
+
*
|
|
172
|
+
* @private within the repository
|
|
173
|
+
*/
|
|
174
|
+
export function convertImageDataToAsciiArt(options: ConvertImageDataToAsciiArtOptions): ReadonlyArray<string> {
|
|
175
|
+
const { imageData, columns, rows, colorDepth = 'TRUE_COLOR', alphaThreshold = DEFAULT_ALPHA_THRESHOLD } = options;
|
|
176
|
+
|
|
177
|
+
if (!Number.isInteger(columns) || columns <= 0 || !Number.isInteger(rows) || rows <= 0) {
|
|
178
|
+
throw new UnexpectedError(
|
|
179
|
+
spaceTrim(`
|
|
180
|
+
ASCII-art grid size is invalid.
|
|
181
|
+
|
|
182
|
+
Both \`columns\` and \`rows\` must be positive integers but \`${columns}\` × \`${rows}\` was requested.
|
|
183
|
+
`),
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (
|
|
188
|
+
imageData.width <= 0 ||
|
|
189
|
+
imageData.height <= 0 ||
|
|
190
|
+
imageData.data.length < imageData.width * imageData.height * RGBA_CHANNEL_COUNT
|
|
191
|
+
) {
|
|
192
|
+
throw new UnexpectedError(
|
|
193
|
+
spaceTrim(`
|
|
194
|
+
ASCII-art source image data is invalid.
|
|
195
|
+
|
|
196
|
+
Expected a RGBA buffer of at least \`${imageData.width} × ${imageData.height} × ${RGBA_CHANNEL_COUNT}\` bytes
|
|
197
|
+
but got \`${imageData.data.length}\` bytes.
|
|
198
|
+
`),
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const halfCellRowCount = rows * 2;
|
|
203
|
+
const asciiArtLines: Array<string> = [];
|
|
204
|
+
|
|
205
|
+
for (let rowIndex = 0; rowIndex < rows; rowIndex++) {
|
|
206
|
+
let line = '';
|
|
207
|
+
let currentForegroundCode: string | undefined = undefined;
|
|
208
|
+
let currentBackgroundCode: string | undefined = undefined;
|
|
209
|
+
|
|
210
|
+
for (let columnIndex = 0; columnIndex < columns; columnIndex++) {
|
|
211
|
+
const topHalfColor = computeHalfCellColor(
|
|
212
|
+
imageData,
|
|
213
|
+
columnIndex,
|
|
214
|
+
rowIndex * 2,
|
|
215
|
+
columns,
|
|
216
|
+
halfCellRowCount,
|
|
217
|
+
alphaThreshold,
|
|
218
|
+
);
|
|
219
|
+
const bottomHalfColor = computeHalfCellColor(
|
|
220
|
+
imageData,
|
|
221
|
+
columnIndex,
|
|
222
|
+
rowIndex * 2 + 1,
|
|
223
|
+
columns,
|
|
224
|
+
halfCellRowCount,
|
|
225
|
+
alphaThreshold,
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
let character: string;
|
|
229
|
+
let nextForegroundCode: string | undefined;
|
|
230
|
+
let nextBackgroundCode: string | undefined;
|
|
231
|
+
|
|
232
|
+
if (topHalfColor.isOpaque && bottomHalfColor.isOpaque) {
|
|
233
|
+
character = UPPER_HALF_BLOCK;
|
|
234
|
+
nextForegroundCode = createForegroundColorCode(topHalfColor, colorDepth);
|
|
235
|
+
nextBackgroundCode = createBackgroundColorCode(bottomHalfColor, colorDepth);
|
|
236
|
+
} else if (topHalfColor.isOpaque) {
|
|
237
|
+
character = UPPER_HALF_BLOCK;
|
|
238
|
+
nextForegroundCode = createForegroundColorCode(topHalfColor, colorDepth);
|
|
239
|
+
nextBackgroundCode = undefined;
|
|
240
|
+
} else if (bottomHalfColor.isOpaque) {
|
|
241
|
+
character = LOWER_HALF_BLOCK;
|
|
242
|
+
nextForegroundCode = createForegroundColorCode(bottomHalfColor, colorDepth);
|
|
243
|
+
nextBackgroundCode = undefined;
|
|
244
|
+
} else {
|
|
245
|
+
character = ' ';
|
|
246
|
+
nextForegroundCode = undefined;
|
|
247
|
+
nextBackgroundCode = undefined;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (nextForegroundCode !== currentForegroundCode || nextBackgroundCode !== currentBackgroundCode) {
|
|
251
|
+
// Note: A reset is required whenever a previously set color must be cleared,
|
|
252
|
+
// otherwise stale background color would bleed into transparent cells.
|
|
253
|
+
const isResetNeeded =
|
|
254
|
+
(currentForegroundCode !== undefined && nextForegroundCode === undefined) ||
|
|
255
|
+
(currentBackgroundCode !== undefined && nextBackgroundCode === undefined);
|
|
256
|
+
|
|
257
|
+
if (isResetNeeded) {
|
|
258
|
+
line += ANSI_RESET;
|
|
259
|
+
currentForegroundCode = undefined;
|
|
260
|
+
currentBackgroundCode = undefined;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (nextForegroundCode !== undefined && nextForegroundCode !== currentForegroundCode) {
|
|
264
|
+
line += nextForegroundCode;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (nextBackgroundCode !== undefined && nextBackgroundCode !== currentBackgroundCode) {
|
|
268
|
+
line += nextBackgroundCode;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
currentForegroundCode = nextForegroundCode;
|
|
272
|
+
currentBackgroundCode = nextBackgroundCode;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
line += character;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (currentForegroundCode !== undefined || currentBackgroundCode !== undefined) {
|
|
279
|
+
line += ANSI_RESET;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
asciiArtLines.push(line);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return asciiArtLines;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Computes the area-averaged color of one half-cell of the output grid.
|
|
290
|
+
*
|
|
291
|
+
* Color channels are alpha-weighted so semi-transparent edge pixels do not darken towards black.
|
|
292
|
+
*
|
|
293
|
+
* @private helper of `convertImageDataToAsciiArt`
|
|
294
|
+
*/
|
|
295
|
+
function computeHalfCellColor(
|
|
296
|
+
imageData: AsciiArtImageData,
|
|
297
|
+
columnIndex: number,
|
|
298
|
+
halfCellRowIndex: number,
|
|
299
|
+
columns: number,
|
|
300
|
+
halfCellRowCount: number,
|
|
301
|
+
alphaThreshold: number,
|
|
302
|
+
): HalfCellColor {
|
|
303
|
+
const startX = Math.floor((columnIndex * imageData.width) / columns);
|
|
304
|
+
const endX = Math.max(startX + 1, Math.floor(((columnIndex + 1) * imageData.width) / columns));
|
|
305
|
+
const startY = Math.floor((halfCellRowIndex * imageData.height) / halfCellRowCount);
|
|
306
|
+
const endY = Math.max(startY + 1, Math.floor(((halfCellRowIndex + 1) * imageData.height) / halfCellRowCount));
|
|
307
|
+
|
|
308
|
+
let redSum = 0;
|
|
309
|
+
let greenSum = 0;
|
|
310
|
+
let blueSum = 0;
|
|
311
|
+
let alphaSum = 0;
|
|
312
|
+
let sampledPixelCount = 0;
|
|
313
|
+
|
|
314
|
+
for (let y = startY; y < endY && y < imageData.height; y++) {
|
|
315
|
+
for (let x = startX; x < endX && x < imageData.width; x++) {
|
|
316
|
+
const pixelOffset = (y * imageData.width + x) * RGBA_CHANNEL_COUNT;
|
|
317
|
+
const alpha = imageData.data[pixelOffset + 3]!;
|
|
318
|
+
|
|
319
|
+
redSum += imageData.data[pixelOffset]! * alpha;
|
|
320
|
+
greenSum += imageData.data[pixelOffset + 1]! * alpha;
|
|
321
|
+
blueSum += imageData.data[pixelOffset + 2]! * alpha;
|
|
322
|
+
alphaSum += alpha;
|
|
323
|
+
sampledPixelCount++;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const averageAlpha = sampledPixelCount === 0 ? 0 : alphaSum / sampledPixelCount;
|
|
328
|
+
|
|
329
|
+
if (averageAlpha < alphaThreshold || alphaSum === 0) {
|
|
330
|
+
return { red: 0, green: 0, blue: 0, isOpaque: false };
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return {
|
|
334
|
+
red: Math.round(redSum / alphaSum),
|
|
335
|
+
green: Math.round(greenSum / alphaSum),
|
|
336
|
+
blue: Math.round(blueSum / alphaSum),
|
|
337
|
+
isOpaque: true,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Creates the ANSI escape code that sets the foreground color of following characters.
|
|
343
|
+
*
|
|
344
|
+
* @private helper of `convertImageDataToAsciiArt`
|
|
345
|
+
*/
|
|
346
|
+
function createForegroundColorCode(color: HalfCellColor, colorDepth: AsciiArtColorDepth): string {
|
|
347
|
+
if (colorDepth === 'TRUE_COLOR') {
|
|
348
|
+
return `\u001b[38;2;${color.red};${color.green};${color.blue}m`;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return `\u001b[38;5;${mapColorToAnsi256(color)}m`;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Creates the ANSI escape code that sets the background color of following characters.
|
|
356
|
+
*
|
|
357
|
+
* @private helper of `convertImageDataToAsciiArt`
|
|
358
|
+
*/
|
|
359
|
+
function createBackgroundColorCode(color: HalfCellColor, colorDepth: AsciiArtColorDepth): string {
|
|
360
|
+
if (colorDepth === 'TRUE_COLOR') {
|
|
361
|
+
return `\u001b[48;2;${color.red};${color.green};${color.blue}m`;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return `\u001b[48;5;${mapColorToAnsi256(color)}m`;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Maps a 24-bit color onto the closest entry of the 256-color ANSI palette.
|
|
369
|
+
*
|
|
370
|
+
* Uses the 6×6×6 color cube (entries 16-231) and the grayscale ramp (entries 232-255).
|
|
371
|
+
*
|
|
372
|
+
* @private helper of `convertImageDataToAsciiArt`
|
|
373
|
+
*/
|
|
374
|
+
function mapColorToAnsi256(color: HalfCellColor): number {
|
|
375
|
+
const { red, green, blue } = color;
|
|
376
|
+
|
|
377
|
+
// Note: Prefer the finer grayscale ramp when the color is (nearly) achromatic
|
|
378
|
+
const maxChannel = Math.max(red, green, blue);
|
|
379
|
+
const minChannel = Math.min(red, green, blue);
|
|
380
|
+
if (maxChannel - minChannel < ANSI_256_ACHROMATIC_CHANNEL_SPREAD) {
|
|
381
|
+
const gray = Math.round((red + green + blue) / 3);
|
|
382
|
+
if (gray < 4) {
|
|
383
|
+
return 16; // <- Note: Pure black lives in the color cube
|
|
384
|
+
}
|
|
385
|
+
if (gray > ANSI_256_NEAR_WHITE_GRAY_LEVEL) {
|
|
386
|
+
return ANSI_256_WHITE_INDEX; // <- Note: Pure white lives in the color cube
|
|
387
|
+
}
|
|
388
|
+
return 232 + Math.round(((gray - 8) / ANSI_256_GRAYSCALE_RAMP_MAX_LEVEL) * ANSI_256_GRAYSCALE_RAMP_INDEX_SPAN);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const redIndex = Math.round((red / 255) * 5);
|
|
392
|
+
const greenIndex = Math.round((green / 255) * 5);
|
|
393
|
+
const blueIndex = Math.round((blue / 255) * 5);
|
|
394
|
+
|
|
395
|
+
return 16 + 36 * redIndex + 6 * greenIndex + blueIndex;
|
|
396
|
+
}
|
package/src/version.ts
CHANGED
|
@@ -16,11 +16,11 @@ export const BOOK_LANGUAGE_VERSION: string_semantic_version = '2.0.0';
|
|
|
16
16
|
* @generated
|
|
17
17
|
* @see https://github.com/webgptorg/promptbook
|
|
18
18
|
*/
|
|
19
|
-
export const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version = '0.113.0-
|
|
19
|
+
export const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version = '0.113.0-8';
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Represents the version string of the Promptbook engine.
|
|
23
|
-
* It follows semantic versioning (e.g., `0.113.0-
|
|
23
|
+
* It follows semantic versioning (e.g., `0.113.0-5`).
|
|
24
24
|
*
|
|
25
25
|
* @generated
|
|
26
26
|
*/
|