@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.
Files changed (141) hide show
  1. package/apps/agents-server/src/app/admin/update/AdvancedOriginRepositoryPanel.tsx +76 -0
  2. package/apps/agents-server/src/app/admin/update/CurrentDeploymentCard.tsx +160 -0
  3. package/apps/agents-server/src/app/admin/update/PendingCommitsCard.tsx +86 -0
  4. package/apps/agents-server/src/app/admin/update/TargetEnvironmentCard.tsx +331 -0
  5. package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +20 -873
  6. package/apps/agents-server/src/app/admin/update/UpdateJobCard.tsx +329 -0
  7. package/apps/agents-server/src/app/admin/update/UpdateOverview.ts +74 -0
  8. package/apps/agents-server/src/app/admin/update/buildDeploymentTimeBehindLabel.ts +29 -0
  9. package/apps/agents-server/src/app/admin/update/formatHumanReadableTimestamp.ts +18 -0
  10. package/apps/agents-server/src/app/admin/update/getUpdateJobFailureMessage.ts +13 -0
  11. package/apps/agents-server/src/app/admin/update/getUpdateJobSuccessMessage.ts +13 -0
  12. package/apps/agents-server/src/app/admin/update/useUpdateClientState.ts +441 -0
  13. package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +13 -1
  14. package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/AgentCodePageClient.tsx +14 -559
  15. package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/AgentCodePageHeader.tsx +84 -0
  16. package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/AgentCodePageSection.tsx +52 -0
  17. package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/GeneratedCodePreview.tsx +138 -0
  18. package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/GeneratedHarnessSection.tsx +98 -0
  19. package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/SourceBookSection.tsx +66 -0
  20. package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/TranspiledCodeErrorBanner.tsx +30 -0
  21. package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/TranspiledCodeExportWarningBanner.tsx +62 -0
  22. package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/Transpiler.ts +9 -0
  23. package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/useAgentCodeExportState.ts +478 -0
  24. package/apps/agents-server/src/app/system/utilities/mocked-chats/cloneMockedChatPreset.ts +17 -0
  25. package/apps/agents-server/src/app/system/utilities/mocked-chats/confirmDeleteMockedChat.ts +16 -0
  26. package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedMessage.ts +81 -0
  27. package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedParticipant.ts +146 -0
  28. package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedSettings.ts +19 -0
  29. package/apps/agents-server/src/app/system/utilities/mocked-chats/createDuplicatedDraft.ts +66 -0
  30. package/apps/agents-server/src/app/system/utilities/mocked-chats/findMockedChatById.ts +51 -0
  31. package/apps/agents-server/src/app/system/utilities/mocked-chats/persistMockedChats.ts +51 -0
  32. package/apps/agents-server/src/app/system/utilities/mocked-chats/useMockedChatsEditorState.ts +16 -426
  33. package/apps/agents-server/src/components/Homepage/buildFreeGraphBoxLayout.ts +446 -0
  34. package/apps/agents-server/src/components/Homepage/buildGraphLayoutNodes.ts +415 -157
  35. package/apps/agents-server/src/components/Homepage/useAgentsGraphCanvasState.ts +2 -1
  36. package/apps/agents-server/src/database/sqlite/$provideLocalSqliteSupabase.ts +3 -1541
  37. package/apps/agents-server/src/database/sqlite/localSqliteSupabase/LocalSqliteQueryBuilder.ts +623 -0
  38. package/apps/agents-server/src/database/sqlite/localSqliteSupabase/LocalSqliteSupabaseClient.ts +64 -0
  39. package/apps/agents-server/src/database/sqlite/localSqliteSupabase/ensureTable.ts +93 -0
  40. package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteFilters.ts +202 -0
  41. package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteMutationPayload.ts +131 -0
  42. package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteRowOperations.ts +102 -0
  43. package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteSql.ts +59 -0
  44. package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteTableSchema.ts +329 -0
  45. package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteTypes.ts +84 -0
  46. package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteValueCodec.ts +63 -0
  47. package/apps/agents-server/src/database/sqlite/localSqliteSupabase/normalizeSqliteError.ts +22 -0
  48. package/apps/agents-server/src/search/createDefaultServerSearchProviders/loadLocalOrganizationSearchDataset.ts +12 -1
  49. package/apps/agents-server/src/tools/send_email.ts +1 -2
  50. package/apps/agents-server/src/utils/agentOrganization/loadAgentOrganizationState.ts +13 -1
  51. package/apps/agents-server/src/utils/backup/createServerBackupZipStream.ts +7 -1382
  52. package/apps/agents-server/src/utils/backup/serverBackup/appendAgentBackupEntriesToZip.ts +27 -0
  53. package/apps/agents-server/src/utils/backup/serverBackup/appendConversationBackupEntriesToZip.ts +140 -0
  54. package/apps/agents-server/src/utils/backup/serverBackup/appendFileBackupEntriesToZip.ts +147 -0
  55. package/apps/agents-server/src/utils/backup/serverBackup/appendMessageBackupEntriesToZip.ts +65 -0
  56. package/apps/agents-server/src/utils/backup/serverBackup/appendMetadataBackupEntriesToZip.ts +39 -0
  57. package/apps/agents-server/src/utils/backup/serverBackup/appendSectionEntriesToZip.ts +92 -0
  58. package/apps/agents-server/src/utils/backup/serverBackup/appendUserBackupEntriesToZip.ts +80 -0
  59. package/apps/agents-server/src/utils/backup/serverBackup/createRedactedWalletBackupRecord.ts +34 -0
  60. package/apps/agents-server/src/utils/backup/serverBackup/createServerBackupManifest.ts +82 -0
  61. package/apps/agents-server/src/utils/backup/serverBackup/downloadBackupBinaryContent.ts +39 -0
  62. package/apps/agents-server/src/utils/backup/serverBackup/resolveFeedbackThreadMessages.ts +53 -0
  63. package/apps/agents-server/src/utils/backup/serverBackup/serverBackupAttachments.ts +151 -0
  64. package/apps/agents-server/src/utils/backup/serverBackup/serverBackupContext.ts +167 -0
  65. package/apps/agents-server/src/utils/backup/serverBackup/serverBackupFilenames.ts +161 -0
  66. package/apps/agents-server/src/utils/backup/serverBackup/serverBackupPreviews.ts +97 -0
  67. package/apps/agents-server/src/utils/backup/serverBackup/serverBackupRowUtilities.ts +158 -0
  68. package/apps/agents-server/src/utils/backup/serverBackup/serverBackupTypes.ts +59 -0
  69. package/apps/agents-server/src/utils/createLocalAgentSourceImporter.ts +159 -0
  70. package/apps/agents-server/src/utils/createMissingImportedAgentFallback.ts +60 -0
  71. package/apps/agents-server/src/utils/customDomainRouting.ts +157 -12
  72. package/apps/agents-server/src/utils/externalChatRunner/processExternalUserChatJob.ts +1 -1
  73. package/apps/agents-server/src/utils/importAgentWithFallback.ts +1 -58
  74. package/apps/agents-server/src/utils/localAgentRouteReferences.ts +167 -0
  75. package/apps/agents-server/src/utils/localChatRunner/processLocalUserChatJob.ts +1 -1
  76. package/apps/agents-server/src/utils/managementApi/managementApiAgents.ts +17 -3
  77. package/apps/agents-server/src/utils/messages/sendMessage.ts +5 -3
  78. package/apps/agents-server/src/utils/resolveAgentStateFromSource.ts +7 -1
  79. package/apps/agents-server/src/utils/resolveInheritedAgentSource.ts +54 -5
  80. package/apps/agents-server/src/utils/resolveServerAgentContext.ts +12 -1
  81. package/apps/agents-server/src/utils/resolveStoredAgentState.ts +2 -1
  82. package/apps/agents-server/src/utils/speech-to-text/SpeechToTextFailoverRecognition/SpeechToTextFailoverRecognitionProviderRuntime.ts +0 -1
  83. package/apps/agents-server/src/utils/speech-to-text/SpeechToTextFailoverRecognition.ts +34 -2
  84. package/apps/agents-server/src/utils/userChat/userChatMessageLifecycle.ts +39 -9
  85. package/apps/agents-server/tests/e2e/support/ChatHistoryNavigationSupport.ts +5 -0
  86. package/esm/index.es.js +875 -60
  87. package/esm/index.es.js.map +1 -1
  88. package/esm/scripts/find-refactor-candidates/find-refactor-candidates.d.ts +7 -0
  89. package/esm/scripts/find-refactor-candidates/selectMostImportantRefactorCandidates.d.ts +12 -0
  90. package/esm/scripts/run-codex-prompts/common/resolveCoderAgent.d.ts +20 -0
  91. package/esm/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +5 -0
  92. package/esm/scripts/run-codex-prompts/ui/buildCoderRunAgentVisual.d.ts +29 -0
  93. package/esm/scripts/run-codex-prompts/ui/buildCoderRunUiFrame.d.ts +4 -0
  94. package/esm/src/avatars/renderAvatarVisualAsciiArt.d.ts +75 -0
  95. package/esm/src/book-components/Chat/Chat/insertDictationChunk.d.ts +1 -1
  96. package/esm/src/book-components/Chat/Chat/insertDictationChunk.test.d.ts +1 -0
  97. package/esm/src/book-components/Chat/Chat/learnDictationDictionary.test.d.ts +1 -0
  98. package/esm/src/book-components/Chat/Chat/refineFinalDictationChunk.test.d.ts +1 -0
  99. package/esm/src/cli/cli-commands/common/createPositiveIntegerOptionParser.d.ts +10 -0
  100. package/esm/src/utils/ascii-art/$detectTerminalAnsiColorDepth.d.ts +15 -0
  101. package/esm/src/utils/ascii-art/convertImageDataToAsciiArt.d.ts +80 -0
  102. package/esm/src/version.d.ts +1 -1
  103. package/package.json +1 -1
  104. package/src/avatars/avatarAnimationScheduler.ts +2 -1
  105. package/src/avatars/renderAvatarVisualAsciiArt.ts +138 -0
  106. package/src/avatars/visuals/octopus3d3AvatarVisual.ts +6 -2
  107. package/src/avatars/visuals/octopus3d4AvatarVisual.ts +14 -18
  108. package/src/book-components/Chat/Chat/insertDictationChunk.ts +3 -3
  109. package/src/book-components/Chat/Chat/learnDictationDictionary.ts +1 -1
  110. package/src/book-components/Chat/Chat/useChatInputAreaDictation.ts +133 -26
  111. package/src/cli/cli-commands/agents-server/buildAgentsServer.ts +3 -1
  112. package/src/cli/cli-commands/coder/boilerplateTemplates.ts +14 -21
  113. package/src/cli/cli-commands/coder/find-refactor-candidates.ts +9 -2
  114. package/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.ts +1 -4
  115. package/src/cli/cli-commands/coder/run.ts +3 -27
  116. package/src/cli/cli-commands/common/createPositiveIntegerOptionParser.ts +31 -0
  117. package/src/commitments/TEAM/TEAM.ts +5 -5
  118. package/src/other/templates/getTemplatesPipelineCollection.ts +770 -1169
  119. package/src/utils/ascii-art/$detectTerminalAnsiColorDepth.ts +45 -0
  120. package/src/utils/ascii-art/convertImageDataToAsciiArt.ts +396 -0
  121. package/src/version.ts +2 -2
  122. package/src/versions.txt +2 -0
  123. package/umd/index.umd.js +875 -60
  124. package/umd/index.umd.js.map +1 -1
  125. package/umd/scripts/find-refactor-candidates/find-refactor-candidates.d.ts +7 -0
  126. package/umd/scripts/find-refactor-candidates/selectMostImportantRefactorCandidates.d.ts +12 -0
  127. package/umd/scripts/run-codex-prompts/common/resolveCoderAgent.d.ts +20 -0
  128. package/umd/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +5 -0
  129. package/umd/scripts/run-codex-prompts/ui/buildCoderRunAgentVisual.d.ts +29 -0
  130. package/umd/scripts/run-codex-prompts/ui/buildCoderRunUiFrame.d.ts +4 -0
  131. package/umd/src/avatars/renderAvatarVisualAsciiArt.d.ts +75 -0
  132. package/umd/src/book-components/Chat/Chat/insertDictationChunk.d.ts +1 -1
  133. package/umd/src/book-components/Chat/Chat/insertDictationChunk.test.d.ts +1 -0
  134. package/umd/src/book-components/Chat/Chat/learnDictationDictionary.test.d.ts +1 -0
  135. package/umd/src/book-components/Chat/Chat/refineFinalDictationChunk.test.d.ts +1 -0
  136. package/umd/src/cli/cli-commands/common/createPositiveIntegerOptionParser.d.ts +10 -0
  137. package/umd/src/utils/ascii-art/$detectTerminalAnsiColorDepth.d.ts +15 -0
  138. package/umd/src/utils/ascii-art/convertImageDataToAsciiArt.d.ts +80 -0
  139. package/umd/src/version.d.ts +1 -1
  140. package/esm/scripts/run-codex-prompts/common/resolveAgentSystemMessage.d.ts +0 -6
  141. package/umd/scripts/run-codex-prompts/common/resolveAgentSystemMessage.d.ts +0 -6
