@promptbook/cli 0.112.0-125 → 0.112.0-127
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 +5 -5
- package/apps/agents-server/README.md +3 -0
- package/apps/agents-server/playwright.config.ts +1 -0
- package/apps/agents-server/public/promptbook-logo-blue.png +0 -0
- package/apps/agents-server/public/promptbook-logo-white.png +0 -0
- package/apps/agents-server/src/app/[agentName]/layout.tsx +1 -0
- package/apps/agents-server/src/app/actions.ts +2 -2
- package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +68 -36
- package/apps/agents-server/src/app/agents/[agentName]/ActiveAgentBreadcrumbBinder.tsx +30 -0
- package/apps/agents-server/src/app/agents/[agentName]/AgentChatWrapper.tsx +2 -0
- package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatHistoryPayloadState.ts +38 -4
- package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatHistorySyncOperations.ts +4 -1
- package/apps/agents-server/src/app/agents/[agentName]/chat/CanonicalAgentChatSurface.tsx +19 -15
- package/apps/agents-server/src/app/agents/[agentName]/chat/useCanonicalAgentChatPanelState.ts +58 -7
- package/apps/agents-server/src/app/agents/[agentName]/layout.tsx +47 -1
- package/apps/agents-server/src/app/api/chat/citation-label/route.ts +133 -0
- package/apps/agents-server/src/app/globals.css +78 -0
- package/apps/agents-server/src/components/Header/ActiveAgentBreadcrumbContext.tsx +82 -0
- package/apps/agents-server/src/components/Header/useHeaderActiveAgent.ts +26 -7
- package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +35 -32
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/ManGoNewAgentWizard.tsx +151 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/ManGoOnboardingNavigation.tsx +50 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/BookLanguagePanel.tsx +125 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/DropZone.tsx +83 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/EmailTestRun.tsx +216 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/KnowledgeList.tsx +79 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/Logo.tsx +20 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/MarkdownBookEditor.tsx +154 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/MarkdownPreview.tsx +188 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/RailStepper.tsx +115 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/StepFrame.tsx +47 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/TestChat.tsx +159 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/WizardShell.tsx +114 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/brand/RailArtwork.tsx +60 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/BookStep.tsx +135 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/DoneStep.tsx +215 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/KnowledgeStep.tsx +152 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/TestStep.tsx +262 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/ZadaniStep.tsx +64 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Badge.tsx +41 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Banner.tsx +69 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Button.tsx +77 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Card.tsx +33 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Field.tsx +103 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/IconButton.tsx +40 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Spinner.tsx +14 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/tokens.ts +37 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/config/bookSections.ts +62 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/config/emailScenarios.ts +22 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/config/steps.ts +46 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/index.ts +11 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/lib/cn.ts +4 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/lib/format.ts +9 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/lib/id.ts +11 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/agentEvalService.ts +30 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/agentTestService.ts +69 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/bookService.ts +21 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/createManGoAgentSource.ts +107 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/draftService.ts +45 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/uploadService.ts +27 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/state/OnboardingProvider.tsx +121 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/types.ts +52 -0
- package/apps/agents-server/src/components/NewAgentDialog/createNewAgentWizardSource.ts +1 -1
- package/apps/agents-server/src/components/NewAgentDialog/trackNewAgentCreationEvent.ts +1 -1
- package/apps/agents-server/src/components/NewAgentDialog/useNewAgentDialog.tsx +76 -0
- package/apps/agents-server/src/constants/newAgentWizard.ts +17 -8
- package/apps/agents-server/src/database/getMetadata.ts +37 -1
- package/apps/agents-server/src/database/metadataDefaults.ts +18 -7
- package/apps/agents-server/src/database/migrations/2026-06-2200-new-agent-wizard-metadata-key.sql +27 -0
- package/apps/agents-server/src/database/migrations/2026-06-2201-new-agent-wizard-mango-default.sql +11 -0
- package/apps/agents-server/src/generated/reservedPaths.ts +2 -0
- package/apps/agents-server/src/languages/translations/english.yaml +1 -1
- package/apps/agents-server/src/tools/createChatAttachmentToolFunctions.ts +8 -4
- package/apps/agents-server/src/utils/chat/resolveAgentsServerCitationLabel.ts +130 -0
- package/apps/agents-server/src/utils/chat/resolveCitationSourceLabel.ts +436 -0
- package/apps/agents-server/src/utils/knowledge/resolveWebsiteKnowledgeSourcesForServer.ts +10 -1
- package/apps/agents-server/src/utils/session.ts +62 -5
- package/apps/agents-server/src/utils/transpilers/resolveTranspiledTeamExport.ts +10 -10
- package/apps/agents-server/src/utils/userChat/userChatProgressCard.ts +198 -63
- package/apps/agents-server/src/utils/vpsConfiguration.ts +1 -0
- package/apps/agents-server/src/utils/vpsSelfUpdate.ts +81 -8
- package/esm/index.es.js +1052 -455
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-codex-prompts/git/commitChanges.d.ts +3 -1
- package/esm/scripts/run-codex-prompts/main/runPromptRound.d.ts +2 -2
- package/esm/scripts/run-codex-prompts/server/buildCoderServerPromptResponse.d.ts +50 -0
- package/esm/scripts/run-codex-prompts/server/buildCoderServerRunState.d.ts +23 -0
- package/esm/scripts/run-codex-prompts/server/coderServerHtml.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/server/runCoderHttpServer.d.ts +13 -1
- package/esm/scripts/run-codex-prompts/server/updatePromptSection.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +1 -0
- package/esm/scripts/run-codex-prompts/ui/buildRunUiFrameShared.d.ts +4 -0
- package/esm/scripts/run-codex-prompts/ui/renderCoderRunUi.d.ts +1 -0
- package/esm/src/_packages/components.index.d.ts +2 -0
- package/esm/src/_packages/types.index.d.ts +2 -0
- package/esm/src/avatars/avatarAnimationScheduler.d.ts +4 -0
- package/esm/src/book-components/Chat/Chat/ChatCitationModal.d.ts +2 -0
- package/esm/src/book-components/Chat/Chat/ChatMessageItem.d.ts +4 -0
- package/esm/src/book-components/Chat/Chat/ChatMessageList.d.ts +4 -0
- package/esm/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
- package/esm/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +2 -0
- package/esm/src/book-components/Chat/Chat/ChatToolCallModalContent.d.ts +3 -1
- package/esm/src/book-components/Chat/Chat/TeamToolCallModalContent.d.ts +2 -0
- package/esm/src/book-components/Chat/SourceChip/SourceChip.d.ts +6 -1
- package/esm/src/book-components/Chat/hooks/useResolvedCitationLabel.d.ts +12 -0
- package/esm/src/book-components/Chat/types/ChatMessage.d.ts +4 -0
- package/esm/src/book-components/Chat/types/ChatParticipant.d.ts +1 -1
- package/esm/src/book-components/Chat/types/CitationLabelResolver.d.ts +8 -0
- package/esm/src/book-components/Chat/utils/citationHelpers.d.ts +9 -0
- package/esm/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.d.ts +14 -0
- package/esm/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.test.d.ts +1 -0
- package/esm/src/book-components/Chat/utils/parseCitationsFromContent.d.ts +4 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/_packages/components.index.ts +2 -0
- package/src/_packages/types.index.ts +2 -0
- package/src/avatars/avatarAnimationScheduler.ts +61 -20
- package/src/avatars/visuals/octopus3d2AvatarVisual.ts +106 -21
- package/src/avatars/visuals/octopus3d3AvatarVisual.ts +131 -28
- package/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/augmentAgentModelRequirementsFromSource.ts +18 -2
- package/src/book-2.0/book-language-documentation/renderGroupedCommitmentDocumentationMarkdown.ts +7 -1
- package/src/book-components/Chat/Chat/Chat.tsx +4 -0
- package/src/book-components/Chat/Chat/ChatCitationModal.tsx +17 -3
- package/src/book-components/Chat/Chat/ChatMessageItem.tsx +22 -2
- package/src/book-components/Chat/Chat/ChatMessageList.tsx +6 -0
- package/src/book-components/Chat/Chat/ChatProps.tsx +6 -0
- package/src/book-components/Chat/Chat/ChatToolCallModal.tsx +4 -0
- package/src/book-components/Chat/Chat/ChatToolCallModalContent.tsx +4 -0
- package/src/book-components/Chat/Chat/TeamToolCallModalContent.tsx +16 -3
- package/src/book-components/Chat/Chat/useChatPostprocessedMessages.ts +13 -2
- package/src/book-components/Chat/SourceChip/SourceChip.module.css +8 -0
- package/src/book-components/Chat/SourceChip/SourceChip.tsx +19 -5
- package/src/book-components/Chat/hooks/useResolvedCitationLabel.ts +65 -0
- package/src/book-components/Chat/save/html/htmlSaveFormatDefinition.ts +315 -88
- package/src/book-components/Chat/save/react/reactSaveFormatDefinition.ts +7 -1
- package/src/book-components/Chat/types/ChatMessage.ts +5 -0
- package/src/book-components/Chat/types/ChatParticipant.ts +1 -1
- package/src/book-components/Chat/types/CitationLabelResolver.ts +9 -0
- package/src/book-components/Chat/utils/citationHelpers.ts +90 -2
- package/src/book-components/Chat/utils/createCitationFootnoteRenderModel.ts +3 -0
- package/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.ts +178 -0
- package/src/book-components/Chat/utils/parseCitationsFromContent.ts +6 -0
- package/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.ts +13 -2
- package/src/cli/cli-commands/coder/getDefaultCoderPackageJsonScripts.ts +1 -1
- package/src/cli/cli-commands/coder/run.ts +17 -20
- package/src/cli/cli-commands/coder/server.ts +13 -16
- package/src/cli/common/$deprecateCliCommand.ts +10 -1
- package/src/commitments/GOAL/GOAL.ts +7 -2
- package/src/commitments/LANGUAGE/LANGUAGE.ts +7 -2
- package/src/commitments/TEAM/TEAM.ts +12 -1
- package/src/commitments/USE_PROJECT/createUseProjectToolFunctions.ts +8 -1
- package/src/import-plugins/JsonFileImportPlugin.ts +15 -2
- package/src/import-plugins/TextFileImportPlugin.ts +8 -1
- package/src/llm-providers/_common/register/$registeredLlmToolsMessage.ts +6 -1
- package/src/other/templates/getTemplatesPipelineCollection.ts +696 -941
- package/src/utils/chat/chatAttachments/resolveChatAttachmentContent.ts +8 -1
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -1
- package/umd/index.umd.js +1055 -458
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-codex-prompts/git/commitChanges.d.ts +3 -1
- package/umd/scripts/run-codex-prompts/main/runPromptRound.d.ts +2 -2
- package/umd/scripts/run-codex-prompts/server/buildCoderServerPromptResponse.d.ts +50 -0
- package/umd/scripts/run-codex-prompts/server/buildCoderServerRunState.d.ts +23 -0
- package/umd/scripts/run-codex-prompts/server/coderServerHtml.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/server/runCoderHttpServer.d.ts +13 -1
- package/umd/scripts/run-codex-prompts/server/updatePromptSection.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +1 -0
- package/umd/scripts/run-codex-prompts/ui/buildRunUiFrameShared.d.ts +4 -0
- package/umd/scripts/run-codex-prompts/ui/renderCoderRunUi.d.ts +1 -0
- package/umd/src/_packages/components.index.d.ts +2 -0
- package/umd/src/_packages/types.index.d.ts +2 -0
- package/umd/src/avatars/avatarAnimationScheduler.d.ts +4 -0
- package/umd/src/book-components/Chat/Chat/ChatCitationModal.d.ts +2 -0
- package/umd/src/book-components/Chat/Chat/ChatMessageItem.d.ts +4 -0
- package/umd/src/book-components/Chat/Chat/ChatMessageList.d.ts +4 -0
- package/umd/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
- package/umd/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +2 -0
- package/umd/src/book-components/Chat/Chat/ChatToolCallModalContent.d.ts +3 -1
- package/umd/src/book-components/Chat/Chat/TeamToolCallModalContent.d.ts +2 -0
- package/umd/src/book-components/Chat/SourceChip/SourceChip.d.ts +6 -1
- package/umd/src/book-components/Chat/hooks/useResolvedCitationLabel.d.ts +12 -0
- package/umd/src/book-components/Chat/types/ChatMessage.d.ts +4 -0
- package/umd/src/book-components/Chat/types/ChatParticipant.d.ts +1 -1
- package/umd/src/book-components/Chat/types/CitationLabelResolver.d.ts +8 -0
- package/umd/src/book-components/Chat/utils/citationHelpers.d.ts +9 -0
- package/umd/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.d.ts +14 -0
- package/umd/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.test.d.ts +1 -0
- package/umd/src/book-components/Chat/utils/parseCitationsFromContent.d.ts +4 -0
- package/umd/src/version.d.ts +1 -1
package/umd/index.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('commander'), require('spacetrim'), require('fs/promises'), require('path'), require('child_process'), require('crypto'), require('fs'), require('dotenv'), require('moment'), require('waitasecond'), require('prompts'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('socket.io-client'), require('jszip'), require('@mozilla/readability'), require('jsdom'), require('crypto-js'), require('showdown'), require('glob-promise'), require('http'), require('express'), require('socket.io'), require('express-openapi-validator'), require('swagger-ui-express'), require('react'), require('react-dom/server'), require('@anthropic-ai/sdk'), require('bottleneck'), require('@azure/openai'), require('rxjs'), require('@openai/agents'), require('openai'), require('typescript'), require('ignore'), require('readline'), require('
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'colors', 'commander', 'spacetrim', 'fs/promises', 'path', 'child_process', 'crypto', 'fs', 'dotenv', 'moment', 'waitasecond', 'prompts', 'crypto-js/enc-hex', 'crypto-js/sha256', 'socket.io-client', 'jszip', '@mozilla/readability', 'jsdom', 'crypto-js', 'showdown', 'glob-promise', 'http', 'express', 'socket.io', 'express-openapi-validator', 'swagger-ui-express', 'react', 'react-dom/server', '@anthropic-ai/sdk', 'bottleneck', '@azure/openai', 'rxjs', '@openai/agents', 'openai', 'typescript', 'ignore', 'readline', 'mime-types', 'papaparse', 'url', '
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global._spaceTrim, global.promises, global.path, global.child_process, global.crypto, global.fs, global.dotenv, global.moment, global.waitasecond, global.prompts, global.hexEncoder, global.sha256, global.socket_ioClient, global.JSZip, global.readability, global.jsdom, global.CryptoJS, global.showdown, global.glob, global.http, global.express, global.socket_io, global.OpenApiValidator, global.swaggerUi, global.react, global.server, global.Anthropic, global.Bottleneck, global.openai, global.rxjs, global.agents, global.OpenAI, global.ts, global.ignore, global.readline, global.
|
|
5
|
-
})(this, (function (exports, colors, commander, _spaceTrim, promises, path, child_process, crypto, fs, dotenv, moment, waitasecond, prompts, hexEncoder, sha256, socket_ioClient, JSZip, readability, jsdom, CryptoJS, showdown, glob, http, express, socket_io, OpenApiValidator, swaggerUi, react, server, Anthropic, Bottleneck, openai, rxjs, agents, OpenAI, ts, ignore, readline, mimeTypes, papaparse, url,
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('commander'), require('spacetrim'), require('fs/promises'), require('path'), require('child_process'), require('crypto'), require('fs'), require('dotenv'), require('moment'), require('waitasecond'), require('prompts'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('socket.io-client'), require('jszip'), require('@mozilla/readability'), require('jsdom'), require('crypto-js'), require('showdown'), require('glob-promise'), require('http'), require('express'), require('socket.io'), require('express-openapi-validator'), require('swagger-ui-express'), require('react'), require('react-dom/server'), require('@anthropic-ai/sdk'), require('bottleneck'), require('@azure/openai'), require('rxjs'), require('@openai/agents'), require('openai'), require('typescript'), require('ignore'), require('readline'), require('events'), require('mime-types'), require('papaparse'), require('url'), require('pg'), require('@supabase/supabase-js')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'colors', 'commander', 'spacetrim', 'fs/promises', 'path', 'child_process', 'crypto', 'fs', 'dotenv', 'moment', 'waitasecond', 'prompts', 'crypto-js/enc-hex', 'crypto-js/sha256', 'socket.io-client', 'jszip', '@mozilla/readability', 'jsdom', 'crypto-js', 'showdown', 'glob-promise', 'http', 'express', 'socket.io', 'express-openapi-validator', 'swagger-ui-express', 'react', 'react-dom/server', '@anthropic-ai/sdk', 'bottleneck', '@azure/openai', 'rxjs', '@openai/agents', 'openai', 'typescript', 'ignore', 'readline', 'events', 'mime-types', 'papaparse', 'url', 'pg', '@supabase/supabase-js'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global._spaceTrim, global.promises, global.path, global.child_process, global.crypto, global.fs, global.dotenv, global.moment, global.waitasecond, global.prompts, global.hexEncoder, global.sha256, global.socket_ioClient, global.JSZip, global.readability, global.jsdom, global.CryptoJS, global.showdown, global.glob, global.http, global.express, global.socket_io, global.OpenApiValidator, global.swaggerUi, global.react, global.server, global.Anthropic, global.Bottleneck, global.openai, global.rxjs, global.agents, global.OpenAI, global.ts, global.ignore, global.readline, global.events, global.mimeTypes, global.papaparse, global.url, global.pg));
|
|
5
|
+
})(this, (function (exports, colors, commander, _spaceTrim, promises, path, child_process, crypto, fs, dotenv, moment, waitasecond, prompts, hexEncoder, sha256, socket_ioClient, JSZip, readability, jsdom, CryptoJS, showdown, glob, http, express, socket_io, OpenApiValidator, swaggerUi, react, server, Anthropic, Bottleneck, openai, rxjs, agents, OpenAI, ts, ignore, readline, events, mimeTypes, papaparse, url, pg) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
8
|
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
* @generated
|
|
64
64
|
* @see https://github.com/webgptorg/promptbook
|
|
65
65
|
*/
|
|
66
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
66
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-127';
|
|
67
67
|
/**
|
|
68
68
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
69
69
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -2697,8 +2697,16 @@
|
|
|
2697
2697
|
* Builds a `.env` block containing missing Agents Server variables and documentation links.
|
|
2698
2698
|
*/
|
|
2699
2699
|
function buildMissingEnvVariablesBlock$1(variables) {
|
|
2700
|
-
const variableBlocks = variables.map(({ documentationUrl, name, value }) =>
|
|
2701
|
-
|
|
2700
|
+
const variableBlocks = variables.map(({ documentationUrl, name, value }) => _spaceTrim.spaceTrim(`
|
|
2701
|
+
${AGENTS_SERVER_ENV_CREATED_COMMENT}
|
|
2702
|
+
# Documentation: ${documentationUrl}
|
|
2703
|
+
${name}=${value}
|
|
2704
|
+
`));
|
|
2705
|
+
return _spaceTrim.spaceTrim((block) => `
|
|
2706
|
+
# Promptbook Agents Server
|
|
2707
|
+
|
|
2708
|
+
${block(variableBlocks.join('\n\n'))}
|
|
2709
|
+
`);
|
|
2702
2710
|
}
|
|
2703
2711
|
// Note: [🟡] Code for Agents Server environment bootstrapping [ensureAgentsServerEnvFile](src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.ts) should never be published outside of `@promptbook/cli`
|
|
2704
2712
|
|
|
@@ -4270,6 +4278,13 @@
|
|
|
4270
4278
|
},
|
|
4271
4279
|
];
|
|
4272
4280
|
}
|
|
4281
|
+
/**
|
|
4282
|
+
* Builds one OSC 8 terminal hyperlink to an HTTP URL.
|
|
4283
|
+
*/
|
|
4284
|
+
function buildTerminalUrlLink(url, availableWidth) {
|
|
4285
|
+
const displayUrl = fitPlainText(url, availableWidth);
|
|
4286
|
+
return `\u001B]8;;${url}\u0007${displayUrl}\u001B]8;;\u0007`;
|
|
4287
|
+
}
|
|
4273
4288
|
/**
|
|
4274
4289
|
* Builds the colored phase badge shown in the session box.
|
|
4275
4290
|
*/
|
|
@@ -4460,6 +4475,9 @@
|
|
|
4460
4475
|
}
|
|
4461
4476
|
const configurationRows = [
|
|
4462
4477
|
...buildOptionalSessionRow('Context', options.config.context),
|
|
4478
|
+
...buildOptionalSessionRow('Server', options.config.serverUrl
|
|
4479
|
+
? buildTerminalUrlLink(options.config.serverUrl, bodyWidth - SESSION_LABEL_WIDTH - 1)
|
|
4480
|
+
: undefined),
|
|
4463
4481
|
...buildOptionalSessionRow('Test', options.config.testCommand),
|
|
4464
4482
|
];
|
|
4465
4483
|
return [
|
|
@@ -4902,7 +4920,8 @@
|
|
|
4902
4920
|
* @private internal entry point of coder run UI
|
|
4903
4921
|
*/
|
|
4904
4922
|
function renderCoderRunUi(startTime, options = {}) {
|
|
4905
|
-
|
|
4923
|
+
var _a;
|
|
4924
|
+
const state = (_a = options.state) !== null && _a !== void 0 ? _a : new CoderRunUiState(startTime);
|
|
4906
4925
|
const buildFrameLinesFromState = options.buildFrameLines || buildCoderRunUiFrame;
|
|
4907
4926
|
if (!process.stdout.isTTY) {
|
|
4908
4927
|
return {
|
|
@@ -7881,8 +7900,11 @@
|
|
|
7881
7900
|
if (!trimmedContent) {
|
|
7882
7901
|
return requirements;
|
|
7883
7902
|
}
|
|
7884
|
-
|
|
7885
|
-
|
|
7903
|
+
const goalSection = _spaceTrim.spaceTrim((block) => `
|
|
7904
|
+
## Goal
|
|
7905
|
+
|
|
7906
|
+
${block(trimmedContent)}
|
|
7907
|
+
`);
|
|
7886
7908
|
const requirementsWithGoal = this.appendToSystemMessage(requirements, goalSection, '\n\n');
|
|
7887
7909
|
return this.appendToPromptSuffix(requirementsWithGoal, trimmedContent);
|
|
7888
7910
|
}
|
|
@@ -8404,8 +8426,11 @@
|
|
|
8404
8426
|
if (!trimmedContent) {
|
|
8405
8427
|
return requirements;
|
|
8406
8428
|
}
|
|
8407
|
-
|
|
8408
|
-
|
|
8429
|
+
const languageSection = _spaceTrim.spaceTrim((block) => `
|
|
8430
|
+
## Language
|
|
8431
|
+
|
|
8432
|
+
- Your language is ${block(trimmedContent)}
|
|
8433
|
+
`);
|
|
8409
8434
|
return this.appendToSystemMessage(requirements, languageSection, '\n\n');
|
|
8410
8435
|
}
|
|
8411
8436
|
}
|
|
@@ -13370,41 +13395,91 @@
|
|
|
13370
13395
|
context.fill();
|
|
13371
13396
|
context.restore();
|
|
13372
13397
|
}
|
|
13398
|
+
/**
|
|
13399
|
+
* Number of latitude segments used by the single blobby octopus mesh.
|
|
13400
|
+
*
|
|
13401
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
13402
|
+
*/
|
|
13403
|
+
const LATITUDE_PATCH_COUNT$1 = 12;
|
|
13404
|
+
/**
|
|
13405
|
+
* Number of longitude segments used by the single blobby octopus mesh.
|
|
13406
|
+
*
|
|
13407
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
13408
|
+
*/
|
|
13409
|
+
const LONGITUDE_PATCH_COUNT$1 = 24;
|
|
13373
13410
|
/**
|
|
13374
13411
|
* Resolves all visible projected patches for the single blobby octopus mesh.
|
|
13375
13412
|
*
|
|
13413
|
+
* Within a single frame, mesh corner samples and longitude-only lobe-wave values are
|
|
13414
|
+
* quantized to the patch grid and computed once each rather than re-evaluated for every
|
|
13415
|
+
* patch corner — the patch loop alone would call `sampleBlobbyOctopusSurfacePoint`
|
|
13416
|
+
* `latitudePatchCount * longitudePatchCount * 4` times without caching, even though most
|
|
13417
|
+
* corners are shared between neighboring patches.
|
|
13418
|
+
*
|
|
13376
13419
|
* @private helper of `octopus3d2AvatarVisual`
|
|
13377
13420
|
*/
|
|
13378
13421
|
function resolveVisibleBlobbyOctopusPatches(options) {
|
|
13379
13422
|
const { center, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, morphologyProfile, animationPhase, timeMs, } = options;
|
|
13380
|
-
const latitudePatchCount =
|
|
13381
|
-
const longitudePatchCount =
|
|
13423
|
+
const latitudePatchCount = LATITUDE_PATCH_COUNT$1;
|
|
13424
|
+
const longitudePatchCount = LONGITUDE_PATCH_COUNT$1;
|
|
13382
13425
|
const surfacePatches = [];
|
|
13426
|
+
const latitudeBoundaries = new Float64Array(latitudePatchCount + 1);
|
|
13427
|
+
const longitudeBoundaries = new Float64Array(longitudePatchCount + 1);
|
|
13428
|
+
for (let boundaryIndex = 0; boundaryIndex <= latitudePatchCount; boundaryIndex++) {
|
|
13429
|
+
latitudeBoundaries[boundaryIndex] = -Math.PI / 2 + (boundaryIndex / latitudePatchCount) * Math.PI;
|
|
13430
|
+
}
|
|
13431
|
+
for (let boundaryIndex = 0; boundaryIndex <= longitudePatchCount; boundaryIndex++) {
|
|
13432
|
+
longitudeBoundaries[boundaryIndex] = -Math.PI + (boundaryIndex / longitudePatchCount) * Math.PI * 2;
|
|
13433
|
+
}
|
|
13434
|
+
const cachedLobeWavesByCornerLongitude = new Float64Array(longitudePatchCount + 1);
|
|
13435
|
+
for (let boundaryIndex = 0; boundaryIndex <= longitudePatchCount; boundaryIndex++) {
|
|
13436
|
+
cachedLobeWavesByCornerLongitude[boundaryIndex] = resolveLowerLobeWave(longitudeBoundaries[boundaryIndex], morphologyProfile, animationPhase, timeMs);
|
|
13437
|
+
}
|
|
13438
|
+
const cornerCount = (latitudePatchCount + 1) * (longitudePatchCount + 1);
|
|
13439
|
+
const transformedCornerSamples = new Array(cornerCount);
|
|
13440
|
+
for (let latitudeBoundaryIndex = 0; latitudeBoundaryIndex <= latitudePatchCount; latitudeBoundaryIndex++) {
|
|
13441
|
+
const cornerLatitude = latitudeBoundaries[latitudeBoundaryIndex];
|
|
13442
|
+
for (let longitudeBoundaryIndex = 0; longitudeBoundaryIndex <= longitudePatchCount; longitudeBoundaryIndex++) {
|
|
13443
|
+
const cornerLongitude = longitudeBoundaries[longitudeBoundaryIndex];
|
|
13444
|
+
const cornerIndex = latitudeBoundaryIndex * (longitudePatchCount + 1) + longitudeBoundaryIndex;
|
|
13445
|
+
const cornerSample = sampleBlobbyOctopusSurfacePointWithLongitudeCache(options, cornerLatitude, cornerLongitude, cachedLobeWavesByCornerLongitude[longitudeBoundaryIndex]);
|
|
13446
|
+
transformedCornerSamples[cornerIndex] = transformScenePoint(cornerSample, center, rotationX, rotationY);
|
|
13447
|
+
}
|
|
13448
|
+
}
|
|
13383
13449
|
for (let latitudeIndex = 0; latitudeIndex < latitudePatchCount; latitudeIndex++) {
|
|
13384
|
-
const startLatitude =
|
|
13385
|
-
const endLatitude =
|
|
13450
|
+
const startLatitude = latitudeBoundaries[latitudeIndex];
|
|
13451
|
+
const endLatitude = latitudeBoundaries[latitudeIndex + 1];
|
|
13386
13452
|
const centerLatitude = (startLatitude + endLatitude) / 2;
|
|
13387
13453
|
const verticalProgress = (Math.sin(centerLatitude) + 1) / 2;
|
|
13454
|
+
const startCornerRowOffset = latitudeIndex * (longitudePatchCount + 1);
|
|
13455
|
+
const endCornerRowOffset = (latitudeIndex + 1) * (longitudePatchCount + 1);
|
|
13388
13456
|
for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
|
|
13389
|
-
const startLongitude =
|
|
13390
|
-
const endLongitude =
|
|
13457
|
+
const startLongitude = longitudeBoundaries[longitudeIndex];
|
|
13458
|
+
const endLongitude = longitudeBoundaries[longitudeIndex + 1];
|
|
13391
13459
|
const centerLongitude = (startLongitude + endLongitude) / 2;
|
|
13392
|
-
const
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
|
|
13396
|
-
|
|
13460
|
+
const transformedCorners = [
|
|
13461
|
+
transformedCornerSamples[startCornerRowOffset + longitudeIndex],
|
|
13462
|
+
transformedCornerSamples[startCornerRowOffset + longitudeIndex + 1],
|
|
13463
|
+
transformedCornerSamples[endCornerRowOffset + longitudeIndex + 1],
|
|
13464
|
+
transformedCornerSamples[endCornerRowOffset + longitudeIndex],
|
|
13397
13465
|
];
|
|
13398
|
-
const transformedCorners = localCorners.map((localCorner) => transformScenePoint(localCorner, center, rotationX, rotationY));
|
|
13399
13466
|
const surfaceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
|
|
13400
13467
|
if (surfaceNormal.z <= 0.01) {
|
|
13401
13468
|
continue;
|
|
13402
13469
|
}
|
|
13403
|
-
const projectedCorners =
|
|
13470
|
+
const projectedCorners = [
|
|
13471
|
+
projectScenePoint(transformedCorners[0], size, sceneCenterX, sceneCenterY),
|
|
13472
|
+
projectScenePoint(transformedCorners[1], size, sceneCenterX, sceneCenterY),
|
|
13473
|
+
projectScenePoint(transformedCorners[2], size, sceneCenterX, sceneCenterY),
|
|
13474
|
+
projectScenePoint(transformedCorners[3], size, sceneCenterX, sceneCenterY),
|
|
13475
|
+
];
|
|
13404
13476
|
surfacePatches.push({
|
|
13405
13477
|
corners: projectedCorners,
|
|
13406
|
-
averageDepth: transformedCorners.
|
|
13407
|
-
transformedCorners.
|
|
13478
|
+
averageDepth: (transformedCorners[0].z +
|
|
13479
|
+
transformedCorners[1].z +
|
|
13480
|
+
transformedCorners[2].z +
|
|
13481
|
+
transformedCorners[3].z) /
|
|
13482
|
+
4,
|
|
13408
13483
|
lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$1), -1, 1),
|
|
13409
13484
|
fillStyle: resolveBlobbySurfacePatchFillStyle(palette, verticalProgress, Math.max(0, Math.cos(centerLongitude)), resolveLowerLobeWave(centerLongitude, morphologyProfile, animationPhase, timeMs)),
|
|
13410
13485
|
outlineColor: verticalProgress < 0.58 ? `${palette.highlight}73` : `${palette.shadow}8a`,
|
|
@@ -13422,12 +13497,21 @@
|
|
|
13422
13497
|
* @private helper of `octopus3d2AvatarVisual`
|
|
13423
13498
|
*/
|
|
13424
13499
|
function sampleBlobbyOctopusSurfacePoint(options, latitude, longitude) {
|
|
13500
|
+
const { morphologyProfile, animationPhase, timeMs } = options;
|
|
13501
|
+
return sampleBlobbyOctopusSurfacePointWithLongitudeCache(options, latitude, longitude, resolveLowerLobeWave(longitude, morphologyProfile, animationPhase, timeMs));
|
|
13502
|
+
}
|
|
13503
|
+
/**
|
|
13504
|
+
* Samples one point on the continuous Octopus 3D 2 surface using a precomputed lower-lobe wave
|
|
13505
|
+
* to skip the per-call trig evaluation for `latitudePatchCount + 1` longitude-shared corners.
|
|
13506
|
+
*
|
|
13507
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
13508
|
+
*/
|
|
13509
|
+
function sampleBlobbyOctopusSurfacePointWithLongitudeCache(options, latitude, longitude, lowerLobeWave) {
|
|
13425
13510
|
const { radiusX, radiusY, radiusZ, morphologyProfile, timeMs, animationPhase } = options;
|
|
13426
13511
|
const cosineLatitude = Math.max(0, Math.cos(latitude));
|
|
13427
13512
|
const verticalProgress = (Math.sin(latitude) + 1) / 2;
|
|
13428
13513
|
const upperBlend = Math.pow(1 - verticalProgress, 1.2);
|
|
13429
13514
|
const lowerBlend = Math.pow(verticalProgress, 1.42);
|
|
13430
|
-
const lowerLobeWave = resolveLowerLobeWave(longitude, morphologyProfile, animationPhase, timeMs);
|
|
13431
13515
|
const skirtEnvelope = Math.pow(cosineLatitude, 0.5) * lowerBlend;
|
|
13432
13516
|
const horizontalScale = 1.02 +
|
|
13433
13517
|
skirtEnvelope * (0.34 + (morphologyProfile.tentacles.rootSpreadScale - 1) * 0.22 + lowerLobeWave * 0.22) -
|
|
@@ -13724,45 +13808,102 @@
|
|
|
13724
13808
|
context.fill();
|
|
13725
13809
|
context.restore();
|
|
13726
13810
|
}
|
|
13811
|
+
/**
|
|
13812
|
+
* Number of latitude segments used by the continuous Octopus 3D 3 mesh.
|
|
13813
|
+
*
|
|
13814
|
+
* @private helper of `octopus3d3AvatarVisual`
|
|
13815
|
+
*/
|
|
13816
|
+
const LATITUDE_PATCH_COUNT = 16;
|
|
13817
|
+
/**
|
|
13818
|
+
* Number of longitude segments used by the continuous Octopus 3D 3 mesh.
|
|
13819
|
+
*
|
|
13820
|
+
* @private helper of `octopus3d3AvatarVisual`
|
|
13821
|
+
*/
|
|
13822
|
+
const LONGITUDE_PATCH_COUNT = 40;
|
|
13727
13823
|
/**
|
|
13728
13824
|
* Resolves visible projected patches for the continuous octopus mesh.
|
|
13729
13825
|
*
|
|
13826
|
+
* Within a single frame, mesh corner samples and longitude-only computations (tentacle
|
|
13827
|
+
* influence and lobe wave) are quantized to the patch grid and computed once each rather
|
|
13828
|
+
* than re-evaluated for every patch corner — the patch loop alone calls `sampleContinuousOctopusSurfacePoint`
|
|
13829
|
+
* for `latitudePatchCount * longitudePatchCount * 4` corners without caching, and each call
|
|
13830
|
+
* triggers an inner 8-iteration `Math.exp` loop, which dominates the per-frame cost.
|
|
13831
|
+
*
|
|
13730
13832
|
* @private helper of `octopus3d3AvatarVisual`
|
|
13731
13833
|
*/
|
|
13732
13834
|
function resolveVisibleContinuousOctopusPatches(options) {
|
|
13733
13835
|
const { center, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette } = options;
|
|
13734
|
-
const latitudePatchCount =
|
|
13735
|
-
const longitudePatchCount =
|
|
13836
|
+
const latitudePatchCount = LATITUDE_PATCH_COUNT;
|
|
13837
|
+
const longitudePatchCount = LONGITUDE_PATCH_COUNT;
|
|
13736
13838
|
const surfacePatches = [];
|
|
13839
|
+
const latitudeBoundaries = new Float64Array(latitudePatchCount + 1);
|
|
13840
|
+
const longitudeBoundaries = new Float64Array(longitudePatchCount + 1);
|
|
13841
|
+
for (let boundaryIndex = 0; boundaryIndex <= latitudePatchCount; boundaryIndex++) {
|
|
13842
|
+
latitudeBoundaries[boundaryIndex] = -Math.PI / 2 + (boundaryIndex / latitudePatchCount) * Math.PI;
|
|
13843
|
+
}
|
|
13844
|
+
for (let boundaryIndex = 0; boundaryIndex <= longitudePatchCount; boundaryIndex++) {
|
|
13845
|
+
longitudeBoundaries[boundaryIndex] = -Math.PI + (boundaryIndex / longitudePatchCount) * Math.PI * 2;
|
|
13846
|
+
}
|
|
13847
|
+
const cachedTentacleInfluencesByCornerLongitude = new Array(longitudePatchCount + 1);
|
|
13848
|
+
const cachedLobeWavesByCornerLongitude = new Float64Array(longitudePatchCount + 1);
|
|
13849
|
+
const cachedTentacleInfluencesByPatchCenterLongitude = new Array(longitudePatchCount);
|
|
13850
|
+
const cachedLobeWavesByPatchCenterLongitude = new Float64Array(longitudePatchCount);
|
|
13851
|
+
const cachedCosByPatchCenterLongitude = new Float64Array(longitudePatchCount);
|
|
13852
|
+
for (let boundaryIndex = 0; boundaryIndex <= longitudePatchCount; boundaryIndex++) {
|
|
13853
|
+
const cornerLongitude = longitudeBoundaries[boundaryIndex];
|
|
13854
|
+
cachedTentacleInfluencesByCornerLongitude[boundaryIndex] = resolveContinuousTentacleInfluence(options, cornerLongitude);
|
|
13855
|
+
cachedLobeWavesByCornerLongitude[boundaryIndex] = resolveContinuousLobeWave(options, cornerLongitude);
|
|
13856
|
+
}
|
|
13857
|
+
for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
|
|
13858
|
+
const patchCenterLongitude = (longitudeBoundaries[longitudeIndex] + longitudeBoundaries[longitudeIndex + 1]) / 2;
|
|
13859
|
+
cachedTentacleInfluencesByPatchCenterLongitude[longitudeIndex] = resolveContinuousTentacleInfluence(options, patchCenterLongitude);
|
|
13860
|
+
cachedLobeWavesByPatchCenterLongitude[longitudeIndex] = resolveContinuousLobeWave(options, patchCenterLongitude);
|
|
13861
|
+
cachedCosByPatchCenterLongitude[longitudeIndex] = Math.max(0, Math.cos(patchCenterLongitude));
|
|
13862
|
+
}
|
|
13863
|
+
const cornerCount = (latitudePatchCount + 1) * (longitudePatchCount + 1);
|
|
13864
|
+
const transformedCornerSamples = new Array(cornerCount);
|
|
13865
|
+
for (let latitudeBoundaryIndex = 0; latitudeBoundaryIndex <= latitudePatchCount; latitudeBoundaryIndex++) {
|
|
13866
|
+
const cornerLatitude = latitudeBoundaries[latitudeBoundaryIndex];
|
|
13867
|
+
for (let longitudeBoundaryIndex = 0; longitudeBoundaryIndex <= longitudePatchCount; longitudeBoundaryIndex++) {
|
|
13868
|
+
const cornerLongitude = longitudeBoundaries[longitudeBoundaryIndex];
|
|
13869
|
+
const cornerIndex = latitudeBoundaryIndex * (longitudePatchCount + 1) + longitudeBoundaryIndex;
|
|
13870
|
+
const cornerSample = sampleContinuousOctopusSurfacePointWithLongitudeCache(options, cornerLatitude, cornerLongitude, cachedTentacleInfluencesByCornerLongitude[longitudeBoundaryIndex], cachedLobeWavesByCornerLongitude[longitudeBoundaryIndex]);
|
|
13871
|
+
transformedCornerSamples[cornerIndex] = transformScenePoint(cornerSample, center, rotationX, rotationY);
|
|
13872
|
+
}
|
|
13873
|
+
}
|
|
13737
13874
|
for (let latitudeIndex = 0; latitudeIndex < latitudePatchCount; latitudeIndex++) {
|
|
13738
|
-
const startLatitude =
|
|
13739
|
-
const endLatitude =
|
|
13875
|
+
const startLatitude = latitudeBoundaries[latitudeIndex];
|
|
13876
|
+
const endLatitude = latitudeBoundaries[latitudeIndex + 1];
|
|
13740
13877
|
const centerLatitude = (startLatitude + endLatitude) / 2;
|
|
13741
13878
|
const verticalProgress = (Math.sin(centerLatitude) + 1) / 2;
|
|
13879
|
+
const startCornerRowOffset = latitudeIndex * (longitudePatchCount + 1);
|
|
13880
|
+
const endCornerRowOffset = (latitudeIndex + 1) * (longitudePatchCount + 1);
|
|
13742
13881
|
for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
|
|
13743
|
-
const
|
|
13744
|
-
|
|
13745
|
-
|
|
13746
|
-
|
|
13747
|
-
|
|
13748
|
-
sampleContinuousOctopusSurfacePoint(options, startLatitude, endLongitude),
|
|
13749
|
-
sampleContinuousOctopusSurfacePoint(options, endLatitude, endLongitude),
|
|
13750
|
-
sampleContinuousOctopusSurfacePoint(options, endLatitude, startLongitude),
|
|
13882
|
+
const transformedCorners = [
|
|
13883
|
+
transformedCornerSamples[startCornerRowOffset + longitudeIndex],
|
|
13884
|
+
transformedCornerSamples[startCornerRowOffset + longitudeIndex + 1],
|
|
13885
|
+
transformedCornerSamples[endCornerRowOffset + longitudeIndex + 1],
|
|
13886
|
+
transformedCornerSamples[endCornerRowOffset + longitudeIndex],
|
|
13751
13887
|
];
|
|
13752
|
-
const transformedCorners = localCorners.map((localCorner) => transformScenePoint(localCorner, center, rotationX, rotationY));
|
|
13753
13888
|
const surfaceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
|
|
13754
13889
|
if (surfaceNormal.z <= 0.008) {
|
|
13755
13890
|
continue;
|
|
13756
13891
|
}
|
|
13757
|
-
const projectedCorners =
|
|
13758
|
-
|
|
13759
|
-
|
|
13892
|
+
const projectedCorners = [
|
|
13893
|
+
projectScenePoint(transformedCorners[0], size, sceneCenterX, sceneCenterY),
|
|
13894
|
+
projectScenePoint(transformedCorners[1], size, sceneCenterX, sceneCenterY),
|
|
13895
|
+
projectScenePoint(transformedCorners[2], size, sceneCenterX, sceneCenterY),
|
|
13896
|
+
projectScenePoint(transformedCorners[3], size, sceneCenterX, sceneCenterY),
|
|
13897
|
+
];
|
|
13760
13898
|
surfacePatches.push({
|
|
13761
13899
|
corners: projectedCorners,
|
|
13762
|
-
averageDepth: transformedCorners.
|
|
13763
|
-
transformedCorners.
|
|
13900
|
+
averageDepth: (transformedCorners[0].z +
|
|
13901
|
+
transformedCorners[1].z +
|
|
13902
|
+
transformedCorners[2].z +
|
|
13903
|
+
transformedCorners[3].z) /
|
|
13904
|
+
4,
|
|
13764
13905
|
lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION), -1, 1),
|
|
13765
|
-
fillStyle: resolveContinuousSurfacePatchFillStyle(palette, verticalProgress,
|
|
13906
|
+
fillStyle: resolveContinuousSurfacePatchFillStyle(palette, verticalProgress, cachedCosByPatchCenterLongitude[longitudeIndex], cachedTentacleInfluencesByPatchCenterLongitude[longitudeIndex].core, cachedLobeWavesByPatchCenterLongitude[longitudeIndex]),
|
|
13766
13907
|
outlineColor: verticalProgress < 0.54 ? `${palette.highlight}69` : `${palette.shadow}78`,
|
|
13767
13908
|
});
|
|
13768
13909
|
}
|
|
@@ -13778,16 +13919,27 @@
|
|
|
13778
13919
|
* @private helper of `octopus3d3AvatarVisual`
|
|
13779
13920
|
*/
|
|
13780
13921
|
function sampleContinuousOctopusSurfacePoint(options, latitude, longitude) {
|
|
13922
|
+
return sampleContinuousOctopusSurfacePointWithLongitudeCache(options, latitude, longitude, resolveContinuousTentacleInfluence(options, longitude), resolveContinuousLobeWave(options, longitude));
|
|
13923
|
+
}
|
|
13924
|
+
/**
|
|
13925
|
+
* Samples one point on the continuous Octopus 3D 3 surface using precomputed longitude-only
|
|
13926
|
+
* values to skip the per-call `Math.exp` tentacle-influence loop and the lobe-wave trig call.
|
|
13927
|
+
*
|
|
13928
|
+
* The patch loop quantizes the mesh into a fixed `(latitudePatchCount + 1) * (longitudePatchCount + 1)`
|
|
13929
|
+
* corner grid, so the same longitude is reused across every latitude row and each
|
|
13930
|
+
* tentacle/lobe value can be computed once per frame instead of `latitudePatchCount * 4` times.
|
|
13931
|
+
*
|
|
13932
|
+
* @private helper of `octopus3d3AvatarVisual`
|
|
13933
|
+
*/
|
|
13934
|
+
function sampleContinuousOctopusSurfacePointWithLongitudeCache(options, latitude, longitude, tentacleInfluence, lowerLobeWave) {
|
|
13781
13935
|
const { radiusX, radiusY, radiusZ, morphologyProfile, timeMs, animationPhase } = options;
|
|
13782
13936
|
const cosineLatitude = Math.max(0, Math.cos(latitude));
|
|
13783
13937
|
const verticalProgress = (Math.sin(latitude) + 1) / 2;
|
|
13784
13938
|
const upperBlend = Math.pow(1 - verticalProgress, 1.28);
|
|
13785
13939
|
const lowerBlend = smoothStep(0.38, 1, verticalProgress);
|
|
13786
13940
|
const tipBlend = smoothStep(0.68, 1, verticalProgress);
|
|
13787
|
-
const tentacleInfluence = resolveContinuousTentacleInfluence(options, longitude);
|
|
13788
13941
|
const centerPull = resolveSignedAngularDistance(longitude, tentacleInfluence.centerLongitude);
|
|
13789
13942
|
const effectiveLongitude = longitude + centerPull * lowerBlend * tentacleInfluence.core * (0.24 + tipBlend * 0.2);
|
|
13790
|
-
const lowerLobeWave = resolveContinuousLobeWave(options, longitude);
|
|
13791
13943
|
const mantleRipple = Math.sin(longitude * morphologyProfile.body.lobeCount +
|
|
13792
13944
|
animationPhase * 0.6 +
|
|
13793
13945
|
timeMs / (1750 + morphologyProfile.body.lobeCount * 30)) *
|
|
@@ -17192,7 +17344,15 @@
|
|
|
17192
17344
|
* Builds the teammate request text, optionally including context.
|
|
17193
17345
|
*/
|
|
17194
17346
|
function buildTeammateRequest(message, context) {
|
|
17195
|
-
|
|
17347
|
+
if (!context) {
|
|
17348
|
+
return message;
|
|
17349
|
+
}
|
|
17350
|
+
return _spaceTrim.spaceTrim((block) => `
|
|
17351
|
+
${block(message)}
|
|
17352
|
+
|
|
17353
|
+
Context:
|
|
17354
|
+
${block(context)}
|
|
17355
|
+
`);
|
|
17196
17356
|
}
|
|
17197
17357
|
/**
|
|
17198
17358
|
* Builds a minimal chat prompt for teammate calls.
|
|
@@ -21215,7 +21375,11 @@
|
|
|
21215
21375
|
const lineRangedContent = applyOptionalLineRange(decodedContent, args.startLine, args.endLine);
|
|
21216
21376
|
const wasCharacterTruncated = lineRangedContent.length > MAX_PROJECT_FILE_CONTENT_CHARACTERS;
|
|
21217
21377
|
const contentToReturn = wasCharacterTruncated
|
|
21218
|
-
?
|
|
21378
|
+
? _spaceTrim.spaceTrim((block) => `
|
|
21379
|
+
${block(lineRangedContent.slice(0, MAX_PROJECT_FILE_CONTENT_CHARACTERS))}
|
|
21380
|
+
|
|
21381
|
+
[...truncated...]
|
|
21382
|
+
`)
|
|
21219
21383
|
: lineRangedContent;
|
|
21220
21384
|
const wasTruncated = decoded.isTruncated || wasCharacterTruncated;
|
|
21221
21385
|
if (wasCharacterTruncated) {
|
|
@@ -26090,7 +26254,8 @@
|
|
|
26090
26254
|
/**
|
|
26091
26255
|
* Commits staged changes with the provided message using the dedicated coding-agent identity when configured,
|
|
26092
26256
|
* otherwise falls back to the default Git configuration. Remote pushing is opt-in via `options.autoPush`,
|
|
26093
|
-
* `options.includePaths` can restrict staging,
|
|
26257
|
+
* `options.includePaths` can restrict staging, `options.onlyPaths` can restrict the commit pathspec,
|
|
26258
|
+
* and `options.excludePaths` can keep temporary artifacts out of the created commit.
|
|
26094
26259
|
*/
|
|
26095
26260
|
async function commitChanges(message, options) {
|
|
26096
26261
|
const projectPath = (options === null || options === void 0 ? void 0 : options.projectPath) || process.cwd();
|
|
@@ -26102,7 +26267,7 @@
|
|
|
26102
26267
|
const signingFlag = buildAgentGitSigningFlag();
|
|
26103
26268
|
await stageCommitChanges(projectPath, agentEnv, options === null || options === void 0 ? void 0 : options.includePaths, options === null || options === void 0 ? void 0 : options.excludePaths);
|
|
26104
26269
|
await runGitCommand({
|
|
26105
|
-
command: buildGitCommitCommand(commitMessagePath, signingFlag),
|
|
26270
|
+
command: buildGitCommitCommand(commitMessagePath, signingFlag, options === null || options === void 0 ? void 0 : options.onlyPaths),
|
|
26106
26271
|
cwd: projectPath,
|
|
26107
26272
|
env: agentEnv,
|
|
26108
26273
|
});
|
|
@@ -26282,12 +26447,15 @@
|
|
|
26282
26447
|
/**
|
|
26283
26448
|
* Builds the `git commit` command with an optional signing flag.
|
|
26284
26449
|
*/
|
|
26285
|
-
function buildGitCommitCommand(commitMessagePath, signingFlag) {
|
|
26450
|
+
function buildGitCommitCommand(commitMessagePath, signingFlag, onlyPaths) {
|
|
26286
26451
|
const commandParts = ['git commit'];
|
|
26287
26452
|
if (signingFlag) {
|
|
26288
26453
|
commandParts.push(signingFlag);
|
|
26289
26454
|
}
|
|
26290
26455
|
commandParts.push(`--file "${commitMessagePath}"`);
|
|
26456
|
+
if (onlyPaths && onlyPaths.length > 0) {
|
|
26457
|
+
commandParts.push('--', ...onlyPaths.map(quoteShellPath$1));
|
|
26458
|
+
}
|
|
26291
26459
|
return commandParts.join(' ');
|
|
26292
26460
|
}
|
|
26293
26461
|
/**
|
|
@@ -27785,7 +27953,11 @@
|
|
|
27785
27953
|
if (normalized.length <= OUTPUT_SNIPPET_MAX_CHARS) {
|
|
27786
27954
|
return normalized;
|
|
27787
27955
|
}
|
|
27788
|
-
return
|
|
27956
|
+
return _spaceTrim.spaceTrim((block) => `
|
|
27957
|
+
${block(normalized.slice(0, OUTPUT_SNIPPET_MAX_CHARS))}
|
|
27958
|
+
|
|
27959
|
+
...[truncated]
|
|
27960
|
+
`);
|
|
27789
27961
|
}
|
|
27790
27962
|
/**
|
|
27791
27963
|
* Builds one command failure message that keeps a useful snippet of CLI output.
|
|
@@ -27795,7 +27967,11 @@
|
|
|
27795
27967
|
if (!outputSnippet) {
|
|
27796
27968
|
return `Command "bash ${scriptPathPosix}" exited with code ${code !== null && code !== void 0 ? code : 'unknown'}`;
|
|
27797
27969
|
}
|
|
27798
|
-
return
|
|
27970
|
+
return _spaceTrim.spaceTrim((block) => `
|
|
27971
|
+
Command "bash ${scriptPathPosix}" exited with code ${code !== null && code !== void 0 ? code : 'unknown'}
|
|
27972
|
+
|
|
27973
|
+
${block(outputSnippet)}
|
|
27974
|
+
`);
|
|
27799
27975
|
}
|
|
27800
27976
|
/**
|
|
27801
27977
|
* Runs a script until a completion marker is observed and output is idle for a set timeout.
|
|
@@ -27912,7 +28088,9 @@
|
|
|
27912
28088
|
* Handles process exit and resolves or rejects accordingly.
|
|
27913
28089
|
*/
|
|
27914
28090
|
const handleExit = (code) => {
|
|
27915
|
-
const failure = code === 0 || markerSeen
|
|
28091
|
+
const failure = code === 0 || markerSeen
|
|
28092
|
+
? undefined
|
|
28093
|
+
: new Error(buildCommandFailureMessage(scriptPathPosix, code, fullOutput));
|
|
27916
28094
|
const status = failure ? `failed with exit code ${code !== null && code !== void 0 ? code : 'unknown'}` : 'succeeded';
|
|
27917
28095
|
settleWithLog(status, () => {
|
|
27918
28096
|
if (!failure) {
|
|
@@ -27930,8 +28108,14 @@
|
|
|
27930
28108
|
});
|
|
27931
28109
|
commandProcess.on('error', (error) => {
|
|
27932
28110
|
const outputSnippet = createOutputSnippet(fullOutput);
|
|
27933
|
-
const
|
|
27934
|
-
|
|
28111
|
+
const failureMessage = outputSnippet
|
|
28112
|
+
? _spaceTrim.spaceTrim((block) => `
|
|
28113
|
+
Command "bash ${scriptPathPosix}" failed: ${error.message}
|
|
28114
|
+
|
|
28115
|
+
${block(outputSnippet)}
|
|
28116
|
+
`)
|
|
28117
|
+
: `Command "bash ${scriptPathPosix}" failed: ${error.message}`;
|
|
28118
|
+
const failure = new Error(failureMessage);
|
|
27935
28119
|
settleWithLog('failed before completion', () => reject(failure), failure);
|
|
27936
28120
|
});
|
|
27937
28121
|
});
|
|
@@ -28270,7 +28454,11 @@
|
|
|
28270
28454
|
if (normalized.length <= maxChars) {
|
|
28271
28455
|
return normalized;
|
|
28272
28456
|
}
|
|
28273
|
-
return
|
|
28457
|
+
return spaceTrim((block) => `
|
|
28458
|
+
${block(normalized.slice(0, maxChars))}
|
|
28459
|
+
|
|
28460
|
+
...[truncated]
|
|
28461
|
+
`);
|
|
28274
28462
|
}
|
|
28275
28463
|
/**
|
|
28276
28464
|
* Returns true if at least one regex matches the provided text.
|
|
@@ -34919,11 +35107,19 @@
|
|
|
34919
35107
|
try {
|
|
34920
35108
|
const json = JSON.parse(content);
|
|
34921
35109
|
const formattedJson = JSON.stringify(json, null, 4);
|
|
34922
|
-
return
|
|
35110
|
+
return _spaceTrim.spaceTrim((block) => `
|
|
35111
|
+
\`\`\`json
|
|
35112
|
+
${block(formattedJson)}
|
|
35113
|
+
\`\`\`
|
|
35114
|
+
`);
|
|
34923
35115
|
}
|
|
34924
35116
|
catch (error) {
|
|
34925
35117
|
// If JSON is invalid, still import it but maybe not as pretty JSON
|
|
34926
|
-
return
|
|
35118
|
+
return _spaceTrim.spaceTrim((block) => `
|
|
35119
|
+
\`\`\`json
|
|
35120
|
+
${block(content)}
|
|
35121
|
+
\`\`\`
|
|
35122
|
+
`);
|
|
34927
35123
|
}
|
|
34928
35124
|
},
|
|
34929
35125
|
};
|
|
@@ -34947,7 +35143,11 @@
|
|
|
34947
35143
|
import(content, mimeType) {
|
|
34948
35144
|
const extension = mimeTypeToExtension(mimeType);
|
|
34949
35145
|
const codeBlockType = extension || 'txt';
|
|
34950
|
-
return
|
|
35146
|
+
return _spaceTrim.spaceTrim((block) => `
|
|
35147
|
+
\`\`\`${codeBlockType}
|
|
35148
|
+
${block(content)}
|
|
35149
|
+
\`\`\`
|
|
35150
|
+
`);
|
|
34951
35151
|
},
|
|
34952
35152
|
};
|
|
34953
35153
|
|
|
@@ -35194,11 +35394,19 @@
|
|
|
35194
35394
|
const examples = [];
|
|
35195
35395
|
const initialMessage = (_a = parseResult.commitments.find((commitment) => commitment.type === 'INITIAL MESSAGE')) === null || _a === void 0 ? void 0 : _a.content;
|
|
35196
35396
|
if (initialMessage) {
|
|
35197
|
-
examples.push(
|
|
35397
|
+
examples.push(_spaceTrim.spaceTrim((block) => `
|
|
35398
|
+
**Agent:**
|
|
35399
|
+
${block(initialMessage)}
|
|
35400
|
+
`));
|
|
35198
35401
|
}
|
|
35199
35402
|
if (samples && samples.length > 0) {
|
|
35200
35403
|
for (const sample of samples) {
|
|
35201
|
-
examples.push(
|
|
35404
|
+
examples.push(_spaceTrim.spaceTrim((block) => `
|
|
35405
|
+
**User:** ${block(String(sample.question))}
|
|
35406
|
+
|
|
35407
|
+
**Agent:**
|
|
35408
|
+
${block(sample.answer)}
|
|
35409
|
+
`));
|
|
35202
35410
|
}
|
|
35203
35411
|
}
|
|
35204
35412
|
return examples;
|
|
@@ -35633,10 +35841,14 @@
|
|
|
35633
35841
|
* Formats prepared model requirements for a text-only CLI harness prompt.
|
|
35634
35842
|
*/
|
|
35635
35843
|
function formatAgentModelRequirementsForRunner(modelRequirements) {
|
|
35844
|
+
const promptSuffix = modelRequirements.promptSuffix.trim();
|
|
35636
35845
|
return [
|
|
35637
35846
|
modelRequirements.systemMessage.trim(),
|
|
35638
|
-
|
|
35639
|
-
?
|
|
35847
|
+
promptSuffix
|
|
35848
|
+
? _spaceTrim.spaceTrim((block) => `
|
|
35849
|
+
## Prompt suffix
|
|
35850
|
+
${block(promptSuffix)}
|
|
35851
|
+
`)
|
|
35640
35852
|
: '',
|
|
35641
35853
|
]
|
|
35642
35854
|
.filter(Boolean)
|
|
@@ -39289,7 +39501,7 @@
|
|
|
39289
39501
|
*/
|
|
39290
39502
|
const DEFAULT_CODER_PACKAGE_JSON_SCRIPTS = {
|
|
39291
39503
|
'coder:generate-boilerplates': 'ptbk coder generate-boilerplates --template ./prompts/templates/common.md',
|
|
39292
|
-
'coder:run': 'ptbk coder run --harness openai-codex --model gpt-5.4 --thinking-level xhigh --agent agents/developer.book --context AGENTS.md
|
|
39504
|
+
'coder:run': 'ptbk coder run --harness openai-codex --model gpt-5.4 --thinking-level xhigh --agent agents/developer.book --context AGENTS.md',
|
|
39293
39505
|
// 'coder:find-refactor-candidates': 'ptbk coder find-refactor-candidates',
|
|
39294
39506
|
'coder:verify': 'ptbk coder verify',
|
|
39295
39507
|
};
|
|
@@ -39748,33 +39960,26 @@
|
|
|
39748
39960
|
command.option('--preserve-logs', 'Keep generated temp prompt/log artifacts after successful rounds for debugging and analytics', false);
|
|
39749
39961
|
addPromptRunnerExecutionOptions(command);
|
|
39750
39962
|
command.option('--priority <minimum-priority>', 'Filter prompts by minimum priority level', parseIntOption$1, 0);
|
|
39751
|
-
command.option('--wait
|
|
39752
|
-
Wait between prompt rounds.
|
|
39753
|
-
|
|
39754
|
-
|
|
39755
|
-
|
|
39756
|
-
|
|
39757
|
-
command.option('--no-wait', 'Skip all waiting between prompts and run non-interactively');
|
|
39963
|
+
command.option('--wait <duration>', _spaceTrim.spaceTrim(`
|
|
39964
|
+
Wait this long between prompt rounds to avoid hitting rate limits of the harness.
|
|
39965
|
+
Accepts durations like 1h, 30m, 5s.
|
|
39966
|
+
`));
|
|
39967
|
+
// Note: --no-auto disables the default auto behaviour and waits for user confirmation before each prompt
|
|
39968
|
+
command.option('--no-auto', 'Wait for user confirmation before each prompt instead of running automatically through the queue');
|
|
39758
39969
|
command.option('--auto-migrate', 'Run testing-server database migrations automatically after each successfully processed prompt');
|
|
39759
39970
|
command.option('--allow-destructive-auto-migrate', 'Allow auto-migrate even when heuristic SQL safety check flags destructive pending migrations');
|
|
39760
39971
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
39761
|
-
const { dryRun, agent, context, test, preserveLogs, priority, wait, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
39972
|
+
const { dryRun, agent, context, test, preserveLogs, priority, wait, auto, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
39762
39973
|
const testCommand = normalizeCommandOptionValue$1(test);
|
|
39763
39974
|
const runnerOptions = normalizePromptRunnerCliOptions(cliOptions, {
|
|
39764
39975
|
isAgentRequired: !dryRun,
|
|
39765
39976
|
});
|
|
39766
|
-
// [1] Parse the --wait
|
|
39767
|
-
//
|
|
39768
|
-
//
|
|
39769
|
-
//
|
|
39770
|
-
|
|
39771
|
-
|
|
39772
|
-
if (wait === true) {
|
|
39773
|
-
waitForUser = true;
|
|
39774
|
-
}
|
|
39775
|
-
else if (typeof wait === 'string' && wait !== '') {
|
|
39776
|
-
waitBetweenPrompts = parseDuration(wait);
|
|
39777
|
-
}
|
|
39977
|
+
// [1] Parse the --wait and --no-auto options:
|
|
39978
|
+
// default: run automatically through the queue (no waiting)
|
|
39979
|
+
// --no-auto: wait for user confirmation before each prompt (interactive mode)
|
|
39980
|
+
// --wait <duration>: wait that long between prompt rounds to avoid rate limits
|
|
39981
|
+
const waitForUser = !auto;
|
|
39982
|
+
const waitBetweenPrompts = typeof wait === 'string' && wait !== '' ? parseDuration(wait) : 0;
|
|
39778
39983
|
// Convert commander options to RunOptions format
|
|
39779
39984
|
const runOptions = {
|
|
39780
39985
|
dryRun,
|
|
@@ -39887,30 +40092,23 @@
|
|
|
39887
40092
|
command.option('--preserve-logs', 'Keep generated temp prompt/log artifacts after successful rounds for debugging and analytics', false);
|
|
39888
40093
|
addPromptRunnerExecutionOptions(command);
|
|
39889
40094
|
command.option('--priority <minimum-priority>', 'Filter prompts by minimum priority level', parseIntOption, 0);
|
|
39890
|
-
command.option('--wait
|
|
39891
|
-
Wait between prompt rounds.
|
|
39892
|
-
|
|
39893
|
-
|
|
39894
|
-
|
|
39895
|
-
command.option('--no-wait', 'Skip all waiting between prompts and run non-interactively');
|
|
40095
|
+
command.option('--wait <duration>', _spaceTrim.spaceTrim(`
|
|
40096
|
+
Wait this long between prompt rounds to avoid hitting rate limits of the harness.
|
|
40097
|
+
Accepts durations like 1h, 30m, 5s.
|
|
40098
|
+
`));
|
|
40099
|
+
command.option('--no-auto', 'Wait for user confirmation before each prompt instead of running automatically through the queue');
|
|
39896
40100
|
command.option('--auto-migrate', 'Run testing-server database migrations automatically after each successfully processed prompt');
|
|
39897
40101
|
command.option('--allow-destructive-auto-migrate', 'Allow auto-migrate even when heuristic SQL safety check flags destructive pending migrations');
|
|
39898
40102
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
39899
|
-
const { port: rawPort, dryRun, agent, context, test, preserveLogs, priority, wait, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
40103
|
+
const { port: rawPort, dryRun, agent, context, test, preserveLogs, priority, wait, auto, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
39900
40104
|
const port = parseCoderServerPort(rawPort);
|
|
39901
40105
|
const testCommand = normalizeCommandOptionValue(test);
|
|
39902
40106
|
const runnerOptions = normalizePromptRunnerCliOptions(cliOptions, {
|
|
39903
40107
|
isAgentRequired: !dryRun,
|
|
39904
40108
|
});
|
|
39905
|
-
// [1] Parse the --wait
|
|
39906
|
-
|
|
39907
|
-
|
|
39908
|
-
if (wait === true) {
|
|
39909
|
-
waitForUser = true;
|
|
39910
|
-
}
|
|
39911
|
-
else if (typeof wait === 'string' && wait !== '') {
|
|
39912
|
-
waitBetweenPrompts = parseDuration(wait);
|
|
39913
|
-
}
|
|
40109
|
+
// [1] Parse the --wait and --no-auto options (same logic as `coder run`)
|
|
40110
|
+
const waitForUser = !auto;
|
|
40111
|
+
const waitBetweenPrompts = typeof wait === 'string' && wait !== '' ? parseDuration(wait) : 0;
|
|
39914
40112
|
const runOptions = {
|
|
39915
40113
|
port,
|
|
39916
40114
|
dryRun,
|
|
@@ -40516,7 +40714,12 @@
|
|
|
40516
40714
|
* @private internal function of `$registeredLlmToolsMessage`
|
|
40517
40715
|
*/
|
|
40518
40716
|
function createUsedEnvMessage() {
|
|
40519
|
-
return $usedEnvFilename === null
|
|
40717
|
+
return $usedEnvFilename === null
|
|
40718
|
+
? `Unknown \`.env\` file`
|
|
40719
|
+
: _spaceTrim.spaceTrim(`
|
|
40720
|
+
Used \`.env\` file:
|
|
40721
|
+
${$usedEnvFilename}
|
|
40722
|
+
`);
|
|
40520
40723
|
}
|
|
40521
40724
|
// TODO: [®] DRY Register logic
|
|
40522
40725
|
// TODO: [🧠][⚛] Maybe pass env as argument
|
|
@@ -53106,7 +53309,11 @@
|
|
|
53106
53309
|
* @private utility of CLI
|
|
53107
53310
|
*/
|
|
53108
53311
|
function $deprecateCliCommand(command, deprecationMessage) {
|
|
53109
|
-
command.description(
|
|
53312
|
+
command.description(_spaceTrim.spaceTrim((block) => `
|
|
53313
|
+
${block(command.description())}
|
|
53314
|
+
|
|
53315
|
+
Deprecated: ${block(deprecationMessage)}
|
|
53316
|
+
`));
|
|
53110
53317
|
command.hook('preAction', () => {
|
|
53111
53318
|
console.warn(colors__default["default"].yellow(createDeprecatedCliCommandWarning(command, deprecationMessage)));
|
|
53112
53319
|
});
|
|
@@ -65915,7 +66122,11 @@
|
|
|
65915
66122
|
};
|
|
65916
66123
|
}
|
|
65917
66124
|
return {
|
|
65918
|
-
content:
|
|
66125
|
+
content: _spaceTrim.spaceTrim((block) => `
|
|
66126
|
+
${block(content.slice(0, Math.max(0, maxCharacters)))}
|
|
66127
|
+
|
|
66128
|
+
[...truncated...]
|
|
66129
|
+
`),
|
|
65919
66130
|
isTruncated: true,
|
|
65920
66131
|
};
|
|
65921
66132
|
}
|
|
@@ -69215,7 +69426,7 @@
|
|
|
69215
69426
|
/**
|
|
69216
69427
|
* CLI usage text for this script.
|
|
69217
69428
|
*/
|
|
69218
|
-
const USAGE = 'Usage: run-codex-prompts [--dry-run] [--harness <harness-name>] [--model <model>] [--context <context-or-file>] [--test <test-command...>] [--preserve-logs] [--no-ui] [--thinking-level <thinking-level>] [--priority <minimum-priority>] [--allow-credits] [--auto-migrate] [--allow-destructive-auto-migrate] [--wait
|
|
69429
|
+
const USAGE = 'Usage: run-codex-prompts [--dry-run] [--harness <harness-name>] [--model <model>] [--context <context-or-file>] [--test <test-command...>] [--preserve-logs] [--no-ui] [--thinking-level <thinking-level>] [--priority <minimum-priority>] [--allow-credits] [--auto-migrate] [--allow-destructive-auto-migrate] [--wait <duration>] [--no-auto] [--no-commit] [--ignore-git-changes] [--no-normalize-line-endings] [--auto-push] [--auto-pull]';
|
|
69219
69430
|
/**
|
|
69220
69431
|
* Top-level flags supported by this command.
|
|
69221
69432
|
*/
|
|
@@ -69233,7 +69444,7 @@
|
|
|
69233
69444
|
'--auto-migrate',
|
|
69234
69445
|
'--allow-destructive-auto-migrate',
|
|
69235
69446
|
'--wait',
|
|
69236
|
-
'--no-
|
|
69447
|
+
'--no-auto',
|
|
69237
69448
|
'--no-commit',
|
|
69238
69449
|
'--ignore-git-changes',
|
|
69239
69450
|
'--no-normalize-line-endings',
|
|
@@ -69271,22 +69482,20 @@
|
|
|
69271
69482
|
const allowDestructiveAutoMigrate = args.includes('--allow-destructive-auto-migrate');
|
|
69272
69483
|
const autoPush = args.includes('--auto-push');
|
|
69273
69484
|
const autoPull = args.includes('--auto-pull');
|
|
69274
|
-
// [1] Parse --wait
|
|
69275
|
-
//
|
|
69276
|
-
// --
|
|
69485
|
+
// [1] Parse --wait <duration> and --no-auto:
|
|
69486
|
+
// default: run automatically through the queue (no waiting)
|
|
69487
|
+
// --no-auto: wait for user confirmation before each prompt (interactive mode)
|
|
69277
69488
|
// --wait 1h: wait 1h between prompt rounds to avoid rate limits
|
|
69278
|
-
const
|
|
69279
|
-
let waitForUser = false;
|
|
69489
|
+
const waitForUser = args.includes('--no-auto');
|
|
69280
69490
|
let waitBetweenPrompts = 0;
|
|
69281
|
-
|
|
69282
|
-
|
|
69283
|
-
|
|
69284
|
-
|
|
69285
|
-
|
|
69286
|
-
|
|
69287
|
-
waitBetweenPrompts = parseDuration(
|
|
69491
|
+
const hasWaitFlag = args.includes('--wait');
|
|
69492
|
+
const waitValue = readOptionValue(args, '--wait');
|
|
69493
|
+
if (hasWaitFlag) {
|
|
69494
|
+
if (waitValue === undefined || waitValue.startsWith('-')) {
|
|
69495
|
+
exitWithUsageError('Missing value for --wait. Use a duration like 1h, 30m, 5s.');
|
|
69496
|
+
}
|
|
69497
|
+
waitBetweenPrompts = parseDuration(waitValue);
|
|
69288
69498
|
}
|
|
69289
|
-
// --no-wait (or no flag): both waitForUser and waitBetweenPrompts remain false/0
|
|
69290
69499
|
let thinkingLevel;
|
|
69291
69500
|
if (hasTestCommandFlag && testCommand === undefined) {
|
|
69292
69501
|
exitWithUsageError('Missing value for --test. Use a shell command such as `npm run test` and quote it when it contains top-level CLI flags.');
|
|
@@ -69325,23 +69534,6 @@
|
|
|
69325
69534
|
priority,
|
|
69326
69535
|
};
|
|
69327
69536
|
}
|
|
69328
|
-
/**
|
|
69329
|
-
* Reads an optional value for a flag that may appear with or without a following value.
|
|
69330
|
-
*
|
|
69331
|
-
* Returns `undefined` when the flag is absent, `null` when the flag is present but has no value
|
|
69332
|
-
* (the next token is another flag or the end of args), and the value string otherwise.
|
|
69333
|
-
*/
|
|
69334
|
-
function readOptionalOptionValue(args, flag) {
|
|
69335
|
-
if (!args.includes(flag)) {
|
|
69336
|
-
return undefined;
|
|
69337
|
-
}
|
|
69338
|
-
const index = args.indexOf(flag);
|
|
69339
|
-
const nextArg = args[index + 1];
|
|
69340
|
-
if (nextArg === undefined || nextArg.startsWith('-')) {
|
|
69341
|
-
return null;
|
|
69342
|
-
}
|
|
69343
|
-
return nextArg;
|
|
69344
|
-
}
|
|
69345
69537
|
/**
|
|
69346
69538
|
* Reads a value of a CLI option that follows a given flag.
|
|
69347
69539
|
*/
|
|
@@ -71318,7 +71510,13 @@
|
|
|
71318
71510
|
const taskPrompt = buildCodexPrompt(nextPrompt.file, nextPrompt.section);
|
|
71319
71511
|
// Prepend agent system message before the task so the harness sees agent instructions first
|
|
71320
71512
|
const promptWithAgent = resolvedAgentSystemMessage
|
|
71321
|
-
?
|
|
71513
|
+
? _spaceTrim.spaceTrim((block) => `
|
|
71514
|
+
${block(resolvedAgentSystemMessage.trim())}
|
|
71515
|
+
|
|
71516
|
+
## Your Task
|
|
71517
|
+
|
|
71518
|
+
${block(taskPrompt)}
|
|
71519
|
+
`)
|
|
71322
71520
|
: taskPrompt;
|
|
71323
71521
|
const codexPrompt = appendCoderContext(promptWithAgent, resolvedCoderContext);
|
|
71324
71522
|
const scriptPath = buildScriptPath(nextPrompt.file, nextPrompt.section);
|
|
@@ -71387,11 +71585,11 @@
|
|
|
71387
71585
|
*/
|
|
71388
71586
|
function setPromptRoundRunningState(options) {
|
|
71389
71587
|
const { isRichUiEnabled, promptLabel, scriptPath, uiHandle } = options;
|
|
71588
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setCurrentPrompt(promptLabel);
|
|
71589
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setCurrentScriptPath(scriptPath);
|
|
71590
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setPhase('running');
|
|
71591
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setStatusMessage('Running');
|
|
71390
71592
|
if (isRichUiEnabled) {
|
|
71391
|
-
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setCurrentPrompt(promptLabel);
|
|
71392
|
-
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setCurrentScriptPath(scriptPath);
|
|
71393
|
-
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setPhase('running');
|
|
71394
|
-
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setStatusMessage('Running');
|
|
71395
71593
|
return;
|
|
71396
71594
|
}
|
|
71397
71595
|
console.info(colors__default["default"].blue(`Processing ${promptLabel}`));
|
|
@@ -71661,7 +71859,7 @@
|
|
|
71661
71859
|
}
|
|
71662
71860
|
if (options.noCommit && !options.waitForUser && !options.ignoreGitChanges) {
|
|
71663
71861
|
throw new NotAllowed(_spaceTrim.spaceTrim(`
|
|
71664
|
-
Flag \`--no-commit\` requires \`--ignore-git-changes\` when
|
|
71862
|
+
Flag \`--no-commit\` requires \`--ignore-git-changes\` when running in auto mode (the default; pass \`--no-auto\` for interactive confirmation).
|
|
71665
71863
|
|
|
71666
71864
|
Without commits, the next prompt round would fail the clean working tree check.
|
|
71667
71865
|
`));
|
|
@@ -71693,7 +71891,11 @@
|
|
|
71693
71891
|
function createRunDisplays(options, runStartDate) {
|
|
71694
71892
|
const isRichUiEnabled = !options.dryRun && !options.noUi && Boolean(process.stdout.isTTY);
|
|
71695
71893
|
const progressDisplay = options.dryRun || options.noUi || isRichUiEnabled ? undefined : new CliProgressDisplay(runStartDate, options.priority);
|
|
71696
|
-
const uiHandle = isRichUiEnabled
|
|
71894
|
+
const uiHandle = isRichUiEnabled || options.uiState
|
|
71895
|
+
? renderCoderRunUi(runStartDate, {
|
|
71896
|
+
state: options.uiState,
|
|
71897
|
+
})
|
|
71898
|
+
: undefined;
|
|
71697
71899
|
return {
|
|
71698
71900
|
isRichUiEnabled,
|
|
71699
71901
|
progressDisplay,
|
|
@@ -71758,6 +71960,7 @@
|
|
|
71758
71960
|
modelName: actualRunnerModel,
|
|
71759
71961
|
thinkingLevel: options.thinkingLevel,
|
|
71760
71962
|
context: options.context,
|
|
71963
|
+
serverUrl: options.serverUrl,
|
|
71761
71964
|
priority: options.priority,
|
|
71762
71965
|
testCommand: options.testCommand,
|
|
71763
71966
|
});
|
|
@@ -71916,6 +72119,166 @@
|
|
|
71916
72119
|
runCodexPrompts: runCodexPrompts
|
|
71917
72120
|
});
|
|
71918
72121
|
|
|
72122
|
+
/**
|
|
72123
|
+
* Converts parsed prompt files into a web-board response with derived columns and tags.
|
|
72124
|
+
*/
|
|
72125
|
+
function buildCoderServerPromptFileResponses(options) {
|
|
72126
|
+
const activePrompt = getActivePrompt(options.uiState);
|
|
72127
|
+
return [
|
|
72128
|
+
...options.promptFiles.map((promptFile) => buildCoderServerPromptFileResponse({
|
|
72129
|
+
promptFile,
|
|
72130
|
+
isFinished: false,
|
|
72131
|
+
minimumPriority: options.minimumPriority,
|
|
72132
|
+
activePrompt,
|
|
72133
|
+
})),
|
|
72134
|
+
...options.finishedPromptFiles.map((promptFile) => buildCoderServerPromptFileResponse({
|
|
72135
|
+
promptFile,
|
|
72136
|
+
isFinished: true,
|
|
72137
|
+
minimumPriority: options.minimumPriority,
|
|
72138
|
+
activePrompt,
|
|
72139
|
+
})),
|
|
72140
|
+
];
|
|
72141
|
+
}
|
|
72142
|
+
/**
|
|
72143
|
+
* Builds one prompt-file response.
|
|
72144
|
+
*/
|
|
72145
|
+
function buildCoderServerPromptFileResponse(options) {
|
|
72146
|
+
const { promptFile, isFinished, minimumPriority, activePrompt } = options;
|
|
72147
|
+
return {
|
|
72148
|
+
filePath: promptFile.path,
|
|
72149
|
+
fileName: promptFile.name,
|
|
72150
|
+
relativeFilePath: path.relative(process.cwd(), promptFile.path).replace(/\\/gu, '/'),
|
|
72151
|
+
isFinished,
|
|
72152
|
+
sections: promptFile.sections.map((section) => buildCoderServerPromptSectionResponse({
|
|
72153
|
+
promptFile,
|
|
72154
|
+
section,
|
|
72155
|
+
isFinished,
|
|
72156
|
+
minimumPriority,
|
|
72157
|
+
activePrompt,
|
|
72158
|
+
})),
|
|
72159
|
+
};
|
|
72160
|
+
}
|
|
72161
|
+
/**
|
|
72162
|
+
* Builds one prompt-section response with derived board metadata.
|
|
72163
|
+
*/
|
|
72164
|
+
function buildCoderServerPromptSectionResponse(options) {
|
|
72165
|
+
const { promptFile, section, isFinished, minimumPriority, activePrompt } = options;
|
|
72166
|
+
const isUnwritten = isPromptToBeWritten(promptFile, section);
|
|
72167
|
+
const isActive = isPromptActive(promptFile, section, activePrompt);
|
|
72168
|
+
const column = getPromptColumn({
|
|
72169
|
+
section,
|
|
72170
|
+
isFinished,
|
|
72171
|
+
isUnwritten,
|
|
72172
|
+
isActive,
|
|
72173
|
+
minimumPriority,
|
|
72174
|
+
});
|
|
72175
|
+
return {
|
|
72176
|
+
index: section.index,
|
|
72177
|
+
status: section.status,
|
|
72178
|
+
column,
|
|
72179
|
+
priority: section.priority,
|
|
72180
|
+
summary: buildPromptSummary(promptFile, section),
|
|
72181
|
+
content: buildCodexPrompt(promptFile, section),
|
|
72182
|
+
label: buildPromptLabelForDisplay(promptFile, section),
|
|
72183
|
+
tags: buildPromptTags({
|
|
72184
|
+
section,
|
|
72185
|
+
isUnwritten,
|
|
72186
|
+
isActive,
|
|
72187
|
+
activePrompt,
|
|
72188
|
+
}),
|
|
72189
|
+
};
|
|
72190
|
+
}
|
|
72191
|
+
/**
|
|
72192
|
+
* Chooses the web-board column for one prompt section without changing persisted prompt status.
|
|
72193
|
+
*/
|
|
72194
|
+
function getPromptColumn(options) {
|
|
72195
|
+
const { section, isFinished, isUnwritten, isActive, minimumPriority } = options;
|
|
72196
|
+
if (isFinished) {
|
|
72197
|
+
return 'finished';
|
|
72198
|
+
}
|
|
72199
|
+
if (section.status === 'failed') {
|
|
72200
|
+
return 'errors';
|
|
72201
|
+
}
|
|
72202
|
+
if (section.status === 'done') {
|
|
72203
|
+
return 'done';
|
|
72204
|
+
}
|
|
72205
|
+
if (section.status === 'not-ready' || isUnwritten) {
|
|
72206
|
+
return 'backlog';
|
|
72207
|
+
}
|
|
72208
|
+
if (isActive) {
|
|
72209
|
+
return 'in-progress';
|
|
72210
|
+
}
|
|
72211
|
+
if (!hasSufficientPriority(section, minimumPriority)) {
|
|
72212
|
+
return 'low-priority';
|
|
72213
|
+
}
|
|
72214
|
+
return 'todo';
|
|
72215
|
+
}
|
|
72216
|
+
/**
|
|
72217
|
+
* Builds all tags shown on a prompt card.
|
|
72218
|
+
*/
|
|
72219
|
+
function buildPromptTags(options) {
|
|
72220
|
+
var _a;
|
|
72221
|
+
const tags = [];
|
|
72222
|
+
if (options.section.status === 'not-ready') {
|
|
72223
|
+
tags.push({ id: 'not-ready', label: '[-]' });
|
|
72224
|
+
}
|
|
72225
|
+
if (options.isUnwritten) {
|
|
72226
|
+
tags.push({ id: 'unwritten', label: '@@@' });
|
|
72227
|
+
}
|
|
72228
|
+
if (options.isActive) {
|
|
72229
|
+
tags.push(((_a = options.activePrompt) === null || _a === void 0 ? void 0 : _a.phase) === 'verifying'
|
|
72230
|
+
? { id: 'verifying', label: 'Verifying' }
|
|
72231
|
+
: { id: 'implementing', label: 'Implementing' });
|
|
72232
|
+
}
|
|
72233
|
+
return tags;
|
|
72234
|
+
}
|
|
72235
|
+
/**
|
|
72236
|
+
* Extracts an active prompt only while an agent is implementing or verifying it.
|
|
72237
|
+
*/
|
|
72238
|
+
function getActivePrompt(uiState) {
|
|
72239
|
+
if (!(uiState === null || uiState === void 0 ? void 0 : uiState.currentPromptLabel)) {
|
|
72240
|
+
return undefined;
|
|
72241
|
+
}
|
|
72242
|
+
if (uiState.phase !== 'running' && uiState.phase !== 'verifying') {
|
|
72243
|
+
return undefined;
|
|
72244
|
+
}
|
|
72245
|
+
return {
|
|
72246
|
+
label: uiState.currentPromptLabel,
|
|
72247
|
+
phase: uiState.phase,
|
|
72248
|
+
};
|
|
72249
|
+
}
|
|
72250
|
+
/**
|
|
72251
|
+
* Checks whether a parsed section is the prompt currently handled by the active agent.
|
|
72252
|
+
*/
|
|
72253
|
+
function isPromptActive(promptFile, section, activePrompt) {
|
|
72254
|
+
if (!activePrompt || section.status !== 'todo') {
|
|
72255
|
+
return false;
|
|
72256
|
+
}
|
|
72257
|
+
return buildPromptLabelForDisplay(promptFile, section) === activePrompt.label;
|
|
72258
|
+
}
|
|
72259
|
+
// Note: [🟡] Code for CLI command [coder server](scripts/run-codex-prompts/server/buildCoderServerPromptResponse.ts) should never be published outside of `@promptbook/cli`
|
|
72260
|
+
|
|
72261
|
+
/**
|
|
72262
|
+
* Builds a plain JSON-safe snapshot from the shared terminal UI state.
|
|
72263
|
+
*/
|
|
72264
|
+
function buildCoderServerRunState(uiState) {
|
|
72265
|
+
return {
|
|
72266
|
+
config: uiState.config,
|
|
72267
|
+
phase: uiState.phase,
|
|
72268
|
+
currentPromptLabel: uiState.currentPromptLabel,
|
|
72269
|
+
currentAttempt: uiState.currentAttempt,
|
|
72270
|
+
maxAttempts: uiState.maxAttempts,
|
|
72271
|
+
statusMessage: uiState.statusMessage,
|
|
72272
|
+
detailLines: [...uiState.detailLines],
|
|
72273
|
+
agentStatusLines: [...uiState.agentStatusLines],
|
|
72274
|
+
agentStatusTableRows: [...uiState.agentStatusTableRows],
|
|
72275
|
+
agentOutputLines: [...uiState.agentOutputLines],
|
|
72276
|
+
errors: [...uiState.errors],
|
|
72277
|
+
progress: uiState.getProgress(),
|
|
72278
|
+
};
|
|
72279
|
+
}
|
|
72280
|
+
// Note: [🟡] Code for CLI command [coder server](scripts/run-codex-prompts/server/buildCoderServerRunState.ts) should never be published outside of `@promptbook/cli`
|
|
72281
|
+
|
|
71919
72282
|
/**
|
|
71920
72283
|
* Overwrites the body of one prompt section with new content, preserving the status line.
|
|
71921
72284
|
*
|
|
@@ -71928,9 +72291,14 @@
|
|
|
71928
72291
|
var _a;
|
|
71929
72292
|
const rawContent = await promises.readFile(filePath, 'utf-8');
|
|
71930
72293
|
const promptFile = parsePromptFile(filePath, rawContent);
|
|
71931
|
-
const section = promptFile.sections.find((
|
|
72294
|
+
const section = promptFile.sections.find((sectionCandidate) => sectionCandidate.index === sectionIndex);
|
|
71932
72295
|
if (!section) {
|
|
71933
|
-
throw new
|
|
72296
|
+
throw new NotFoundError(_spaceTrim.spaceTrim(`
|
|
72297
|
+
Prompt section \`${sectionIndex}\` was not found.
|
|
72298
|
+
|
|
72299
|
+
File:
|
|
72300
|
+
\`${filePath}\`
|
|
72301
|
+
`));
|
|
71934
72302
|
}
|
|
71935
72303
|
// Lines before the status line (usually empty lines at section start)
|
|
71936
72304
|
const linesBeforeStatus = section.statusLineIndex !== undefined
|
|
@@ -71957,7 +72325,11 @@
|
|
|
71957
72325
|
...promptFile.lines.slice(section.endLine + 1),
|
|
71958
72326
|
];
|
|
71959
72327
|
const updatedContent = updatedLines.join(promptFile.eol) + (promptFile.hasFinalEol ? promptFile.eol : '');
|
|
72328
|
+
if (updatedContent === rawContent) {
|
|
72329
|
+
return false;
|
|
72330
|
+
}
|
|
71960
72331
|
await promises.writeFile(filePath, updatedContent, 'utf-8');
|
|
72332
|
+
return true;
|
|
71961
72333
|
}
|
|
71962
72334
|
// Note: [🟡] Code for CLI command [coder server](scripts/run-codex-prompts/server/updatePromptSection.ts) should never be published outside of `@promptbook/cli`
|
|
71963
72335
|
|
|
@@ -71978,38 +72350,37 @@
|
|
|
71978
72350
|
<style>
|
|
71979
72351
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
71980
72352
|
body {
|
|
71981
|
-
font-family: -apple-system, BlinkMacSystemFont,
|
|
71982
|
-
background: #
|
|
71983
|
-
color: #
|
|
72353
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
72354
|
+
background: #f6f7f9;
|
|
72355
|
+
color: #1f2933;
|
|
71984
72356
|
min-height: 100vh;
|
|
71985
72357
|
}
|
|
71986
72358
|
|
|
71987
72359
|
header {
|
|
71988
|
-
background: #
|
|
72360
|
+
background: #22313f;
|
|
71989
72361
|
color: white;
|
|
71990
|
-
padding: 12px
|
|
72362
|
+
padding: 12px 18px;
|
|
71991
72363
|
display: flex;
|
|
71992
72364
|
align-items: center;
|
|
71993
72365
|
gap: 12px;
|
|
71994
72366
|
position: sticky;
|
|
71995
72367
|
top: 0;
|
|
71996
72368
|
z-index: 10;
|
|
71997
|
-
box-shadow: 0 2px
|
|
72369
|
+
box-shadow: 0 2px 10px rgba(15,23,42,0.22);
|
|
71998
72370
|
}
|
|
71999
|
-
header h1 { font-size: 17px; font-weight: 700; flex-shrink: 0; }
|
|
72371
|
+
header h1 { font-size: 17px; font-weight: 700; flex-shrink: 0; letter-spacing: 0; }
|
|
72000
72372
|
|
|
72001
72373
|
.status-badge {
|
|
72002
72374
|
padding: 3px 10px;
|
|
72003
|
-
border-radius:
|
|
72375
|
+
border-radius: 999px;
|
|
72004
72376
|
font-size: 11px;
|
|
72005
72377
|
font-weight: 700;
|
|
72006
|
-
letter-spacing: 0.5px;
|
|
72007
72378
|
text-transform: uppercase;
|
|
72008
72379
|
flex-shrink: 0;
|
|
72009
72380
|
}
|
|
72010
|
-
.status-RUNNING
|
|
72011
|
-
.status-PAUSING
|
|
72012
|
-
.status-PAUSED
|
|
72381
|
+
.status-RUNNING { background: #0b875b; color: white; }
|
|
72382
|
+
.status-PAUSING { background: #d97904; color: white; }
|
|
72383
|
+
.status-PAUSED { background: #b42318; color: white; }
|
|
72013
72384
|
|
|
72014
72385
|
#pause-label {
|
|
72015
72386
|
font-size: 12px;
|
|
@@ -72022,57 +72393,122 @@
|
|
|
72022
72393
|
}
|
|
72023
72394
|
|
|
72024
72395
|
.btn {
|
|
72025
|
-
padding: 6px
|
|
72026
|
-
border:
|
|
72396
|
+
padding: 6px 12px;
|
|
72397
|
+
border: 0;
|
|
72027
72398
|
border-radius: 4px;
|
|
72028
72399
|
cursor: pointer;
|
|
72029
72400
|
font-size: 13px;
|
|
72030
|
-
font-weight:
|
|
72031
|
-
transition: opacity 0.15s;
|
|
72401
|
+
font-weight: 700;
|
|
72402
|
+
transition: background 0.15s, opacity 0.15s;
|
|
72032
72403
|
flex-shrink: 0;
|
|
72033
72404
|
}
|
|
72034
|
-
.btn:
|
|
72035
|
-
.btn-pause
|
|
72036
|
-
.btn-resume { background: #
|
|
72405
|
+
.btn:disabled { opacity: 0.55; cursor: default; }
|
|
72406
|
+
.btn-pause { background: #ffd166; color: #1f2933; }
|
|
72407
|
+
.btn-resume { background: #0b875b; color: white; }
|
|
72408
|
+
.btn-save { background: #2563eb; color: white; }
|
|
72409
|
+
.btn-cancel { background: #edf0f4; color: #1f2933; }
|
|
72410
|
+
|
|
72411
|
+
.run-strip {
|
|
72412
|
+
background: white;
|
|
72413
|
+
border-bottom: 1px solid #d8dee8;
|
|
72414
|
+
padding: 12px 18px;
|
|
72415
|
+
display: grid;
|
|
72416
|
+
grid-template-columns: minmax(220px, 1.2fr) minmax(240px, 1fr) minmax(260px, 1.4fr);
|
|
72417
|
+
gap: 14px;
|
|
72418
|
+
align-items: center;
|
|
72419
|
+
}
|
|
72420
|
+
.run-title {
|
|
72421
|
+
font-size: 14px;
|
|
72422
|
+
font-weight: 700;
|
|
72423
|
+
overflow: hidden;
|
|
72424
|
+
text-overflow: ellipsis;
|
|
72425
|
+
white-space: nowrap;
|
|
72426
|
+
}
|
|
72427
|
+
.run-subtitle,
|
|
72428
|
+
.run-current,
|
|
72429
|
+
.run-output {
|
|
72430
|
+
color: #64748b;
|
|
72431
|
+
font-size: 12px;
|
|
72432
|
+
line-height: 1.45;
|
|
72433
|
+
overflow: hidden;
|
|
72434
|
+
}
|
|
72435
|
+
.run-current,
|
|
72436
|
+
.run-output {
|
|
72437
|
+
display: -webkit-box;
|
|
72438
|
+
-webkit-box-orient: vertical;
|
|
72439
|
+
-webkit-line-clamp: 2;
|
|
72440
|
+
}
|
|
72441
|
+
.progress-shell {
|
|
72442
|
+
display: grid;
|
|
72443
|
+
grid-template-columns: 1fr auto;
|
|
72444
|
+
gap: 8px;
|
|
72445
|
+
align-items: center;
|
|
72446
|
+
}
|
|
72447
|
+
.progress-track {
|
|
72448
|
+
height: 10px;
|
|
72449
|
+
background: #e4e9f0;
|
|
72450
|
+
border-radius: 999px;
|
|
72451
|
+
overflow: hidden;
|
|
72452
|
+
}
|
|
72453
|
+
.progress-fill {
|
|
72454
|
+
display: block;
|
|
72455
|
+
height: 100%;
|
|
72456
|
+
width: 0;
|
|
72457
|
+
background: linear-gradient(90deg, #0b875b, #2563eb);
|
|
72458
|
+
transition: width 0.2s;
|
|
72459
|
+
}
|
|
72460
|
+
.progress-label {
|
|
72461
|
+
color: #475569;
|
|
72462
|
+
font-size: 12px;
|
|
72463
|
+
font-weight: 700;
|
|
72464
|
+
min-width: 72px;
|
|
72465
|
+
text-align: right;
|
|
72466
|
+
}
|
|
72037
72467
|
|
|
72038
72468
|
.board {
|
|
72039
72469
|
display: flex;
|
|
72040
72470
|
gap: 14px;
|
|
72041
72471
|
padding: 16px;
|
|
72042
72472
|
overflow-x: auto;
|
|
72043
|
-
min-height: calc(100vh -
|
|
72473
|
+
min-height: calc(100vh - 119px);
|
|
72044
72474
|
align-items: flex-start;
|
|
72045
72475
|
}
|
|
72046
72476
|
|
|
72047
72477
|
.column {
|
|
72048
|
-
background: #
|
|
72049
|
-
border-
|
|
72478
|
+
background: #e9edf3;
|
|
72479
|
+
border-top: 4px solid #94a3b8;
|
|
72480
|
+
border-radius: 6px;
|
|
72050
72481
|
padding: 10px;
|
|
72051
72482
|
min-width: 250px;
|
|
72052
72483
|
width: 270px;
|
|
72053
72484
|
flex-shrink: 0;
|
|
72054
72485
|
}
|
|
72486
|
+
.column-backlog { border-top-color: #64748b; }
|
|
72487
|
+
.column-low-priority { border-top-color: #d97904; }
|
|
72488
|
+
.column-todo { border-top-color: #2563eb; }
|
|
72489
|
+
.column-in-progress { border-top-color: #7c3aed; }
|
|
72490
|
+
.column-done { border-top-color: #0b875b; }
|
|
72491
|
+
.column-errors { border-top-color: #b42318; }
|
|
72492
|
+
.column-finished { border-top-color: #0891b2; }
|
|
72055
72493
|
|
|
72056
72494
|
.column-header {
|
|
72057
72495
|
font-size: 12px;
|
|
72058
|
-
font-weight:
|
|
72496
|
+
font-weight: 800;
|
|
72059
72497
|
text-transform: uppercase;
|
|
72060
|
-
|
|
72061
|
-
color: #5e6c84;
|
|
72498
|
+
color: #475569;
|
|
72062
72499
|
margin-bottom: 10px;
|
|
72063
72500
|
display: flex;
|
|
72064
72501
|
align-items: center;
|
|
72065
72502
|
justify-content: space-between;
|
|
72503
|
+
gap: 8px;
|
|
72066
72504
|
}
|
|
72067
|
-
|
|
72068
72505
|
.column-count {
|
|
72069
|
-
background:
|
|
72070
|
-
border-radius:
|
|
72071
|
-
padding:
|
|
72506
|
+
background: rgba(255,255,255,0.72);
|
|
72507
|
+
border-radius: 999px;
|
|
72508
|
+
padding: 2px 8px;
|
|
72072
72509
|
font-size: 11px;
|
|
72073
|
-
color: #
|
|
72510
|
+
color: #475569;
|
|
72074
72511
|
}
|
|
72075
|
-
|
|
72076
72512
|
.column-cards { min-height: 40px; }
|
|
72077
72513
|
|
|
72078
72514
|
.card {
|
|
@@ -72080,57 +72516,61 @@
|
|
|
72080
72516
|
border-radius: 6px;
|
|
72081
72517
|
padding: 10px 12px;
|
|
72082
72518
|
margin-bottom: 8px;
|
|
72083
|
-
box-shadow: 0 1px 3px rgba(
|
|
72519
|
+
box-shadow: 0 1px 3px rgba(15,23,42,0.12);
|
|
72084
72520
|
cursor: pointer;
|
|
72085
|
-
|
|
72086
|
-
border-left: 3px solid transparent;
|
|
72087
|
-
}
|
|
72088
|
-
.card:hover {
|
|
72089
|
-
box-shadow: 0 4px 10px rgba(0,0,0,0.14);
|
|
72090
|
-
transform: translateY(-1px);
|
|
72521
|
+
border-left: 3px solid #94a3b8;
|
|
72091
72522
|
}
|
|
72092
|
-
.card
|
|
72093
|
-
.card-
|
|
72094
|
-
.card-
|
|
72095
|
-
.card-
|
|
72523
|
+
.card:hover { box-shadow: 0 4px 12px rgba(15,23,42,0.16); }
|
|
72524
|
+
.card-backlog { border-left-color: #64748b; }
|
|
72525
|
+
.card-low-priority { border-left-color: #d97904; }
|
|
72526
|
+
.card-todo { border-left-color: #2563eb; }
|
|
72527
|
+
.card-in-progress { border-left-color: #7c3aed; }
|
|
72528
|
+
.card-done { border-left-color: #0b875b; }
|
|
72529
|
+
.card-errors { border-left-color: #b42318; }
|
|
72530
|
+
.card-finished { border-left-color: #0891b2; }
|
|
72096
72531
|
|
|
72097
72532
|
.card-file {
|
|
72098
72533
|
font-size: 10px;
|
|
72099
|
-
color: #
|
|
72100
|
-
margin-bottom:
|
|
72101
|
-
font-weight:
|
|
72534
|
+
color: #7b8794;
|
|
72535
|
+
margin-bottom: 6px;
|
|
72536
|
+
font-weight: 600;
|
|
72537
|
+
overflow: hidden;
|
|
72538
|
+
text-overflow: ellipsis;
|
|
72539
|
+
white-space: nowrap;
|
|
72102
72540
|
}
|
|
72103
|
-
|
|
72104
72541
|
.card-summary {
|
|
72105
72542
|
font-size: 13px;
|
|
72106
|
-
line-height: 1.
|
|
72107
|
-
color: #
|
|
72543
|
+
line-height: 1.45;
|
|
72544
|
+
color: #1f2933;
|
|
72108
72545
|
word-break: break-word;
|
|
72109
72546
|
white-space: pre-wrap;
|
|
72110
|
-
max-height:
|
|
72547
|
+
max-height: 76px;
|
|
72111
72548
|
overflow: hidden;
|
|
72112
72549
|
display: -webkit-box;
|
|
72113
72550
|
-webkit-line-clamp: 4;
|
|
72114
72551
|
-webkit-box-orient: vertical;
|
|
72115
72552
|
}
|
|
72116
|
-
|
|
72117
|
-
|
|
72118
|
-
|
|
72119
|
-
|
|
72120
|
-
|
|
72121
|
-
font-weight: 700;
|
|
72553
|
+
.card-tags {
|
|
72554
|
+
display: flex;
|
|
72555
|
+
flex-wrap: wrap;
|
|
72556
|
+
gap: 5px;
|
|
72557
|
+
margin-top: 8px;
|
|
72122
72558
|
}
|
|
72123
|
-
|
|
72124
|
-
|
|
72559
|
+
.card-tag {
|
|
72560
|
+
border-radius: 999px;
|
|
72561
|
+
padding: 2px 7px;
|
|
72125
72562
|
font-size: 10px;
|
|
72126
|
-
|
|
72127
|
-
|
|
72128
|
-
display: none;
|
|
72563
|
+
font-weight: 800;
|
|
72564
|
+
line-height: 1.35;
|
|
72129
72565
|
}
|
|
72130
|
-
.
|
|
72566
|
+
.tag-not-ready { background: #e2e8f0; color: #475569; }
|
|
72567
|
+
.tag-unwritten { background: #fff4cc; color: #8a5a00; }
|
|
72568
|
+
.tag-implementing { background: #ede9fe; color: #5b21b6; }
|
|
72569
|
+
.tag-verifying { background: #fae8ff; color: #86198f; }
|
|
72570
|
+
.tag-priority { background: #ffedd5; color: #9a3412; }
|
|
72131
72571
|
|
|
72132
72572
|
.empty-column {
|
|
72133
|
-
color: #
|
|
72573
|
+
color: #94a3b8;
|
|
72134
72574
|
font-size: 12px;
|
|
72135
72575
|
padding: 10px 4px;
|
|
72136
72576
|
text-align: center;
|
|
@@ -72139,29 +72579,23 @@
|
|
|
72139
72579
|
.modal-overlay {
|
|
72140
72580
|
position: fixed;
|
|
72141
72581
|
inset: 0;
|
|
72142
|
-
background: rgba(
|
|
72582
|
+
background: rgba(15,23,42,0.58);
|
|
72143
72583
|
display: flex;
|
|
72144
72584
|
align-items: flex-start;
|
|
72145
72585
|
justify-content: center;
|
|
72146
|
-
padding:
|
|
72586
|
+
padding: 56px 16px 16px;
|
|
72147
72587
|
z-index: 100;
|
|
72148
|
-
animation: fadeIn 0.1s ease;
|
|
72149
72588
|
}
|
|
72150
72589
|
.modal-overlay.hidden { display: none; }
|
|
72151
72590
|
|
|
72152
|
-
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
|
72153
|
-
|
|
72154
72591
|
.modal {
|
|
72155
72592
|
background: white;
|
|
72156
72593
|
border-radius: 8px;
|
|
72157
72594
|
width: 100%;
|
|
72158
|
-
max-width:
|
|
72159
|
-
padding:
|
|
72160
|
-
box-shadow: 0
|
|
72161
|
-
animation: slideIn 0.15s ease;
|
|
72595
|
+
max-width: 720px;
|
|
72596
|
+
padding: 18px;
|
|
72597
|
+
box-shadow: 0 14px 40px rgba(15,23,42,0.28);
|
|
72162
72598
|
}
|
|
72163
|
-
@keyframes slideIn { from { transform: translateY(-8px); opacity: 0; } to { transform: none; opacity: 1; } }
|
|
72164
|
-
|
|
72165
72599
|
.modal-header {
|
|
72166
72600
|
display: flex;
|
|
72167
72601
|
align-items: flex-start;
|
|
@@ -72169,62 +72603,59 @@
|
|
|
72169
72603
|
margin-bottom: 14px;
|
|
72170
72604
|
gap: 12px;
|
|
72171
72605
|
}
|
|
72172
|
-
|
|
72173
72606
|
.modal-meta { flex: 1; min-width: 0; }
|
|
72174
|
-
.modal-file {
|
|
72175
|
-
|
|
72176
|
-
|
|
72607
|
+
.modal-file {
|
|
72608
|
+
font-size: 11px;
|
|
72609
|
+
color: #7b8794;
|
|
72610
|
+
margin-bottom: 4px;
|
|
72611
|
+
overflow: hidden;
|
|
72612
|
+
text-overflow: ellipsis;
|
|
72613
|
+
white-space: nowrap;
|
|
72614
|
+
}
|
|
72615
|
+
.modal-section-label { font-size: 14px; font-weight: 700; color: #1f2933; }
|
|
72177
72616
|
.modal-status {
|
|
72178
72617
|
font-size: 11px;
|
|
72179
|
-
font-weight:
|
|
72180
|
-
padding:
|
|
72181
|
-
border-radius:
|
|
72618
|
+
font-weight: 800;
|
|
72619
|
+
padding: 3px 8px;
|
|
72620
|
+
border-radius: 999px;
|
|
72182
72621
|
text-transform: uppercase;
|
|
72183
|
-
letter-spacing: 0.4px;
|
|
72184
72622
|
flex-shrink: 0;
|
|
72185
72623
|
}
|
|
72186
|
-
.status-
|
|
72187
|
-
.status-
|
|
72188
|
-
.status-
|
|
72189
|
-
.status-
|
|
72190
|
-
|
|
72624
|
+
.status-backlog { background: #e2e8f0; color: #475569; }
|
|
72625
|
+
.status-low-priority { background: #ffedd5; color: #9a3412; }
|
|
72626
|
+
.status-todo { background: #dbeafe; color: #1d4ed8; }
|
|
72627
|
+
.status-in-progress { background: #ede9fe; color: #5b21b6; }
|
|
72628
|
+
.status-done { background: #dcfce7; color: #166534; }
|
|
72629
|
+
.status-errors { background: #fee2e2; color: #991b1b; }
|
|
72630
|
+
.status-finished { background: #cffafe; color: #155e75; }
|
|
72191
72631
|
.modal-close {
|
|
72192
|
-
background:
|
|
72193
|
-
border:
|
|
72194
|
-
color: #
|
|
72632
|
+
background: transparent;
|
|
72633
|
+
border: 0;
|
|
72634
|
+
color: #64748b;
|
|
72195
72635
|
cursor: pointer;
|
|
72196
|
-
font-size:
|
|
72636
|
+
font-size: 20px;
|
|
72197
72637
|
padding: 0 4px;
|
|
72198
72638
|
line-height: 1;
|
|
72199
|
-
flex-shrink: 0;
|
|
72200
72639
|
}
|
|
72201
|
-
.modal-close:hover { color: #
|
|
72640
|
+
.modal-close:hover { color: #1f2933; }
|
|
72202
72641
|
|
|
72203
72642
|
textarea {
|
|
72204
72643
|
width: 100%;
|
|
72205
|
-
min-height:
|
|
72206
|
-
font-family:
|
|
72644
|
+
min-height: 300px;
|
|
72645
|
+
font-family: "SFMono-Regular", Consolas, "Courier New", monospace;
|
|
72207
72646
|
font-size: 13px;
|
|
72208
|
-
border: 2px solid #
|
|
72647
|
+
border: 2px solid #d8dee8;
|
|
72209
72648
|
border-radius: 4px;
|
|
72210
72649
|
padding: 10px 12px;
|
|
72211
72650
|
resize: vertical;
|
|
72212
|
-
line-height: 1.
|
|
72213
|
-
color: #
|
|
72214
|
-
transition: border-color 0.15s;
|
|
72651
|
+
line-height: 1.6;
|
|
72652
|
+
color: #1f2933;
|
|
72215
72653
|
}
|
|
72216
72654
|
textarea:focus {
|
|
72217
72655
|
outline: none;
|
|
72218
|
-
border-color: #
|
|
72219
|
-
box-shadow: 0 0 0 3px rgba(
|
|
72656
|
+
border-color: #2563eb;
|
|
72657
|
+
box-shadow: 0 0 0 3px rgba(37,99,235,0.12);
|
|
72220
72658
|
}
|
|
72221
|
-
|
|
72222
|
-
.modal-hint {
|
|
72223
|
-
font-size: 11px;
|
|
72224
|
-
color: #8993a4;
|
|
72225
|
-
margin-top: 6px;
|
|
72226
|
-
}
|
|
72227
|
-
|
|
72228
72659
|
.modal-actions {
|
|
72229
72660
|
display: flex;
|
|
72230
72661
|
gap: 8px;
|
|
@@ -72232,67 +72663,50 @@
|
|
|
72232
72663
|
justify-content: flex-end;
|
|
72233
72664
|
}
|
|
72234
72665
|
|
|
72235
|
-
.btn-save { background: #0052cc; color: white; }
|
|
72236
|
-
.btn-cancel { background: #f4f5f7; color: #172b4d; }
|
|
72237
|
-
.btn-cancel:hover { background: #ebecf0; opacity: 1; }
|
|
72238
|
-
|
|
72239
72666
|
.error-banner {
|
|
72240
|
-
background: #
|
|
72241
|
-
border-bottom: 2px solid #
|
|
72242
|
-
color: #
|
|
72243
|
-
padding: 8px
|
|
72667
|
+
background: #fee2e2;
|
|
72668
|
+
border-bottom: 2px solid #b42318;
|
|
72669
|
+
color: #991b1b;
|
|
72670
|
+
padding: 8px 18px;
|
|
72244
72671
|
font-size: 13px;
|
|
72245
|
-
font-weight:
|
|
72672
|
+
font-weight: 700;
|
|
72246
72673
|
}
|
|
72247
72674
|
.error-banner.hidden { display: none; }
|
|
72675
|
+
|
|
72676
|
+
@media (max-width: 860px) {
|
|
72677
|
+
header { flex-wrap: wrap; }
|
|
72678
|
+
#pause-label { order: 4; flex-basis: 100%; }
|
|
72679
|
+
.run-strip { grid-template-columns: 1fr; }
|
|
72680
|
+
.board { min-height: calc(100vh - 212px); }
|
|
72681
|
+
}
|
|
72248
72682
|
</style>
|
|
72249
72683
|
</head>
|
|
72250
72684
|
<body>
|
|
72251
|
-
|
|
72252
72685
|
<div id="error-banner" class="error-banner hidden"></div>
|
|
72253
72686
|
|
|
72254
72687
|
<header>
|
|
72255
|
-
<h1
|
|
72688
|
+
<h1>Ptbk Coder Server</h1>
|
|
72256
72689
|
<span id="status-badge" class="status-badge status-RUNNING">RUNNING</span>
|
|
72257
72690
|
<span id="pause-label"></span>
|
|
72258
|
-
<button id="toggle-btn" class="btn btn-pause"
|
|
72691
|
+
<button id="toggle-btn" class="btn btn-pause">Pause</button>
|
|
72259
72692
|
</header>
|
|
72260
72693
|
|
|
72261
|
-
<
|
|
72262
|
-
<div
|
|
72263
|
-
<div class="
|
|
72264
|
-
|
|
72265
|
-
<span class="column-count" id="count-todo">0</span>
|
|
72266
|
-
</div>
|
|
72267
|
-
<div class="column-cards" id="cards-todo">
|
|
72268
|
-
<div class="empty-column">Loading…</div>
|
|
72269
|
-
</div>
|
|
72694
|
+
<section class="run-strip">
|
|
72695
|
+
<div>
|
|
72696
|
+
<div class="run-title" id="run-title">Initializing...</div>
|
|
72697
|
+
<div class="run-subtitle" id="run-subtitle">Loading runner state</div>
|
|
72270
72698
|
</div>
|
|
72271
|
-
|
|
72272
|
-
|
|
72273
|
-
<div class="
|
|
72274
|
-
Not Ready
|
|
72275
|
-
<span class="column-count" id="count-not-ready">0</span>
|
|
72276
|
-
</div>
|
|
72277
|
-
<div class="column-cards" id="cards-not-ready"></div>
|
|
72699
|
+
<div class="progress-shell">
|
|
72700
|
+
<div class="progress-track"><span class="progress-fill" id="progress-fill"></span></div>
|
|
72701
|
+
<div class="progress-label" id="progress-label">0%</div>
|
|
72278
72702
|
</div>
|
|
72279
|
-
|
|
72280
|
-
|
|
72281
|
-
<div class="
|
|
72282
|
-
Done
|
|
72283
|
-
<span class="column-count" id="count-done">0</span>
|
|
72284
|
-
</div>
|
|
72285
|
-
<div class="column-cards" id="cards-done"></div>
|
|
72703
|
+
<div>
|
|
72704
|
+
<div class="run-current" id="run-current">No active prompt</div>
|
|
72705
|
+
<div class="run-output" id="run-output"></div>
|
|
72286
72706
|
</div>
|
|
72707
|
+
</section>
|
|
72287
72708
|
|
|
72288
|
-
|
|
72289
|
-
<div class="column-header">
|
|
72290
|
-
Failed
|
|
72291
|
-
<span class="column-count" id="count-failed">0</span>
|
|
72292
|
-
</div>
|
|
72293
|
-
<div class="column-cards" id="cards-failed"></div>
|
|
72294
|
-
</div>
|
|
72295
|
-
</div>
|
|
72709
|
+
<div class="board" id="board"></div>
|
|
72296
72710
|
|
|
72297
72711
|
<div class="modal-overlay hidden" id="modal-overlay">
|
|
72298
72712
|
<div class="modal">
|
|
@@ -72302,196 +72716,317 @@
|
|
|
72302
72716
|
<div class="modal-section-label" id="modal-section-label"></div>
|
|
72303
72717
|
</div>
|
|
72304
72718
|
<span class="modal-status" id="modal-status-badge"></span>
|
|
72305
|
-
<button class="modal-close"
|
|
72719
|
+
<button class="modal-close" id="modal-close" title="Close">×</button>
|
|
72306
72720
|
</div>
|
|
72307
72721
|
|
|
72308
|
-
<textarea id="modal-content" placeholder="Prompt content
|
|
72309
|
-
<div class="modal-hint">Tip: press Ctrl+Enter to save, Esc to cancel.</div>
|
|
72722
|
+
<textarea id="modal-content" placeholder="Prompt content"></textarea>
|
|
72310
72723
|
|
|
72311
72724
|
<div class="modal-actions">
|
|
72312
|
-
<button class="btn btn-cancel"
|
|
72313
|
-
<button class="btn btn-save"
|
|
72725
|
+
<button class="btn btn-cancel" id="cancel-button">Cancel</button>
|
|
72726
|
+
<button class="btn btn-save" id="save-button">Save</button>
|
|
72314
72727
|
</div>
|
|
72315
72728
|
</div>
|
|
72316
72729
|
</div>
|
|
72317
72730
|
|
|
72318
72731
|
<script>
|
|
72319
|
-
|
|
72732
|
+
"use strict";
|
|
72733
|
+
|
|
72734
|
+
const BOARD_COLUMNS = [
|
|
72735
|
+
{ id: "backlog", title: "Backlog" },
|
|
72736
|
+
{ id: "low-priority", title: "Low priority" },
|
|
72737
|
+
{ id: "todo", title: "To do" },
|
|
72738
|
+
{ id: "in-progress", title: "In progress" },
|
|
72739
|
+
{ id: "done", title: "Done" },
|
|
72740
|
+
{ id: "errors", title: "Errors" },
|
|
72741
|
+
{ id: "finished", title: "Finished" },
|
|
72742
|
+
];
|
|
72320
72743
|
|
|
72321
72744
|
let modalState = null;
|
|
72322
|
-
let lastPauseState =
|
|
72745
|
+
let lastPauseState = "RUNNING";
|
|
72746
|
+
|
|
72747
|
+
function getColumnTitle(columnId) {
|
|
72748
|
+
const column = BOARD_COLUMNS.find((columnCandidate) => columnCandidate.id === columnId);
|
|
72749
|
+
return column ? column.title : columnId;
|
|
72750
|
+
}
|
|
72751
|
+
|
|
72752
|
+
function showError(message) {
|
|
72753
|
+
const banner = document.getElementById("error-banner");
|
|
72754
|
+
banner.textContent = message;
|
|
72755
|
+
banner.classList.remove("hidden");
|
|
72756
|
+
clearTimeout(banner.timer);
|
|
72757
|
+
banner.timer = setTimeout(() => banner.classList.add("hidden"), 6000);
|
|
72758
|
+
}
|
|
72759
|
+
|
|
72760
|
+
function escapeHtml(value) {
|
|
72761
|
+
const element = document.createElement("div");
|
|
72762
|
+
element.textContent = String(value);
|
|
72763
|
+
return element.innerHTML;
|
|
72764
|
+
}
|
|
72765
|
+
|
|
72766
|
+
function renderBoardSkeleton() {
|
|
72767
|
+
const board = document.getElementById("board");
|
|
72768
|
+
board.innerHTML = "";
|
|
72769
|
+
|
|
72770
|
+
for (const column of BOARD_COLUMNS) {
|
|
72771
|
+
const columnElement = document.createElement("section");
|
|
72772
|
+
columnElement.className = "column column-" + column.id;
|
|
72773
|
+
columnElement.innerHTML =
|
|
72774
|
+
'<div class="column-header">' +
|
|
72775
|
+
'<span>' + escapeHtml(column.title) + '</span>' +
|
|
72776
|
+
'<span class="column-count" id="count-' + column.id + '">0</span>' +
|
|
72777
|
+
'</div>' +
|
|
72778
|
+
'<div class="column-cards" id="cards-' + column.id + '">' +
|
|
72779
|
+
'<div class="empty-column">Loading</div>' +
|
|
72780
|
+
'</div>';
|
|
72781
|
+
board.appendChild(columnElement);
|
|
72782
|
+
}
|
|
72783
|
+
}
|
|
72323
72784
|
|
|
72324
|
-
function
|
|
72325
|
-
|
|
72326
|
-
|
|
72327
|
-
|
|
72328
|
-
|
|
72329
|
-
|
|
72785
|
+
async function fetchStatus() {
|
|
72786
|
+
try {
|
|
72787
|
+
const response = await fetch("/api/status");
|
|
72788
|
+
if (!response.ok) {
|
|
72789
|
+
showError("Status API error: " + response.status);
|
|
72790
|
+
return;
|
|
72791
|
+
}
|
|
72792
|
+
|
|
72793
|
+
const status = await response.json();
|
|
72794
|
+
renderPauseState(status);
|
|
72795
|
+
renderRunState(status.runState);
|
|
72796
|
+
} catch (error) {
|
|
72797
|
+
showError("Could not reach coder server: " + error.message);
|
|
72798
|
+
}
|
|
72330
72799
|
}
|
|
72331
72800
|
|
|
72332
|
-
function
|
|
72333
|
-
|
|
72334
|
-
|
|
72335
|
-
|
|
72801
|
+
function renderPauseState(status) {
|
|
72802
|
+
lastPauseState = status.pauseState;
|
|
72803
|
+
|
|
72804
|
+
const badge = document.getElementById("status-badge");
|
|
72805
|
+
badge.textContent = status.pauseState;
|
|
72806
|
+
badge.className = "status-badge status-" + status.pauseState;
|
|
72807
|
+
|
|
72808
|
+
const toggleButton = document.getElementById("toggle-btn");
|
|
72809
|
+
const pauseLabel = document.getElementById("pause-label");
|
|
72810
|
+
|
|
72811
|
+
if (status.pauseState === "RUNNING") {
|
|
72812
|
+
toggleButton.textContent = "Pause";
|
|
72813
|
+
toggleButton.className = "btn btn-pause";
|
|
72814
|
+
pauseLabel.textContent = "";
|
|
72815
|
+
return;
|
|
72816
|
+
}
|
|
72817
|
+
|
|
72818
|
+
toggleButton.textContent = "Resume";
|
|
72819
|
+
toggleButton.className = "btn btn-resume";
|
|
72820
|
+
pauseLabel.textContent =
|
|
72821
|
+
(status.pauseState === "PAUSING" ? "Pausing before: " : "Paused before: ") +
|
|
72822
|
+
(status.pauseTargetLabel || "next checkpoint");
|
|
72336
72823
|
}
|
|
72337
72824
|
|
|
72338
|
-
|
|
72339
|
-
|
|
72340
|
-
|
|
72341
|
-
|
|
72342
|
-
|
|
72343
|
-
|
|
72344
|
-
lastPauseState = data.pauseState;
|
|
72345
|
-
|
|
72346
|
-
const badge = document.getElementById('status-badge');
|
|
72347
|
-
badge.textContent = data.pauseState;
|
|
72348
|
-
badge.className = 'status-badge status-' + data.pauseState;
|
|
72349
|
-
|
|
72350
|
-
const btn = document.getElementById('toggle-btn');
|
|
72351
|
-
const label = document.getElementById('pause-label');
|
|
72352
|
-
|
|
72353
|
-
if (data.pauseState === 'RUNNING') {
|
|
72354
|
-
btn.textContent = '\\u23f8 Pause';
|
|
72355
|
-
btn.className = 'btn btn-pause';
|
|
72356
|
-
label.textContent = '';
|
|
72357
|
-
} else if (data.pauseState === 'PAUSING') {
|
|
72358
|
-
btn.textContent = '\\u23f5 Resume';
|
|
72359
|
-
btn.className = 'btn btn-resume';
|
|
72360
|
-
label.textContent = 'Pausing before: ' + (data.pauseTargetLabel || '\\u2026');
|
|
72361
|
-
} else {
|
|
72362
|
-
btn.textContent = '\\u23f5 Resume';
|
|
72363
|
-
btn.className = 'btn btn-resume';
|
|
72364
|
-
label.textContent = 'Paused before: ' + (data.pauseTargetLabel || '\\u2026');
|
|
72365
|
-
}
|
|
72366
|
-
} catch (e) {
|
|
72367
|
-
showError('Could not reach coder server: ' + e.message);
|
|
72825
|
+
function renderRunState(runState) {
|
|
72826
|
+
if (!runState) {
|
|
72827
|
+
document.getElementById("run-title").textContent = "Waiting for runner state";
|
|
72828
|
+
document.getElementById("run-subtitle").textContent = "";
|
|
72829
|
+
return;
|
|
72368
72830
|
}
|
|
72831
|
+
|
|
72832
|
+
const progress = runState.progress || {};
|
|
72833
|
+
const percentage = Number(progress.percentage || 0);
|
|
72834
|
+
const runnerParts = [runState.config.agentName, runState.config.modelName, runState.config.thinkingLevel]
|
|
72835
|
+
.filter(Boolean);
|
|
72836
|
+
|
|
72837
|
+
document.getElementById("run-title").textContent = runState.statusMessage || runState.phase;
|
|
72838
|
+
document.getElementById("run-subtitle").textContent = runnerParts.join(" / ");
|
|
72839
|
+
document.getElementById("progress-fill").style.width = Math.max(0, Math.min(100, percentage)) + "%";
|
|
72840
|
+
document.getElementById("progress-label").textContent =
|
|
72841
|
+
percentage + "% " + (progress.sessionDone || 0) + "/" + (progress.sessionTotal || 0);
|
|
72842
|
+
document.getElementById("run-current").textContent = runState.currentPromptLabel
|
|
72843
|
+
? runState.currentPromptLabel + " - attempt " + runState.currentAttempt + "/" + runState.maxAttempts
|
|
72844
|
+
: "No active prompt";
|
|
72845
|
+
|
|
72846
|
+
renderRunOutput(runState);
|
|
72847
|
+
}
|
|
72848
|
+
|
|
72849
|
+
function renderRunOutput(runState) {
|
|
72850
|
+
const statusLines = (runState.agentStatusTableRows || []).map((row) =>
|
|
72851
|
+
row.status + " - " + row.agentName + (row.url ? " - " + row.url : "")
|
|
72852
|
+
);
|
|
72853
|
+
const outputLines = [
|
|
72854
|
+
...(runState.agentStatusLines || []),
|
|
72855
|
+
...statusLines,
|
|
72856
|
+
...(runState.agentOutputLines || []),
|
|
72857
|
+
...(runState.errors || []).map((errorLine) => "Error: " + errorLine),
|
|
72858
|
+
].slice(-3);
|
|
72859
|
+
|
|
72860
|
+
document.getElementById("run-output").textContent = outputLines.join("\\n");
|
|
72369
72861
|
}
|
|
72370
72862
|
|
|
72371
72863
|
async function fetchPrompts() {
|
|
72372
72864
|
try {
|
|
72373
|
-
const
|
|
72374
|
-
if (!
|
|
72375
|
-
|
|
72376
|
-
|
|
72377
|
-
|
|
72865
|
+
const response = await fetch("/api/prompts");
|
|
72866
|
+
if (!response.ok) {
|
|
72867
|
+
showError("Prompts API error: " + response.status);
|
|
72868
|
+
return;
|
|
72869
|
+
}
|
|
72870
|
+
|
|
72871
|
+
renderBoard(await response.json());
|
|
72872
|
+
} catch (error) {
|
|
72873
|
+
showError("Could not load prompts: " + error.message);
|
|
72378
72874
|
}
|
|
72379
72875
|
}
|
|
72380
72876
|
|
|
72381
72877
|
function renderBoard(promptFiles) {
|
|
72382
|
-
const columns =
|
|
72878
|
+
const columns = Object.fromEntries(BOARD_COLUMNS.map((column) => [column.id, []]));
|
|
72383
72879
|
|
|
72384
72880
|
for (const file of promptFiles) {
|
|
72385
72881
|
for (const section of file.sections) {
|
|
72386
|
-
|
|
72387
|
-
|
|
72882
|
+
if (columns[section.column]) {
|
|
72883
|
+
columns[section.column].push({ file, section });
|
|
72884
|
+
}
|
|
72388
72885
|
}
|
|
72389
72886
|
}
|
|
72390
72887
|
|
|
72391
|
-
for (const
|
|
72392
|
-
|
|
72393
|
-
|
|
72394
|
-
|
|
72888
|
+
for (const column of BOARD_COLUMNS) {
|
|
72889
|
+
renderColumn(column.id, columns[column.id]);
|
|
72890
|
+
}
|
|
72891
|
+
}
|
|
72395
72892
|
|
|
72396
|
-
|
|
72397
|
-
|
|
72893
|
+
function renderColumn(columnId, cards) {
|
|
72894
|
+
const container = document.getElementById("cards-" + columnId);
|
|
72895
|
+
const countElement = document.getElementById("count-" + columnId);
|
|
72398
72896
|
|
|
72399
|
-
|
|
72400
|
-
|
|
72401
|
-
continue;
|
|
72402
|
-
}
|
|
72897
|
+
countElement.textContent = cards.length;
|
|
72898
|
+
container.innerHTML = "";
|
|
72403
72899
|
|
|
72404
|
-
|
|
72405
|
-
|
|
72406
|
-
|
|
72407
|
-
|
|
72408
|
-
|
|
72409
|
-
|
|
72410
|
-
|
|
72411
|
-
|
|
72412
|
-
|
|
72413
|
-
|
|
72414
|
-
|
|
72415
|
-
|
|
72416
|
-
|
|
72900
|
+
if (cards.length === 0) {
|
|
72901
|
+
container.innerHTML = '<div class="empty-column">Empty</div>';
|
|
72902
|
+
return;
|
|
72903
|
+
}
|
|
72904
|
+
|
|
72905
|
+
for (const cardData of cards) {
|
|
72906
|
+
container.appendChild(createPromptCard(cardData.file, cardData.section));
|
|
72907
|
+
}
|
|
72908
|
+
}
|
|
72909
|
+
|
|
72910
|
+
function createPromptCard(file, section) {
|
|
72911
|
+
const card = document.createElement("article");
|
|
72912
|
+
card.className = "card card-" + section.column;
|
|
72913
|
+
card.innerHTML =
|
|
72914
|
+
'<div class="card-file">' + escapeHtml(file.relativeFilePath || file.fileName) + " #" + (section.index + 1) + '</div>' +
|
|
72915
|
+
'<div class="card-summary">' + escapeHtml(section.summary) + '</div>' +
|
|
72916
|
+
renderTags(section);
|
|
72917
|
+
card.onclick = () => openModal(file, section);
|
|
72918
|
+
return card;
|
|
72919
|
+
}
|
|
72920
|
+
|
|
72921
|
+
function renderTags(section) {
|
|
72922
|
+
const tags = [...(section.tags || [])];
|
|
72923
|
+
if (section.priority > 0) {
|
|
72924
|
+
tags.push({ id: "priority", label: "P" + section.priority });
|
|
72417
72925
|
}
|
|
72926
|
+
|
|
72927
|
+
if (tags.length === 0) {
|
|
72928
|
+
return "";
|
|
72929
|
+
}
|
|
72930
|
+
|
|
72931
|
+
return '<div class="card-tags">' + tags.map((tag) =>
|
|
72932
|
+
'<span class="card-tag tag-' + escapeHtml(tag.id) + '">' + escapeHtml(tag.label) + '</span>'
|
|
72933
|
+
).join("") + '</div>';
|
|
72418
72934
|
}
|
|
72419
72935
|
|
|
72420
72936
|
function openModal(file, section) {
|
|
72421
72937
|
modalState = { filePath: file.filePath, sectionIndex: section.index };
|
|
72422
72938
|
|
|
72423
|
-
document.getElementById(
|
|
72424
|
-
document.getElementById(
|
|
72939
|
+
document.getElementById("modal-file").textContent = file.relativeFilePath || file.fileName;
|
|
72940
|
+
document.getElementById("modal-section-label").textContent = "Section " + (section.index + 1);
|
|
72425
72941
|
|
|
72426
|
-
const
|
|
72427
|
-
|
|
72428
|
-
|
|
72942
|
+
const statusBadge = document.getElementById("modal-status-badge");
|
|
72943
|
+
statusBadge.textContent = getColumnTitle(section.column);
|
|
72944
|
+
statusBadge.className = "modal-status status-" + section.column;
|
|
72429
72945
|
|
|
72430
|
-
document.getElementById(
|
|
72431
|
-
document.getElementById(
|
|
72432
|
-
setTimeout(() => document.getElementById(
|
|
72946
|
+
document.getElementById("modal-content").value = section.content;
|
|
72947
|
+
document.getElementById("modal-overlay").classList.remove("hidden");
|
|
72948
|
+
setTimeout(() => document.getElementById("modal-content").focus(), 50);
|
|
72433
72949
|
}
|
|
72434
72950
|
|
|
72435
72951
|
function closeModal() {
|
|
72436
|
-
document.getElementById(
|
|
72952
|
+
document.getElementById("modal-overlay").classList.add("hidden");
|
|
72437
72953
|
modalState = null;
|
|
72438
72954
|
}
|
|
72439
72955
|
|
|
72440
72956
|
async function saveModal() {
|
|
72441
|
-
if (!modalState)
|
|
72957
|
+
if (!modalState) {
|
|
72958
|
+
return;
|
|
72959
|
+
}
|
|
72442
72960
|
|
|
72443
|
-
const content = document.getElementById(
|
|
72444
|
-
const
|
|
72445
|
-
|
|
72446
|
-
|
|
72961
|
+
const content = document.getElementById("modal-content").value;
|
|
72962
|
+
const saveButton = document.getElementById("save-button");
|
|
72963
|
+
saveButton.disabled = true;
|
|
72964
|
+
saveButton.textContent = "Saving...";
|
|
72447
72965
|
|
|
72448
72966
|
try {
|
|
72449
|
-
const
|
|
72450
|
-
method:
|
|
72451
|
-
headers: {
|
|
72967
|
+
const response = await fetch("/api/prompts/update", {
|
|
72968
|
+
method: "PUT",
|
|
72969
|
+
headers: { "Content-Type": "application/json" },
|
|
72452
72970
|
body: JSON.stringify({
|
|
72453
|
-
filePath:
|
|
72971
|
+
filePath: modalState.filePath,
|
|
72454
72972
|
sectionIndex: modalState.sectionIndex,
|
|
72455
72973
|
content,
|
|
72456
72974
|
}),
|
|
72457
72975
|
});
|
|
72458
|
-
|
|
72976
|
+
|
|
72977
|
+
if (!response.ok) {
|
|
72978
|
+
throw new Error("HTTP " + response.status);
|
|
72979
|
+
}
|
|
72980
|
+
|
|
72459
72981
|
closeModal();
|
|
72460
|
-
fetchPrompts();
|
|
72461
|
-
} catch (
|
|
72462
|
-
showError(
|
|
72982
|
+
await fetchPrompts();
|
|
72983
|
+
} catch (error) {
|
|
72984
|
+
showError("Save failed: " + error.message);
|
|
72463
72985
|
} finally {
|
|
72464
|
-
|
|
72465
|
-
|
|
72986
|
+
saveButton.disabled = false;
|
|
72987
|
+
saveButton.textContent = "Save";
|
|
72466
72988
|
}
|
|
72467
72989
|
}
|
|
72468
72990
|
|
|
72469
|
-
document.getElementById(
|
|
72991
|
+
document.getElementById("toggle-btn").onclick = async () => {
|
|
72470
72992
|
try {
|
|
72471
|
-
const endpoint = lastPauseState ===
|
|
72472
|
-
await fetch(endpoint, { method:
|
|
72993
|
+
const endpoint = lastPauseState === "RUNNING" ? "/api/pause" : "/api/resume";
|
|
72994
|
+
await fetch(endpoint, { method: "POST" });
|
|
72473
72995
|
await fetchStatus();
|
|
72474
|
-
} catch (
|
|
72475
|
-
showError(
|
|
72996
|
+
} catch (error) {
|
|
72997
|
+
showError("Toggle failed: " + error.message);
|
|
72476
72998
|
}
|
|
72477
72999
|
};
|
|
72478
73000
|
|
|
72479
|
-
document.
|
|
72480
|
-
|
|
72481
|
-
|
|
73001
|
+
document.getElementById("modal-close").onclick = closeModal;
|
|
73002
|
+
document.getElementById("cancel-button").onclick = closeModal;
|
|
73003
|
+
document.getElementById("save-button").onclick = saveModal;
|
|
73004
|
+
|
|
73005
|
+
document.addEventListener("keydown", (event) => {
|
|
73006
|
+
if (event.key === "Escape") {
|
|
73007
|
+
closeModal();
|
|
73008
|
+
return;
|
|
73009
|
+
}
|
|
73010
|
+
if ((event.ctrlKey || event.metaKey) && event.key === "Enter") {
|
|
73011
|
+
saveModal();
|
|
73012
|
+
}
|
|
72482
73013
|
});
|
|
72483
73014
|
|
|
72484
|
-
document.getElementById(
|
|
72485
|
-
if (
|
|
73015
|
+
document.getElementById("modal-overlay").addEventListener("click", (event) => {
|
|
73016
|
+
if (event.target === document.getElementById("modal-overlay")) {
|
|
73017
|
+
closeModal();
|
|
73018
|
+
}
|
|
72486
73019
|
});
|
|
72487
73020
|
|
|
73021
|
+
renderBoardSkeleton();
|
|
72488
73022
|
fetchStatus();
|
|
72489
73023
|
fetchPrompts();
|
|
72490
|
-
setInterval(fetchStatus,
|
|
73024
|
+
setInterval(fetchStatus, 2000);
|
|
72491
73025
|
setInterval(fetchPrompts, 5000);
|
|
72492
73026
|
</script>
|
|
72493
73027
|
</body>
|
|
72494
|
-
</html
|
|
73028
|
+
</html>
|
|
73029
|
+
`;
|
|
72495
73030
|
// Note: [🟡] Code for CLI command [coder server](scripts/run-codex-prompts/server/coderServerHtml.ts) should never be published outside of `@promptbook/cli`
|
|
72496
73031
|
// Note: Keep in sync with apps/coder-server/index.html
|
|
72497
73032
|
|
|
@@ -72501,6 +73036,12 @@
|
|
|
72501
73036
|
* @private internal constant of `ptbk coder server`
|
|
72502
73037
|
*/
|
|
72503
73038
|
const PROMPTS_DIRECTORY_NAME = 'prompts';
|
|
73039
|
+
/**
|
|
73040
|
+
* Directory containing human-verified prompt files, relative to `prompts/`.
|
|
73041
|
+
*
|
|
73042
|
+
* @private internal constant of `ptbk coder server`
|
|
73043
|
+
*/
|
|
73044
|
+
const FINISHED_PROMPTS_DIRECTORY_NAME = 'done';
|
|
72504
73045
|
/**
|
|
72505
73046
|
* Starts the lightweight HTTP server that serves the coder kanban UI and REST API.
|
|
72506
73047
|
*
|
|
@@ -72514,24 +73055,29 @@
|
|
|
72514
73055
|
*
|
|
72515
73056
|
* @private internal utility of `ptbk coder server`
|
|
72516
73057
|
*/
|
|
72517
|
-
function startCoderHttpServer(
|
|
73058
|
+
function startCoderHttpServer(options) {
|
|
73059
|
+
const { port, minimumPriority, serverUrl, uiState } = options;
|
|
72518
73060
|
const promptsDir = path.join(process.cwd(), PROMPTS_DIRECTORY_NAME);
|
|
72519
|
-
const server = http.createServer(async (
|
|
73061
|
+
const server = http.createServer(async (request, response) => {
|
|
72520
73062
|
try {
|
|
72521
|
-
await handleRequest(
|
|
73063
|
+
await handleRequest(request, response, {
|
|
73064
|
+
promptsDir,
|
|
73065
|
+
minimumPriority,
|
|
73066
|
+
uiState,
|
|
73067
|
+
});
|
|
72522
73068
|
}
|
|
72523
73069
|
catch (error) {
|
|
72524
73070
|
const message = error instanceof Error ? error.message : String(error);
|
|
72525
73071
|
console.error(colors__default["default"].red(`Coder server request error: ${message}`));
|
|
72526
|
-
if (!
|
|
72527
|
-
|
|
73072
|
+
if (!response.headersSent) {
|
|
73073
|
+
response.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
72528
73074
|
}
|
|
72529
|
-
|
|
73075
|
+
response.end('Internal server error');
|
|
72530
73076
|
}
|
|
72531
73077
|
});
|
|
72532
73078
|
server.listen(port, () => {
|
|
72533
73079
|
console.info(_spaceTrim.spaceTrim(`
|
|
72534
|
-
Coder server running at ${colors__default["default"].cyan(
|
|
73080
|
+
Coder server running at ${colors__default["default"].cyan(serverUrl)}
|
|
72535
73081
|
Open the URL above in your browser to see the kanban board.
|
|
72536
73082
|
Press ${colors__default["default"].bold('p')} to pause / resume the agent runner.
|
|
72537
73083
|
`));
|
|
@@ -72545,51 +73091,57 @@
|
|
|
72545
73091
|
/**
|
|
72546
73092
|
* Routes one HTTP request to the appropriate handler.
|
|
72547
73093
|
*/
|
|
72548
|
-
async function handleRequest(
|
|
72549
|
-
const
|
|
72550
|
-
const
|
|
73094
|
+
async function handleRequest(request, response, options) {
|
|
73095
|
+
const { promptsDir, minimumPriority, uiState } = options;
|
|
73096
|
+
const urlPath = new URL(request.url || '/', `http://localhost`).pathname;
|
|
73097
|
+
const method = (request.method || 'GET').toUpperCase();
|
|
72551
73098
|
// Serve the kanban UI
|
|
72552
73099
|
if (urlPath === '/' && method === 'GET') {
|
|
72553
|
-
|
|
73100
|
+
response.writeHead(200, {
|
|
72554
73101
|
'Content-Type': 'text/html; charset=utf-8',
|
|
72555
73102
|
'Cache-Control': 'no-cache',
|
|
72556
73103
|
});
|
|
72557
|
-
|
|
73104
|
+
response.end(CODER_SERVER_HTML);
|
|
72558
73105
|
return;
|
|
72559
73106
|
}
|
|
72560
73107
|
// GET /api/status
|
|
72561
73108
|
if (urlPath === '/api/status' && method === 'GET') {
|
|
72562
|
-
|
|
72563
|
-
|
|
73109
|
+
response.writeHead(200, jsonHeaders());
|
|
73110
|
+
response.end(JSON.stringify({
|
|
72564
73111
|
pauseState: getPauseState(),
|
|
72565
73112
|
pauseTargetLabel: getPauseTargetLabel(),
|
|
73113
|
+
runState: uiState ? buildCoderServerRunState(uiState) : undefined,
|
|
72566
73114
|
}));
|
|
72567
73115
|
return;
|
|
72568
73116
|
}
|
|
72569
73117
|
// GET /api/prompts
|
|
72570
73118
|
if (urlPath === '/api/prompts' && method === 'GET') {
|
|
72571
|
-
const promptData = await loadPromptsForApi(
|
|
72572
|
-
|
|
72573
|
-
|
|
73119
|
+
const promptData = await loadPromptsForApi({
|
|
73120
|
+
promptsDir,
|
|
73121
|
+
minimumPriority,
|
|
73122
|
+
uiState,
|
|
73123
|
+
});
|
|
73124
|
+
response.writeHead(200, jsonHeaders());
|
|
73125
|
+
response.end(JSON.stringify(promptData));
|
|
72574
73126
|
return;
|
|
72575
73127
|
}
|
|
72576
73128
|
// POST /api/pause
|
|
72577
73129
|
if (urlPath === '/api/pause' && method === 'POST') {
|
|
72578
73130
|
requestPause();
|
|
72579
|
-
|
|
72580
|
-
|
|
73131
|
+
response.writeHead(200, jsonHeaders());
|
|
73132
|
+
response.end(JSON.stringify({ pauseState: getPauseState() }));
|
|
72581
73133
|
return;
|
|
72582
73134
|
}
|
|
72583
73135
|
// POST /api/resume
|
|
72584
73136
|
if (urlPath === '/api/resume' && method === 'POST') {
|
|
72585
73137
|
requestResume();
|
|
72586
|
-
|
|
72587
|
-
|
|
73138
|
+
response.writeHead(200, jsonHeaders());
|
|
73139
|
+
response.end(JSON.stringify({ pauseState: getPauseState() }));
|
|
72588
73140
|
return;
|
|
72589
73141
|
}
|
|
72590
73142
|
// PUT /api/prompts/update
|
|
72591
73143
|
if (urlPath === '/api/prompts/update' && method === 'PUT') {
|
|
72592
|
-
const body = await readRequestBody(
|
|
73144
|
+
const body = await readRequestBody(request);
|
|
72593
73145
|
const parsed = JSON.parse(body);
|
|
72594
73146
|
if (typeof parsed.filePath !== 'string' ||
|
|
72595
73147
|
typeof parsed.sectionIndex !== 'number' ||
|
|
@@ -72600,49 +73152,85 @@
|
|
|
72600
73152
|
Expected: \`{ filePath: string, sectionIndex: number, content: string }\`
|
|
72601
73153
|
`));
|
|
72602
73154
|
}
|
|
72603
|
-
|
|
72604
|
-
|
|
72605
|
-
|
|
73155
|
+
const promptFilePath = resolveEditablePromptFilePath(parsed.filePath, promptsDir);
|
|
73156
|
+
const isUpdated = await updatePromptSection(promptFilePath, parsed.sectionIndex, parsed.content);
|
|
73157
|
+
if (isUpdated) {
|
|
73158
|
+
await commitPromptEdit(promptFilePath, parsed.sectionIndex);
|
|
73159
|
+
}
|
|
73160
|
+
response.writeHead(200, jsonHeaders());
|
|
73161
|
+
response.end(JSON.stringify({ success: true, committed: isUpdated }));
|
|
72606
73162
|
return;
|
|
72607
73163
|
}
|
|
72608
|
-
|
|
72609
|
-
|
|
73164
|
+
response.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
73165
|
+
response.end('Not found');
|
|
72610
73166
|
}
|
|
72611
73167
|
/**
|
|
72612
73168
|
* Loads all prompt files and converts them to the API response shape.
|
|
72613
73169
|
*/
|
|
72614
|
-
async function loadPromptsForApi(
|
|
73170
|
+
async function loadPromptsForApi(options) {
|
|
73171
|
+
const { promptsDir, minimumPriority, uiState } = options;
|
|
73172
|
+
const promptFiles = await loadPromptFilesSafely(promptsDir);
|
|
73173
|
+
const finishedPromptFiles = await loadPromptFilesSafely(path.join(promptsDir, FINISHED_PROMPTS_DIRECTORY_NAME));
|
|
73174
|
+
return buildCoderServerPromptFileResponses({
|
|
73175
|
+
promptFiles,
|
|
73176
|
+
finishedPromptFiles,
|
|
73177
|
+
minimumPriority,
|
|
73178
|
+
uiState,
|
|
73179
|
+
});
|
|
73180
|
+
}
|
|
73181
|
+
/**
|
|
73182
|
+
* Loads prompt files from a directory that may not exist yet.
|
|
73183
|
+
*/
|
|
73184
|
+
async function loadPromptFilesSafely(promptsDir) {
|
|
72615
73185
|
try {
|
|
72616
|
-
|
|
72617
|
-
return promptFiles.map((file) => ({
|
|
72618
|
-
filePath: file.path,
|
|
72619
|
-
fileName: file.name,
|
|
72620
|
-
sections: file.sections.map((section) => ({
|
|
72621
|
-
index: section.index,
|
|
72622
|
-
status: section.status,
|
|
72623
|
-
priority: section.priority,
|
|
72624
|
-
summary: buildPromptSummary(file, section),
|
|
72625
|
-
content: buildCodexPrompt(file, section),
|
|
72626
|
-
})),
|
|
72627
|
-
}));
|
|
73186
|
+
return await loadPromptFiles(promptsDir);
|
|
72628
73187
|
}
|
|
72629
73188
|
catch (error) {
|
|
72630
|
-
// Prompts directory may not exist yet; return empty list
|
|
72631
73189
|
if (error.code === 'ENOENT') {
|
|
72632
73190
|
return [];
|
|
72633
73191
|
}
|
|
72634
73192
|
throw error;
|
|
72635
73193
|
}
|
|
72636
73194
|
}
|
|
73195
|
+
/**
|
|
73196
|
+
* Resolves and validates one editable prompt file path received from the browser.
|
|
73197
|
+
*/
|
|
73198
|
+
function resolveEditablePromptFilePath(filePath, promptsDir) {
|
|
73199
|
+
const promptFilePath = path.resolve(filePath);
|
|
73200
|
+
const promptsDirectoryPath = path.resolve(promptsDir);
|
|
73201
|
+
const relativePromptFilePath = path.relative(promptsDirectoryPath, promptFilePath);
|
|
73202
|
+
const isOutsidePromptsDirectory = relativePromptFilePath === '' ||
|
|
73203
|
+
relativePromptFilePath.startsWith('..') ||
|
|
73204
|
+
path.isAbsolute(relativePromptFilePath);
|
|
73205
|
+
if (isOutsidePromptsDirectory || !promptFilePath.toLowerCase().endsWith('.md')) {
|
|
73206
|
+
throw new NotAllowed(_spaceTrim.spaceTrim(`
|
|
73207
|
+
Prompt file edits are limited to Markdown files inside \`${promptsDirectoryPath}\`.
|
|
73208
|
+
|
|
73209
|
+
Requested file:
|
|
73210
|
+
\`${filePath}\`
|
|
73211
|
+
`));
|
|
73212
|
+
}
|
|
73213
|
+
return promptFilePath;
|
|
73214
|
+
}
|
|
73215
|
+
/**
|
|
73216
|
+
* Commits a browser prompt edit to Git without sweeping unrelated staged files into the commit.
|
|
73217
|
+
*/
|
|
73218
|
+
async function commitPromptEdit(promptFilePath, sectionIndex) {
|
|
73219
|
+
const relativePromptFilePath = path.relative(process.cwd(), promptFilePath).replace(/\\/gu, '/');
|
|
73220
|
+
await commitChanges(`Edit coder prompt ${relativePromptFilePath}#${sectionIndex + 1}`, {
|
|
73221
|
+
includePaths: [relativePromptFilePath],
|
|
73222
|
+
onlyPaths: [relativePromptFilePath],
|
|
73223
|
+
});
|
|
73224
|
+
}
|
|
72637
73225
|
/**
|
|
72638
73226
|
* Reads the full request body as a UTF-8 string.
|
|
72639
73227
|
*/
|
|
72640
|
-
function readRequestBody(
|
|
73228
|
+
function readRequestBody(request) {
|
|
72641
73229
|
return new Promise((resolve, reject) => {
|
|
72642
73230
|
const chunks = [];
|
|
72643
|
-
|
|
72644
|
-
|
|
72645
|
-
|
|
73231
|
+
request.on('data', (chunk) => chunks.push(chunk));
|
|
73232
|
+
request.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
|
|
73233
|
+
request.on('error', reject);
|
|
72646
73234
|
});
|
|
72647
73235
|
}
|
|
72648
73236
|
/**
|
|
@@ -72671,12 +73259,21 @@
|
|
|
72671
73259
|
*/
|
|
72672
73260
|
async function runCodexPromptsServer(options) {
|
|
72673
73261
|
const { port, ...runOptions } = options;
|
|
72674
|
-
const
|
|
73262
|
+
const serverUrl = `http://localhost:${port}`;
|
|
73263
|
+
const uiState = new CoderRunUiState(moment__default["default"]());
|
|
73264
|
+
const serverHandle = startCoderHttpServer({
|
|
73265
|
+
port,
|
|
73266
|
+
minimumPriority: runOptions.priority,
|
|
73267
|
+
serverUrl,
|
|
73268
|
+
uiState,
|
|
73269
|
+
});
|
|
72675
73270
|
console.info(colors__default["default"].gray('Starting prompt runner in server (keep-alive) mode…'));
|
|
72676
73271
|
try {
|
|
72677
73272
|
await runCodexPrompts({
|
|
72678
73273
|
...runOptions,
|
|
72679
73274
|
keepAlive: true,
|
|
73275
|
+
serverUrl,
|
|
73276
|
+
uiState,
|
|
72680
73277
|
});
|
|
72681
73278
|
}
|
|
72682
73279
|
finally {
|