@agimon-ai/doompi-user-feedback 0.0.1-alpha.9 → 0.0.1-alpha.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/README.md +96 -35
  2. package/dist/apiContracts.cjs +17 -0
  3. package/dist/apiContracts.cjs.map +1 -0
  4. package/dist/apiContracts.d.mts +53 -0
  5. package/dist/apiContracts.d.mts.map +1 -0
  6. package/dist/apiContracts.mjs +13 -0
  7. package/dist/apiContracts.mjs.map +1 -0
  8. package/dist/extensions/pi.cjs +523 -1
  9. package/dist/extensions/pi.cjs.map +1 -1
  10. package/dist/extensions/pi.d.mts +3 -4
  11. package/dist/extensions/pi.d.mts.map +1 -1
  12. package/dist/extensions/pi.mjs +514 -1
  13. package/dist/extensions/pi.mjs.map +1 -1
  14. package/dist/extensions/server.cjs +125 -0
  15. package/dist/extensions/server.cjs.map +1 -0
  16. package/dist/extensions/server.d.mts +5 -0
  17. package/dist/extensions/server.d.mts.map +1 -0
  18. package/dist/extensions/server.mjs +120 -0
  19. package/dist/extensions/server.mjs.map +1 -0
  20. package/dist/extensions/web.mjs +621 -0
  21. package/dist/extensions/web.mjs.map +1 -0
  22. package/dist/index.cjs +0 -1
  23. package/dist/index.d.mts +49 -4
  24. package/dist/index.d.mts.map +1 -0
  25. package/dist/index.mjs +1 -1
  26. package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
  27. package/dist/runQuestionnaire-C4n_SWi2.mjs +436 -0
  28. package/dist/runQuestionnaire-C4n_SWi2.mjs.map +1 -0
  29. package/dist/runQuestionnaire-CRYC7DRF.cjs +439 -0
  30. package/dist/runQuestionnaire-CRYC7DRF.cjs.map +1 -0
  31. package/dist/validationService-BuqweEhq.cjs +577 -0
  32. package/dist/validationService-BuqweEhq.cjs.map +1 -0
  33. package/dist/validationService-CS-VJaMo.mjs +500 -0
  34. package/dist/validationService-CS-VJaMo.mjs.map +1 -0
  35. package/package.json +71 -25
  36. package/dist/_virtual/_rolldown/runtime.cjs +0 -1
  37. package/dist/adapters/config/configAdapter.cjs +0 -2
  38. package/dist/adapters/config/configAdapter.cjs.map +0 -1
  39. package/dist/adapters/config/configAdapter.mjs +0 -2
  40. package/dist/adapters/config/configAdapter.mjs.map +0 -1
  41. package/dist/adapters/doom/voiceQuestionHandoff.cjs +0 -5
  42. package/dist/adapters/doom/voiceQuestionHandoff.cjs.map +0 -1
  43. package/dist/adapters/doom/voiceQuestionHandoff.d.cts +0 -32
  44. package/dist/adapters/doom/voiceQuestionHandoff.d.cts.map +0 -1
  45. package/dist/adapters/doom/voiceQuestionHandoff.d.mts +0 -32
  46. package/dist/adapters/doom/voiceQuestionHandoff.d.mts.map +0 -1
  47. package/dist/adapters/doom/voiceQuestionHandoff.mjs +0 -5
  48. package/dist/adapters/doom/voiceQuestionHandoff.mjs.map +0 -1
  49. package/dist/adapters/pi/askUserQuestionAdapter.cjs +0 -15
  50. package/dist/adapters/pi/askUserQuestionAdapter.cjs.map +0 -1
  51. package/dist/adapters/pi/askUserQuestionAdapter.mjs +0 -15
  52. package/dist/adapters/pi/askUserQuestionAdapter.mjs.map +0 -1
  53. package/dist/adapters/pi/reconcileAdapter.cjs +0 -2
  54. package/dist/adapters/pi/reconcileAdapter.cjs.map +0 -1
  55. package/dist/adapters/pi/reconcileAdapter.mjs +0 -2
  56. package/dist/adapters/pi/reconcileAdapter.mjs.map +0 -1
  57. package/dist/adapters/pi/rpcQuestionnaireAdapter.cjs +0 -2
  58. package/dist/adapters/pi/rpcQuestionnaireAdapter.cjs.map +0 -1
  59. package/dist/adapters/pi/rpcQuestionnaireAdapter.mjs +0 -2
  60. package/dist/adapters/pi/rpcQuestionnaireAdapter.mjs.map +0 -1
  61. package/dist/events.cjs +0 -1
  62. package/dist/events.d.cts +0 -2
  63. package/dist/events.d.mts +0 -2
  64. package/dist/events.mjs +0 -1
  65. package/dist/extensions/pi.d.cts +0 -6
  66. package/dist/extensions/pi.d.cts.map +0 -1
  67. package/dist/index.d.cts +0 -4
  68. package/dist/schemas/events.cjs +0 -1
  69. package/dist/schemas/events.d.cts +0 -22
  70. package/dist/schemas/events.d.cts.map +0 -1
  71. package/dist/schemas/events.d.mts +0 -22
  72. package/dist/schemas/events.d.mts.map +0 -1
  73. package/dist/schemas/events.mjs +0 -1
  74. package/dist/schemas/questionnaire.cjs +0 -2
  75. package/dist/schemas/questionnaire.cjs.map +0 -1
  76. package/dist/schemas/questionnaire.d.cts +0 -18
  77. package/dist/schemas/questionnaire.d.cts.map +0 -1
  78. package/dist/schemas/questionnaire.d.mts +0 -18
  79. package/dist/schemas/questionnaire.d.mts.map +0 -1
  80. package/dist/schemas/questionnaire.mjs +0 -2
  81. package/dist/schemas/questionnaire.mjs.map +0 -1
  82. package/dist/services/questionnaireCoordinator.cjs +0 -2
  83. package/dist/services/questionnaireCoordinator.cjs.map +0 -1
  84. package/dist/services/questionnaireCoordinator.mjs +0 -2
  85. package/dist/services/questionnaireCoordinator.mjs.map +0 -1
  86. package/dist/services/responseService.cjs +0 -2
  87. package/dist/services/responseService.cjs.map +0 -1
  88. package/dist/services/responseService.mjs +0 -2
  89. package/dist/services/responseService.mjs.map +0 -1
  90. package/dist/services/validationService.cjs +0 -2
  91. package/dist/services/validationService.cjs.map +0 -1
  92. package/dist/services/validationService.mjs +0 -2
  93. package/dist/services/validationService.mjs.map +0 -1
  94. package/dist/services/voiceQuestionNarration.cjs +0 -2
  95. package/dist/services/voiceQuestionNarration.cjs.map +0 -1
  96. package/dist/services/voiceQuestionNarration.mjs +0 -2
  97. package/dist/services/voiceQuestionNarration.mjs.map +0 -1
  98. package/dist/tui/externalEditor.cjs +0 -2
  99. package/dist/tui/externalEditor.cjs.map +0 -1
  100. package/dist/tui/externalEditor.mjs +0 -2
  101. package/dist/tui/externalEditor.mjs.map +0 -1
  102. package/dist/tui/questionnaireComponent.cjs +0 -2
  103. package/dist/tui/questionnaireComponent.cjs.map +0 -1
  104. package/dist/tui/questionnaireComponent.mjs +0 -2
  105. package/dist/tui/questionnaireComponent.mjs.map +0 -1
  106. package/dist/tui/runQuestionnaire.cjs +0 -2
  107. package/dist/tui/runQuestionnaire.cjs.map +0 -1
  108. package/dist/tui/runQuestionnaire.mjs +0 -2
  109. package/dist/tui/runQuestionnaire.mjs.map +0 -1
  110. package/dist/types/questionnaire.d.cts +0 -31
  111. package/dist/types/questionnaire.d.cts.map +0 -1
  112. package/dist/types/questionnaire.d.mts +0 -31
  113. package/dist/types/questionnaire.d.mts.map +0 -1
  114. package/dist/voiceQuestionHandoff.cjs +0 -1
  115. package/dist/voiceQuestionHandoff.d.cts +0 -4
  116. package/dist/voiceQuestionHandoff.d.mts +0 -4
  117. package/dist/voiceQuestionHandoff.mjs +0 -1