@@ -15,4 +15,11 @@ export type FindRefactorCandidatesOptions = {
15
15
  * Aggressiveness level used to score candidate files.
16
16
  */
17
17
  readonly level?: RefactorCandidateLevel;
18
+ /**
19
+ * Maximum number of refactor prompts to create in this run.
20
+ *
21
+ * When more candidates are found than this limit, only the most important ones (by severity)
22
+ * are turned into prompts. When omitted, a prompt is created for every candidate.
23
+ */
24
+ readonly limit?: number;
18
25
  };
@@ -0,0 +1,12 @@
1
+ import type { RefactorCandidate } from './RefactorCandidate';
2
+ /**
3
+ * Keeps at most `limit` refactor candidates, preferring the most important ones.
4
+ *
5
+ * When there are more candidates than `limit`, only the highest-severity candidates are kept
6
+ * (ties broken by relative path for determinism). When `limit` is `undefined` or there are fewer
7
+ * candidates than the limit, every candidate is returned. The original input order is preserved
8
+ * among the kept candidates, so `limit` acts purely as a filter and never reorders prompts.
9
+ *
10
+ * @private function of findRefactorCandidates
11
+ */
12
+ export declare function selectMostImportantRefactorCandidates(candidates: ReadonlyArray<RefactorCandidate>, limit: number | undefined): ReadonlyArray<RefactorCandidate>;
@@ -0,0 +1,20 @@
1
+ import type { string_book } from '../../../src/book-2.0/agent-source/string_book';
2
+ /**
3
+ * Agent data resolved from the optional `--agent` book file.
4
+ */
5
+ export type ResolvedCoderAgent = {
6
+ /**
7
+ * Raw source of the agent `.book` file.
8
+ */
9
+ readonly agentSource: string_book;
10
+ /**
11
+ * Compiled system message injected into each coding prompt.
12
+ */
13
+ readonly systemMessage: string;
14
+ };
15
+ /**
16
+ * Reads an optional agent `.book` file and compiles its system message for injection into coder prompts.
17
+ *
18
+ * Returns `undefined` when no agent path is provided.
19
+ */
20
+ export declare function resolveCoderAgent(agentPath: string | undefined, currentWorkingDirectory: string): Promise<ResolvedCoderAgent | undefined>;
@@ -41,6 +41,7 @@ export type { CoderRunProgressSnapshot };
41
41
  */
