taskchef 8.6.2 → 8.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +8 -4
- package/assets/README.md +19 -0
- package/assets/taskchef-app-rounded.png +0 -0
- package/assets/taskchef-avatar-square.png +0 -0
- package/assets/taskchef-avatar-square.svg +8 -0
- package/assets/taskchef-sidebar-dark.svg +6 -0
- package/assets/taskchef-sidebar-light.svg +6 -0
- package/assets/taskchef-sidebar.svg +6 -0
- package/docs/advanced-guide.md +20 -29
- package/docs/dashboard-ui.md +15 -0
- package/docs/diagrams/taskchef-next-reply-lookup.drawio +38 -0
- package/docs/diagrams/taskchef-next-reply-lookup.drawio.png +0 -0
- package/docs/diagrams/taskchef-next-storage.drawio +41 -0
- package/docs/diagrams/taskchef-next-storage.drawio.png +0 -0
- package/docs/images/taskchef-pr-icon-comparison.jpg +0 -0
- package/docs/images/taskchef-unified-status-popup.jpg +0 -0
- package/docs/mcp-app.md +278 -6
- package/docs/spec.md +24 -69
- package/docs/taskchef-next-github.md +206 -0
- package/docs/taskchef-next-status-research.md +102 -0
- package/docs/taskchef-next-storage.md +167 -0
- package/docs/workflows.md +4 -2
- package/node_modules/@napi-rs/keyring/LICENSE +21 -0
- package/node_modules/@napi-rs/keyring/README.md +45 -0
- package/node_modules/@napi-rs/keyring/index.d.ts +232 -0
- package/node_modules/@napi-rs/keyring/index.js +706 -0
- package/node_modules/@napi-rs/keyring/keytar.d.ts +53 -0
- package/node_modules/@napi-rs/keyring/keytar.js +26 -0
- package/node_modules/@napi-rs/keyring/package.json +126 -0
- package/node_modules/@napi-rs/keyring-darwin-arm64/README.md +3 -0
- package/node_modules/@napi-rs/keyring-darwin-arm64/keyring.darwin-arm64.node +0 -0
- package/node_modules/@napi-rs/keyring-darwin-arm64/package.json +32 -0
- package/node_modules/@napi-rs/keyring-darwin-x64/README.md +3 -0
- package/node_modules/@napi-rs/keyring-darwin-x64/keyring.darwin-x64.node +0 -0
- package/node_modules/@napi-rs/keyring-darwin-x64/package.json +32 -0
- package/node_modules/@napi-rs/keyring-linux-arm64-gnu/README.md +3 -0
- package/node_modules/@napi-rs/keyring-linux-arm64-gnu/keyring.linux-arm64-gnu.node +0 -0
- package/node_modules/@napi-rs/keyring-linux-arm64-gnu/package.json +35 -0
- package/node_modules/@napi-rs/keyring-linux-arm64-musl/README.md +3 -0
- package/node_modules/@napi-rs/keyring-linux-arm64-musl/keyring.linux-arm64-musl.node +0 -0
- package/node_modules/@napi-rs/keyring-linux-arm64-musl/package.json +35 -0
- package/node_modules/@napi-rs/keyring-linux-x64-gnu/README.md +3 -0
- package/node_modules/@napi-rs/keyring-linux-x64-gnu/keyring.linux-x64-gnu.node +0 -0
- package/node_modules/@napi-rs/keyring-linux-x64-gnu/package.json +35 -0
- package/node_modules/@napi-rs/keyring-linux-x64-musl/README.md +3 -0
- package/node_modules/@napi-rs/keyring-linux-x64-musl/keyring.linux-x64-musl.node +0 -0
- package/node_modules/@napi-rs/keyring-linux-x64-musl/package.json +35 -0
- package/node_modules/@napi-rs/keyring-win32-arm64-msvc/README.md +3 -0
- package/node_modules/@napi-rs/keyring-win32-arm64-msvc/keyring.win32-arm64-msvc.node +0 -0
- package/node_modules/@napi-rs/keyring-win32-arm64-msvc/package.json +32 -0
- package/node_modules/@napi-rs/keyring-win32-x64-msvc/README.md +3 -0
- package/node_modules/@napi-rs/keyring-win32-x64-msvc/keyring.win32-x64-msvc.node +0 -0
- package/node_modules/@napi-rs/keyring-win32-x64-msvc/package.json +32 -0
- package/node_modules/@types/debug/LICENSE +21 -0
- package/node_modules/@types/debug/README.md +69 -0
- package/node_modules/@types/debug/index.d.ts +50 -0
- package/node_modules/@types/debug/package.json +58 -0
- package/node_modules/@types/mdast/LICENSE +21 -0
- package/node_modules/@types/mdast/README.md +15 -0
- package/node_modules/@types/mdast/index.d.ts +1123 -0
- package/node_modules/@types/mdast/package.json +47 -0
- package/node_modules/@types/ms/LICENSE +21 -0
- package/node_modules/@types/ms/README.md +82 -0
- package/node_modules/@types/ms/index.d.ts +63 -0
- package/node_modules/@types/ms/package.json +26 -0
- package/node_modules/@types/unist/LICENSE +21 -0
- package/node_modules/@types/unist/README.md +15 -0
- package/node_modules/@types/unist/index.d.ts +119 -0
- package/node_modules/@types/unist/package.json +60 -0
- package/node_modules/character-entities/index.d.ts +6 -0
- package/node_modules/character-entities/index.js +2132 -0
- package/node_modules/character-entities/license +22 -0
- package/node_modules/character-entities/package.json +78 -0
- package/node_modules/character-entities/readme.md +152 -0
- package/node_modules/decode-named-character-reference/index.d.ts +13 -0
- package/node_modules/decode-named-character-reference/index.d.ts.map +1 -0
- package/node_modules/decode-named-character-reference/index.dom.d.ts +6 -0
- package/node_modules/decode-named-character-reference/index.dom.d.ts.map +1 -0
- package/node_modules/decode-named-character-reference/index.dom.js +32 -0
- package/node_modules/decode-named-character-reference/index.js +19 -0
- package/node_modules/decode-named-character-reference/license +22 -0
- package/node_modules/decode-named-character-reference/package.json +90 -0
- package/node_modules/decode-named-character-reference/readme.md +136 -0
- package/node_modules/dequal/dist/index.js +86 -0
- package/node_modules/dequal/dist/index.min.js +1 -0
- package/node_modules/dequal/dist/index.mjs +84 -0
- package/node_modules/dequal/index.d.ts +1 -0
- package/node_modules/dequal/license +21 -0
- package/node_modules/dequal/lite/index.d.ts +1 -0
- package/node_modules/dequal/lite/index.js +31 -0
- package/node_modules/dequal/lite/index.min.js +1 -0
- package/node_modules/dequal/lite/index.mjs +29 -0
- package/node_modules/dequal/package.json +57 -0
- package/node_modules/dequal/readme.md +112 -0
- package/node_modules/devlop/lib/default.js +9 -0
- package/node_modules/devlop/lib/development.d.ts +84 -0
- package/node_modules/devlop/lib/development.js +238 -0
- package/node_modules/devlop/license +22 -0
- package/node_modules/devlop/package.json +80 -0
- package/node_modules/devlop/readme.md +360 -0
- package/node_modules/mdast-util-from-markdown/dev/index.d.ts +23 -0
- package/node_modules/mdast-util-from-markdown/dev/index.js +2 -0
- package/node_modules/mdast-util-from-markdown/dev/lib/index.d.ts +53 -0
- package/node_modules/mdast-util-from-markdown/dev/lib/index.d.ts.map +1 -0
- package/node_modules/mdast-util-from-markdown/dev/lib/index.js +1348 -0
- package/node_modules/mdast-util-from-markdown/dev/lib/types.d.ts +295 -0
- package/node_modules/mdast-util-from-markdown/dev/lib/types.js +2 -0
- package/node_modules/mdast-util-from-markdown/index.d.ts +23 -0
- package/node_modules/mdast-util-from-markdown/index.js +2 -0
- package/node_modules/mdast-util-from-markdown/lib/index.d.ts +53 -0
- package/node_modules/mdast-util-from-markdown/lib/index.js +1177 -0
- package/node_modules/mdast-util-from-markdown/lib/types.d.ts +295 -0
- package/node_modules/mdast-util-from-markdown/lib/types.js +2 -0
- package/node_modules/mdast-util-from-markdown/license +22 -0
- package/node_modules/mdast-util-from-markdown/package.json +139 -0
- package/node_modules/mdast-util-from-markdown/readme.md +537 -0
- package/node_modules/mdast-util-to-string/index.d.ts +2 -0
- package/node_modules/mdast-util-to-string/index.js +5 -0
- package/node_modules/mdast-util-to-string/lib/index.d.ts +31 -0
- package/node_modules/mdast-util-to-string/lib/index.js +108 -0
- package/node_modules/mdast-util-to-string/license +22 -0
- package/node_modules/mdast-util-to-string/package.json +78 -0
- package/node_modules/mdast-util-to-string/readme.md +218 -0
- package/node_modules/micromark/dev/index.d.ts +82 -0
- package/node_modules/micromark/dev/index.d.ts.map +1 -0
- package/node_modules/micromark/dev/index.js +68 -0
- package/node_modules/micromark/dev/lib/compile.d.ts +16 -0
- package/node_modules/micromark/dev/lib/compile.d.ts.map +1 -0
- package/node_modules/micromark/dev/lib/compile.js +1162 -0
- package/node_modules/micromark/dev/lib/constructs.d.ts +73 -0
- package/node_modules/micromark/dev/lib/constructs.d.ts.map +1 -0
- package/node_modules/micromark/dev/lib/constructs.js +101 -0
- package/node_modules/micromark/dev/lib/create-tokenizer.d.ts +46 -0
- package/node_modules/micromark/dev/lib/create-tokenizer.d.ts.map +1 -0
- package/node_modules/micromark/dev/lib/create-tokenizer.js +718 -0
- package/node_modules/micromark/dev/lib/initialize/content.d.ts +4 -0
- package/node_modules/micromark/dev/lib/initialize/content.d.ts.map +1 -0
- package/node_modules/micromark/dev/lib/initialize/content.js +99 -0
- package/node_modules/micromark/dev/lib/initialize/document.d.ts +10 -0
- package/node_modules/micromark/dev/lib/initialize/document.d.ts.map +1 -0
- package/node_modules/micromark/dev/lib/initialize/document.js +449 -0
- package/node_modules/micromark/dev/lib/initialize/flow.d.ts +4 -0
- package/node_modules/micromark/dev/lib/initialize/flow.d.ts.map +1 -0
- package/node_modules/micromark/dev/lib/initialize/flow.js +86 -0
- package/node_modules/micromark/dev/lib/initialize/text.d.ts +8 -0
- package/node_modules/micromark/dev/lib/initialize/text.d.ts.map +1 -0
- package/node_modules/micromark/dev/lib/initialize/text.js +248 -0
- package/node_modules/micromark/dev/lib/parse.d.ts +10 -0
- package/node_modules/micromark/dev/lib/parse.d.ts.map +1 -0
- package/node_modules/micromark/dev/lib/parse.js +58 -0
- package/node_modules/micromark/dev/lib/postprocess.d.ts +9 -0
- package/node_modules/micromark/dev/lib/postprocess.d.ts.map +1 -0
- package/node_modules/micromark/dev/lib/postprocess.js +19 -0
- package/node_modules/micromark/dev/lib/preprocess.d.ts +13 -0
- package/node_modules/micromark/dev/lib/preprocess.d.ts.map +1 -0
- package/node_modules/micromark/dev/lib/preprocess.js +139 -0
- package/node_modules/micromark/dev/stream.d.ts +35 -0
- package/node_modules/micromark/dev/stream.d.ts.map +1 -0
- package/node_modules/micromark/dev/stream.js +270 -0
- package/node_modules/micromark/index.d.ts +82 -0
- package/node_modules/micromark/index.d.ts.map +1 -0
- package/node_modules/micromark/index.js +60 -0
- package/node_modules/micromark/lib/compile.d.ts +16 -0
- package/node_modules/micromark/lib/compile.d.ts.map +1 -0
- package/node_modules/micromark/lib/compile.js +1068 -0
- package/node_modules/micromark/lib/constructs.d.ts +73 -0
- package/node_modules/micromark/lib/constructs.d.ts.map +1 -0
- package/node_modules/micromark/lib/constructs.js +85 -0
- package/node_modules/micromark/lib/create-tokenizer.d.ts +46 -0
- package/node_modules/micromark/lib/create-tokenizer.d.ts.map +1 -0
- package/node_modules/micromark/lib/create-tokenizer.js +613 -0
- package/node_modules/micromark/lib/initialize/content.d.ts +4 -0
- package/node_modules/micromark/lib/initialize/content.d.ts.map +1 -0
- package/node_modules/micromark/lib/initialize/content.js +79 -0
- package/node_modules/micromark/lib/initialize/document.d.ts +10 -0
- package/node_modules/micromark/lib/initialize/document.d.ts.map +1 -0
- package/node_modules/micromark/lib/initialize/document.js +370 -0
- package/node_modules/micromark/lib/initialize/flow.d.ts +4 -0
- package/node_modules/micromark/lib/initialize/flow.d.ts.map +1 -0
- package/node_modules/micromark/lib/initialize/flow.js +58 -0
- package/node_modules/micromark/lib/initialize/text.d.ts +8 -0
- package/node_modules/micromark/lib/initialize/text.d.ts.map +1 -0
- package/node_modules/micromark/lib/initialize/text.js +216 -0
- package/node_modules/micromark/lib/parse.d.ts +10 -0
- package/node_modules/micromark/lib/parse.d.ts.map +1 -0
- package/node_modules/micromark/lib/parse.js +56 -0
- package/node_modules/micromark/lib/postprocess.d.ts +9 -0
- package/node_modules/micromark/lib/postprocess.d.ts.map +1 -0
- package/node_modules/micromark/lib/postprocess.js +18 -0
- package/node_modules/micromark/lib/preprocess.d.ts +13 -0
- package/node_modules/micromark/lib/preprocess.d.ts.map +1 -0
- package/node_modules/micromark/lib/preprocess.js +112 -0
- package/node_modules/micromark/license +22 -0
- package/node_modules/micromark/package.json +87 -0
- package/node_modules/micromark/readme.md +488 -0
- package/node_modules/micromark/stream.d.ts +35 -0
- package/node_modules/micromark/stream.d.ts.map +1 -0
- package/node_modules/micromark/stream.js +256 -0
- package/node_modules/micromark-core-commonmark/dev/index.d.ts +23 -0
- package/node_modules/micromark-core-commonmark/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/index.js +22 -0
- package/node_modules/micromark-core-commonmark/dev/lib/attention.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/attention.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/attention.js +294 -0
- package/node_modules/micromark-core-commonmark/dev/lib/autolink.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/autolink.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/autolink.js +269 -0
- package/node_modules/micromark-core-commonmark/dev/lib/blank-line.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/blank-line.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/blank-line.js +62 -0
- package/node_modules/micromark-core-commonmark/dev/lib/block-quote.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/block-quote.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/block-quote.js +162 -0
- package/node_modules/micromark-core-commonmark/dev/lib/character-escape.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/character-escape.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/character-escape.js +69 -0
- package/node_modules/micromark-core-commonmark/dev/lib/character-reference.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/character-reference.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/character-reference.js +166 -0
- package/node_modules/micromark-core-commonmark/dev/lib/code-fenced.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/code-fenced.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/code-fenced.js +472 -0
- package/node_modules/micromark-core-commonmark/dev/lib/code-indented.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/code-indented.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/code-indented.js +178 -0
- package/node_modules/micromark-core-commonmark/dev/lib/code-text.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/code-text.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/code-text.js +257 -0
- package/node_modules/micromark-core-commonmark/dev/lib/content.d.ts +7 -0
- package/node_modules/micromark-core-commonmark/dev/lib/content.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/content.js +185 -0
- package/node_modules/micromark-core-commonmark/dev/lib/definition.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/definition.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/definition.js +295 -0
- package/node_modules/micromark-core-commonmark/dev/lib/hard-break-escape.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/hard-break-escape.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/hard-break-escape.js +65 -0
- package/node_modules/micromark-core-commonmark/dev/lib/heading-atx.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/heading-atx.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/heading-atx.js +229 -0
- package/node_modules/micromark-core-commonmark/dev/lib/html-flow.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/html-flow.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/html-flow.js +938 -0
- package/node_modules/micromark-core-commonmark/dev/lib/html-text.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/html-text.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/html-text.js +783 -0
- package/node_modules/micromark-core-commonmark/dev/lib/label-end.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/label-end.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/label-end.js +658 -0
- package/node_modules/micromark-core-commonmark/dev/lib/label-start-image.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/label-start-image.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/label-start-image.js +119 -0
- package/node_modules/micromark-core-commonmark/dev/lib/label-start-link.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/label-start-link.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/label-start-link.js +71 -0
- package/node_modules/micromark-core-commonmark/dev/lib/line-ending.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/line-ending.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/line-ending.js +34 -0
- package/node_modules/micromark-core-commonmark/dev/lib/list.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/list.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/list.js +306 -0
- package/node_modules/micromark-core-commonmark/dev/lib/partial-non-lazy-continuation.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/partial-non-lazy-continuation.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/partial-non-lazy-continuation.js +67 -0
- package/node_modules/micromark-core-commonmark/dev/lib/setext-underline.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/setext-underline.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/setext-underline.js +213 -0
- package/node_modules/micromark-core-commonmark/dev/lib/thematic-break.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/dev/lib/thematic-break.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/dev/lib/thematic-break.js +120 -0
- package/node_modules/micromark-core-commonmark/index.d.ts +23 -0
- package/node_modules/micromark-core-commonmark/index.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/index.js +22 -0
- package/node_modules/micromark-core-commonmark/lib/attention.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/attention.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/attention.js +231 -0
- package/node_modules/micromark-core-commonmark/lib/autolink.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/autolink.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/autolink.js +233 -0
- package/node_modules/micromark-core-commonmark/lib/blank-line.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/blank-line.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/blank-line.js +61 -0
- package/node_modules/micromark-core-commonmark/lib/block-quote.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/block-quote.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/block-quote.js +143 -0
- package/node_modules/micromark-core-commonmark/lib/character-escape.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/character-escape.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/character-escape.js +64 -0
- package/node_modules/micromark-core-commonmark/lib/character-reference.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/character-reference.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/character-reference.js +149 -0
- package/node_modules/micromark-core-commonmark/lib/code-fenced.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/code-fenced.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/code-fenced.js +422 -0
- package/node_modules/micromark-core-commonmark/lib/code-indented.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/code-indented.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/code-indented.js +159 -0
- package/node_modules/micromark-core-commonmark/lib/code-text.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/code-text.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/code-text.js +225 -0
- package/node_modules/micromark-core-commonmark/lib/content.d.ts +7 -0
- package/node_modules/micromark-core-commonmark/lib/content.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/content.js +163 -0
- package/node_modules/micromark-core-commonmark/lib/definition.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/definition.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/definition.js +254 -0
- package/node_modules/micromark-core-commonmark/lib/hard-break-escape.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/hard-break-escape.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +60 -0
- package/node_modules/micromark-core-commonmark/lib/heading-atx.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/heading-atx.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/heading-atx.js +191 -0
- package/node_modules/micromark-core-commonmark/lib/html-flow.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/html-flow.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/html-flow.js +827 -0
- package/node_modules/micromark-core-commonmark/lib/html-text.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/html-text.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/html-text.js +678 -0
- package/node_modules/micromark-core-commonmark/lib/label-end.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/label-end.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/label-end.js +561 -0
- package/node_modules/micromark-core-commonmark/lib/label-start-image.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/label-start-image.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/label-start-image.js +110 -0
- package/node_modules/micromark-core-commonmark/lib/label-start-link.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/label-start-link.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/label-start-link.js +63 -0
- package/node_modules/micromark-core-commonmark/lib/line-ending.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/line-ending.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/line-ending.js +33 -0
- package/node_modules/micromark-core-commonmark/lib/list.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/list.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/list.js +213 -0
- package/node_modules/micromark-core-commonmark/lib/partial-non-lazy-continuation.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/partial-non-lazy-continuation.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/partial-non-lazy-continuation.js +61 -0
- package/node_modules/micromark-core-commonmark/lib/setext-underline.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/setext-underline.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/setext-underline.js +187 -0
- package/node_modules/micromark-core-commonmark/lib/thematic-break.d.ts +4 -0
- package/node_modules/micromark-core-commonmark/lib/thematic-break.d.ts.map +1 -0
- package/node_modules/micromark-core-commonmark/lib/thematic-break.js +102 -0
- package/node_modules/micromark-core-commonmark/license +22 -0
- package/node_modules/micromark-core-commonmark/package.json +62 -0
- package/node_modules/micromark-core-commonmark/readme.md +171 -0
- package/node_modules/micromark-factory-destination/dev/index.d.ts +42 -0
- package/node_modules/micromark-factory-destination/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-factory-destination/dev/index.js +255 -0
- package/node_modules/micromark-factory-destination/index.d.ts +42 -0
- package/node_modules/micromark-factory-destination/index.d.ts.map +1 -0
- package/node_modules/micromark-factory-destination/index.js +206 -0
- package/node_modules/micromark-factory-destination/license +22 -0
- package/node_modules/micromark-factory-destination/package.json +57 -0
- package/node_modules/micromark-factory-destination/readme.md +234 -0
- package/node_modules/micromark-factory-label/dev/index.d.ts +37 -0
- package/node_modules/micromark-factory-label/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-factory-label/dev/index.js +172 -0
- package/node_modules/micromark-factory-label/index.d.ts +37 -0
- package/node_modules/micromark-factory-label/index.d.ts.map +1 -0
- package/node_modules/micromark-factory-label/index.js +148 -0
- package/node_modules/micromark-factory-label/license +22 -0
- package/node_modules/micromark-factory-label/package.json +60 -0
- package/node_modules/micromark-factory-label/readme.md +224 -0
- package/node_modules/micromark-factory-space/dev/index.d.ts +60 -0
- package/node_modules/micromark-factory-space/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-factory-space/dev/index.js +122 -0
- package/node_modules/micromark-factory-space/index.d.ts +60 -0
- package/node_modules/micromark-factory-space/index.d.ts.map +1 -0
- package/node_modules/micromark-factory-space/index.js +116 -0
- package/node_modules/micromark-factory-space/license +22 -0
- package/node_modules/micromark-factory-space/package.json +46 -0
- package/node_modules/micromark-factory-space/readme.md +225 -0
- package/node_modules/micromark-factory-title/dev/index.d.ts +36 -0
- package/node_modules/micromark-factory-title/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-factory-title/dev/index.js +169 -0
- package/node_modules/micromark-factory-title/index.d.ts +36 -0
- package/node_modules/micromark-factory-title/index.d.ts.map +1 -0
- package/node_modules/micromark-factory-title/index.js +158 -0
- package/node_modules/micromark-factory-title/license +22 -0
- package/node_modules/micromark-factory-title/package.json +58 -0
- package/node_modules/micromark-factory-title/readme.md +229 -0
- package/node_modules/micromark-factory-whitespace/dev/index.d.ts +22 -0
- package/node_modules/micromark-factory-whitespace/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-factory-whitespace/dev/index.js +53 -0
- package/node_modules/micromark-factory-whitespace/index.d.ts +22 -0
- package/node_modules/micromark-factory-whitespace/index.d.ts.map +1 -0
- package/node_modules/micromark-factory-whitespace/index.js +44 -0
- package/node_modules/micromark-factory-whitespace/license +22 -0
- package/node_modules/micromark-factory-whitespace/package.json +57 -0
- package/node_modules/micromark-factory-whitespace/readme.md +205 -0
- package/node_modules/micromark-util-character/dev/index.d.ts +195 -0
- package/node_modules/micromark-util-character/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-util-character/dev/index.js +252 -0
- package/node_modules/micromark-util-character/index.d.ts +195 -0
- package/node_modules/micromark-util-character/index.d.ts.map +1 -0
- package/node_modules/micromark-util-character/index.js +246 -0
- package/node_modules/micromark-util-character/license +22 -0
- package/node_modules/micromark-util-character/package.json +57 -0
- package/node_modules/micromark-util-character/readme.md +446 -0
- package/node_modules/micromark-util-chunked/dev/index.d.ts +41 -0
- package/node_modules/micromark-util-chunked/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-util-chunked/dev/index.js +89 -0
- package/node_modules/micromark-util-chunked/index.d.ts +41 -0
- package/node_modules/micromark-util-chunked/index.d.ts.map +1 -0
- package/node_modules/micromark-util-chunked/index.js +81 -0
- package/node_modules/micromark-util-chunked/license +22 -0
- package/node_modules/micromark-util-chunked/package.json +57 -0
- package/node_modules/micromark-util-chunked/readme.md +219 -0
- package/node_modules/micromark-util-classify-character/dev/index.d.ts +18 -0
- package/node_modules/micromark-util-classify-character/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-util-classify-character/dev/index.js +38 -0
- package/node_modules/micromark-util-classify-character/index.d.ts +18 -0
- package/node_modules/micromark-util-classify-character/index.d.ts.map +1 -0
- package/node_modules/micromark-util-classify-character/index.js +27 -0
- package/node_modules/micromark-util-classify-character/license +22 -0
- package/node_modules/micromark-util-classify-character/package.json +59 -0
- package/node_modules/micromark-util-classify-character/readme.md +205 -0
- package/node_modules/micromark-util-combine-extensions/index.d.ts +22 -0
- package/node_modules/micromark-util-combine-extensions/index.d.ts.map +1 -0
- package/node_modules/micromark-util-combine-extensions/index.js +143 -0
- package/node_modules/micromark-util-combine-extensions/license +22 -0
- package/node_modules/micromark-util-combine-extensions/package.json +52 -0
- package/node_modules/micromark-util-combine-extensions/readme.md +201 -0
- package/node_modules/micromark-util-decode-numeric-character-reference/dev/index.d.ts +16 -0
- package/node_modules/micromark-util-decode-numeric-character-reference/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-util-decode-numeric-character-reference/dev/index.js +42 -0
- package/node_modules/micromark-util-decode-numeric-character-reference/index.d.ts +16 -0
- package/node_modules/micromark-util-decode-numeric-character-reference/index.d.ts.map +1 -0
- package/node_modules/micromark-util-decode-numeric-character-reference/index.js +32 -0
- package/node_modules/micromark-util-decode-numeric-character-reference/license +22 -0
- package/node_modules/micromark-util-decode-numeric-character-reference/package.json +59 -0
- package/node_modules/micromark-util-decode-numeric-character-reference/readme.md +184 -0
- package/node_modules/micromark-util-decode-string/dev/index.d.ts +14 -0
- package/node_modules/micromark-util-decode-string/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-util-decode-string/dev/index.js +53 -0
- package/node_modules/micromark-util-decode-string/index.d.ts +14 -0
- package/node_modules/micromark-util-decode-string/index.d.ts.map +1 -0
- package/node_modules/micromark-util-decode-string/index.js +45 -0
- package/node_modules/micromark-util-decode-string/license +22 -0
- package/node_modules/micromark-util-decode-string/package.json +63 -0
- package/node_modules/micromark-util-decode-string/readme.md +179 -0
- package/node_modules/micromark-util-edit-map/dev/index.d.ts +78 -0
- package/node_modules/micromark-util-edit-map/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-util-edit-map/dev/index.js +237 -0
- package/node_modules/micromark-util-edit-map/index.d.ts +78 -0
- package/node_modules/micromark-util-edit-map/index.d.ts.map +1 -0
- package/node_modules/micromark-util-edit-map/index.js +225 -0
- package/node_modules/micromark-util-edit-map/license +22 -0
- package/node_modules/micromark-util-edit-map/package.json +48 -0
- package/node_modules/micromark-util-edit-map/readme.md +234 -0
- package/node_modules/micromark-util-encode/index.d.ts +14 -0
- package/node_modules/micromark-util-encode/index.d.ts.map +1 -0
- package/node_modules/micromark-util-encode/index.js +33 -0
- package/node_modules/micromark-util-encode/license +22 -0
- package/node_modules/micromark-util-encode/package.json +47 -0
- package/node_modules/micromark-util-encode/readme.md +176 -0
- package/node_modules/micromark-util-html-tag-name/index.d.ts +30 -0
- package/node_modules/micromark-util-html-tag-name/index.d.ts.map +1 -0
- package/node_modules/micromark-util-html-tag-name/index.js +93 -0
- package/node_modules/micromark-util-html-tag-name/license +22 -0
- package/node_modules/micromark-util-html-tag-name/package.json +47 -0
- package/node_modules/micromark-util-html-tag-name/readme.md +193 -0
- package/node_modules/micromark-util-normalize-identifier/dev/index.d.ts +21 -0
- package/node_modules/micromark-util-normalize-identifier/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-util-normalize-identifier/dev/index.js +38 -0
- package/node_modules/micromark-util-normalize-identifier/index.d.ts +21 -0
- package/node_modules/micromark-util-normalize-identifier/index.d.ts.map +1 -0
- package/node_modules/micromark-util-normalize-identifier/index.js +33 -0
- package/node_modules/micromark-util-normalize-identifier/license +22 -0
- package/node_modules/micromark-util-normalize-identifier/package.json +58 -0
- package/node_modules/micromark-util-normalize-identifier/readme.md +187 -0
- package/node_modules/micromark-util-resolve-all/index.d.ts +22 -0
- package/node_modules/micromark-util-resolve-all/index.d.ts.map +1 -0
- package/node_modules/micromark-util-resolve-all/index.js +32 -0
- package/node_modules/micromark-util-resolve-all/license +22 -0
- package/node_modules/micromark-util-resolve-all/package.json +48 -0
- package/node_modules/micromark-util-resolve-all/readme.md +238 -0
- package/node_modules/micromark-util-sanitize-uri/dev/index.d.ts +36 -0
- package/node_modules/micromark-util-sanitize-uri/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-util-sanitize-uri/dev/index.js +124 -0
- package/node_modules/micromark-util-sanitize-uri/index.d.ts +36 -0
- package/node_modules/micromark-util-sanitize-uri/index.d.ts.map +1 -0
- package/node_modules/micromark-util-sanitize-uri/index.js +107 -0
- package/node_modules/micromark-util-sanitize-uri/license +22 -0
- package/node_modules/micromark-util-sanitize-uri/package.json +59 -0
- package/node_modules/micromark-util-sanitize-uri/readme.md +214 -0
- package/node_modules/micromark-util-subtokenize/dev/index.d.ts +12 -0
- package/node_modules/micromark-util-subtokenize/dev/index.d.ts.map +1 -0
- package/node_modules/micromark-util-subtokenize/dev/index.js +284 -0
- package/node_modules/micromark-util-subtokenize/dev/lib/splice-buffer.d.ts +161 -0
- package/node_modules/micromark-util-subtokenize/dev/lib/splice-buffer.d.ts.map +1 -0
- package/node_modules/micromark-util-subtokenize/dev/lib/splice-buffer.js +288 -0
- package/node_modules/micromark-util-subtokenize/index.d.ts +12 -0
- package/node_modules/micromark-util-subtokenize/index.d.ts.map +1 -0
- package/node_modules/micromark-util-subtokenize/index.js +228 -0
- package/node_modules/micromark-util-subtokenize/lib/splice-buffer.d.ts +161 -0
- package/node_modules/micromark-util-subtokenize/lib/splice-buffer.d.ts.map +1 -0
- package/node_modules/micromark-util-subtokenize/lib/splice-buffer.js +251 -0
- package/node_modules/micromark-util-subtokenize/license +22 -0
- package/node_modules/micromark-util-subtokenize/package.json +60 -0
- package/node_modules/micromark-util-subtokenize/readme.md +181 -0
- package/node_modules/micromark-util-symbol/lib/codes.d.ts +139 -0
- package/node_modules/micromark-util-symbol/lib/codes.d.ts.map +1 -0
- package/node_modules/micromark-util-symbol/lib/codes.js +158 -0
- package/node_modules/micromark-util-symbol/lib/constants.d.ts +37 -0
- package/node_modules/micromark-util-symbol/lib/constants.d.ts.map +1 -0
- package/node_modules/micromark-util-symbol/lib/constants.js +44 -0
- package/node_modules/micromark-util-symbol/lib/default.d.ts +5 -0
- package/node_modules/micromark-util-symbol/lib/default.d.ts.map +1 -0
- package/node_modules/micromark-util-symbol/lib/default.js +4 -0
- package/node_modules/micromark-util-symbol/lib/types.d.ts +106 -0
- package/node_modules/micromark-util-symbol/lib/types.d.ts.map +1 -0
- package/node_modules/micromark-util-symbol/lib/types.js +453 -0
- package/node_modules/micromark-util-symbol/lib/values.d.ts +102 -0
- package/node_modules/micromark-util-symbol/lib/values.d.ts.map +1 -0
- package/node_modules/micromark-util-symbol/lib/values.js +109 -0
- package/node_modules/micromark-util-symbol/license +22 -0
- package/node_modules/micromark-util-symbol/package.json +43 -0
- package/node_modules/micromark-util-symbol/readme.md +168 -0
- package/node_modules/micromark-util-types/index.d.ts +1315 -0
- package/node_modules/micromark-util-types/index.js +2 -0
- package/node_modules/micromark-util-types/license +22 -0
- package/node_modules/micromark-util-types/package.json +37 -0
- package/node_modules/micromark-util-types/readme.md +151 -0
- package/node_modules/smol-toml/LICENSE +24 -0
- package/node_modules/smol-toml/README.md +605 -0
- package/node_modules/smol-toml/dist/date.d.ts +41 -0
- package/node_modules/smol-toml/dist/date.js +156 -0
- package/node_modules/smol-toml/dist/error.d.ts +37 -0
- package/node_modules/smol-toml/dist/error.js +67 -0
- package/node_modules/smol-toml/dist/extract.js +289 -0
- package/node_modules/smol-toml/dist/index.cjs +770 -0
- package/node_modules/smol-toml/dist/index.d.ts +44 -0
- package/node_modules/smol-toml/dist/index.js +34 -0
- package/node_modules/smol-toml/dist/parse.d.ts +73 -0
- package/node_modules/smol-toml/dist/parse.js +164 -0
- package/node_modules/smol-toml/dist/primitive.js +151 -0
- package/node_modules/smol-toml/dist/stringify.d.ts +32 -0
- package/node_modules/smol-toml/dist/stringify.js +219 -0
- package/node_modules/smol-toml/dist/struct.js +156 -0
- package/node_modules/smol-toml/dist/util.d.ts +43 -0
- package/node_modules/smol-toml/dist/util.js +57 -0
- package/node_modules/smol-toml/package.json +68 -0
- package/node_modules/unist-util-stringify-position/index.d.ts +1 -0
- package/node_modules/unist-util-stringify-position/index.js +1 -0
- package/node_modules/unist-util-stringify-position/lib/index.d.ts +61 -0
- package/node_modules/unist-util-stringify-position/lib/index.js +84 -0
- package/node_modules/unist-util-stringify-position/license +22 -0
- package/node_modules/unist-util-stringify-position/package.json +80 -0
- package/node_modules/unist-util-stringify-position/readme.md +206 -0
- package/package.json +27 -8
- package/scripts/prepare-github-keyring.js +29 -0
- package/src/codex-app.js +20 -2
- package/src/codex-pricing.js +79 -0
- package/src/codex-projects.js +90 -0
- package/src/codex-session-scanner.js +748 -0
- package/src/codex-session-usage.js +332 -0
- package/src/dashboard/app.js +2 -2
- package/src/dashboard/dist/app.js +135 -60
- package/src/dashboard/dist/app.js.map +1 -1
- package/src/dashboard/dist/styles.css +1 -1
- package/src/dashboard/react/components/AnimatedUsage.test.tsx +78 -0
- package/src/dashboard/react/components/CardStatusIcons.test.tsx +146 -0
- package/src/dashboard/react/components/CardStatusIcons.tsx +138 -0
- package/src/dashboard/react/components/ImageGallery.tsx +22 -0
- package/src/dashboard/react/components/ModelSettings.test.tsx +4 -4
- package/src/dashboard/react/components/ModelSettings.tsx +1 -1
- package/src/dashboard/react/components/OpenChatButton.test.tsx +19 -0
- package/src/dashboard/react/components/OpenChatButton.tsx +2 -1
- package/src/dashboard/react/components/PrGlyph.tsx +35 -0
- package/src/dashboard/react/components/PullRequestBadges.tsx +18 -0
- package/src/dashboard/react/components/QueuedPrompts.test.tsx +42 -0
- package/src/dashboard/react/components/QueuedPrompts.tsx +34 -0
- package/src/dashboard/react/components/RelativeTime.test.tsx +100 -0
- package/src/dashboard/react/components/RelativeTime.tsx +46 -11
- package/src/dashboard/react/components/ReplyCover.test.tsx +30 -0
- package/src/dashboard/react/components/ReplyCover.tsx +33 -0
- package/src/dashboard/react/components/ReplyImagePreview.test.tsx +90 -0
- package/src/dashboard/react/components/ReplyImagePreview.tsx +34 -0
- package/src/dashboard/react/components/ReplyMarkdown.test.tsx +108 -0
- package/src/dashboard/react/components/ReplyMarkdown.tsx +112 -0
- package/src/dashboard/react/components/SavedUsageFormat.test.tsx +11 -0
- package/src/dashboard/react/components/SavedUsageFormat.tsx +68 -0
- package/src/dashboard/react/components/StatusBadge.tsx +2 -2
- package/src/dashboard/react/components/TaskBoard.test.tsx +256 -1
- package/src/dashboard/react/components/TaskBoard.tsx +136 -28
- package/src/dashboard/react/components/TaskCard.tsx +7 -4
- package/src/dashboard/react/components/TaskDetail.test.tsx +92 -1
- package/src/dashboard/react/components/TaskDetail.tsx +37 -10
- package/src/dashboard/react/components/TurnContent.test.tsx +44 -0
- package/src/dashboard/react/components/TurnContent.tsx +53 -0
- package/src/dashboard/react/components/UsagePanel.tsx +2 -2
- package/src/dashboard/react/image-cache.test.ts +23 -0
- package/src/dashboard/react/image-cache.ts +33 -0
- package/src/dashboard/react/presentation.test.tsx +31 -0
- package/src/dashboard/react/styles.css +126 -2
- package/src/dashboard/react/types.ts +55 -1
- package/src/dashboard/time.js +39 -0
- package/src/dashboard.js +4 -3
- package/src/data/codex-pricing.json +537 -0
- package/src/mcp-app/dist/index.html +216 -112
- package/src/mcp-app/react/AppearancePicker.test.tsx +50 -0
- package/src/mcp-app/react/AppearancePicker.tsx +56 -0
- package/src/mcp-app/react/GitHubConnection.test.tsx +78 -0
- package/src/mcp-app/react/GitHubConnection.tsx +78 -0
- package/src/mcp-app/react/NextNotificationCenter.test.tsx +121 -0
- package/src/mcp-app/react/NextNotificationCenter.tsx +94 -0
- package/src/mcp-app/react/NextTaskDetail.test.tsx +124 -0
- package/src/mcp-app/react/NextTaskDetail.tsx +147 -0
- package/src/mcp-app/react/ProjectPicker.tsx +49 -0
- package/src/mcp-app/react/main.test.tsx +499 -49
- package/src/mcp-app/react/main.tsx +359 -86
- package/src/mcp-app/react/styles.css +186 -9
- package/src/mcp-app/react/themes.test.ts +34 -0
- package/src/mcp-app/react/themes.ts +112 -0
- package/src/mcp-app.js +238 -120
- package/src/mcp.js +8 -1
- package/src/next-cache.js +16 -0
- package/src/next-github.js +273 -0
- package/src/next-notifications.js +90 -0
- package/src/recorded-usage-tracker.js +92 -0
- package/src/reply-image.js +65 -0
- package/src/usage-tracker.js +7 -6
- package/src/usage.js +7 -355
- package/src/user-prompt.js +55 -0
- package/src/version.js +2 -1
- package/node_modules/proper-lockfile/CHANGELOG.md +0 -108
- package/node_modules/which/CHANGELOG.md +0 -166
- package/src/resolve-ccusage.js +0 -17
|
@@ -4,13 +4,86 @@ import { useState } from "react";
|
|
|
4
4
|
import { afterEach, expect, test, vi } from "vitest";
|
|
5
5
|
import { fixtureTask } from "../fixtures";
|
|
6
6
|
import { ActivityTimeline } from "./ActivityTimeline";
|
|
7
|
-
import { ManualTransitionConfirmation, type TerminalStatus } from "./TaskDetail";
|
|
7
|
+
import { ManualTransitionConfirmation, TaskDetail, type TerminalStatus } from "./TaskDetail";
|
|
8
8
|
|
|
9
9
|
afterEach(() => {
|
|
10
10
|
cleanup();
|
|
11
11
|
vi.restoreAllMocks();
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
+
test("shows only metadata available from a DB-backed observed task", () => {
|
|
15
|
+
renderObservedDetail({
|
|
16
|
+
archive: false,
|
|
17
|
+
lastTurnEvent: "inProgress",
|
|
18
|
+
lastTurnEventAt: null,
|
|
19
|
+
recentFileActivity: true,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const metadata = screen.getByRole("heading", { name: "Metadata" }).closest("section")!;
|
|
23
|
+
expect(within(metadata).getByText("Archive status")).toBeVisible();
|
|
24
|
+
expect(within(metadata).getByText("Active")).toBeVisible();
|
|
25
|
+
expect(within(metadata).queryByText("Location")).not.toBeInTheDocument();
|
|
26
|
+
expect(within(metadata).getByText("inProgress")).toBeVisible();
|
|
27
|
+
expect(within(metadata).queryByText("Observed messages")).not.toBeInTheDocument();
|
|
28
|
+
expect(within(metadata).queryByText("Log bytes sampled")).not.toBeInTheDocument();
|
|
29
|
+
expect(within(metadata).getByText("Queue reason")).toBeVisible();
|
|
30
|
+
expect(metadata).not.toHaveTextContent("undefined");
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("shows archived database chat status without claiming a file location", () => {
|
|
34
|
+
renderObservedDetail({
|
|
35
|
+
archive: true,
|
|
36
|
+
lastTurnEvent: "completed",
|
|
37
|
+
lastTurnEventAt: null,
|
|
38
|
+
recentFileActivity: false,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const metadata = screen.getByRole("heading", { name: "Metadata" }).closest("section")!;
|
|
42
|
+
expect(within(metadata).getByText("Archive status")).toBeVisible();
|
|
43
|
+
expect(within(metadata).getByText("Archived")).toBeVisible();
|
|
44
|
+
expect(within(metadata).queryByText("Location")).not.toBeInTheDocument();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("keeps log message and byte counts in observed task metadata", () => {
|
|
48
|
+
renderObservedDetail({
|
|
49
|
+
archive: true,
|
|
50
|
+
lastTurnEvent: "completed",
|
|
51
|
+
lastTurnEventAt: null,
|
|
52
|
+
recentFileActivity: false,
|
|
53
|
+
userMessages: 2,
|
|
54
|
+
assistantMessages: 3,
|
|
55
|
+
sampledBytes: 1024,
|
|
56
|
+
fileBytes: 4096,
|
|
57
|
+
}, "Local Codex log");
|
|
58
|
+
|
|
59
|
+
const metadata = screen.getByRole("heading", { name: "Metadata" }).closest("section")!;
|
|
60
|
+
expect(within(metadata).getByText("Location")).toBeVisible();
|
|
61
|
+
expect(within(metadata).getByText("Archived sessions")).toBeVisible();
|
|
62
|
+
expect(within(metadata).getByText("Observed messages")).toBeVisible();
|
|
63
|
+
expect(within(metadata).getByText("2 user, 3 assistant")).toBeVisible();
|
|
64
|
+
expect(within(metadata).getByText("Log bytes sampled")).toBeVisible();
|
|
65
|
+
expect(within(metadata).getByText("1024 of 4096")).toBeVisible();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
function renderObservedDetail(observed: NonNullable<ReturnType<typeof fixtureTask>["observed"]>, updatedBy = "Local Codex database") {
|
|
69
|
+
render(
|
|
70
|
+
<MantineProvider>
|
|
71
|
+
<TaskDetail
|
|
72
|
+
busy={false}
|
|
73
|
+
error={null}
|
|
74
|
+
highlightTurnRef={null}
|
|
75
|
+
onClose={() => {}}
|
|
76
|
+
onCopy={() => {}}
|
|
77
|
+
onOpenCodex={() => {}}
|
|
78
|
+
onTransition={async () => ({ ok: true })}
|
|
79
|
+
opened
|
|
80
|
+
readOnly
|
|
81
|
+
task={fixtureTask({ observed, updatedBy })}
|
|
82
|
+
/>
|
|
83
|
+
</MantineProvider>,
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
14
87
|
test("clears a manual-transition confirmation only after success", async () => {
|
|
15
88
|
const onTransition = vi.fn().mockResolvedValue({ ok: true });
|
|
16
89
|
render(<ConfirmationHarness onTransition={onTransition} />);
|
|
@@ -162,3 +235,21 @@ function ConfirmationHarness({ onTransition }: { onTransition: (status: Terminal
|
|
|
162
235
|
</MantineProvider>
|
|
163
236
|
);
|
|
164
237
|
}
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
test("read-only Details allows copying an ID without exposing manual status actions", () => {
|
|
241
|
+
const onCopy = vi.fn();
|
|
242
|
+
render(<MantineProvider><TaskDetail busy={false} error={null} highlightTurnRef={null} onClose={vi.fn()} onCopy={onCopy} onOpenCodex={vi.fn()} onTransition={vi.fn()} opened readOnly task={fixtureTask()} /></MantineProvider>);
|
|
243
|
+
expect(screen.queryByRole("button", {name:"More task actions"})).not.toBeInTheDocument();
|
|
244
|
+
fireEvent.click(screen.getByRole("button", {name:"Copy Task ID"}));
|
|
245
|
+
expect(onCopy).toHaveBeenCalledOnce();
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
test("observed web details show the full same-turn request and response", () => {
|
|
249
|
+
const task=fixtureTask({promptExcerpt:'Short request',promptText:'Full recorded request',replyExcerpt:'Short response',replyText:'Full recorded response',
|
|
250
|
+
observed:{archive:false,lastTurnEvent:'completed',lastTurnEventAt:null,recentFileActivity:false}});
|
|
251
|
+
render(<MantineProvider><TaskDetail task={task} opened readOnly busy={false} error={null} highlightTurnRef={null} onClose={()=>{}} onCopy={()=>{}} onOpenCodex={()=>{}} onTransition={async()=>({ok:true})} /></MantineProvider>);
|
|
252
|
+
expect(screen.getByLabelText('Latest turn request')).toHaveTextContent('Full recorded request');
|
|
253
|
+
expect(screen.getByLabelText('Latest turn response')).toHaveTextContent('Full recorded response');
|
|
254
|
+
expect(screen.queryByText('Latest saved reply (excerpt)')).toBeNull();
|
|
255
|
+
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PullRequestBadges } from "./PullRequestBadges";
|
|
1
2
|
import {
|
|
2
3
|
ActionIcon,
|
|
3
4
|
Alert,
|
|
@@ -26,6 +27,7 @@ import type { Task } from "../types";
|
|
|
26
27
|
import { ActivityTimeline } from "./ActivityTimeline";
|
|
27
28
|
import { GitHubLinks } from "./GitHubLinks";
|
|
28
29
|
import { OpenChatButton } from "./OpenChatButton";
|
|
30
|
+
import { TurnContent } from "./TurnContent";
|
|
29
31
|
import { RelativeTime } from "./RelativeTime";
|
|
30
32
|
import { StatusBadge } from "./StatusBadge";
|
|
31
33
|
import { UsagePanel } from "./UsagePanel";
|
|
@@ -48,6 +50,8 @@ export function TaskDetail({
|
|
|
48
50
|
task,
|
|
49
51
|
notifications,
|
|
50
52
|
notice,
|
|
53
|
+
readOnly = false,
|
|
54
|
+
extraActions,
|
|
51
55
|
}: {
|
|
52
56
|
busy: boolean;
|
|
53
57
|
error: string | null;
|
|
@@ -60,6 +64,8 @@ export function TaskDetail({
|
|
|
60
64
|
task: Task | null;
|
|
61
65
|
notifications?: ReactNode;
|
|
62
66
|
notice?: string | null;
|
|
67
|
+
readOnly?: boolean;
|
|
68
|
+
extraActions?: React.ReactNode;
|
|
63
69
|
}) {
|
|
64
70
|
const mobile = useMediaQuery("(max-width: 48em)");
|
|
65
71
|
const [confirmStatus, setConfirmStatus] = useState<TerminalStatus | null>(null);
|
|
@@ -90,11 +96,13 @@ export function TaskDetail({
|
|
|
90
96
|
<Text c="teal" fw={700} size="xs" tt="uppercase">{task.project.name}</Text>
|
|
91
97
|
<Title id="task-detail-title" order={2} size="h3" tabIndex={-1}>{task.title}</Title>
|
|
92
98
|
</Box>
|
|
93
|
-
<StatusBadge status={task.status} />
|
|
99
|
+
<StatusBadge status={task.status} label={task.statusLabel} />
|
|
94
100
|
</Group>
|
|
95
101
|
<Group gap="xs" mt="md">
|
|
96
102
|
<OpenChatButton loading={busy} onClick={onOpenCodex} taskTitle={task.title} />
|
|
97
|
-
|
|
103
|
+
{extraActions}
|
|
104
|
+
{readOnly && <Button leftSection={<IconClipboard size={14} />} onClick={onCopy} variant="default">Copy Task ID</Button>}
|
|
105
|
+
{!readOnly && <Menu position="bottom-start" shadow="md" withinPortal zIndex={360}>
|
|
98
106
|
<Menu.Target>
|
|
99
107
|
<Tooltip label="More task actions">
|
|
100
108
|
<ActionIcon aria-label="More task actions" className="taskchef-detail-more" disabled={busy} variant="default">
|
|
@@ -111,9 +119,10 @@ export function TaskDetail({
|
|
|
111
119
|
<Menu.Item color="red" leftSection={<IconX size={14} />} onClick={() => setConfirmStatus("failed")}>Mark failed</Menu.Item>
|
|
112
120
|
)}
|
|
113
121
|
</Menu.Dropdown>
|
|
114
|
-
</Menu>
|
|
122
|
+
</Menu>}
|
|
115
123
|
</Group>
|
|
116
124
|
<Box mt="sm">
|
|
125
|
+
<PullRequestBadges pullRequests={task.pullRequests} />
|
|
117
126
|
<GitHubLinks task={task} />
|
|
118
127
|
</Box>
|
|
119
128
|
</Box>
|
|
@@ -130,19 +139,20 @@ export function TaskDetail({
|
|
|
130
139
|
{notice && <Alert color="teal" role="status">{notice}</Alert>}
|
|
131
140
|
{error && <Alert color="red" role="alert">{error}</Alert>}
|
|
132
141
|
|
|
133
|
-
<section aria-labelledby="usage-heading">
|
|
142
|
+
{!readOnly && <section aria-labelledby="usage-heading">
|
|
134
143
|
<Title id="usage-heading" mb="xs" order={3} size="h5">Usage</Title>
|
|
135
144
|
<UsagePanel task={task} />
|
|
136
|
-
</section>
|
|
137
|
-
<Divider />
|
|
138
|
-
<section aria-labelledby="activity-heading">
|
|
145
|
+
</section>}
|
|
146
|
+
{!readOnly && <Divider />}
|
|
147
|
+
{!readOnly && <section aria-labelledby="activity-heading">
|
|
139
148
|
<Title id="activity-heading" mb="sm" order={3} size="h5">Activity timeline</Title>
|
|
140
149
|
<ActivityTimeline highlightTurnRef={highlightTurnRef} task={task} />
|
|
141
|
-
</section>
|
|
142
|
-
<section aria-labelledby="instruction-heading">
|
|
150
|
+
</section>}
|
|
151
|
+
{!readOnly && <section aria-labelledby="instruction-heading">
|
|
143
152
|
<Title id="instruction-heading" mb="xs" order={3} size="h5">Original instruction</Title>
|
|
144
153
|
<Box className="taskchef-code-panel" component="pre">{task.instruction}</Box>
|
|
145
|
-
</section>
|
|
154
|
+
</section>}
|
|
155
|
+
{task.observed && <section aria-label="Latest turn"><TurnContent task={task} /></section>}
|
|
146
156
|
<section aria-labelledby="metadata-heading">
|
|
147
157
|
<Title id="metadata-heading" mb="xs" order={3} size="h5">Metadata</Title>
|
|
148
158
|
<dl className="taskchef-metadata">
|
|
@@ -153,6 +163,23 @@ export function TaskDetail({
|
|
|
153
163
|
<dt>Created</dt><dd><RelativeTime label="Created time" value={task.createdAt} /></dd>
|
|
154
164
|
<dt>Updated</dt><dd><RelativeTime label="Updated time" value={task.meaningfulUpdatedAt ?? task.updatedAt} /></dd>
|
|
155
165
|
<dt>Updated by</dt><dd>{task.updatedBy ?? "—"}</dd>
|
|
166
|
+
{task.observed?.directChildCount !== undefined && <><dt>Direct subagent chats (all history)</dt><dd>{task.observed.directChildCount}</dd></>}
|
|
167
|
+
{task.observed && <>
|
|
168
|
+
<dt>Queue reason</dt><dd>{task.summary}</dd>
|
|
169
|
+
{task.updatedBy === "Local Codex database" ? <>
|
|
170
|
+
<dt>Archive status</dt><dd>{task.observed.archive ? "Archived" : "Active"}</dd>
|
|
171
|
+
</> : <>
|
|
172
|
+
<dt>Location</dt><dd>{task.observed.archive ? "Archived sessions" : "Active sessions"}</dd>
|
|
173
|
+
</>}
|
|
174
|
+
{task.statusLabel && <><dt>Schedule</dt><dd>{task.scheduled ? "Active" : "None active"}</dd><dt>Latest input</dt><dd>{task.inputSource}</dd><dt>Done reason</dt><dd>{task.observed.archive ? "Archived" : task.manualDone ? "Manual mark" : "Not marked"}</dd></>}
|
|
175
|
+
<dt>Latest turn event</dt><dd>{task.observed.lastTurnEvent ?? "Unknown"}</dd>
|
|
176
|
+
{task.observed.userMessages !== undefined && task.observed.assistantMessages !== undefined && <>
|
|
177
|
+
<dt>Observed messages</dt><dd>{task.observed.userMessages} user, {task.observed.assistantMessages} assistant</dd>
|
|
178
|
+
</>}
|
|
179
|
+
{task.observed.sampledBytes !== undefined && task.observed.fileBytes !== undefined && <>
|
|
180
|
+
<dt>Log bytes sampled</dt><dd>{task.observed.sampledBytes} of {task.observed.fileBytes}</dd>
|
|
181
|
+
</>}
|
|
182
|
+
</>}
|
|
156
183
|
</dl>
|
|
157
184
|
</section>
|
|
158
185
|
</Stack>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { cleanup, render, screen } from "@testing-library/react";
|
|
2
|
+
import { afterEach, expect, test } from "vitest";
|
|
3
|
+
import { fixtureTask } from "../fixtures";
|
|
4
|
+
import { TurnContent } from "./TurnContent";
|
|
5
|
+
afterEach(cleanup);
|
|
6
|
+
test("a running request is visible without a stale or placeholder reply", () => {
|
|
7
|
+
const task={...fixtureTask(),status:"working" as const,promptExcerpt:"Current **request**",replyExcerpt:null};
|
|
8
|
+
render(<TurnContent task={task} compact />);
|
|
9
|
+
expect(screen.getByLabelText("Latest turn request").querySelector('strong')?.textContent).toBe('request');
|
|
10
|
+
expect(screen.queryByLabelText("Latest turn response")).toBeNull();
|
|
11
|
+
});
|
|
12
|
+
test("details use full text, and only actual scheduled input has a clock", () => {
|
|
13
|
+
const task={...fixtureTask(),scheduled:true,inputSource:"ordinary" as const,promptExcerpt:"Short",promptText:"Full request",replyExcerpt:"Short result",replyText:"Full result"};
|
|
14
|
+
const {rerender}=render(<TurnContent task={task} />);
|
|
15
|
+
expect(screen.getByText('Full request')).toBeVisible(); expect(screen.getByText('Full result')).toBeVisible();
|
|
16
|
+
expect(screen.queryByLabelText('Scheduled prompt')).toBeNull();
|
|
17
|
+
rerender(<TurnContent task={{...task,inputSource:'scheduled'}} />);
|
|
18
|
+
expect(screen.getByLabelText('Scheduled prompt')).toBeVisible();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("cards show only the prompt while running and only the response otherwise", () => {
|
|
22
|
+
const task={...fixtureTask(),status:"working" as const,promptExcerpt:"Current request",replyExcerpt:"Current response"};
|
|
23
|
+
const {rerender}=render(<TurnContent task={task} compact />);
|
|
24
|
+
expect(screen.getByText('Current request')).toBeVisible();expect(screen.queryByText('Current response')).toBeNull();
|
|
25
|
+
rerender(<TurnContent task={{...task,status:'needs_input'}} compact />);
|
|
26
|
+
expect(screen.queryByText('Current request')).toBeNull();expect(screen.getByText('Current response')).toBeVisible();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
test("details hide generated request labels and put worked time before the complete reply", () => {
|
|
31
|
+
render(<TurnContent task={{...fixtureTask(),promptText:"## My request:\nPlease review.",replyText:"Full response.",observed:{archive:false,recentFileActivity:false,lastTurnEvent:"completed",lastTurnEventAt:null,latestTurnDurationMs:298000}}} />);
|
|
32
|
+
expect(screen.getByLabelText('Latest turn request')).toHaveTextContent('Please review.');
|
|
33
|
+
expect(screen.getByLabelText('Latest turn request')).not.toHaveTextContent('My request:');
|
|
34
|
+
expect(screen.getByRole('separator')).toHaveTextContent('Worked for 4m');
|
|
35
|
+
expect(screen.getByLabelText('Latest turn response')).toHaveTextContent('Full response.');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("card prompt cleanup does not change response headings", () => {
|
|
39
|
+
const task={...fixtureTask(),status:"working" as const,promptExcerpt:"## My request:\nReview this.",replyExcerpt:"## My requests:\nA response section."};
|
|
40
|
+
const {rerender}=render(<TurnContent task={task} compact />);
|
|
41
|
+
expect(screen.getByLabelText("Latest turn request")).not.toHaveTextContent("My request:");
|
|
42
|
+
rerender(<TurnContent task={{...task,status:"needs_input"}} compact />);
|
|
43
|
+
expect(screen.getByLabelText("Latest turn response")).toHaveTextContent("My requests:");
|
|
44
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { IconClock } from "@tabler/icons-react";
|
|
2
|
+
import { useCallback, useLayoutEffect, useRef, useState } from "react";
|
|
3
|
+
import type { Task } from "../types";
|
|
4
|
+
import { ImageGallery } from "./ImageGallery";
|
|
5
|
+
import { ReplyImagePreview } from "./ReplyImagePreview";
|
|
6
|
+
import { formatWorkedDuration } from "../../time.js";
|
|
7
|
+
import { ReplyMarkdown } from "./ReplyMarkdown";
|
|
8
|
+
|
|
9
|
+
const hidePromptImage = () => null;
|
|
10
|
+
|
|
11
|
+
export function CollapsedMarkdown({ text }: { text: string }) {
|
|
12
|
+
const content = useRef<HTMLDivElement>(null);
|
|
13
|
+
const [expanded, setExpanded] = useState(false);
|
|
14
|
+
const [clipped, setClipped] = useState(false);
|
|
15
|
+
useLayoutEffect(() => {
|
|
16
|
+
const element = content.current;
|
|
17
|
+
if (!element || expanded) return;
|
|
18
|
+
const measure = () => setClipped(element.scrollHeight > element.clientHeight + 1);
|
|
19
|
+
measure();
|
|
20
|
+
const observer = new ResizeObserver(measure);
|
|
21
|
+
observer.observe(element);
|
|
22
|
+
return () => observer.disconnect();
|
|
23
|
+
}, [text, expanded]);
|
|
24
|
+
return <>
|
|
25
|
+
<div ref={content} className={expanded ? "" : "taskchef-turn-collapsed"}><ReplyMarkdown text={text} hideRequestLabels renderImage={hidePromptImage} /></div>
|
|
26
|
+
{(clipped || expanded) && <button type="button" className="taskchef-turn-expand" aria-expanded={expanded} onClick={() => setExpanded(value => !value)}>{expanded ? "Show less" : "Show more…"}</button>}
|
|
27
|
+
</>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function TurnContent({ task, compact = false, loadImage, workedDurationMs, onLightboxChange, onAnnotationChange }: { task: Task; compact?: boolean; loadImage?: (task: Task, url?: string) => Promise<string | null>; workedDurationMs?: number | null; onLightboxChange?: (opened: boolean) => void; onAnnotationChange?: (id: string, opened: boolean) => void }) {
|
|
31
|
+
const currentTask = useRef(task);
|
|
32
|
+
currentTask.current = task;
|
|
33
|
+
const renderImage = useCallback((url: string, alt: string) => loadImage ? <ReplyImagePreview key={`${task.id}:${task.turnId}:${url}`} task={currentTask.current} url={url} alt={alt} loadImage={loadImage} onLightboxChange={onLightboxChange} /> : null, [task.id, task.turnId, loadImage, onLightboxChange]);
|
|
34
|
+
const prompt = compact ? task.promptExcerpt : task.promptText ?? task.promptExcerpt;
|
|
35
|
+
const reply = compact ? task.replyExcerpt : task.replyText ?? task.replyExcerpt;
|
|
36
|
+
if (compact) {
|
|
37
|
+
const text = task.status === "working" ? prompt : reply;
|
|
38
|
+
return text ? <div className="taskchef-turn-card" aria-label={task.status === "working" ? "Latest turn request" : "Latest turn response"}><ReplyMarkdown key={`${task.id}:${task.turnId}`} compact annotations={task.annotations} hideRequestLabels={task.status === "working"} text={text} renderImage={task.status === "working" ? hidePromptImage : undefined} /></div> : null;
|
|
39
|
+
}
|
|
40
|
+
const promptImages = task.promptImages ?? (task.promptImage ? [task.promptImage] : []);
|
|
41
|
+
const duration = workedDurationMs ?? task.observed?.latestTurnDurationMs;
|
|
42
|
+
return <div className="taskchef-turn-content">
|
|
43
|
+
{prompt && <div className="taskchef-turn-prompt" aria-label="Latest turn request">
|
|
44
|
+
{task.inputSource === "scheduled" && <IconClock className="taskchef-schedule-clock taskchef-prompt-clock" size={14} stroke={1.5} aria-label="Scheduled prompt" />}
|
|
45
|
+
{loadImage && promptImages.length > 0 && <ImageGallery task={task} images={promptImages} loadImage={loadImage} onLightboxChange={onLightboxChange} />}
|
|
46
|
+
<CollapsedMarkdown key={`prompt:${task.id}:${task.turnId}`} text={prompt} />
|
|
47
|
+
</div>}
|
|
48
|
+
{reply && <>
|
|
49
|
+
<div className="taskchef-turn-divider" role="separator">{duration != null && Number.isFinite(duration) && duration >= 0 ? `Worked for ${formatWorkedDuration(duration)}` : null}</div>
|
|
50
|
+
<div className="taskchef-turn-response" aria-label="Latest turn response"><ReplyMarkdown key={`${task.id}:${task.turnId}`} onAnnotationChange={onAnnotationChange} annotations={task.annotations} text={reply} renderImage={loadImage ? renderImage : undefined} /></div>
|
|
51
|
+
</>}
|
|
52
|
+
</div>;
|
|
53
|
+
}
|
|
@@ -36,7 +36,7 @@ export function UsagePanel({ task }: { task: Task }) {
|
|
|
36
36
|
animated: usage.kind === "pending" || usage.kind === "calculating" || ready?.knownSoFar,
|
|
37
37
|
label: "Tokens",
|
|
38
38
|
title: ready ? `${formatFullTokens(ready.usage.totalTokens)} tokens` : usage.label,
|
|
39
|
-
value: ready ? formatCompactTokens(ready.usage.totalTokens) : stateValue,
|
|
39
|
+
value: ready ? `${ready.usage.partial ? "≥" : ""}${formatCompactTokens(ready.usage.totalTokens)}` : stateValue,
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
accessibleValue: ready
|
|
@@ -54,7 +54,7 @@ export function UsagePanel({ task }: { task: Task }) {
|
|
|
54
54
|
? "Estimated cost unavailable"
|
|
55
55
|
: `Unrounded estimate: $${ready.usage.estimatedCostUsd}`,
|
|
56
56
|
value: ready
|
|
57
|
-
? ready.usage.estimatedCostUsd == null ? "n/a" : formatEstimatedCost(ready.usage.estimatedCostUsd)
|
|
57
|
+
? ready.usage.estimatedCostUsd == null ? "n/a" : `${ready.usage.costPartial ? "≥" : ""}${formatEstimatedCost(ready.usage.estimatedCostUsd)}`
|
|
58
58
|
: stateValue,
|
|
59
59
|
},
|
|
60
60
|
{
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { expect, test, vi } from "vitest";
|
|
2
|
+
import { cachedImageLoader } from "./image-cache";
|
|
3
|
+
import { fixtureTask } from "./fixtures";
|
|
4
|
+
|
|
5
|
+
test('covers and Details share in-flight and completed image requests, scoped to turn and chat', async () => {
|
|
6
|
+
const load = vi.fn().mockResolvedValue('data:image/png;base64,AAAA');
|
|
7
|
+
const cached = cachedImageLoader(load); const task = {...fixtureTask(), turnId:'turn-1'};
|
|
8
|
+
const first = cached(task,'/image.png');
|
|
9
|
+
expect(cached(task,'/image.png')).toBe(first);
|
|
10
|
+
await first; await cached(task,'/image.png');
|
|
11
|
+
expect(load).toHaveBeenCalledTimes(1);
|
|
12
|
+
await cached({...task,turnId:'turn-2'},'/image.png');
|
|
13
|
+
await cached({...task,id:'other-chat'},'/image.png');
|
|
14
|
+
expect(load).toHaveBeenCalledTimes(3);
|
|
15
|
+
});
|
|
16
|
+
test('failed and missing images can be retried', async () => {
|
|
17
|
+
const load = vi.fn().mockResolvedValueOnce(null).mockRejectedValueOnce(new Error('offline')).mockResolvedValue('data:image/png;base64,AAAA');
|
|
18
|
+
const cached = cachedImageLoader(load); const task = fixtureTask();
|
|
19
|
+
expect(await cached(task,'/image.png')).toBeNull();
|
|
20
|
+
await expect(cached(task,'/image.png')).rejects.toThrow('offline');
|
|
21
|
+
expect(await cached(task,'/image.png')).toContain('data:image/png');
|
|
22
|
+
expect(load).toHaveBeenCalledTimes(3);
|
|
23
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Task } from "./types";
|
|
2
|
+
|
|
3
|
+
// Covers and Details reuse the same request. Bound retained image data per board.
|
|
4
|
+
export function cachedImageLoader(load: (task: Task, url?: string) => Promise<string | null>) {
|
|
5
|
+
const cache = new Map<string, { promise: Promise<string | null>; bytes: number }>();
|
|
6
|
+
let bytes = 0;
|
|
7
|
+
return (task: Task, url?: string): Promise<string | null> => {
|
|
8
|
+
const key = JSON.stringify([task.id, task.turnId, url]);
|
|
9
|
+
const existing = cache.get(key);
|
|
10
|
+
if (existing) { cache.delete(key); cache.set(key, existing); return existing.promise; }
|
|
11
|
+
const entry = { bytes: 0, promise: Promise.resolve(null) as Promise<string | null> };
|
|
12
|
+
entry.promise = load(task, url).then(source => {
|
|
13
|
+
if (!source) { if (cache.get(key) === entry) cache.delete(key); return null; }
|
|
14
|
+
if (cache.get(key) === entry) {
|
|
15
|
+
entry.bytes = source.length * 2;
|
|
16
|
+
bytes += entry.bytes;
|
|
17
|
+
while (cache.size > 64 || bytes > 32 * 1024 * 1024) {
|
|
18
|
+
const oldest = cache.keys().next().value!;
|
|
19
|
+
bytes -= cache.get(oldest)!.bytes;
|
|
20
|
+
cache.delete(oldest);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return source;
|
|
24
|
+
}, error => { if (cache.get(key) === entry) cache.delete(key); throw error; });
|
|
25
|
+
cache.set(key, entry);
|
|
26
|
+
while (cache.size > 64) {
|
|
27
|
+
const oldest = cache.keys().next().value!;
|
|
28
|
+
bytes -= cache.get(oldest)!.bytes;
|
|
29
|
+
cache.delete(oldest);
|
|
30
|
+
}
|
|
31
|
+
return entry.promise;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -18,9 +18,40 @@ import { ShimmerText } from "./components/ShimmerText";
|
|
|
18
18
|
import { GitHubLinks } from "./components/GitHubLinks";
|
|
19
19
|
import { LinkedText } from "./components/LinkedText";
|
|
20
20
|
import { UsagePanel } from "./components/UsagePanel";
|
|
21
|
+
import { TaskCard } from "./components/TaskCard";
|
|
22
|
+
import { TaskBoard } from "./components/TaskBoard";
|
|
21
23
|
|
|
22
24
|
afterEach(cleanup);
|
|
23
25
|
|
|
26
|
+
test("Next cards show saved replies and keep diagnostics off the card", () => {
|
|
27
|
+
const parent = fixtureTask({
|
|
28
|
+
status: "needs_input", updatedBy: "Local Codex database", replyExcerpt: "**CI passed.** The PR is ready for review.",
|
|
29
|
+
summary: "Latest turn ended. Chat remains open for input or review.",
|
|
30
|
+
observed: { archive: false, lastTurnEvent: "completed", lastTurnEventAt: null, recentFileActivity: false, directChildCount: 133 },
|
|
31
|
+
});
|
|
32
|
+
const empty = fixtureTask({ id: "empty", title: "Empty", replyExcerpt: null, observed: { archive: false, lastTurnEvent: "inProgress", lastTurnEventAt: null, recentFileActivity: true, directChildCount: 0 } });
|
|
33
|
+
render(<MantineProvider>
|
|
34
|
+
<TaskCard task={parent} onOpenCodex={() => {}} onOpenDetail={() => {}} />
|
|
35
|
+
<TaskBoard tasks={[parent, empty]} completedLimit={5} onMoreCompleted={() => {}} onOpenCodex={() => {}} onOpenDetail={() => {}} />
|
|
36
|
+
</MantineProvider>);
|
|
37
|
+
expect(screen.getAllByText("CI passed.")).toHaveLength(2);
|
|
38
|
+
expect(screen.queryByText(/direct subagent/)).not.toBeInTheDocument();
|
|
39
|
+
expect(screen.queryByText(/Latest turn ended/)).not.toBeInTheDocument();
|
|
40
|
+
expect(screen.queryByText("No reply text to show for this turn.")).not.toBeInTheDocument();
|
|
41
|
+
expect(screen.queryByText("Request")).not.toBeInTheDocument();
|
|
42
|
+
expect(screen.queryByText("Result")).not.toBeInTheDocument();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("observed list cards show the prompt while running and the response otherwise", () => {
|
|
46
|
+
const task = fixtureTask({ status: "working", promptExcerpt: "Current request", replyExcerpt: "Previous result", observed: { archive: false, lastTurnEvent: "inProgress", lastTurnEventAt: null, recentFileActivity: true, directChildCount: 0 } });
|
|
47
|
+
const { rerender } = render(<MantineProvider><TaskCard task={task} onOpenCodex={() => {}} onOpenDetail={() => {}} /></MantineProvider>);
|
|
48
|
+
expect(screen.getByText("Current request")).toBeInTheDocument();
|
|
49
|
+
expect(screen.queryByText("Previous result")).not.toBeInTheDocument();
|
|
50
|
+
rerender(<MantineProvider><TaskCard task={{ ...task, status: "needs_input" }} onOpenCodex={() => {}} onOpenDetail={() => {}} /></MantineProvider>);
|
|
51
|
+
expect(screen.getByText("Previous result")).toBeInTheDocument();
|
|
52
|
+
expect(screen.queryByText("Current request")).not.toBeInTheDocument();
|
|
53
|
+
});
|
|
54
|
+
|
|
24
55
|
describe("token and working presentation", () => {
|
|
25
56
|
test("keeps pending, calculating, ready cost, and unavailable wording distinct", () => {
|
|
26
57
|
expect(usageView(fixtureTask()).label).toBe("Token usage pending");
|
|
@@ -104,11 +104,11 @@ body {
|
|
|
104
104
|
}
|
|
105
105
|
.taskchef-board:focus-visible { outline: 2px solid var(--mantine-color-teal-6); outline-offset: 2px; }
|
|
106
106
|
.taskchef-board-dragging { scroll-snap-type: none; user-select: none; cursor: grabbing; }
|
|
107
|
-
.taskchef-board-lane { min-width: 0; scroll-snap-align: start; cursor: grab; }
|
|
107
|
+
.taskchef-board-lane { min-width: 0; scroll-snap-align: start; cursor: grab; padding: 8px; border-radius: 10px; }
|
|
108
108
|
.taskchef-board-lane-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; padding: 0 13px 6px; margin-bottom: 6px; }
|
|
109
109
|
.taskchef-board-lane-heading h2 { font-size: var(--mantine-font-size-sm); font-weight: 680; }
|
|
110
110
|
.taskchef-board-empty { padding: 12px 4px; }
|
|
111
|
-
.taskchef-board-card { display: flex; flex-direction: column; min-width: 0; cursor:
|
|
111
|
+
.taskchef-board-card { display: flex; flex-direction: column; min-width: 0; cursor: grab; background: light-dark(#fff, #202421); border-color: var(--taskchef-border); box-shadow: 0 1px 2px light-dark(rgb(22 31 25 / 3%), transparent); }
|
|
112
112
|
.taskchef-board-card:hover { border-color: light-dark(#bdc8c0, #5b685e); }
|
|
113
113
|
.taskchef-board-project { color: var(--taskchef-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
114
114
|
.taskchef-board-title { line-height: 1.3; }
|
|
@@ -218,3 +218,127 @@ body {
|
|
|
218
218
|
@media (prefers-reduced-motion: reduce) {
|
|
219
219
|
.taskchef-refresh-spinning { animation: none; }
|
|
220
220
|
}
|
|
221
|
+
|
|
222
|
+
/* Markdown replies share the same renderer in the board and Details. */
|
|
223
|
+
.taskchef-markdown { white-space: normal; overflow-wrap: anywhere; min-width: 0; }
|
|
224
|
+
.taskchef-markdown > :first-child { margin-top: 0; }
|
|
225
|
+
.taskchef-markdown > :last-child { margin-bottom: 0; }
|
|
226
|
+
.taskchef-markdown p, .taskchef-markdown ul, .taskchef-markdown ol, .taskchef-markdown blockquote { margin: 0.6em 0; }
|
|
227
|
+
.taskchef-markdown h1, .taskchef-markdown h2, .taskchef-markdown h3, .taskchef-markdown h4, .taskchef-markdown h5, .taskchef-markdown h6 { font-size: 1.05em; margin: 1em 0 0.4em; }
|
|
228
|
+
.taskchef-markdown ul, .taskchef-markdown ol { padding-left: 1.5em; }
|
|
229
|
+
.taskchef-markdown a { color: var(--mantine-color-anchor); }
|
|
230
|
+
.taskchef-markdown code { background: var(--mantine-color-default-hover); border-radius: 3px; padding: 0.1em 0.25em; font-size: 0.9em; }
|
|
231
|
+
.taskchef-markdown pre { overflow-x: auto; max-width: 100%; padding: 0.75em; background: var(--mantine-color-default-hover); border-radius: 6px; white-space: pre; }
|
|
232
|
+
.taskchef-markdown pre code { padding: 0; background: none; }
|
|
233
|
+
.taskchef-markdown blockquote { border-left: 3px solid var(--mantine-color-default-border); padding-left: 0.75em; }
|
|
234
|
+
.taskchef-markdown-table { overflow-x: auto; max-width: 100%; }
|
|
235
|
+
.taskchef-markdown table { border-collapse: collapse; width: 100%; }
|
|
236
|
+
.taskchef-markdown th, .taskchef-markdown td { border: 0; padding: 0.75em 1.5em 0.75em 0; text-align: left; vertical-align: top; overflow-wrap: normal; }
|
|
237
|
+
.taskchef-markdown th:last-child, .taskchef-markdown td:last-child { padding-right: 0; }
|
|
238
|
+
.taskchef-markdown:not(.taskchef-markdown--compact) thead tr { border-bottom: 1px solid var(--mantine-color-default-border); }
|
|
239
|
+
.taskchef-markdown:not(.taskchef-markdown--compact) tbody tr:not(:last-child) { border-bottom: 1px solid color-mix(in srgb, var(--mantine-color-default-border) 55%, transparent); }
|
|
240
|
+
.taskchef-markdown--compact { display: inline; }
|
|
241
|
+
.taskchef-markdown--compact :is(p,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,pre,table,thead,tbody,tr,th,td,.taskchef-markdown-table) { display: inline; margin: 0; padding: 0; border: 0; font-size: inherit; white-space: normal; }
|
|
242
|
+
.taskchef-markdown--compact :is(p,li,pre,blockquote,tr)::after { content: " "; }
|
|
243
|
+
.taskchef-markdown--compact li::before { content: "• "; }
|
|
244
|
+
.taskchef-markdown--compact :is(th,td)::after { content: " | "; }
|
|
245
|
+
|
|
246
|
+
.taskchef-reply-cover { display: flex; align-items: center; justify-content: center; width: calc(100% + 24px); height: 150px; margin: -12px -12px 10px; padding: 0; border: 0; border-radius: var(--mantine-radius-default) var(--mantine-radius-default) 0 0; overflow: hidden; background: light-dark(#eef1ee, #151a17); color: var(--mantine-color-dimmed); cursor: pointer; flex-shrink: 0; }
|
|
247
|
+
.taskchef-reply-cover img { width: 100%; height: 100%; object-fit: contain; }
|
|
248
|
+
.taskchef-reply-cover span { font-size: var(--mantine-font-size-xs); padding: 12px; }
|
|
249
|
+
.taskchef-reply-cover:focus-visible { outline: 2px solid var(--mantine-primary-color-filled); outline-offset: 2px; }
|
|
250
|
+
|
|
251
|
+
.taskchef-board-project { display: flex; align-items: center; gap: 5px; }
|
|
252
|
+
.taskchef-board-project > svg { flex-shrink: 0; }
|
|
253
|
+
.taskchef-board-project > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
254
|
+
.taskchef-card-stats, .taskchef-card-pr-icons { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
|
255
|
+
.taskchef-card-pr-icons { flex-wrap: wrap; }
|
|
256
|
+
.taskchef-card-pr-icons:empty { display: none; }
|
|
257
|
+
.taskchef-card-status-icon { display: inline-flex; position: relative; align-items: center; justify-content: center; width: 20px; height: 22px; padding: 0; flex-shrink: 0; background: none; border: 0; color: var(--taskchef-muted); cursor: pointer; }
|
|
258
|
+
.taskchef-card-status-icon:focus-visible { outline: 1px solid currentColor; outline-offset: 2px; border-radius: 3px; }
|
|
259
|
+
|
|
260
|
+
.taskchef-status-tooltip { background: var(--taskchef-surface-muted); color: var(--taskchef-text); border: 1px solid var(--taskchef-border); }
|
|
261
|
+
|
|
262
|
+
.taskchef-status-row { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: 12px; line-height: 1.5; }
|
|
263
|
+
.taskchef-status-row-icon { display: inline-flex; align-items: center; justify-content: center; width: 18px; flex: 0 0 18px; color: var(--taskchef-muted); }
|
|
264
|
+
.taskchef-status-row-content { min-width: 0; flex: 1; }
|
|
265
|
+
.taskchef-status-pr-title { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: inherit; color: inherit; }
|
|
266
|
+
.taskchef-popup-pr-icon { position: relative; display: inline-flex; width: 18px; height: 18px; align-items: center; }
|
|
267
|
+
|
|
268
|
+
.taskchef-pr-access-warning { position: absolute; right: -6px; top: -3px; color: #eac54f; }
|
|
269
|
+
|
|
270
|
+
.taskchef-schedule-clock { transform: scaleX(-1); }
|
|
271
|
+
|
|
272
|
+
.taskchef-pr-access-alert { box-shadow: inset 0 0 0 1px #eac54f; border-radius: 4px; padding: 6px 8px 6px 0; }
|
|
273
|
+
|
|
274
|
+
.taskchef-board-lane-title { display: flex; align-items: center; gap: 4px; }
|
|
275
|
+
/* Codex desktop's default spinner geometry and animation cadence. */
|
|
276
|
+
.taskchef-running-spinner { flex-shrink: 0; color: var(--mantine-color-dimmed); animation: taskchef-running-spin 2s steps(60, end) infinite; }
|
|
277
|
+
@keyframes taskchef-running-spin { to { transform: rotate(360deg); } }
|
|
278
|
+
@media (prefers-reduced-motion: reduce) { .taskchef-running-spinner { animation: none; } }
|
|
279
|
+
|
|
280
|
+
.taskchef-board-card:active { cursor: grabbing; }
|
|
281
|
+
.taskchef-board-lane-drop-target {
|
|
282
|
+
background: light-dark(rgba(47, 158, 68, 0.08), rgba(81, 207, 102, 0.08));
|
|
283
|
+
box-shadow: inset 0 0 0 1px light-dark(rgba(47, 158, 68, 0.5), rgba(81, 207, 102, 0.4));
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.taskchef-card-turn-usage { font-size: 12px; white-space: nowrap; }
|
|
287
|
+
|
|
288
|
+
.taskchef-board-title { position: relative; }
|
|
289
|
+
.taskchef-board-title:has(.taskchef-chat-unread-dot) { padding-right: 16px; }
|
|
290
|
+
.taskchef-chat-unread-dot { position: absolute; right: 0; top: 5px; width: 7px; height: 7px; border-radius: 50%; background: #2f81f7; }
|
|
291
|
+
|
|
292
|
+
.taskchef-turn-content { display: flex; flex-direction: column; gap: 12px; min-width: 0; font-size: var(--mantine-font-size-sm); }
|
|
293
|
+
.taskchef-turn-prompt { align-self: flex-end; max-width: 85%; min-width: 0; padding: 10px 12px; border-radius: 12px; background: light-dark(#eaf1fc, #1c3d69); color: light-dark(#202c3d, #edf3fc); overflow-wrap: anywhere; }
|
|
294
|
+
.taskchef-prompt-clock { float: left; margin: 3px 6px 0 0; }
|
|
295
|
+
.taskchef-turn-response { width: 100%; min-width: 0; overflow-wrap: anywhere; }
|
|
296
|
+
.taskchef-turn-card { margin: 8px 0; font-size: var(--mantine-font-size-sm); }
|
|
297
|
+
.taskchef-turn-card .taskchef-markdown { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
|
|
298
|
+
.taskchef-turn-collapsed { line-height: 1.55; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; max-height: calc(3 * 1.55em); overflow: hidden; }
|
|
299
|
+
.taskchef-turn-expand { padding: 0; margin-top: 5px; border: 0; background: transparent; color: inherit; text-decoration: underline; font: inherit; font-size: var(--mantine-font-size-xs); cursor: pointer; }
|
|
300
|
+
.taskchef-turn-expand:focus-visible { outline: 2px solid var(--mantine-primary-color-filled); outline-offset: 2px; }
|
|
301
|
+
|
|
302
|
+
.taskchef-turn-collapsed .taskchef-markdown :is(p,ul,ol,blockquote) { margin-top: 0; margin-bottom: 0; }
|
|
303
|
+
|
|
304
|
+
.taskchef-turn-divider { margin-top: 20px; padding-bottom: 8px; border-bottom: 1px solid var(--mantine-color-default-border); color: var(--mantine-color-dimmed); font-size: var(--mantine-font-size-xs); }
|
|
305
|
+
.taskchef-response-image { display: block; margin: 16px 0; }
|
|
306
|
+
.taskchef-image-thumbnail { display: block; padding: 0; border: 1px solid var(--mantine-color-default-border); border-radius: 8px; background: transparent; overflow: hidden; cursor: zoom-in; max-width: 100%; }
|
|
307
|
+
.taskchef-image-thumbnail img { display: block; max-width: 100%; width: auto; max-height: 160px; object-fit: contain; }
|
|
308
|
+
.taskchef-image-thumbnail:focus-visible { outline: 2px solid var(--mantine-primary-color-filled); outline-offset: 3px; }
|
|
309
|
+
.taskchef-image-lightbox img { display: block; max-width: calc(100vw - 64px); max-height: calc(100dvh - 140px); object-fit: contain; }
|
|
310
|
+
|
|
311
|
+
.taskchef-prompt-images { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:12px; }
|
|
312
|
+
.taskchef-prompt-images .taskchef-response-image { margin:0; max-width:100%; }
|
|
313
|
+
.taskchef-prompt-images .taskchef-image-thumbnail img { max-height:120px; }
|
|
314
|
+
|
|
315
|
+
.taskchef-turn-prompt .taskchef-markdown p:empty { display:none; }
|
|
316
|
+
|
|
317
|
+
.taskchef-annotation-link { color: var(--mantine-color-anchor); font: inherit; padding: 0; border: 0; background: none; text-decoration: underline; cursor: pointer; }
|
|
318
|
+
.taskchef-annotation-popup { font-size: var(--mantine-font-size-sm); line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 50vh; overflow-y: auto; text-align: left; }
|
|
319
|
+
.taskchef-annotation-label { color: var(--mantine-color-dimmed); margin-top: 8px; margin-bottom: 4px; }
|
|
320
|
+
.taskchef-annotation-label:first-child { margin-top: 0; }
|
|
321
|
+
|
|
322
|
+
.taskchef-image-placeholder { display: inline-block; width: 180px; height: 120px; max-width: 100%; border-radius: 8px; background: var(--mantine-color-default-hover); }
|
|
323
|
+
.taskchef-queued-prompts { margin-top: 16px; }
|
|
324
|
+
.taskchef-queued-heading { font-size: 12px; color: var(--mantine-color-dimmed); margin-bottom: 8px; }
|
|
325
|
+
.taskchef-queued-prompts > ol { list-style: none; padding: 0; margin: 0; }
|
|
326
|
+
.taskchef-queued-prompts > ol > li { display: flex; align-items: flex-start; gap: 8px; border-top: 1px solid var(--mantine-color-default-border); padding: 10px 0; }
|
|
327
|
+
.taskchef-queued-prompts.is-compact { margin-top: 8px; }
|
|
328
|
+
.taskchef-queued-prompts.is-compact > ol > li { display: flex; align-items: center; gap: 6px; padding: 4px 0; font-size: 12px; }
|
|
329
|
+
.taskchef-queued-prompts.is-compact > ol > li > span { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
|
330
|
+
.taskchef-queued-prompts.is-compact .taskchef-markdown { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
|
331
|
+
.taskchef-queued-prompts.is-compact .taskchef-reply-cover { flex: 0 0 28px; width: 28px; height: 22px; min-height: 22px; margin: 0; border-radius: 3px; }
|
|
332
|
+
.taskchef-queued-prompts.is-compact .taskchef-reply-cover span { font-size: 0; }
|
|
333
|
+
|
|
334
|
+
.taskchef-prompt-images .taskchef-image-thumbnail { width: 180px; height: 120px; display: flex; align-items: center; justify-content: center; }
|
|
335
|
+
.taskchef-prompt-images .taskchef-image-thumbnail img { width: 100%; height: 100%; object-fit: contain; }
|
|
336
|
+
|
|
337
|
+
.taskchef-queued-prompts.is-compact .taskchef-markdown * { white-space: nowrap; }
|
|
338
|
+
|
|
339
|
+
.taskchef-pending-questions { margin: 20px 0; padding: 16px 0; border-top: 1px solid var(--mantine-color-default-border); border-bottom: 1px solid var(--mantine-color-default-border); }
|
|
340
|
+
.taskchef-pending-questions ol { padding-left: 24px; margin: 8px 0 0; font-size: var(--mantine-font-size-sm); }
|
|
341
|
+
.taskchef-pending-questions li { padding: 4px 0; white-space: pre-wrap; }
|
|
342
|
+
|
|
343
|
+
.taskchef-queue-icon { flex: 0 0 16px; color: var(--mantine-color-dimmed); margin-top: 2px; }
|
|
344
|
+
.taskchef-queue-content { flex: 1; min-width: 0; }
|