package/README.md CHANGED
@@ -1,62 +1,123 @@
1
1
  # @agimon-ai/doompi-user-feedback
2
2
 
3
- **Sometimes the agent needs an answer. Make it ask.**
3
+ Ask structured questions in interactive Pi sessions, including sessions using autonomous Voice.
4
4
 
5
- This package provides the structured `ask_user_question` interaction for Pi. In a normal
6
- terminal session it opens a blocking questionnaire and returns the selected answer to the
7
- agent. The question does not get buried in prose and the turn does not continue on a
8
- guess.
5
+ Part of the [DoomPi distribution](https://www.npmjs.com/package/@agimon-ai/doompi).
9
6
 
10
- In autonomous Voice mode there is no modal to click. The extension formats the choices as
11
- plain text, hands them to narration, terminates the turn, and accepts the next spoken reply
12
- as an ordinary user message.
7
+ The `ask_user_question` tool presents concrete options and waits for a choice or custom-text answer.
13
8
 
14
- This implementation is written for Pi and has no dependency on the old Juicesharp
15
- packages. It keeps the established `rpiv:ask-user:prompt` and `rpiv:ask-user:blocked`
16
- channel names so existing Doompi listeners can migrate without being rewritten.
9
+ > **Alpha:** tool and Voice-handoff contracts may change between releases.
17
10
 
18
- This is part of [Doompi](https://www.npmjs.com/package/@agimon-ai/doompi). The bundled
19
- `ask-user` layer loads it where structured feedback is wanted.
11
+ ## Requirements
20
12
 
21
- ## Install
22
-
23
- ```bash
24
- npm install @agimon-ai/doompi-user-feedback
25
- ```
13
+ - Node.js 22.19.0 or newer
14
+ - Pi 0.85.0 and Pi TUI 0.85.0
26
15
 
27
- ## How it loads
16
+ ## Install
28
17
 
29
- Put the bare package name in a layer, then add that layer to a major mode:
18
+ Define a layer in `.doom/modes.yaml`, then include it in a major mode:
30
19
 
31
20
  ```yaml
32
21
  layers:
33
- ask-user:
22
+ feedback:
34
23
  packages: ['@agimon-ai/doompi-user-feedback']
35
24
 
36
25
  majorMode:
37
- dev:
38
- description: Development mode with structured user clarification.
39
- layers: [ask-user]
26
+ minimal:
27
+ description: Interactive questions without the full default composition.
28
+ layers: [feedback]
29
+ ```
30
+
31
+ For standalone Pi:
32
+
33
+ ```bash
34
+ pi install npm:@agimon-ai/doompi-user-feedback
40
35
  ```
41
36
 
42
- The package's Pi manifest selects the Pi adapter. The explicit `/extensions/pi` subpath
43
- remains available when an adapter path is required.
37
+ Pi loads the package through `package.json.pi.extensions`. Each factory invocation owns one package
38
+ instance. Session replacement resets its state, and shutdown removes its registrations.
39
+
40
+ ## Ask a question
41
+
42
+ ```json
43
+ {
44
+ "questions": [
45
+ {
46
+ "header": "Storage",
47
+ "question": "Where should session results be stored?",
48
+ "options": [
49
+ {
50
+ "label": "Project files",
51
+ "description": "Easy to inspect and commit, but visible in the repository."
52
+ },
53
+ {
54
+ "label": "User state",
55
+ "description": "Keeps generated state outside the repository."
56
+ }
57
+ ],
58
+ "multiSelect": false
59
+ }
60
+ ]
61
+ }
62
+ ```
63
+
64
+ A call accepts 1 to 4 questions. Each question requires 2 to 4 options. Headers are at most 16
65
+ characters; option labels are at most 60 characters. Use `multiSelect: true` when several choices
66
+ are valid. An option can include a Markdown `preview` for meaningful visual comparison.
67
+
68
+ The tool result contains readable answer text plus structured `details.answers`; cancellation sets
69
+ `cancelled: true`. Pressing Escape declines the questionnaire. Do not add an `Other` option because
70
+ the UI supplies a custom-text row.
44
71
 
45
- ## Reusable voice handoff
72
+ ## UI, RPC, and headless behavior
46
73
 
47
- `@agimon-ai/doompi-user-feedback/voice-question-handoff` exposes the same minor-mode
48
- detection, plain-text formatting, and narration handoff to other tools.
49
- `createVoiceQuestionHandoff()` returns a session-scoped handle; call `dispose()` when its
50
- session ends so subscriptions do not outlive their owner.
74
+ The tool requires an interactive UI. It uses the TUI questionnaire when available and can use Pi's
75
+ dialog or RPC UI bridge. A headless context without either UI returns a structured `no_ui`
76
+ cancellation rather than waiting forever.
51
77
 
52
- Voice results include the readable question, set `terminate: true`, and mark the turn as
53
- waiting for a response. The answer then arrives through the normal user-message path.
78
+ Questionnaires are coordinated one at a time. Cancellation, session replacement, or shutdown
79
+ aborts the active prompt and settles queued work.
80
+
81
+ ## Autonomous Voice
82
+
83
+ While autonomous Voice mode is active, `ask_user_question` leaves Pi's active tool set. Voice already
84
+ speaks its own question through `narrate` and then waits for the spoken reply, so keeping a
85
+ questionnaire tool alongside it asks the same thing twice. The agent asks by narrating, and the
86
+ answer arrives as an ordinary user message.
87
+
88
+ The gate tracks its own removal. A tool switched off by the user stays off, no other package's tools
89
+ are touched, and the removal is restored when Voice deactivates, when the Voice services unload, or
90
+ when this runtime shuts down.
91
+
92
+ A call already in flight when Voice activates still hands off: the extension formats the questions as
93
+ plain text, requests narration, and returns `terminate: true`, ending the turn while it waits.
94
+
95
+ Both paths use the shared `doom/minor-mode-catalog` and `doom/narration` Cordis services. If a
96
+ provider unloads, User Feedback restores the tool and falls back to its interactive questionnaire
97
+ without retaining the old provider.
54
98
 
55
99
  ## Public API
56
100
 
57
- The package exports the extension, event names, reusable voice handoff, and Pi adapter
58
- through supported subpaths.
101
+ Question and result types are available from the package root. Cross-extension ask-user events and
102
+ Voice services come from `@agimon-ai/doompi-core`; consumers should use those Cordis
103
+ contracts. Pi loads the default export of `/extensions/pi` through package metadata, so installation
104
+ does not require a manual registration call.
105
+
106
+ ## Development
107
+
108
+ Run from this package directory in the workspace:
109
+
110
+ ```bash
111
+ pnpm build
112
+ pnpm typecheck
113
+ pnpm test
114
+ pnpm lint
115
+ ```
116
+
117
+ Maintained by [Agimon](https://agimon.ai/about).
59
118
 
60
119
  ## License
61
120
 
62
121
  MIT
122
+
123
+ The named Pi and server factories live in `src/extensions`. Tools return typed declarations using questionnaire services. TUI renderers are supplied by the Pi entry. Each Pi mount owns optional Voice service subscriptions, a live tool restriction, and awaited questionnaire shutdown through `onDispose`. Public types are exposed through flat `src/exports`.
@@ -0,0 +1,17 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ //#region src/schemas/apiContracts.ts
6
+ /** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
7
+ const apiContracts = (0, require("@agimon-ai/doompi-core/apiContracts").defineApiContract)({
8
+ version: 1,
9
+ http: [],
10
+ sockets: [],
11
+ dynamic: []
12
+ });
13
+ //#endregion
14
+ exports.apiContracts = apiContracts;
15
+ exports.default = apiContracts;
16
+
17
+ //# sourceMappingURL=apiContracts.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiContracts.cjs","names":["defineApiContract"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/doompi-core/apiContracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":";;;;;;AAGA,MAAa,gBAAA,gDAAeA,CAAAA,CAAAA,kBAAAA,CAAkB;CAAE,SAAS;CAAG,MAAM,CAAC;CAAG,SAAS,CAAC;CAAG,SAAS,CAAC;AAAE,CAAC"}
@@ -0,0 +1,53 @@
1
+ //#region src/schemas/apiContracts.d.ts
2
+ /** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
3
+ export declare const apiContracts: {
4
+ version: 1;
5
+ protocols?: Record<string, string> | undefined;
6
+ schemas?: Record<string, boolean | object> | undefined;
7
+ http: {
8
+ id: string;
9
+ scope: "global" | "session" | "workspace";
10
+ basePath?: string | undefined;
11
+ path: string;
12
+ method: "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PUT";
13
+ description: string;
14
+ availability?: string | undefined;
15
+ authentication: "device" | "none" | "owner";
16
+ parameters?: {
17
+ name: string;
18
+ in: "header" | "path" | "query";
19
+ required: boolean;
20
+ schema: boolean | object;
21
+ }[] | undefined;
22
+ body?: {
23
+ contentType: string;
24
+ contentTypes?: string[] | undefined;
25
+ required: boolean;
26
+ schema: boolean | object;
27
+ } | undefined;
28
+ responses: Record<string, {
29
+ description: string;
30
+ contentType?: string | undefined;
31
+ schema?: boolean | object | undefined;
32
+ events?: Record<string, boolean | object> | undefined;
33
+ }>;
34
+ }[];
35
+ sockets: {
36
+ id: string;
37
+ scope: "global" | "session" | "workspace";
38
+ description: string;
39
+ availability?: string | undefined;
40
+ service: string;
41
+ member: string;
42
+ direction: "client-to-server" | "server-to-client";
43
+ kind: "channel" | "method" | "state";
44
+ input: boolean | object;
45
+ output?: boolean | object | undefined;
46
+ errors?: boolean | object | undefined;
47
+ }[];
48
+ dynamic: string[];
49
+ gaps?: string[] | undefined;
50
+ };
51
+ //#endregion
52
+ export { apiContracts as default };
53
+ //# sourceMappingURL=apiContracts.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiContracts.d.mts","names":[],"sources":["../src/schemas/apiContracts.ts"],"mappings":";;qBAGa"}
@@ -0,0 +1,13 @@
1
+ import { defineApiContract } from "@agimon-ai/doompi-core/apiContracts";
2
+ //#region src/schemas/apiContracts.ts
3
+ /** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
4
+ const apiContracts = defineApiContract({
5
+ version: 1,
6
+ http: [],
7
+ sockets: [],
8
+ dynamic: []
9
+ });
10
+ //#endregion
11
+ export { apiContracts, apiContracts as default };
12
+
13
+ //# sourceMappingURL=apiContracts.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/doompi-core/apiContracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":";;;AAGA,MAAa,eAAe,kBAAkB;CAAE,SAAS;CAAG,MAAM,CAAC;CAAG,SAAS,CAAC;CAAG,SAAS,CAAC;AAAE,CAAC"}