42
42
  export declare class CoderRunUiState extends EventEmitter {
43
43
  config: CoderRunConfig;
44
+ agentVisualLines: string[] | undefined;
44
45
  currentPromptLabel: string;
45
46
  currentScriptPaths: string[];
46
47
  currentAttempt: number;
@@ -72,6 +73,10 @@ export declare class CoderRunUiState extends EventEmitter {
72
73
  * Replaces the configuration shown in the UI header.
73
74
  */
74
75
  setConfig(config: CoderRunConfig): void;
76
+ /**
77
+ * Replaces the ASCII-art agent visual shown instead of the default brand banner.
78
+ */
79
+ setAgentVisualLines(agentVisualLines: ReadonlyArray<string> | undefined): void;
75
80
  /**
76
81
  * Feeds new prompt statistics from the main loop so the progress bar updates.
77
82
  */
@@ -0,0 +1,29 @@
1
+ import type { string_book } from '../../../src/book-2.0/agent-source/string_book';
2
+ /**
3
+ * Output width of the coder-run agent visual in terminal character cells.
4
+ *
5
+ * @private internal constant of coder run UI
6
+ */
7
+ export declare const CODER_RUN_AGENT_VISUAL_COLUMNS = 24;
8
+ /**
9
+ * Output height of the coder-run agent visual in terminal character cells.
10
+ *
11
+ * Half of the columns keeps the square avatar visually square in a common terminal font.
12
+ *
13
+ * @private internal constant of coder run UI
14
+ */
15
+ export declare const CODER_RUN_AGENT_VISUAL_ROWS = 12;
16
+ /**
17
+ * Builds the ANSI ASCII-art visual of the `--agent` book shown above the coder-run dashboard.
18
+ *
19
+ * The agent's avatar visual is resolved the same way as on the website - the `META AVATAR`
20
+ * commitment wins, then the `META VISUAL` commitment, then the shared default visual - and is
21
+ * rendered dynamically through the shared canvas avatar pipeline into terminal ASCII art.
22
+ *
23
+ * The visual is decorative, so any failure (for example when the optional `@napi-rs/canvas`
24
+ * module is not installed) returns `null` and the caller keeps the default brand banner.
25
+ *
26
+ * @param agentSource Source of the `--agent` book file.
27
+ * @returns ANSI-colored ASCII-art lines or `null` when the visual cannot be rendered.
28
+ */
29
+ export declare function buildCoderRunAgentVisual(agentSource: string_book): Promise<ReadonlyArray<string> | null>;
@@ -11,6 +11,10 @@ export type BuildCoderRunUiFrameOptions = {
11
11
  readonly terminalWidth: number;
12
12
  readonly animationFrame: number;
13
13
  readonly spinner: string;
14
+ /**
15
+ * ANSI ASCII-art lines of the `--agent` avatar visual shown instead of the default brand banner.
16
+ */
17
+ readonly agentVisualLines?: readonly string[];
14
18
  readonly pauseState: CoderRunPauseState;
15
19
  readonly pauseTargetLabel: string;
16
20
  readonly config: CoderRunConfig;
@@ -0,0 +1,75 @@
1
+ import type { AsciiArtColorDepth } from '../utils/ascii-art/convertImageDataToAsciiArt';
2
+ import type { AvatarDefinition } from './types/AvatarDefinition';
3
+ import type { AvatarVisualId } from './types/AvatarVisualDefinition';
4
+ /**
5
+ * Default output width of the ASCII avatar in terminal character cells.
6
+ *
7
+ * @private within the repository
8
+ */
9
+ export declare const DEFAULT_AVATAR_ASCII_ART_COLUMNS = 32;
10
+ /**
11
+ * Factory creating a drawable canvas of the requested pixel size.
12
+ *
13
+ * In browsers this is typically `document.createElement('canvas')` (with width/height set),
14
+ * in Node.js an adapter around `createCanvas` of `@napi-rs/canvas` or a compatible library.
15
+ *
16
+ * @private within the repository
17
+ */
18
+ export type CreateCanvasForAsciiArt = (width: number, height: number) => HTMLCanvasElement;
19
+ /**
20
+ * Options for `renderAvatarVisualAsciiArt`.
21
+ *
22
+ * @private within the repository
23
+ */
24
+ export type RenderAvatarVisualAsciiArtOptions = {
25
+ /**
26
+ * Stable visual identity of the rendered agent avatar.
27
+ */
28
+ readonly avatarDefinition: AvatarDefinition;
29
+ /**
30
+ * Built-in avatar visual to render, the same one used on the website.
31
+ */
32
+ readonly visualId: AvatarVisualId;
33
+ /**
34
+ * Output width in terminal character cells.
35
+ *
36
+ * @default `DEFAULT_AVATAR_ASCII_ART_COLUMNS`
37
+ */
38
+ readonly columns?: number;
39
+ /**
40
+ * Output height in terminal character cells.
41
+ *
42
+ * @default `columns / 2` so the square avatar stays visually square in a common terminal font
43
+ */
44
+ readonly rows?: number;
45
+ /**
46
+ * Color depth of the emitted ANSI escape codes.
47
+ *
48
+ * @default 'TRUE_COLOR'
49
+ */
50
+ readonly colorDepth?: AsciiArtColorDepth;
51
+ /**
52
+ * Animation timestamp for animated visuals.
53
+ *
54
+ * @default `STATIC_AVATAR_ASCII_ART_FRAME_TIME_MS`
55
+ */
56
+ readonly timeMs?: number;
57
+ /**
58
+ * Platform-specific canvas factory used to rasterize the visual.
59
+ */
60
+ readonly createCanvas: CreateCanvasForAsciiArt;
61
+ };
62
+ /**
63
+ * Renders one built-in avatar visual into ANSI-colored ASCII art for terminal display.
64
+ *
65
+ * This is the universal bridge between the canvas avatar visuals shown on the website and
66
+ * text-based terminal UIs: the visual is rasterized through the exact same `renderAvatarVisual`
67
+ * pipeline the web uses, then the resulting pixels are converted into colored half-block
68
+ * characters by `convertImageDataToAsciiArt`.
69
+ *
70
+ * @param options Avatar identity, visual selection, output grid size, and the platform canvas factory.
71
+ * @returns One ANSI-colored string per output row.
72
+ *
73
+ * @private within the repository
74
+ */
75
+ export declare function renderAvatarVisualAsciiArt(options: RenderAvatarVisualAsciiArtOptions): ReadonlyArray<string>;
@@ -8,7 +8,7 @@ export declare function insertDictationChunk(params: {
8
8
  readonly dictatedText: string;
9
9
  readonly selectionStart: number;
10
10
  readonly selectionEnd: number;
11
- readonly shouldReplaceSelection: boolean;
11
+ readonly isReplacingSelection: boolean;
12
12
  }): {
13
13
  nextValue: string;
14
14
  start: number;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Creates a Commander argument parser that accepts only positive integers.
3
+ *
4
+ * The returned parser is meant to be passed as the coercion callback of `command.option(...)`.
5
+ * It throws a branded `NotAllowed` error with a clear message referencing the given option name
6
+ * when the provided value is not a positive integer.
7
+ *
8
+ * @private internal utility of `promptbookCli`
9
+ */
10
+ export declare function createPositiveIntegerOptionParser(optionName: string): (value: string) => number;
@@ -0,0 +1,15 @@
1
+ import type { AsciiArtColorDepth } from './convertImageDataToAsciiArt';
2
+ /**
3
+ * Detects the ANSI color depth supported by the current terminal.
4
+ *
5
+ * Prefers 24-bit true color when the environment advertises it (modern terminals such as
6
+ * Windows Terminal, ConEmu, VS Code, mintty, iTerm2, and WezTerm) and falls back to the
7
+ * portable 256-color palette otherwise.
8
+ *
9
+ * Note: `$` is used to indicate that this function is not a pure function - it reads the process environment
10
+ *
11
+ * @returns Color depth usable by `convertImageDataToAsciiArt`
12
+ *
13
+ * @private within the repository
14
+ */
15
+ export declare function $detectTerminalAnsiColorDepth(): AsciiArtColorDepth;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Color depth of the ANSI escape codes emitted by the ASCII-art conversion.
3
+ *
4
+ * - `TRUE_COLOR` emits 24-bit `38;2;r;g;b` / `48;2;r;g;b` sequences
5
+ * - `ANSI_256` approximates colors on the 256-color ANSI cube for older terminals
6
+ *
7
+ * @private within the repository
8
+ */
9
+ export type AsciiArtColorDepth = 'TRUE_COLOR' | 'ANSI_256';
10
+ /**
11
+ * Minimal structural subset of the DOM `ImageData` accepted by the ASCII-art conversion.
12
+ *
13
+ * Works with browser canvas `ImageData`, `@napi-rs/canvas` image data, or any raw RGBA buffer.
14
+ *
15
+ * @private within the repository
16
+ */
17
+ export type AsciiArtImageData = {
18
+ /**
19
+ * Source image width in pixels.
20
+ */
21
+ readonly width: number;
22
+ /**
23
+ * Source image height in pixels.
24
+ */
25
+ readonly height: number;
26
+ /**
27
+ * Flat RGBA pixel buffer with 4 bytes per pixel.
28
+ */
29
+ readonly data: ArrayLike<number>;
30
+ };
31
+ /**
32
+ * Options for `convertImageDataToAsciiArt`.
33
+ *
34
+ * @private within the repository
35
+ */
36
+ export type ConvertImageDataToAsciiArtOptions = {
37
+ /**
38
+ * Source pixels to convert.
39
+ */
40
+ readonly imageData: AsciiArtImageData;
41
+ /**
42
+ * Output width in terminal character cells.
43
+ */
44
+ readonly columns: number;
45
+ /**
46
+ * Output height in terminal character cells.
47
+ *
48
+ * Each character cell renders two vertically stacked pixels, so `rows = columns / 2`
49
+ * keeps a square image visually square in a common terminal font.
50
+ */
51
+ readonly rows: number;
52
+ /**
53
+ * Color depth of the emitted ANSI escape codes.
54
+ *
55
+ * @default 'TRUE_COLOR'
56
+ */
57
+ readonly colorDepth?: AsciiArtColorDepth;
58
+ /**
59
+ * Alpha channel value (0-255) below which an averaged half-cell is treated as fully transparent.
60
+ *
61
+ * @default 32
62
+ */
63
+ readonly alphaThreshold?: number;
64
+ };
65
+ /**
66
+ * Converts raw RGBA image pixels into colored ASCII art for ANSI terminals.
67
+ *
68
+ * This is the universal image-to-terminal technique used across the repository:
69
+ * every output character cell covers a rectangular region of source pixels which is
70
+ * split into a top and bottom half; each half is area-averaged and rendered with
71
+ * half-block characters (`▀` / `▄`) so one character shows two "pixels" vertically.
72
+ * Transparent halves keep the terminal background so non-rectangular images
73
+ * (for example rounded avatar cards) compose naturally into any terminal UI.
74
+ *
75
+ * @param options Source pixels, output grid size, and ANSI color depth.
76
+ * @returns One ANSI-colored string per output row, each ending with a color reset.
77
+ *
78
+ * @private within the repository
79
+ */
80
+ export declare function convertImageDataToAsciiArt(options: ConvertImageDataToAsciiArtOptions): ReadonlyArray<string>;
@@ -15,7 +15,7 @@ export declare const BOOK_LANGUAGE_VERSION: string_semantic_version;
15
15
  export declare const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version;
16
16
  /**
17
17
  * Represents the version string of the Promptbook engine.
18
- * It follows semantic versioning (e.g., `0.113.0-3`).
18
+ * It follows semantic versioning (e.g., `0.113.0-5`).
19
19
  *
20
20
  * @generated
21
21
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptbook/cli",
3
- "version": "0.113.0-4",
3
+ "version": "0.113.0-8",
4
4
  "description": "Promptbook: Create persistent AI agents that turn your company's scattered knowledge into action",
5
5
  "private": false,
6
6
  "sideEffects": false,
@@ -133,7 +133,8 @@ function ensureAvatarAnimationLoop(): void {
133
133
  // Run the most stale listeners first so each avatar keeps its target FPS even when
134
134
  // total work exceeds the per-frame budget.
135
135
  dueListenerEntries.sort(
136
- (firstListenerEntry, secondListenerEntry) => firstListenerEntry.lastRunAtMs - secondListenerEntry.lastRunAtMs,
136
+ (firstListenerEntry, secondListenerEntry) =>
137
+ firstListenerEntry.lastRunAtMs - secondListenerEntry.lastRunAtMs,
137
138
  );
138
139
 
139
140
  const listenersToRunCount = Math.min(dueListenerEntries.length, MAX_AVATAR_LISTENERS_PER_FRAME);
@@ -0,0 +1,138 @@
1
+ import { spaceTrim } from 'spacetrim';
2
+ import { EnvironmentMismatchError } from '../errors/EnvironmentMismatchError';
3
+ import type { AsciiArtColorDepth } from '../utils/ascii-art/convertImageDataToAsciiArt';
4
+ import { convertImageDataToAsciiArt } from '../utils/ascii-art/convertImageDataToAsciiArt';
5
+ import { DEFAULT_AVATAR_SIZE } from './avatarRenderingUtils';
6
+ import { renderAvatarVisual } from './renderAvatarVisual';
7
+ import type { AvatarDefinition } from './types/AvatarDefinition';
8
+ import type { AvatarVisualId } from './types/AvatarVisualDefinition';
9
+
10
+ /**
11
+ * Default output width of the ASCII avatar in terminal character cells.
12
+ *
13
+ * @private within the repository
14
+ */
15
+ export const DEFAULT_AVATAR_ASCII_ART_COLUMNS = 32;
16
+
17
+ /**
18
+ * Stable animation timestamp used when rasterizing animated avatar visuals into a static ASCII frame.
19
+ *
20
+ * @private within the repository
21
+ */
22
+ const STATIC_AVATAR_ASCII_ART_FRAME_TIME_MS = 840;
23
+
24
+ /**
25
+ * Factory creating a drawable canvas of the requested pixel size.
26
+ *
27
+ * In browsers this is typically `document.createElement('canvas')` (with width/height set),
28
+ * in Node.js an adapter around `createCanvas` of `@napi-rs/canvas` or a compatible library.
29
+ *
30
+ * @private within the repository
31
+ */
32
+ export type CreateCanvasForAsciiArt = (width: number, height: number) => HTMLCanvasElement;
33
+
34
+ /**
35
+ * Options for `renderAvatarVisualAsciiArt`.
36
+ *
37
+ * @private within the repository
38
+ */
39
+ export type RenderAvatarVisualAsciiArtOptions = {
40
+ /**
41
+ * Stable visual identity of the rendered agent avatar.
42
+ */
43
+ readonly avatarDefinition: AvatarDefinition;
44
+
45
+ /**
46
+ * Built-in avatar visual to render, the same one used on the website.
47
+ */
48
+ readonly visualId: AvatarVisualId;
49
+
50
+ /**
51
+ * Output width in terminal character cells.
52
+ *
53
+ * @default `DEFAULT_AVATAR_ASCII_ART_COLUMNS`
54
+ */
55
+ readonly columns?: number;
56
+
57
+ /**
58
+ * Output height in terminal character cells.
59
+ *
60
+ * @default `columns / 2` so the square avatar stays visually square in a common terminal font
61
+ */
62
+ readonly rows?: number;
63
+
64
+ /**
65
+ * Color depth of the emitted ANSI escape codes.
66
+ *
67
+ * @default 'TRUE_COLOR'
68
+ */
69
+ readonly colorDepth?: AsciiArtColorDepth;
70
+
71
+ /**
72
+ * Animation timestamp for animated visuals.
73
+ *
74
+ * @default `STATIC_AVATAR_ASCII_ART_FRAME_TIME_MS`
75
+ */
76
+ readonly timeMs?: number;
77
+
78
+ /**
79
+ * Platform-specific canvas factory used to rasterize the visual.
80
+ */
81
+ readonly createCanvas: CreateCanvasForAsciiArt;
82
+ };
83
+
84
+ /**
85
+ * Renders one built-in avatar visual into ANSI-colored ASCII art for terminal display.
86
+ *
87
+ * This is the universal bridge between the canvas avatar visuals shown on the website and
88
+ * text-based terminal UIs: the visual is rasterized through the exact same `renderAvatarVisual`
89
+ * pipeline the web uses, then the resulting pixels are converted into colored half-block
90
+ * characters by `convertImageDataToAsciiArt`.
91
+ *
92
+ * @param options Avatar identity, visual selection, output grid size, and the platform canvas factory.
93
+ * @returns One ANSI-colored string per output row.
94
+ *
95
+ * @private within the repository
96
+ */
97
+ export function renderAvatarVisualAsciiArt(options: RenderAvatarVisualAsciiArtOptions): ReadonlyArray<string> {
98
+ const columns = options.columns ?? DEFAULT_AVATAR_ASCII_ART_COLUMNS;
99
+ const rows = options.rows ?? Math.round(columns / 2);
100
+
101
+ const canvas = options.createCanvas(DEFAULT_AVATAR_SIZE, DEFAULT_AVATAR_SIZE);
102
+
103
+ if (!canvas.style) {
104
+ // Note: `renderAvatarVisual` expects a browser canvas shape; Node.js canvases only need this tiny compatibility shim.
105
+ (canvas as { style: HTMLCanvasElement['style'] }).style = {} as HTMLCanvasElement['style'];
106
+ }
107
+
108
+ renderAvatarVisual({
109
+ canvas,
110
+ avatarDefinition: options.avatarDefinition,
111
+ visualId: options.visualId,
112
+ size: DEFAULT_AVATAR_SIZE,
113
+ timeMs: options.timeMs ?? STATIC_AVATAR_ASCII_ART_FRAME_TIME_MS,
114
+ devicePixelRatio: 1,
115
+ });
116
+
117
+ const context = canvas.getContext('2d');
118
+
119
+ if (!context) {
120
+ throw new EnvironmentMismatchError(
121
+ spaceTrim(`
122
+ 2D canvas rendering context is unavailable while converting the avatar visual to ASCII art.
123
+
124
+ Provide a \`createCanvas\` factory whose canvases support \`getContext('2d')\`,
125
+ for example \`createCanvas\` of \`@napi-rs/canvas\` in Node.js.
126
+ `),
127
+ );
128
+ }
129
+
130
+ const imageData = context.getImageData(0, 0, DEFAULT_AVATAR_SIZE, DEFAULT_AVATAR_SIZE);
131
+
132
+ return convertImageDataToAsciiArt({
133
+ imageData,
134
+ columns,
135
+ rows,
136
+ colorDepth: options.colorDepth,
137
+ });
138
+ }
@@ -502,12 +502,16 @@ function resolveVisibleContinuousOctopusPatches(
502
502
  }
503
503
 
504
504
  for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
505
- const patchCenterLongitude = (longitudeBoundaries[longitudeIndex]! + longitudeBoundaries[longitudeIndex + 1]!) / 2;
505
+ const patchCenterLongitude =
506
+ (longitudeBoundaries[longitudeIndex]! + longitudeBoundaries[longitudeIndex + 1]!) / 2;
506
507
  cachedTentacleInfluencesByPatchCenterLongitude[longitudeIndex] = resolveContinuousTentacleInfluence(
507
508
  options,
508
509
  patchCenterLongitude,
509
510
  );
510
- cachedLobeWavesByPatchCenterLongitude[longitudeIndex] = resolveContinuousLobeWave(options, patchCenterLongitude);
511
+ cachedLobeWavesByPatchCenterLongitude[longitudeIndex] = resolveContinuousLobeWave(
512
+ options,
513
+ patchCenterLongitude,
514
+ );
511
515
  cachedCosByPatchCenterLongitude[longitudeIndex] = Math.max(0, Math.cos(patchCenterLongitude));
512
516
  }
513
517
 
@@ -193,8 +193,14 @@ export const octopus3d4AvatarVisual: AvatarVisualDefinition = {
193
193
  isAnimated: true,
194
194
  supportsPointerTracking: true,
195
195
  render({ context, size, palette, createRandom, timeMs, interaction }) {
196
- const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset, tentacleProfiles, skinSpots } =
197
- getOctopus3d4StableState(createRandom);
196
+ const {
197
+ morphologyProfile,
198
+ animationPhase,
199
+ leftEyePhaseOffset,
200
+ rightEyePhaseOffset,
201
+ tentacleProfiles,
202
+ skinSpots,
203
+ } = getOctopus3d4StableState(createRandom);
198
204
  const sceneCenterX = size * 0.5;
199
205
  const sceneCenterY = size * 0.535;
200
206
  const bob = Math.sin(timeMs / 980 + animationPhase) * size * 0.013;
@@ -568,7 +574,8 @@ function resolveVisibleBlobbyContinuousPatches(
568
574
  }
569
575
 
570
576
  for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
571
- const patchCenterLongitude = (longitudeBoundaries[longitudeIndex]! + longitudeBoundaries[longitudeIndex + 1]!) / 2;
577
+ const patchCenterLongitude =
578
+ (longitudeBoundaries[longitudeIndex]! + longitudeBoundaries[longitudeIndex + 1]!) / 2;
572
579
  cachedTentacleInfluencesByPatchCenterLongitude[longitudeIndex] = resolveBlobbyTentacleInfluence(
573
580
  options,
574
581
  patchCenterLongitude,
@@ -702,8 +709,7 @@ function sampleBlobbyContinuousSurfacePointWithLongitudeCache(
702
709
  const lowerBlend = smoothStep(0.34, 1, verticalProgress);
703
710
  const tipBlend = smoothStep(0.66, 1, verticalProgress);
704
711
  const centerPull = resolveSignedAngularDistance(longitude, tentacleInfluence.centerLongitude);
705
- const effectiveLongitude =
706
- longitude + centerPull * lowerBlend * tentacleInfluence.core * (0.26 + tipBlend * 0.22);
712
+ const effectiveLongitude = longitude + centerPull * lowerBlend * tentacleInfluence.core * (0.26 + tipBlend * 0.22);
707
713
  const mantleRipple =
708
714
  Math.sin(
709
715
  longitude * morphologyProfile.body.lobeCount +
@@ -742,10 +748,7 @@ function sampleBlobbyContinuousSurfacePointWithLongitudeCache(
742
748
  lowerBlend * tentacleInfluence.core * (0.12 + tentacleInfluence.depthScale * 0.07) -
743
749
  Math.max(0, -Math.cos(effectiveLongitude)) * 0.05;
744
750
  const tentacleTubeRadius =
745
- lowerBlend *
746
- tentacleInfluence.core *
747
- (0.12 + tipBlend * 0.07 + tentacleInfluence.widthScale * 0.028) *
748
- radiusX;
751
+ lowerBlend * tentacleInfluence.core * (0.12 + tipBlend * 0.07 + tentacleInfluence.widthScale * 0.028) * radiusX;
749
752
  const planarRadiusX = cosineLatitude * radiusX * horizontalScale + tentacleTubeRadius;
750
753
  const planarRadiusZ = cosineLatitude * radiusZ * depthScale + tentacleTubeRadius * 0.74;
751
754
  const lowerDrop =
@@ -759,10 +762,7 @@ function sampleBlobbyContinuousSurfacePointWithLongitudeCache(
759
762
  const combinedTentacleSway = (primaryTentacleWave + secondaryTentacleWave) * radiusX * (0.06 + tipBlend * 0.06);
760
763
 
761
764
  return {
762
- x:
763
- Math.sin(effectiveLongitude) * planarRadiusX +
764
- combinedTentacleSway +
765
- tentacleCurl * radiusX * 0.18,
765
+ x: Math.sin(effectiveLongitude) * planarRadiusX + combinedTentacleSway + tentacleCurl * radiusX * 0.18,
766
766
  y:
767
767
  Math.sin(latitude) * radiusY * (1 + upperBlend * 0.14) -
768
768
  upperBlend * radiusY * 0.12 +
@@ -911,11 +911,7 @@ function drawBlobbyContinuousSurfacePatch(
911
911
  drawProjectedQuad(context, surfacePatch.corners, surfacePatch.fillStyle);
912
912
 
913
913
  if (surfacePatch.lightIntensity > 0) {
914
- drawProjectedQuad(
915
- context,
916
- surfacePatch.corners,
917
- `rgba(255, 255, 255, ${0.2 * surfacePatch.lightIntensity})`,
918
- );
914
+ drawProjectedQuad(context, surfacePatch.corners, `rgba(255, 255, 255, ${0.2 * surfacePatch.lightIntensity})`);
919
915
  } else if (surfacePatch.lightIntensity < 0) {
920
916
  drawProjectedQuad(
921
917
  context,
@@ -8,11 +8,11 @@ export function insertDictationChunk(params: {
8
8
  readonly dictatedText: string;
9
9
  readonly selectionStart: number;
10
10
  readonly selectionEnd: number;
11
- readonly shouldReplaceSelection: boolean;
11
+ readonly isReplacingSelection: boolean;
12
12
  }): { nextValue: string; start: number; caret: number } {
13
- const { currentValue, dictatedText, selectionStart, selectionEnd, shouldReplaceSelection } = params;
13
+ const { currentValue, dictatedText, selectionStart, selectionEnd, isReplacingSelection } = params;
14
14
  const replaceStart = selectionStart;
15
- const replaceEnd = shouldReplaceSelection ? selectionEnd : selectionStart;
15
+ const replaceEnd = isReplacingSelection ? selectionEnd : selectionStart;
16
16
  const prefix = currentValue.slice(0, replaceStart);
17
17
  const suffix = currentValue.slice(replaceEnd);
18
18
  const previousCharacter = prefix.slice(-1);
@@ -30,7 +30,7 @@ export function learnDictationDictionary(
30
30
  continue;
31
31
  }
32
32
 
33
- if (previousWord.toLowerCase() !== correctedWord.toLowerCase()) {
33
+ if (previousWord !== correctedWord) {
34
34
  nextDictionary[previousWord.toLowerCase()] = correctedWord;
35
35
  }
36
36
  }