@code-yeongyu/senpi 2026.9.12-3 → 2026.9.13-2
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/CHANGELOG.md +63 -0
- package/README.md +3 -1
- package/dist/bun/cli.js +2 -3
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/runtime-modules.d.ts +3 -0
- package/dist/bun/runtime-modules.d.ts.map +1 -0
- package/dist/bun/runtime-modules.js +17 -0
- package/dist/bun/runtime-modules.js.map +1 -0
- package/dist/bun/runtime-setup.js +2 -5
- package/dist/bun/runtime-setup.js.map +1 -1
- package/dist/core/agent-session.d.ts +2 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +38 -30
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/discovered-resource-scope.d.ts +23 -0
- package/dist/core/discovered-resource-scope.d.ts.map +1 -0
- package/dist/core/discovered-resource-scope.js +44 -0
- package/dist/core/discovered-resource-scope.js.map +1 -0
- package/dist/core/extensions/builtin/ask-user/notify.d.ts +24 -0
- package/dist/core/extensions/builtin/ask-user/notify.d.ts.map +1 -0
- package/dist/core/extensions/builtin/ask-user/notify.js +11 -0
- package/dist/core/extensions/builtin/ask-user/notify.js.map +1 -0
- package/dist/core/extensions/builtin/ask-user/registry.d.ts +2 -0
- package/dist/core/extensions/builtin/ask-user/registry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ask-user/registry.js.map +1 -1
- package/dist/core/extensions/builtin/ask-user/resume.d.ts +1 -1
- package/dist/core/extensions/builtin/ask-user/resume.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ask-user/resume.js +10 -20
- package/dist/core/extensions/builtin/ask-user/resume.js.map +1 -1
- package/dist/core/extensions/builtin/ask-user/tool.d.ts +5 -2
- package/dist/core/extensions/builtin/ask-user/tool.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ask-user/tool.js +41 -6
- package/dist/core/extensions/builtin/ask-user/tool.js.map +1 -1
- package/dist/core/extensions/builtin/goal/channel-state-subscriptions.d.ts +2 -1
- package/dist/core/extensions/builtin/goal/channel-state-subscriptions.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/channel-state-subscriptions.js +1 -1
- package/dist/core/extensions/builtin/goal/channel-state-subscriptions.js.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.js +27 -13
- package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/config-loader.d.ts +2 -0
- package/dist/core/extensions/builtin/hooks/config-loader.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/config-loader.js +27 -0
- package/dist/core/extensions/builtin/hooks/config-loader.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/dispatcher.js +1 -0
- package/dist/core/extensions/builtin/hooks/dispatcher.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/index.js +51 -2
- package/dist/core/extensions/builtin/hooks/index.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/lifecycle-adapter.d.ts +18 -1
- package/dist/core/extensions/builtin/hooks/lifecycle-adapter.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/lifecycle-adapter.js +36 -1
- package/dist/core/extensions/builtin/hooks/lifecycle-adapter.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/matcher.js +1 -0
- package/dist/core/extensions/builtin/hooks/matcher.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/output-parser.js +6 -0
- package/dist/core/extensions/builtin/hooks/output-parser.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust-storage.d.ts +2 -0
- package/dist/core/extensions/builtin/hooks/trust-storage.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust-storage.js +13 -0
- package/dist/core/extensions/builtin/hooks/trust-storage.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/types.d.ts +14 -2
- package/dist/core/extensions/builtin/hooks/types.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/types.js +1 -1
- package/dist/core/extensions/builtin/hooks/types.js.map +1 -1
- package/dist/core/extensions/builtin/monitor-state-event.d.ts +1 -0
- package/dist/core/extensions/builtin/monitor-state-event.d.ts.map +1 -1
- package/dist/core/extensions/builtin/monitor-state-event.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/bash.d.ts +1 -0
- package/dist/core/extensions/builtin/terminal/tools/bash.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/bash.js +13 -2
- package/dist/core/extensions/builtin/terminal/tools/bash.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +5 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -16
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +16 -5
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +28 -5
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +8 -3
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +12 -6
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/keybindings.d.ts +8 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +7 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/package-manager.d.ts +4 -2
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +7 -2
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts +2 -0
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +3 -0
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/resource-loader.d.ts +9 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +69 -21
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +1 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-shapes.d.ts +1 -0
- package/dist/core/settings-shapes.d.ts.map +1 -1
- package/dist/core/settings-shapes.js.map +1 -1
- package/dist/core/source-info.d.ts +5 -1
- package/dist/core/source-info.d.ts.map +1 -1
- package/dist/core/source-info.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +5 -0
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/modes/app-server/server/skills.d.ts.map +1 -1
- package/dist/modes/app-server/server/skills.js +1 -0
- package/dist/modes/app-server/server/skills.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-answer-chip.d.ts +17 -0
- package/dist/modes/interactive/components/ask-user-answer-chip.d.ts.map +1 -0
- package/dist/modes/interactive/components/ask-user-answer-chip.js +86 -0
- package/dist/modes/interactive/components/ask-user-answer-chip.js.map +1 -0
- package/dist/modes/interactive/components/ask-user-answer-key.d.ts +3 -1
- package/dist/modes/interactive/components/ask-user-answer-key.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-answer-key.js +11 -1
- package/dist/modes/interactive/components/ask-user-answer-key.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-async-widget.d.ts +5 -2
- package/dist/modes/interactive/components/ask-user-async-widget.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-async-widget.js +18 -12
- package/dist/modes/interactive/components/ask-user-async-widget.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-countdown.d.ts +8 -0
- package/dist/modes/interactive/components/ask-user-countdown.d.ts.map +1 -0
- package/dist/modes/interactive/components/ask-user-countdown.js +23 -0
- package/dist/modes/interactive/components/ask-user-countdown.js.map +1 -0
- package/dist/modes/interactive/components/ask-user-question-keys.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-keys.js +85 -17
- package/dist/modes/interactive/components/ask-user-question-keys.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-render.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-render.js +22 -7
- package/dist/modes/interactive/components/ask-user-question-render.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-state.d.ts +15 -0
- package/dist/modes/interactive/components/ask-user-question-state.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-state.js +57 -13
- package/dist/modes/interactive/components/ask-user-question-state.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question.d.ts +8 -2
- package/dist/modes/interactive/components/ask-user-question.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question.js +16 -8
- package/dist/modes/interactive/components/ask-user-question.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts +2 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +2 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +10 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/loaded-resource-section.d.ts +14 -0
- package/dist/modes/interactive/components/loaded-resource-section.d.ts.map +1 -0
- package/dist/modes/interactive/components/loaded-resource-section.js +25 -0
- package/dist/modes/interactive/components/loaded-resource-section.js.map +1 -0
- package/dist/modes/interactive/components/user-message.d.ts +2 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +12 -2
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +14 -11
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +263 -165
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/loaded-resource-scopes.d.ts +28 -0
- package/dist/modes/interactive/loaded-resource-scopes.d.ts.map +1 -0
- package/dist/modes/interactive/loaded-resource-scopes.js +107 -0
- package/dist/modes/interactive/loaded-resource-scopes.js.map +1 -0
- package/dist/modes/interactive/tips/catalog/input-tips.d.ts +1 -1
- package/dist/modes/interactive/tips/catalog/input-tips.js +2 -2
- package/dist/modes/interactive/tips/catalog/input-tips.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
- package/dist/modes/rpc/host-lifecycle.js +7 -0
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/session-worker.js +5 -0
- package/dist/modes/rpc/session-worker.js.map +1 -1
- package/docs/environment-variables.md +5 -1
- package/docs/extensions.md +43 -5
- package/docs/keybindings.md +5 -2
- package/docs/packages.md +17 -0
- package/docs/rpc.md +6 -3
- package/docs/settings.md +5 -1
- package/docs/tui.md +15 -3
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +28 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +16 -4
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/session-env.ts +6 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +6 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/run-eval-cell.ts +31 -12
- package/node_modules/@earendil-works/chord/package.json +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.d.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.js +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +4 -4
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.d.ts +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.js +6 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +55 -17
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +9 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/responses-completion-grace.d.ts +30 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/responses-completion-grace.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/responses-completion-grace.js +94 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/responses-completion-grace.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/websocket-liveness.d.ts +48 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/websocket-liveness.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/websocket-liveness.js +104 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/websocket-liveness.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/devin-provider.d.ts +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/devin-provider.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/devin-provider.js +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/devin-provider.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +7 -3
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +10 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/README.md +11 -3
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +2 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.js +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/mouse-input.d.ts +37 -0
- package/node_modules/@earendil-works/pi-tui/dist/mouse-input.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/mouse-input.js +97 -0
- package/node_modules/@earendil-works/pi-tui/dist/mouse-input.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +2 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +38 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +25 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +110 -4
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js +5 -50
- package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.d.ts +12 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.js +129 -3
- package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +28 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +160 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +13 -9
- package/dist/bun/register-cursor-agent.d.ts +0 -2
- package/dist/bun/register-cursor-agent.d.ts.map +0 -1
- package/dist/bun/register-cursor-agent.js +0 -4
- package/dist/bun/register-cursor-agent.js.map +0 -1
|
@@ -29,6 +29,7 @@ export class AskUserQuestionState {
|
|
|
29
29
|
this.selected = new Map();
|
|
30
30
|
this.texts = new Map();
|
|
31
31
|
this.request = request;
|
|
32
|
+
this.submitRowIndex = this.commentRowIndex;
|
|
32
33
|
}
|
|
33
34
|
get activeQuestion() {
|
|
34
35
|
return this.request.questions[this.activeIndex];
|
|
@@ -43,6 +44,12 @@ export class AskUserQuestionState {
|
|
|
43
44
|
get activeTabIndex() {
|
|
44
45
|
return this.focus === "submit" ? this.request.questions.length : this.activeIndex;
|
|
45
46
|
}
|
|
47
|
+
get commentRowIndex() {
|
|
48
|
+
return this.request.questions.length;
|
|
49
|
+
}
|
|
50
|
+
get isCommentFocused() {
|
|
51
|
+
return this.focus === "submit" && this.submitRowIndex === this.commentRowIndex;
|
|
52
|
+
}
|
|
46
53
|
switchQuestion(delta) {
|
|
47
54
|
this.switchTab(delta);
|
|
48
55
|
}
|
|
@@ -50,32 +57,49 @@ export class AskUserQuestionState {
|
|
|
50
57
|
const count = this.request.questions.length + 1;
|
|
51
58
|
const next = (this.activeTabIndex + delta + count) % count;
|
|
52
59
|
if (next === this.request.questions.length) {
|
|
53
|
-
this.
|
|
60
|
+
this.enterSubmit();
|
|
54
61
|
}
|
|
55
62
|
else {
|
|
56
|
-
this.
|
|
57
|
-
this.activeIndex = next;
|
|
58
|
-
this.highlightIndex = 0;
|
|
63
|
+
this.jumpToQuestion(next);
|
|
59
64
|
}
|
|
60
|
-
this.dismissPending = false;
|
|
61
|
-
this.notice = undefined;
|
|
62
65
|
}
|
|
63
66
|
advance() {
|
|
64
67
|
if (this.activeIndex + 1 < this.request.questions.length) {
|
|
65
|
-
this.activeIndex
|
|
66
|
-
this.highlightIndex = 0;
|
|
67
|
-
this.notice = undefined;
|
|
68
|
-
this.dismissPending = false;
|
|
68
|
+
this.jumpToQuestion(this.activeIndex + 1);
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
|
+
this.enterSubmit();
|
|
72
|
+
}
|
|
73
|
+
jumpToQuestion(index) {
|
|
74
|
+
this.focus = "options";
|
|
75
|
+
this.activeIndex = index;
|
|
76
|
+
this.highlightIndex = 0;
|
|
77
|
+
this.clearTransient();
|
|
78
|
+
}
|
|
79
|
+
enterSubmit() {
|
|
71
80
|
this.focus = "submit";
|
|
81
|
+
this.submitRowIndex = this.commentRowIndex;
|
|
72
82
|
this.highlightIndex = 0;
|
|
73
|
-
this.
|
|
74
|
-
this.dismissPending = false;
|
|
83
|
+
this.clearTransient();
|
|
75
84
|
}
|
|
76
85
|
returnToOptions() {
|
|
86
|
+
this.leaveOwnAnswer(0);
|
|
87
|
+
}
|
|
88
|
+
/** Close the own-answer editor and highlight `row` of the active question. */
|
|
89
|
+
leaveOwnAnswer(row) {
|
|
77
90
|
this.focus = "options";
|
|
78
|
-
this.highlightIndex = 0;
|
|
91
|
+
this.highlightIndex = Math.min(Math.max(0, row), this.ownAnswerRowIndex);
|
|
92
|
+
this.clearTransient();
|
|
93
|
+
}
|
|
94
|
+
/** Move the Submit-tab highlight by `delta`, clamped to the review rows and the comment editor. */
|
|
95
|
+
moveSubmitRow(delta) {
|
|
96
|
+
this.submitRowIndex = Math.min(Math.max(0, this.submitRowIndex + delta), this.commentRowIndex);
|
|
97
|
+
this.clearTransient();
|
|
98
|
+
}
|
|
99
|
+
focusComment() {
|
|
100
|
+
this.submitRowIndex = this.commentRowIndex;
|
|
101
|
+
}
|
|
102
|
+
clearTransient() {
|
|
79
103
|
this.notice = undefined;
|
|
80
104
|
this.dismissPending = false;
|
|
81
105
|
}
|
|
@@ -144,6 +168,26 @@ export class AskUserQuestionState {
|
|
|
144
168
|
this.texts.set(questionId, trimmed);
|
|
145
169
|
this.notice = undefined;
|
|
146
170
|
}
|
|
171
|
+
clearAnswer(questionId) {
|
|
172
|
+
this.selected.delete(questionId);
|
|
173
|
+
this.texts.delete(questionId);
|
|
174
|
+
this.notice = undefined;
|
|
175
|
+
}
|
|
176
|
+
/** Seed selections, own texts and the comment from a previously captured draft. */
|
|
177
|
+
restoreDraft(draft) {
|
|
178
|
+
for (const question of this.request.questions) {
|
|
179
|
+
const answer = draft.answers?.[question.id];
|
|
180
|
+
if (!answer)
|
|
181
|
+
continue;
|
|
182
|
+
const selected = answer.selected.filter((label) => question.options.some((option) => option.label === label));
|
|
183
|
+
if (selected.length > 0)
|
|
184
|
+
this.selected.set(question.id, selected);
|
|
185
|
+
if (answer.text !== undefined && answer.text.trim() !== "")
|
|
186
|
+
this.texts.set(question.id, answer.text.trim());
|
|
187
|
+
}
|
|
188
|
+
if (draft.comment !== undefined && draft.comment.trim() !== "")
|
|
189
|
+
this.comment = draft.comment;
|
|
190
|
+
}
|
|
147
191
|
answers() {
|
|
148
192
|
const result = {};
|
|
149
193
|
for (const question of this.request.questions) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask-user-question-state.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/ask-user-question-state.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure interaction state for the ask-user question overlay.\n *\n * Owns per-question selections, own-answer texts, the active tab, the\n * highlighted row and the response-building rules. Rendering and key decoding\n * live in ask-user-question.ts; this module must stay free of pi-tui imports\n * so the rules are unit-testable headless.\n */\n\nimport type { QuestionRequest, QuestionResponse } from \"../../../core/extensions/types.ts\";\n\nexport type QuestionAnswers = QuestionResponse[\"answers\"];\nexport type QuestionDraft = { answers?: QuestionAnswers; comment?: string };\nexport type QuestionFocus = \"options\" | \"own-answer\" | \"submit\";\n\nexport const COMMENT_LABEL = \"Comment (optional; unanswered questions are reported)\";\nexport const OWN_ANSWER_LABEL = \"Type your own answer...\";\nexport const NOT_ANSWERED_NOTICE = \"You have not answered all questions\";\nexport const DISMISS_NOTICE = \"Press Esc again to dismiss (answers will be discarded)\";\nexport const PARTIAL_SUBMIT_NOTICE = \"Press Enter again to submit with unanswered questions\";\n\n/** Countdown chip label: minutes above five minutes, mm:ss at or below. */\nexport function formatCountdownLabel(remainingMs: number): string {\n\tconst totalSeconds = Math.max(0, Math.ceil(remainingMs / 1000));\n\tif (totalSeconds >= 300) return `${Math.ceil(totalSeconds / 60)}m`;\n\tconst minutes = Math.floor(totalSeconds / 60);\n\tconst seconds = totalSeconds % 60;\n\treturn `${String(minutes).padStart(2, \"0\")}:${String(seconds).padStart(2, \"0\")}`;\n}\n\nexport class AskUserQuestionState {\n\treadonly request: QuestionRequest;\n\tactiveIndex = 0;\n\thighlightIndex = 0;\n\tfocus: QuestionFocus = \"options\";\n\tnotice: string | undefined;\n\tcomment: string | undefined;\n\tprivate dismissPending = false;\n\tprivate readonly selected = new Map<string, string[]>();\n\tprivate readonly texts = new Map<string, string>();\n\n\tconstructor(request: QuestionRequest) {\n\t\tthis.request = request;\n\t}\n\n\tget activeQuestion(): QuestionRequest[\"questions\"][number] {\n\t\treturn this.request.questions[this.activeIndex];\n\t}\n\n\t/** Highlightable rows for the active question: options plus the own-answer row. */\n\tget ownAnswerRowIndex(): number {\n\t\treturn this.activeQuestion.options.length;\n\t}\n\n\tget rowCount(): number {\n\t\treturn this.ownAnswerRowIndex + 1;\n\t}\n\n\tget activeTabIndex(): number {\n\t\treturn this.focus === \"submit\" ? this.request.questions.length : this.activeIndex;\n\t}\n\n\tswitchQuestion(delta: number): void {\n\t\tthis.switchTab(delta);\n\t}\n\n\tswitchTab(delta: number): void {\n\t\tconst count = this.request.questions.length + 1;\n\t\tconst next = (this.activeTabIndex + delta + count) % count;\n\t\tif (next === this.request.questions.length) {\n\t\t\tthis.focus = \"submit\";\n\t\t} else {\n\t\t\tthis.focus = \"options\";\n\t\t\tthis.activeIndex = next;\n\t\t\tthis.highlightIndex = 0;\n\t\t}\n\t\tthis.dismissPending = false;\n\t\tthis.notice = undefined;\n\t}\n\n\tadvance(): void {\n\t\tif (this.activeIndex + 1 < this.request.questions.length) {\n\t\t\tthis.activeIndex += 1;\n\t\t\tthis.highlightIndex = 0;\n\t\t\tthis.notice = undefined;\n\t\t\tthis.dismissPending = false;\n\t\t\treturn;\n\t\t}\n\t\tthis.focus = \"submit\";\n\t\tthis.highlightIndex = 0;\n\t\tthis.notice = undefined;\n\t\tthis.dismissPending = false;\n\t}\n\n\treturnToOptions(): void {\n\t\tthis.focus = \"options\";\n\t\tthis.highlightIndex = 0;\n\t\tthis.notice = undefined;\n\t\tthis.dismissPending = false;\n\t}\n\n\trequestDismiss(): \"confirm\" | \"cancel\" {\n\t\tif (!this.hasDraft()) return \"cancel\";\n\t\tif (!this.dismissPending) {\n\t\t\tthis.dismissPending = true;\n\t\t\tthis.notice = DISMISS_NOTICE;\n\t\t\treturn \"confirm\";\n\t\t}\n\t\treturn \"cancel\";\n\t}\n\n\tacceptPartialSubmit(): void {\n\t\tthis.dismissPending = false;\n\t\tthis.notice = undefined;\n\t}\n\n\tprivate hasDraft(): boolean {\n\t\tif ((this.comment ?? \"\").trim() !== \"\") return true;\n\t\treturn this.request.questions.some((question) => this.isAnswered(question.id));\n\t}\n\n\tselectedFor(questionId: string): string[] {\n\t\treturn this.selected.get(questionId) ?? [];\n\t}\n\n\ttextFor(questionId: string): string | undefined {\n\t\treturn this.texts.get(questionId);\n\t}\n\n\tisSelected(questionId: string, label: string): boolean {\n\t\treturn this.selectedFor(questionId).includes(label);\n\t}\n\n\tisAnswered(questionId: string): boolean {\n\t\tif (this.selectedFor(questionId).length > 0) return true;\n\t\treturn (this.texts.get(questionId) ?? \"\").trim() !== \"\";\n\t}\n\n\tansweredCount(): number {\n\t\treturn this.request.questions.filter((question) => this.isAnswered(question.id)).length;\n\t}\n\n\t/** Select (single) or toggle (multi) an option of the active question. */\n\tactivateOption(questionId: string, label: string): void {\n\t\tconst question = this.request.questions.find((entry) => entry.id === questionId);\n\t\tif (!question?.options.some((option) => option.label === label)) return;\n\t\tif (question.multiSelect) {\n\t\t\tconst next = [...this.selectedFor(questionId)];\n\t\t\tconst index = next.indexOf(label);\n\t\t\tif (index >= 0) next.splice(index, 1);\n\t\t\telse next.push(label);\n\t\t\tthis.selected.set(questionId, next);\n\t\t} else {\n\t\t\tthis.selected.set(questionId, [label]);\n\t\t}\n\t\tthis.notice = undefined;\n\t}\n\n\t/** Replace the question's answer with typed text; empty text clears it. */\n\tsetOwnAnswer(questionId: string, text: string): void {\n\t\tconst trimmed = text.trim();\n\t\tthis.selected.delete(questionId);\n\t\tif (trimmed === \"\") this.texts.delete(questionId);\n\t\telse this.texts.set(questionId, trimmed);\n\t\tthis.notice = undefined;\n\t}\n\n\tanswers(): QuestionAnswers {\n\t\tconst result: QuestionAnswers = {};\n\t\tfor (const question of this.request.questions) {\n\t\t\tconst selected = this.selectedFor(question.id);\n\t\t\tconst text = this.texts.get(question.id);\n\t\t\tif (selected.length === 0 && text === undefined) continue;\n\t\t\tresult[question.id] = { selected, ...(text !== undefined ? { text } : {}) };\n\t\t}\n\t\treturn result;\n\t}\n\n\tunanswered(): string[] {\n\t\treturn this.request.questions.filter((question) => !this.isAnswered(question.id)).map((q) => q.id);\n\t}\n\n\t/** Submit outcome: comment wins, then answers; undefined means stay open. */\n\tsubmitOutcome(forcePartial = false): \"answered\" | \"comment-submitted\" | undefined {\n\t\tif ((this.comment ?? \"\").trim() !== \"\") return \"comment-submitted\";\n\t\tif (this.unanswered().length === 0) return \"answered\";\n\t\tif (this.answeredCount() > 0) return \"answered\";\n\t\tif (forcePartial) return \"answered\";\n\t\treturn undefined;\n\t}\n\n\tbuildResponse(status: QuestionResponse[\"status\"], autoResolvedAfterMs?: number): QuestionResponse {\n\t\tconst comment = this.comment !== undefined && this.comment.trim() !== \"\" ? this.comment : undefined;\n\t\treturn {\n\t\t\tstatus,\n\t\t\tanswers: this.answers(),\n\t\t\t...(comment !== undefined ? { comment } : {}),\n\t\t\tunanswered: this.unanswered(),\n\t\t\t...(autoResolvedAfterMs !== undefined ? { autoResolvedAfterMs } : {}),\n\t\t};\n\t}\n\n\trefreshDraft(): QuestionDraft {\n\t\tconst comment = this.comment !== undefined && this.comment.trim() !== \"\" ? this.comment : undefined;\n\t\treturn {\n\t\t\tanswers: this.answers(),\n\t\t\t...(comment !== undefined ? { comment } : {}),\n\t\t};\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ask-user-question-state.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/ask-user-question-state.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure interaction state for the ask-user question overlay.\n *\n * Owns per-question selections, own-answer texts, the active tab, the\n * highlighted row and the response-building rules. Rendering and key decoding\n * live in ask-user-question.ts; this module must stay free of pi-tui imports\n * so the rules are unit-testable headless.\n */\n\nimport type { QuestionRequest, QuestionResponse } from \"../../../core/extensions/types.ts\";\n\nexport type QuestionAnswers = QuestionResponse[\"answers\"];\nexport type QuestionDraft = { answers?: QuestionAnswers; comment?: string };\nexport type QuestionFocus = \"options\" | \"own-answer\" | \"submit\";\n\nexport const COMMENT_LABEL = \"Comment (optional; unanswered questions are reported)\";\nexport const OWN_ANSWER_LABEL = \"Type your own answer...\";\nexport const NOT_ANSWERED_NOTICE = \"You have not answered all questions\";\nexport const DISMISS_NOTICE = \"Press Esc again to dismiss (answers will be discarded)\";\nexport const PARTIAL_SUBMIT_NOTICE = \"Press Enter again to submit with unanswered questions\";\n\n/** Countdown chip label: minutes above five minutes, mm:ss at or below. */\nexport function formatCountdownLabel(remainingMs: number): string {\n\tconst totalSeconds = Math.max(0, Math.ceil(remainingMs / 1000));\n\tif (totalSeconds >= 300) return `${Math.ceil(totalSeconds / 60)}m`;\n\tconst minutes = Math.floor(totalSeconds / 60);\n\tconst seconds = totalSeconds % 60;\n\treturn `${String(minutes).padStart(2, \"0\")}:${String(seconds).padStart(2, \"0\")}`;\n}\n\nexport class AskUserQuestionState {\n\treadonly request: QuestionRequest;\n\tactiveIndex = 0;\n\thighlightIndex = 0;\n\tfocus: QuestionFocus = \"options\";\n\t/** Highlighted row on the Submit tab: a review row per question, then the comment editor. */\n\tsubmitRowIndex: number;\n\tnotice: string | undefined;\n\tcomment: string | undefined;\n\tprivate dismissPending = false;\n\tprivate readonly selected = new Map<string, string[]>();\n\tprivate readonly texts = new Map<string, string>();\n\n\tconstructor(request: QuestionRequest) {\n\t\tthis.request = request;\n\t\tthis.submitRowIndex = this.commentRowIndex;\n\t}\n\n\tget activeQuestion(): QuestionRequest[\"questions\"][number] {\n\t\treturn this.request.questions[this.activeIndex];\n\t}\n\n\t/** Highlightable rows for the active question: options plus the own-answer row. */\n\tget ownAnswerRowIndex(): number {\n\t\treturn this.activeQuestion.options.length;\n\t}\n\n\tget rowCount(): number {\n\t\treturn this.ownAnswerRowIndex + 1;\n\t}\n\n\tget activeTabIndex(): number {\n\t\treturn this.focus === \"submit\" ? this.request.questions.length : this.activeIndex;\n\t}\n\n\tget commentRowIndex(): number {\n\t\treturn this.request.questions.length;\n\t}\n\n\tget isCommentFocused(): boolean {\n\t\treturn this.focus === \"submit\" && this.submitRowIndex === this.commentRowIndex;\n\t}\n\n\tswitchQuestion(delta: number): void {\n\t\tthis.switchTab(delta);\n\t}\n\n\tswitchTab(delta: number): void {\n\t\tconst count = this.request.questions.length + 1;\n\t\tconst next = (this.activeTabIndex + delta + count) % count;\n\t\tif (next === this.request.questions.length) {\n\t\t\tthis.enterSubmit();\n\t\t} else {\n\t\t\tthis.jumpToQuestion(next);\n\t\t}\n\t}\n\n\tadvance(): void {\n\t\tif (this.activeIndex + 1 < this.request.questions.length) {\n\t\t\tthis.jumpToQuestion(this.activeIndex + 1);\n\t\t\treturn;\n\t\t}\n\t\tthis.enterSubmit();\n\t}\n\n\tjumpToQuestion(index: number): void {\n\t\tthis.focus = \"options\";\n\t\tthis.activeIndex = index;\n\t\tthis.highlightIndex = 0;\n\t\tthis.clearTransient();\n\t}\n\n\tenterSubmit(): void {\n\t\tthis.focus = \"submit\";\n\t\tthis.submitRowIndex = this.commentRowIndex;\n\t\tthis.highlightIndex = 0;\n\t\tthis.clearTransient();\n\t}\n\n\treturnToOptions(): void {\n\t\tthis.leaveOwnAnswer(0);\n\t}\n\n\t/** Close the own-answer editor and highlight `row` of the active question. */\n\tleaveOwnAnswer(row: number): void {\n\t\tthis.focus = \"options\";\n\t\tthis.highlightIndex = Math.min(Math.max(0, row), this.ownAnswerRowIndex);\n\t\tthis.clearTransient();\n\t}\n\n\t/** Move the Submit-tab highlight by `delta`, clamped to the review rows and the comment editor. */\n\tmoveSubmitRow(delta: number): void {\n\t\tthis.submitRowIndex = Math.min(Math.max(0, this.submitRowIndex + delta), this.commentRowIndex);\n\t\tthis.clearTransient();\n\t}\n\n\tfocusComment(): void {\n\t\tthis.submitRowIndex = this.commentRowIndex;\n\t}\n\n\tprivate clearTransient(): void {\n\t\tthis.notice = undefined;\n\t\tthis.dismissPending = false;\n\t}\n\n\trequestDismiss(): \"confirm\" | \"cancel\" {\n\t\tif (!this.hasDraft()) return \"cancel\";\n\t\tif (!this.dismissPending) {\n\t\t\tthis.dismissPending = true;\n\t\t\tthis.notice = DISMISS_NOTICE;\n\t\t\treturn \"confirm\";\n\t\t}\n\t\treturn \"cancel\";\n\t}\n\n\tacceptPartialSubmit(): void {\n\t\tthis.dismissPending = false;\n\t\tthis.notice = undefined;\n\t}\n\n\tprivate hasDraft(): boolean {\n\t\tif ((this.comment ?? \"\").trim() !== \"\") return true;\n\t\treturn this.request.questions.some((question) => this.isAnswered(question.id));\n\t}\n\n\tselectedFor(questionId: string): string[] {\n\t\treturn this.selected.get(questionId) ?? [];\n\t}\n\n\ttextFor(questionId: string): string | undefined {\n\t\treturn this.texts.get(questionId);\n\t}\n\n\tisSelected(questionId: string, label: string): boolean {\n\t\treturn this.selectedFor(questionId).includes(label);\n\t}\n\n\tisAnswered(questionId: string): boolean {\n\t\tif (this.selectedFor(questionId).length > 0) return true;\n\t\treturn (this.texts.get(questionId) ?? \"\").trim() !== \"\";\n\t}\n\n\tansweredCount(): number {\n\t\treturn this.request.questions.filter((question) => this.isAnswered(question.id)).length;\n\t}\n\n\t/** Select (single) or toggle (multi) an option of the active question. */\n\tactivateOption(questionId: string, label: string): void {\n\t\tconst question = this.request.questions.find((entry) => entry.id === questionId);\n\t\tif (!question?.options.some((option) => option.label === label)) return;\n\t\tif (question.multiSelect) {\n\t\t\tconst next = [...this.selectedFor(questionId)];\n\t\t\tconst index = next.indexOf(label);\n\t\t\tif (index >= 0) next.splice(index, 1);\n\t\t\telse next.push(label);\n\t\t\tthis.selected.set(questionId, next);\n\t\t} else {\n\t\t\tthis.selected.set(questionId, [label]);\n\t\t}\n\t\tthis.notice = undefined;\n\t}\n\n\t/** Replace the question's answer with typed text; empty text clears it. */\n\tsetOwnAnswer(questionId: string, text: string): void {\n\t\tconst trimmed = text.trim();\n\t\tthis.selected.delete(questionId);\n\t\tif (trimmed === \"\") this.texts.delete(questionId);\n\t\telse this.texts.set(questionId, trimmed);\n\t\tthis.notice = undefined;\n\t}\n\n\tclearAnswer(questionId: string): void {\n\t\tthis.selected.delete(questionId);\n\t\tthis.texts.delete(questionId);\n\t\tthis.notice = undefined;\n\t}\n\n\t/** Seed selections, own texts and the comment from a previously captured draft. */\n\trestoreDraft(draft: QuestionDraft): void {\n\t\tfor (const question of this.request.questions) {\n\t\t\tconst answer = draft.answers?.[question.id];\n\t\t\tif (!answer) continue;\n\t\t\tconst selected = answer.selected.filter((label) => question.options.some((option) => option.label === label));\n\t\t\tif (selected.length > 0) this.selected.set(question.id, selected);\n\t\t\tif (answer.text !== undefined && answer.text.trim() !== \"\") this.texts.set(question.id, answer.text.trim());\n\t\t}\n\t\tif (draft.comment !== undefined && draft.comment.trim() !== \"\") this.comment = draft.comment;\n\t}\n\n\tanswers(): QuestionAnswers {\n\t\tconst result: QuestionAnswers = {};\n\t\tfor (const question of this.request.questions) {\n\t\t\tconst selected = this.selectedFor(question.id);\n\t\t\tconst text = this.texts.get(question.id);\n\t\t\tif (selected.length === 0 && text === undefined) continue;\n\t\t\tresult[question.id] = { selected, ...(text !== undefined ? { text } : {}) };\n\t\t}\n\t\treturn result;\n\t}\n\n\tunanswered(): string[] {\n\t\treturn this.request.questions.filter((question) => !this.isAnswered(question.id)).map((q) => q.id);\n\t}\n\n\t/** Submit outcome: comment wins, then answers; undefined means stay open. */\n\tsubmitOutcome(forcePartial = false): \"answered\" | \"comment-submitted\" | undefined {\n\t\tif ((this.comment ?? \"\").trim() !== \"\") return \"comment-submitted\";\n\t\tif (this.unanswered().length === 0) return \"answered\";\n\t\tif (this.answeredCount() > 0) return \"answered\";\n\t\tif (forcePartial) return \"answered\";\n\t\treturn undefined;\n\t}\n\n\tbuildResponse(status: QuestionResponse[\"status\"], autoResolvedAfterMs?: number): QuestionResponse {\n\t\tconst comment = this.comment !== undefined && this.comment.trim() !== \"\" ? this.comment : undefined;\n\t\treturn {\n\t\t\tstatus,\n\t\t\tanswers: this.answers(),\n\t\t\t...(comment !== undefined ? { comment } : {}),\n\t\t\tunanswered: this.unanswered(),\n\t\t\t...(autoResolvedAfterMs !== undefined ? { autoResolvedAfterMs } : {}),\n\t\t};\n\t}\n\n\trefreshDraft(): QuestionDraft {\n\t\tconst comment = this.comment !== undefined && this.comment.trim() !== \"\" ? this.comment : undefined;\n\t\treturn {\n\t\t\tanswers: this.answers(),\n\t\t\t...(comment !== undefined ? { comment } : {}),\n\t\t};\n\t}\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Ask-user question overlay: tab bar of question headers, numbered options
|
|
3
|
-
* with descriptions, per-question own-answer editor,
|
|
4
|
-
* comment editor, submit footer and a countdown chip. Layout lives in
|
|
3
|
+
* with descriptions, per-question own-answer editor, a Submit tab with review
|
|
4
|
+
* rows and the comment editor, submit footer and a countdown chip. Layout lives in
|
|
5
5
|
* ask-user-question-render.ts, interaction rules in ask-user-question-state.ts
|
|
6
6
|
* and key dispatch in ask-user-question-keys.ts.
|
|
7
7
|
*/
|
|
@@ -12,8 +12,14 @@ export interface AskUserQuestionOptions {
|
|
|
12
12
|
tui?: TUI;
|
|
13
13
|
/** Idle countdown duration; defaults to the request's timeoutMs. */
|
|
14
14
|
timeoutMs?: number;
|
|
15
|
+
/** Authoritative extension deadline; when supplied the component never expires the request itself. */
|
|
16
|
+
getDeadlineAtMs?: () => number;
|
|
15
17
|
/** Draft notification on every selection or keystroke (drives the idle timer). */
|
|
16
18
|
onProgress?: (draft: QuestionDraft) => void;
|
|
19
|
+
/** Answers and comment captured earlier (an async question re-expanded from its widget). */
|
|
20
|
+
initialDraft?: QuestionDraft;
|
|
21
|
+
/** Host digit entry targets the first unanswered sub-question. */
|
|
22
|
+
initialQuestionIndex?: number;
|
|
17
23
|
}
|
|
18
24
|
export declare class AskUserQuestionComponent extends Container implements Focusable {
|
|
19
25
|
private readonly state;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask-user-question.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/ask-user-question.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAuB,KAAK,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAClG,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"ask-user-question.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/ask-user-question.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAuB,KAAK,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAClG,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAe3F,OAAO,EAIN,KAAK,aAAa,EAClB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,WAAW,sBAAsB;IACtC,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sGAAsG;IACtG,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC;IAC/B,kFAAkF;IAClF,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5C,4FAA4F;IAC5F,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,kEAAkE;IAClE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,qBAAa,wBAAyB,SAAQ,SAAU,YAAW,SAAS;IAC3E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuC;IACpE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAe;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+B;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAO;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAO;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAO;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmB;IACjD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAmB;IACtD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmB;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAO;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAO;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAO;IACjC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA2B;IAC7D,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;IAEzB,YACC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,EAC1C,IAAI,GAAE,sBAA2B,EA4DjC;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE9B;IAED,OAAO,IAAI,IAAI,CAEd;IAED,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,MAAM;IAQd,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,SAAS;CA+BjB"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Ask-user question overlay: tab bar of question headers, numbered options
|
|
3
|
-
* with descriptions, per-question own-answer editor,
|
|
4
|
-
* comment editor, submit footer and a countdown chip. Layout lives in
|
|
3
|
+
* with descriptions, per-question own-answer editor, a Submit tab with review
|
|
4
|
+
* rows and the comment editor, submit footer and a countdown chip. Layout lives in
|
|
5
5
|
* ask-user-question-render.ts, interaction rules in ask-user-question-state.ts
|
|
6
6
|
* and key dispatch in ask-user-question-keys.ts.
|
|
7
7
|
*/
|
|
8
8
|
import { Container, Input, Spacer, Text } from "@earendil-works/pi-tui";
|
|
9
|
+
import { AskUserCountdown } from "./ask-user-countdown.js";
|
|
9
10
|
import { handleAskUserKeyInput } from "./ask-user-question-keys.js";
|
|
10
11
|
import { renderCommentLabel, renderHintsLine, renderNotice, renderOwnAnswerLabel, renderQuestionLine, renderQuestionList, renderSubmitLine, renderSubmitSummary, renderTabBar, renderTitle, } from "./ask-user-question-render.js";
|
|
11
12
|
import { AskUserQuestionState, formatCountdownLabel, NOT_ANSWERED_NOTICE, } from "./ask-user-question-state.js";
|
|
12
|
-
import { CountdownTimer } from "./countdown-timer.js";
|
|
13
13
|
import { DynamicBorder } from "./dynamic-border.js";
|
|
14
14
|
export class AskUserQuestionComponent extends Container {
|
|
15
15
|
constructor(request, done, opts = {}) {
|
|
@@ -55,13 +55,20 @@ export class AskUserQuestionComponent extends Container {
|
|
|
55
55
|
this.addChild(this.hintsText);
|
|
56
56
|
this.addChild(new Spacer(1));
|
|
57
57
|
this.addChild(new DynamicBorder());
|
|
58
|
+
if (opts.initialDraft) {
|
|
59
|
+
this.state.restoreDraft(opts.initialDraft);
|
|
60
|
+
if (this.state.comment !== undefined)
|
|
61
|
+
this.commentInput.setValue(this.state.comment);
|
|
62
|
+
}
|
|
63
|
+
if (opts.initialQuestionIndex !== undefined)
|
|
64
|
+
this.state.jumpToQuestion(opts.initialQuestionIndex);
|
|
58
65
|
const timeoutMs = opts.timeoutMs ?? request.timeoutMs;
|
|
59
|
-
if (timeoutMs > 0) {
|
|
60
|
-
this.countdown = new
|
|
61
|
-
this.countdownLabel = formatCountdownLabel(
|
|
66
|
+
if (timeoutMs > 0 || opts.getDeadlineAtMs) {
|
|
67
|
+
this.countdown = new AskUserCountdown(timeoutMs, opts.tui, (remainingMs) => {
|
|
68
|
+
this.countdownLabel = formatCountdownLabel(remainingMs);
|
|
62
69
|
this.updateTitle();
|
|
63
70
|
this.options.tui?.requestRender();
|
|
64
|
-
}, () => this.finish("timed_out", timeoutMs));
|
|
71
|
+
}, () => this.finish("timed_out", timeoutMs), opts.getDeadlineAtMs);
|
|
65
72
|
}
|
|
66
73
|
this.updateAll();
|
|
67
74
|
}
|
|
@@ -90,6 +97,7 @@ export class AskUserQuestionComponent extends Container {
|
|
|
90
97
|
}
|
|
91
98
|
commitOwnAnswer() {
|
|
92
99
|
this.state.setOwnAnswer(this.state.activeQuestion.id, this.ownAnswerInput.getValue());
|
|
100
|
+
this.ownAnswerInput.setValue("");
|
|
93
101
|
this.emitProgress();
|
|
94
102
|
}
|
|
95
103
|
attemptSubmit() {
|
|
@@ -126,7 +134,7 @@ export class AskUserQuestionComponent extends Container {
|
|
|
126
134
|
}
|
|
127
135
|
applyFocusFlags() {
|
|
128
136
|
this.ownAnswerInput.focused = this._focused && this.state.focus === "own-answer";
|
|
129
|
-
this.commentInput.focused = this._focused && this.state.
|
|
137
|
+
this.commentInput.focused = this._focused && this.state.isCommentFocused;
|
|
130
138
|
}
|
|
131
139
|
updateTitle() {
|
|
132
140
|
this.titleText.setText(renderTitle(this.countdownLabel));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask-user-question.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/ask-user-question.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Ask-user question overlay: tab bar of question headers, numbered options\n * with descriptions, per-question own-answer editor, one always-visible\n * comment editor, submit footer and a countdown chip. Layout lives in\n * ask-user-question-render.ts, interaction rules in ask-user-question-state.ts\n * and key dispatch in ask-user-question-keys.ts.\n */\n\nimport { Container, type Focusable, Input, Spacer, Text, type TUI } from \"@earendil-works/pi-tui\";\nimport type { QuestionRequest, QuestionResponse } from \"../../../core/extensions/types.ts\";\nimport { type AskUserKeyHandlerContext, handleAskUserKeyInput } from \"./ask-user-question-keys.ts\";\nimport {\n\trenderCommentLabel,\n\trenderHintsLine,\n\trenderNotice,\n\trenderOwnAnswerLabel,\n\trenderQuestionLine,\n\trenderQuestionList,\n\trenderSubmitLine,\n\trenderSubmitSummary,\n\trenderTabBar,\n\trenderTitle,\n} from \"./ask-user-question-render.ts\";\nimport {\n\tAskUserQuestionState,\n\tformatCountdownLabel,\n\tNOT_ANSWERED_NOTICE,\n\ttype QuestionDraft,\n} from \"./ask-user-question-state.ts\";\nimport { CountdownTimer } from \"./countdown-timer.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\n\nexport interface AskUserQuestionOptions {\n\ttui?: TUI;\n\t/** Idle countdown duration; defaults to the request's timeoutMs. */\n\ttimeoutMs?: number;\n\t/** Draft notification on every selection or keystroke (drives the idle timer). */\n\tonProgress?: (draft: QuestionDraft) => void;\n}\n\nexport class AskUserQuestionComponent extends Container implements Focusable {\n\tprivate readonly state: AskUserQuestionState;\n\tprivate readonly doneCallback: (response: QuestionResponse) => void;\n\tprivate readonly options: AskUserQuestionOptions;\n\tprivate readonly ownAnswerInput = new Input();\n\tprivate readonly commentInput = new Input();\n\tprivate readonly countdown: CountdownTimer | undefined;\n\tprivate readonly titleText: Text;\n\tprivate readonly tabText: Text;\n\tprivate readonly questionText: Text;\n\tprivate readonly listContainer = new Container();\n\tprivate readonly ownAnswerContainer = new Container();\n\tprivate readonly submitContainer = new Container();\n\tprivate readonly noticeText: Text;\n\tprivate readonly submitText: Text;\n\tprivate readonly hintsText: Text;\n\tprivate readonly keyHandlerContext: AskUserKeyHandlerContext;\n\tprivate countdownLabel = \"\";\n\tprivate settled = false;\n\tprivate _focused = false;\n\n\tconstructor(\n\t\trequest: QuestionRequest,\n\t\tdone: (response: QuestionResponse) => void,\n\t\topts: AskUserQuestionOptions = {},\n\t) {\n\t\tsuper();\n\t\tthis.state = new AskUserQuestionState(request);\n\t\tthis.doneCallback = done;\n\t\tthis.options = opts;\n\t\tthis.keyHandlerContext = {\n\t\t\tstate: this.state,\n\t\t\townAnswerInput: this.ownAnswerInput,\n\t\t\tcommentInput: this.commentInput,\n\t\t\tfinish: (status, autoResolvedAfterMs) => this.finish(status, autoResolvedAfterMs),\n\t\t\tattemptSubmit: () => this.attemptSubmit(),\n\t\t\topenOwnAnswer: (initialText) => this.openOwnAnswer(initialText),\n\t\t\tcommitOwnAnswer: () => this.commitOwnAnswer(),\n\t\t\temitProgress: () => this.emitProgress(),\n\t\t\tupdateAll: () => this.updateAll(),\n\t\t};\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.titleText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.titleText);\n\t\tthis.tabText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.tabText);\n\t\tthis.questionText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.questionText);\n\t\tthis.addChild(this.listContainer);\n\t\tthis.addChild(this.ownAnswerContainer);\n\t\tthis.addChild(this.submitContainer);\n\t\tthis.noticeText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.noticeText);\n\t\tthis.submitText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.submitText);\n\t\tthis.hintsText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.hintsText);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\n\t\tconst timeoutMs = opts.timeoutMs ?? request.timeoutMs;\n\t\tif (timeoutMs > 0) {\n\t\t\tthis.countdown = new CountdownTimer(\n\t\t\t\ttimeoutMs,\n\t\t\t\topts.tui,\n\t\t\t\t(seconds) => {\n\t\t\t\t\tthis.countdownLabel = formatCountdownLabel(seconds * 1000);\n\t\t\t\t\tthis.updateTitle();\n\t\t\t\t\tthis.options.tui?.requestRender();\n\t\t\t\t},\n\t\t\t\t() => this.finish(\"timed_out\", timeoutMs),\n\t\t\t);\n\t\t}\n\t\tthis.updateAll();\n\t}\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.applyFocusFlags();\n\t}\n\n\thandleInput(data: string): void {\n\t\thandleAskUserKeyInput(this.keyHandlerContext, data);\n\t}\n\n\tdispose(): void {\n\t\tthis.countdown?.dispose();\n\t}\n\n\tprivate openOwnAnswer(initialText?: string): void {\n\t\tthis.state.focus = \"own-answer\";\n\t\tconst existing = this.state.textFor(this.state.activeQuestion.id) ?? \"\";\n\t\tthis.ownAnswerInput.setValue(\"\");\n\t\tif (existing !== \"\") this.ownAnswerInput.handleInput(existing);\n\t\tif (initialText !== undefined) this.ownAnswerInput.handleInput(initialText);\n\t\tthis.updateAll();\n\t}\n\n\tprivate commitOwnAnswer(): void {\n\t\tthis.state.setOwnAnswer(this.state.activeQuestion.id, this.ownAnswerInput.getValue());\n\t\tthis.emitProgress();\n\t}\n\n\tprivate attemptSubmit(): void {\n\t\tthis.state.comment = this.commentInput.getValue();\n\t\tconst outcome = this.state.submitOutcome(this.state.notice !== undefined);\n\t\tif (!outcome) {\n\t\t\tthis.state.notice = NOT_ANSWERED_NOTICE;\n\t\t\tthis.updateAll();\n\t\t\treturn;\n\t\t}\n\t\tthis.state.acceptPartialSubmit();\n\t\tthis.finish(outcome);\n\t}\n\n\tprivate emitProgress(): void {\n\t\tconst draft = this.state.refreshDraft();\n\t\tif (this.state.focus === \"own-answer\") {\n\t\t\tconst live = this.ownAnswerInput.getValue().trim();\n\t\t\tif (live !== \"\") {\n\t\t\t\tdraft.answers = {\n\t\t\t\t\t...draft.answers,\n\t\t\t\t\t[this.state.activeQuestion.id]: { selected: [], text: live },\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tthis.options.onProgress?.(draft);\n\t}\n\n\tprivate finish(status: QuestionResponse[\"status\"], autoResolvedAfterMs?: number): void {\n\t\tif (this.settled) return;\n\t\tthis.settled = true;\n\t\tthis.countdown?.dispose();\n\t\tthis.state.comment = this.commentInput.getValue();\n\t\tthis.doneCallback(this.state.buildResponse(status, autoResolvedAfterMs));\n\t}\n\n\tprivate applyFocusFlags(): void {\n\t\tthis.ownAnswerInput.focused = this._focused && this.state.focus === \"own-answer\";\n\t\tthis.commentInput.focused = this._focused && this.state.focus === \"submit\";\n\t}\n\n\tprivate updateTitle(): void {\n\t\tthis.titleText.setText(renderTitle(this.countdownLabel));\n\t}\n\n\tprivate updateAll(): void {\n\t\tthis.updateTitle();\n\t\tthis.applyFocusFlags();\n\t\tthis.tabText.setText(renderTabBar(this.state));\n\t\tthis.questionText.setText(\n\t\t\tthis.state.focus === \"submit\" ? \"Review your answers\" : renderQuestionLine(this.state.activeQuestion),\n\t\t);\n\n\t\tthis.listContainer.clear();\n\t\tfor (const line of this.state.focus === \"submit\"\n\t\t\t? renderSubmitSummary(this.state)\n\t\t\t: renderQuestionList(this.state)) {\n\t\t\tthis.listContainer.addChild(new Text(line, 1, 0));\n\t\t}\n\n\t\tthis.ownAnswerContainer.clear();\n\t\tif (this.state.focus === \"own-answer\") {\n\t\t\tthis.ownAnswerContainer.addChild(new Text(renderOwnAnswerLabel(), 1, 0));\n\t\t\tthis.ownAnswerContainer.addChild(this.ownAnswerInput);\n\t\t}\n\n\t\tthis.submitContainer.clear();\n\t\tif (this.state.focus === \"submit\") {\n\t\t\tthis.submitContainer.addChild(new Spacer(1));\n\t\t\tthis.submitContainer.addChild(new Text(renderCommentLabel(), 1, 0));\n\t\t\tthis.submitContainer.addChild(this.commentInput);\n\t\t}\n\t\tthis.noticeText.setText(renderNotice(this.state.notice));\n\t\tthis.submitText.setText(renderSubmitLine(this.state));\n\t\tthis.hintsText.setText(renderHintsLine(this.state));\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ask-user-question.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/ask-user-question.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Ask-user question overlay: tab bar of question headers, numbered options\n * with descriptions, per-question own-answer editor, a Submit tab with review\n * rows and the comment editor, submit footer and a countdown chip. Layout lives in\n * ask-user-question-render.ts, interaction rules in ask-user-question-state.ts\n * and key dispatch in ask-user-question-keys.ts.\n */\n\nimport { Container, type Focusable, Input, Spacer, Text, type TUI } from \"@earendil-works/pi-tui\";\nimport type { QuestionRequest, QuestionResponse } from \"../../../core/extensions/types.ts\";\nimport { AskUserCountdown } from \"./ask-user-countdown.ts\";\nimport { type AskUserKeyHandlerContext, handleAskUserKeyInput } from \"./ask-user-question-keys.ts\";\nimport {\n\trenderCommentLabel,\n\trenderHintsLine,\n\trenderNotice,\n\trenderOwnAnswerLabel,\n\trenderQuestionLine,\n\trenderQuestionList,\n\trenderSubmitLine,\n\trenderSubmitSummary,\n\trenderTabBar,\n\trenderTitle,\n} from \"./ask-user-question-render.ts\";\nimport {\n\tAskUserQuestionState,\n\tformatCountdownLabel,\n\tNOT_ANSWERED_NOTICE,\n\ttype QuestionDraft,\n} from \"./ask-user-question-state.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\n\nexport interface AskUserQuestionOptions {\n\ttui?: TUI;\n\t/** Idle countdown duration; defaults to the request's timeoutMs. */\n\ttimeoutMs?: number;\n\t/** Authoritative extension deadline; when supplied the component never expires the request itself. */\n\tgetDeadlineAtMs?: () => number;\n\t/** Draft notification on every selection or keystroke (drives the idle timer). */\n\tonProgress?: (draft: QuestionDraft) => void;\n\t/** Answers and comment captured earlier (an async question re-expanded from its widget). */\n\tinitialDraft?: QuestionDraft;\n\t/** Host digit entry targets the first unanswered sub-question. */\n\tinitialQuestionIndex?: number;\n}\n\nexport class AskUserQuestionComponent extends Container implements Focusable {\n\tprivate readonly state: AskUserQuestionState;\n\tprivate readonly doneCallback: (response: QuestionResponse) => void;\n\tprivate readonly options: AskUserQuestionOptions;\n\tprivate readonly ownAnswerInput = new Input();\n\tprivate readonly commentInput = new Input();\n\tprivate readonly countdown: AskUserCountdown | undefined;\n\tprivate readonly titleText: Text;\n\tprivate readonly tabText: Text;\n\tprivate readonly questionText: Text;\n\tprivate readonly listContainer = new Container();\n\tprivate readonly ownAnswerContainer = new Container();\n\tprivate readonly submitContainer = new Container();\n\tprivate readonly noticeText: Text;\n\tprivate readonly submitText: Text;\n\tprivate readonly hintsText: Text;\n\tprivate readonly keyHandlerContext: AskUserKeyHandlerContext;\n\tprivate countdownLabel = \"\";\n\tprivate settled = false;\n\tprivate _focused = false;\n\n\tconstructor(\n\t\trequest: QuestionRequest,\n\t\tdone: (response: QuestionResponse) => void,\n\t\topts: AskUserQuestionOptions = {},\n\t) {\n\t\tsuper();\n\t\tthis.state = new AskUserQuestionState(request);\n\t\tthis.doneCallback = done;\n\t\tthis.options = opts;\n\t\tthis.keyHandlerContext = {\n\t\t\tstate: this.state,\n\t\t\townAnswerInput: this.ownAnswerInput,\n\t\t\tcommentInput: this.commentInput,\n\t\t\tfinish: (status, autoResolvedAfterMs) => this.finish(status, autoResolvedAfterMs),\n\t\t\tattemptSubmit: () => this.attemptSubmit(),\n\t\t\topenOwnAnswer: (initialText) => this.openOwnAnswer(initialText),\n\t\t\tcommitOwnAnswer: () => this.commitOwnAnswer(),\n\t\t\temitProgress: () => this.emitProgress(),\n\t\t\tupdateAll: () => this.updateAll(),\n\t\t};\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.titleText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.titleText);\n\t\tthis.tabText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.tabText);\n\t\tthis.questionText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.questionText);\n\t\tthis.addChild(this.listContainer);\n\t\tthis.addChild(this.ownAnswerContainer);\n\t\tthis.addChild(this.submitContainer);\n\t\tthis.noticeText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.noticeText);\n\t\tthis.submitText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.submitText);\n\t\tthis.hintsText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.hintsText);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\n\t\tif (opts.initialDraft) {\n\t\t\tthis.state.restoreDraft(opts.initialDraft);\n\t\t\tif (this.state.comment !== undefined) this.commentInput.setValue(this.state.comment);\n\t\t}\n\n\t\tif (opts.initialQuestionIndex !== undefined) this.state.jumpToQuestion(opts.initialQuestionIndex);\n\n\t\tconst timeoutMs = opts.timeoutMs ?? request.timeoutMs;\n\t\tif (timeoutMs > 0 || opts.getDeadlineAtMs) {\n\t\t\tthis.countdown = new AskUserCountdown(\n\t\t\t\ttimeoutMs,\n\t\t\t\topts.tui,\n\t\t\t\t(remainingMs) => {\n\t\t\t\t\tthis.countdownLabel = formatCountdownLabel(remainingMs);\n\t\t\t\t\tthis.updateTitle();\n\t\t\t\t\tthis.options.tui?.requestRender();\n\t\t\t\t},\n\t\t\t\t() => this.finish(\"timed_out\", timeoutMs),\n\t\t\t\topts.getDeadlineAtMs,\n\t\t\t);\n\t\t}\n\t\tthis.updateAll();\n\t}\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.applyFocusFlags();\n\t}\n\n\thandleInput(data: string): void {\n\t\thandleAskUserKeyInput(this.keyHandlerContext, data);\n\t}\n\n\tdispose(): void {\n\t\tthis.countdown?.dispose();\n\t}\n\n\tprivate openOwnAnswer(initialText?: string): void {\n\t\tthis.state.focus = \"own-answer\";\n\t\tconst existing = this.state.textFor(this.state.activeQuestion.id) ?? \"\";\n\t\tthis.ownAnswerInput.setValue(\"\");\n\t\tif (existing !== \"\") this.ownAnswerInput.handleInput(existing);\n\t\tif (initialText !== undefined) this.ownAnswerInput.handleInput(initialText);\n\t\tthis.updateAll();\n\t}\n\n\tprivate commitOwnAnswer(): void {\n\t\tthis.state.setOwnAnswer(this.state.activeQuestion.id, this.ownAnswerInput.getValue());\n\t\tthis.ownAnswerInput.setValue(\"\");\n\t\tthis.emitProgress();\n\t}\n\n\tprivate attemptSubmit(): void {\n\t\tthis.state.comment = this.commentInput.getValue();\n\t\tconst outcome = this.state.submitOutcome(this.state.notice !== undefined);\n\t\tif (!outcome) {\n\t\t\tthis.state.notice = NOT_ANSWERED_NOTICE;\n\t\t\tthis.updateAll();\n\t\t\treturn;\n\t\t}\n\t\tthis.state.acceptPartialSubmit();\n\t\tthis.finish(outcome);\n\t}\n\n\tprivate emitProgress(): void {\n\t\tconst draft = this.state.refreshDraft();\n\t\tif (this.state.focus === \"own-answer\") {\n\t\t\tconst live = this.ownAnswerInput.getValue().trim();\n\t\t\tif (live !== \"\") {\n\t\t\t\tdraft.answers = {\n\t\t\t\t\t...draft.answers,\n\t\t\t\t\t[this.state.activeQuestion.id]: { selected: [], text: live },\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tthis.options.onProgress?.(draft);\n\t}\n\n\tprivate finish(status: QuestionResponse[\"status\"], autoResolvedAfterMs?: number): void {\n\t\tif (this.settled) return;\n\t\tthis.settled = true;\n\t\tthis.countdown?.dispose();\n\t\tthis.state.comment = this.commentInput.getValue();\n\t\tthis.doneCallback(this.state.buildResponse(status, autoResolvedAfterMs));\n\t}\n\n\tprivate applyFocusFlags(): void {\n\t\tthis.ownAnswerInput.focused = this._focused && this.state.focus === \"own-answer\";\n\t\tthis.commentInput.focused = this._focused && this.state.isCommentFocused;\n\t}\n\n\tprivate updateTitle(): void {\n\t\tthis.titleText.setText(renderTitle(this.countdownLabel));\n\t}\n\n\tprivate updateAll(): void {\n\t\tthis.updateTitle();\n\t\tthis.applyFocusFlags();\n\t\tthis.tabText.setText(renderTabBar(this.state));\n\t\tthis.questionText.setText(\n\t\t\tthis.state.focus === \"submit\" ? \"Review your answers\" : renderQuestionLine(this.state.activeQuestion),\n\t\t);\n\n\t\tthis.listContainer.clear();\n\t\tfor (const line of this.state.focus === \"submit\"\n\t\t\t? renderSubmitSummary(this.state)\n\t\t\t: renderQuestionList(this.state)) {\n\t\t\tthis.listContainer.addChild(new Text(line, 1, 0));\n\t\t}\n\n\t\tthis.ownAnswerContainer.clear();\n\t\tif (this.state.focus === \"own-answer\") {\n\t\t\tthis.ownAnswerContainer.addChild(new Text(renderOwnAnswerLabel(), 1, 0));\n\t\t\tthis.ownAnswerContainer.addChild(this.ownAnswerInput);\n\t\t}\n\n\t\tthis.submitContainer.clear();\n\t\tif (this.state.focus === \"submit\") {\n\t\t\tthis.submitContainer.addChild(new Spacer(1));\n\t\t\tthis.submitContainer.addChild(new Text(renderCommentLabel(), 1, 0));\n\t\t\tthis.submitContainer.addChild(this.commentInput);\n\t\t}\n\t\tthis.noticeText.setText(renderNotice(this.state.notice));\n\t\tthis.submitText.setText(renderSubmitLine(this.state));\n\t\tthis.hintsText.setText(renderHintsLine(this.state));\n\t}\n}\n"]}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { type Component, Container, type Focusable } from "@earendil-works/pi-tui";
|
|
5
5
|
import type { PathMetadata, ResolvedPaths } from "../../../core/package-manager.ts";
|
|
6
6
|
import type { SettingsManager } from "../../../core/settings-manager.ts";
|
|
7
|
+
import type { SourceScope } from "../../../core/source-info.ts";
|
|
7
8
|
type ResourceType = "extensions" | "skills" | "prompts" | "themes";
|
|
8
9
|
type ConfigWriteScope = "global" | "project";
|
|
9
10
|
export type ScopedResolvedPaths = Record<ConfigWriteScope, ResolvedPaths>;
|
|
@@ -24,7 +25,7 @@ interface ResourceSubgroup {
|
|
|
24
25
|
interface ResourceGroup {
|
|
25
26
|
key: string;
|
|
26
27
|
label: string;
|
|
27
|
-
scope:
|
|
28
|
+
scope: SourceScope;
|
|
28
29
|
origin: "package" | "top-level";
|
|
29
30
|
source: string;
|
|
30
31
|
subgroups: ResourceSubgroup[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/config-selector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EACT,KAAK,SAAS,EAOd,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAoB,MAAM,kCAAkC,CAAC;AACtG,OAAO,KAAK,EAAiB,eAAe,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"config-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/config-selector.ts"],"names":[],"mappings":"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"}
|