vibe64 0.1.21 → 0.1.22

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 (143) hide show
  1. package/dist/assets/ProjectTypeGate-B3NHteXC.js +1 -0
  2. package/dist/assets/ProjectTypeGate-fJcYj6sR.css +1 -0
  3. package/dist/assets/{SetupReadinessGate-DkkorR2Y.js → SetupReadinessGate-2twHjoYZ.js} +1 -1
  4. package/dist/assets/{ShellLayout-BcKS2HG9.js → ShellLayout-BjAbXfzf.js} +1 -1
  5. package/dist/assets/{VTabs-BJ8MKoig.js → VTabs-BLGGdbms.js} +1 -1
  6. package/dist/assets/{error-CwT53qTu.js → error-DvUPciuh.js} +1 -1
  7. package/dist/assets/history-DfM4ewyV.js +1 -0
  8. package/dist/assets/home-sh4v0vz7.js +1 -0
  9. package/dist/assets/index-C4JbNnml.css +1 -0
  10. package/dist/assets/{index-BJxDQvyK.js → index-CdFWokfE.js} +1 -1
  11. package/dist/assets/index-D4oqjV9n.js +132 -0
  12. package/dist/assets/{index-CY-wDjNv.js → index-DqoYKexs.js} +15 -15
  13. package/dist/assets/{placement-7FCYadh2.js → placement-QfRaYTFY.js} +1 -1
  14. package/dist/assets/{setup-BzzdD38G.js → setup-B-WOti3H.js} +2 -2
  15. package/dist/assets/{streamEvents-Ba9kHw-1.js → streamEvents-CIqegoLa.js} +1 -1
  16. package/dist/assets/{studioGateApi-hkZdLr1Y.js → studioGateApi-CFtez6lH.js} +1 -1
  17. package/dist/assets/{target-scripts-8hczu84t.js → target-scripts-CI-nAISO.js} +1 -1
  18. package/dist/assets/useStudioTerminal-I8tuBymw.js +1 -0
  19. package/dist/assets/vibe64SessionPanelModel-DLdexNxC.js +1 -0
  20. package/dist/index.html +1 -1
  21. package/node_modules/@local/setup-doctor-core/src/server/doctorToolchain.js +4 -0
  22. package/node_modules/@local/studio-terminal-core/src/server/gitGithubTransport.js +33 -0
  23. package/node_modules/@local/studio-terminal-core/src/server/index.js +1 -0
  24. package/node_modules/@local/studio-terminal-core/src/server/terminalSessions.js +51 -1
  25. package/node_modules/@local/vibe64-adapters/src/server/adapter.js +4 -0
  26. package/node_modules/@local/vibe64-adapters/src/server/adapters/laravel/adapter.js +5 -0
  27. package/node_modules/@local/vibe64-adapters/src/server/adapters/laravel/databaseRuntime.js +50 -0
  28. package/node_modules/@local/vibe64-adapters/src/server/configStore.js +22 -1
  29. package/node_modules/@local/vibe64-adapters/src/server/systemPrompts/agent_conversation.txt +0 -2
  30. package/node_modules/@local/vibe64-adapters/src/server/systemPrompts/draft_issue.txt +18 -0
  31. package/node_modules/@local/vibe64-adapters/src/server/systemPrompts/make_plan.txt +14 -2
  32. package/node_modules/@local/vibe64-adapters/src/server/systemPrompts/prepare_for_merge.txt +2 -0
  33. package/node_modules/@local/vibe64-adapters/src/server/systemPrompts/resolve_pull_request.txt +1 -0
  34. package/node_modules/@local/vibe64-adapters/src/server/systemPrompts/run_deep_ui_check.txt +7 -3
  35. package/node_modules/@local/vibe64-adapters/src/server/workflowCommandTerminal/commitPush.js +4 -22
  36. package/node_modules/@local/vibe64-adapters/src/server/workflowCommandTerminal/factMetadata.js +21 -20
  37. package/node_modules/@local/vibe64-adapters/src/server/workflowCommandTerminal/issuePr.js +27 -4
  38. package/node_modules/@local/vibe64-adapters/src/server/workflowCommandTerminal/mergeSync.js +65 -8
  39. package/node_modules/@local/vibe64-adapters/src/server/workflowCommandTerminal/worktreeDependencies.js +12 -25
  40. package/node_modules/@local/vibe64-adapters/src/server/workflowSessionActions.js +77 -20
  41. package/node_modules/@local/vibe64-core/src/server/terminalWebSocketRoutes.js +14 -5
  42. package/node_modules/@local/vibe64-project/src/server/actions.js +21 -0
  43. package/node_modules/@local/vibe64-project/src/server/registerRoutes.js +6 -0
  44. package/node_modules/@local/vibe64-project/src/server/service.js +125 -8
  45. package/node_modules/@local/vibe64-runtime/src/server/coreProjectTools.js +135 -0
  46. package/node_modules/@local/vibe64-runtime/src/server/index.js +4 -0
  47. package/node_modules/@local/vibe64-runtime/src/server/projectToolRegistry.js +434 -0
  48. package/node_modules/@local/vibe64-runtime/src/server/runtime.js +40 -16
  49. package/node_modules/@local/vibe64-runtime/src/server/sessionWorktreeState.js +25 -0
  50. package/node_modules/@local/vibe64-runtime/src/server/terminalFailureFixRequest.js +112 -0
  51. package/node_modules/@local/vibe64-runtime/src/server/workflowArtifacts.js +2 -2
  52. package/node_modules/@local/vibe64-runtime/src/server/workflowDefinitionBuilders.js +1 -0
  53. package/node_modules/@local/vibe64-runtime/src/server/workflowDefinitionComposers.js +192 -0
  54. package/node_modules/@local/vibe64-runtime/src/server/workflowMachine.js +5 -0
  55. package/node_modules/@local/vibe64-runtime/src/server/workflowModules/coreCoding.js +1309 -419
  56. package/node_modules/@local/vibe64-runtime/src/server/workflowModules/coreLifecycle.js +540 -358
  57. package/node_modules/@local/vibe64-runtime/src/server/workflowModules/coreMaintenance.js +5 -26
  58. package/node_modules/@local/vibe64-runtime/src/server/workflowPresentation.js +153 -26
  59. package/node_modules/@local/vibe64-runtime/src/server/workflowStepMachineHelpers.js +63 -10
  60. package/node_modules/@local/vibe64-runtime/src/server/workflowStepMachines.js +63 -2
  61. package/node_modules/@local/vibe64-sessions/src/server/inputSchemas.js +5 -0
  62. package/node_modules/@local/vibe64-sessions/src/server/service.js +8 -9
  63. package/node_modules/@local/vibe64-terminals/src/server/actions.js +65 -0
  64. package/node_modules/@local/vibe64-terminals/src/server/codexTerminal.js +608 -23
  65. package/node_modules/@local/vibe64-terminals/src/server/commandTerminal.js +261 -4
  66. package/node_modules/@local/vibe64-terminals/src/server/fixCodexJobs.js +420 -0
  67. package/node_modules/@local/vibe64-terminals/src/server/inputSchemas.js +240 -0
  68. package/node_modules/@local/vibe64-terminals/src/server/launchTargetTerminal.js +2 -0
  69. package/node_modules/@local/vibe64-terminals/src/server/registerRoutes.js +226 -0
  70. package/node_modules/@local/vibe64-terminals/src/server/service.js +140 -1
  71. package/node_modules/@local/vibe64-terminals/src/server/targetToolchainTerminal.js +1 -1
  72. package/node_modules/@local/vibe64-terminals/src/server/terminalShared.js +34 -0
  73. package/node_modules/node-pty/build/Makefile +369 -0
  74. package/node_modules/node-pty/build/Release/pty.node +0 -0
  75. package/node_modules/node-pty/build/binding.Makefile +6 -0
  76. package/node_modules/node-pty/build/config.gypi +440 -0
  77. package/node_modules/node-pty/build/pty.target.mk +166 -0
  78. package/node_modules/node-pty/node-addon-api/node_addon_api.Makefile +6 -0
  79. package/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +104 -0
  80. package/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +108 -0
  81. package/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +104 -0
  82. package/node_modules/which/CHANGELOG.md +166 -0
  83. package/package.json +2 -2
  84. package/packages/setup-doctor-core/src/server/doctorToolchain.js +4 -0
  85. package/packages/studio-terminal-core/src/server/gitGithubTransport.js +33 -0
  86. package/packages/studio-terminal-core/src/server/index.js +1 -0
  87. package/packages/studio-terminal-core/src/server/terminalSessions.js +51 -1
  88. package/packages/vibe64-adapters/src/server/adapter.js +4 -0
  89. package/packages/vibe64-adapters/src/server/adapters/laravel/adapter.js +5 -0
  90. package/packages/vibe64-adapters/src/server/adapters/laravel/databaseRuntime.js +50 -0
  91. package/packages/vibe64-adapters/src/server/configStore.js +22 -1
  92. package/packages/vibe64-adapters/src/server/systemPrompts/agent_conversation.txt +0 -2
  93. package/packages/vibe64-adapters/src/server/systemPrompts/draft_issue.txt +18 -0
  94. package/packages/vibe64-adapters/src/server/systemPrompts/make_plan.txt +14 -2
  95. package/packages/vibe64-adapters/src/server/systemPrompts/prepare_for_merge.txt +2 -0
  96. package/packages/vibe64-adapters/src/server/systemPrompts/resolve_pull_request.txt +1 -0
  97. package/packages/vibe64-adapters/src/server/systemPrompts/run_deep_ui_check.txt +7 -3
  98. package/packages/vibe64-adapters/src/server/workflowCommandTerminal/commitPush.js +4 -22
  99. package/packages/vibe64-adapters/src/server/workflowCommandTerminal/factMetadata.js +21 -20
  100. package/packages/vibe64-adapters/src/server/workflowCommandTerminal/issuePr.js +27 -4
  101. package/packages/vibe64-adapters/src/server/workflowCommandTerminal/mergeSync.js +65 -8
  102. package/packages/vibe64-adapters/src/server/workflowCommandTerminal/worktreeDependencies.js +12 -25
  103. package/packages/vibe64-adapters/src/server/workflowSessionActions.js +77 -20
  104. package/packages/vibe64-core/src/server/terminalWebSocketRoutes.js +14 -5
  105. package/packages/vibe64-project/src/server/actions.js +21 -0
  106. package/packages/vibe64-project/src/server/registerRoutes.js +6 -0
  107. package/packages/vibe64-project/src/server/service.js +125 -8
  108. package/packages/vibe64-runtime/src/server/coreProjectTools.js +135 -0
  109. package/packages/vibe64-runtime/src/server/index.js +4 -0
  110. package/packages/vibe64-runtime/src/server/projectToolRegistry.js +434 -0
  111. package/packages/vibe64-runtime/src/server/runtime.js +40 -16
  112. package/packages/vibe64-runtime/src/server/sessionWorktreeState.js +25 -0
  113. package/packages/vibe64-runtime/src/server/terminalFailureFixRequest.js +112 -0
  114. package/packages/vibe64-runtime/src/server/workflowArtifacts.js +2 -2
  115. package/packages/vibe64-runtime/src/server/workflowDefinitionBuilders.js +1 -0
  116. package/packages/vibe64-runtime/src/server/workflowDefinitionComposers.js +192 -0
  117. package/packages/vibe64-runtime/src/server/workflowMachine.js +5 -0
  118. package/packages/vibe64-runtime/src/server/workflowModules/coreCoding.js +1309 -419
  119. package/packages/vibe64-runtime/src/server/workflowModules/coreLifecycle.js +540 -358
  120. package/packages/vibe64-runtime/src/server/workflowModules/coreMaintenance.js +5 -26
  121. package/packages/vibe64-runtime/src/server/workflowPresentation.js +153 -26
  122. package/packages/vibe64-runtime/src/server/workflowStepMachineHelpers.js +63 -10
  123. package/packages/vibe64-runtime/src/server/workflowStepMachines.js +63 -2
  124. package/packages/vibe64-sessions/src/server/inputSchemas.js +5 -0
  125. package/packages/vibe64-sessions/src/server/service.js +8 -9
  126. package/packages/vibe64-terminals/src/server/actions.js +65 -0
  127. package/packages/vibe64-terminals/src/server/codexTerminal.js +608 -23
  128. package/packages/vibe64-terminals/src/server/commandTerminal.js +261 -4
  129. package/packages/vibe64-terminals/src/server/fixCodexJobs.js +420 -0
  130. package/packages/vibe64-terminals/src/server/inputSchemas.js +240 -0
  131. package/packages/vibe64-terminals/src/server/launchTargetTerminal.js +2 -0
  132. package/packages/vibe64-terminals/src/server/registerRoutes.js +226 -0
  133. package/packages/vibe64-terminals/src/server/service.js +140 -1
  134. package/packages/vibe64-terminals/src/server/targetToolchainTerminal.js +1 -1
  135. package/packages/vibe64-terminals/src/server/terminalShared.js +34 -0
  136. package/dist/assets/ProjectTypeGate-DStq4W4X.js +0 -1
  137. package/dist/assets/ProjectTypeGate-Dh2ycSoM.css +0 -1
  138. package/dist/assets/history-HQ_XliX2.js +0 -1
  139. package/dist/assets/home-B89EbUmA.js +0 -1
  140. package/dist/assets/index-16P0GeGq.js +0 -134
  141. package/dist/assets/index-eMhOXhf_.css +0 -1
  142. package/dist/assets/useStudioTerminal-D9TNb50w.js +0 -1
  143. package/dist/assets/vibe64SessionPanelModel-DvY_IbW3.js +0 -1
@@ -0,0 +1,434 @@
1
+ import {
2
+ isPlainObject,
3
+ normalizeText,
4
+ plainClone,
5
+ vibe64Error
6
+ } from "@local/vibe64-core/server/core";
7
+ import { deepFreeze } from "@local/vibe64-core/server/deepFreeze";
8
+
9
+ const PROJECT_TOOL_TYPES = new Set(["command", "prompt"]);
10
+ const PROJECT_TOOL_PARAMETER_TYPES = new Set(["integer", "string", "enum"]);
11
+ const PROJECT_TOOL_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$/u;
12
+
13
+ function normalizeProjectToolId(toolId = "") {
14
+ const normalizedToolId = normalizeText(toolId);
15
+ if (!PROJECT_TOOL_ID_PATTERN.test(normalizedToolId)) {
16
+ throw vibe64Error(
17
+ `Invalid Vibe64 project tool id: ${normalizedToolId || "(empty)"}.`,
18
+ "vibe64_project_tool_invalid"
19
+ );
20
+ }
21
+ return normalizedToolId;
22
+ }
23
+
24
+ function normalizeProjectToolType(type = "") {
25
+ const normalizedType = normalizeText(type);
26
+ if (!PROJECT_TOOL_TYPES.has(normalizedType)) {
27
+ throw vibe64Error(
28
+ `Invalid Vibe64 project tool type: ${normalizedType || "(empty)"}.`,
29
+ "vibe64_project_tool_invalid"
30
+ );
31
+ }
32
+ return normalizedType;
33
+ }
34
+
35
+ function normalizeParameterType(type = "") {
36
+ const normalizedType = normalizeText(type);
37
+ if (!PROJECT_TOOL_PARAMETER_TYPES.has(normalizedType)) {
38
+ throw vibe64Error(
39
+ `Invalid Vibe64 project tool parameter type: ${normalizedType || "(empty)"}.`,
40
+ "vibe64_project_tool_invalid"
41
+ );
42
+ }
43
+ return normalizedType;
44
+ }
45
+
46
+ function normalizeToolOption(option = {}) {
47
+ const optionObject = isPlainObject(option) ? option : {
48
+ value: option
49
+ };
50
+ const value = normalizeText(optionObject.value);
51
+ if (!value) {
52
+ throw vibe64Error(
53
+ "Vibe64 project tool enum option requires a value.",
54
+ "vibe64_project_tool_invalid"
55
+ );
56
+ }
57
+ return {
58
+ label: normalizeText(optionObject.label || value),
59
+ value
60
+ };
61
+ }
62
+
63
+ function normalizeToolParameter(moduleId = "", toolId = "", parameter = {}, index = 0) {
64
+ const parameterObject = isPlainObject(parameter) ? parameter : {};
65
+ const parameterId = normalizeText(parameterObject.id);
66
+ const type = normalizeParameterType(parameterObject.type);
67
+ const context = `${moduleId} project tool ${toolId} parameter ${index + 1}`;
68
+
69
+ if (!parameterId) {
70
+ throw vibe64Error(
71
+ `Vibe64 ${context} requires an id.`,
72
+ "vibe64_project_tool_invalid"
73
+ );
74
+ }
75
+
76
+ const normalizedParameter = {
77
+ defaultValue: parameterObject.defaultValue,
78
+ description: normalizeText(parameterObject.description),
79
+ id: parameterId,
80
+ label: normalizeText(parameterObject.label || parameterId),
81
+ options: [],
82
+ required: parameterObject.required !== false,
83
+ type
84
+ };
85
+
86
+ if (type === "enum") {
87
+ normalizedParameter.options = (Array.isArray(parameterObject.options) ? parameterObject.options : [])
88
+ .map(normalizeToolOption);
89
+ if (!normalizedParameter.options.length) {
90
+ throw vibe64Error(
91
+ `Vibe64 ${context} enum parameter requires options.`,
92
+ "vibe64_project_tool_invalid"
93
+ );
94
+ }
95
+ }
96
+
97
+ return deepFreeze(normalizedParameter);
98
+ }
99
+
100
+ function assertUniqueParameterIds(toolId = "", parameters = []) {
101
+ const seen = new Set();
102
+ for (const parameter of parameters) {
103
+ if (seen.has(parameter.id)) {
104
+ throw vibe64Error(
105
+ `Duplicate Vibe64 project tool parameter ${toolId}.${parameter.id}.`,
106
+ "vibe64_project_tool_invalid"
107
+ );
108
+ }
109
+ seen.add(parameter.id);
110
+ }
111
+ }
112
+
113
+ function normalizeToolParameters(moduleId = "", toolId = "", parameters = []) {
114
+ const normalizedParameters = (Array.isArray(parameters) ? parameters : [])
115
+ .map((parameter, index) => normalizeToolParameter(moduleId, toolId, parameter, index));
116
+ assertUniqueParameterIds(toolId, normalizedParameters);
117
+ return deepFreeze(normalizedParameters);
118
+ }
119
+
120
+ function normalizeProjectToolContribution(moduleId = "", contribution = {}, index = 0) {
121
+ const tool = isPlainObject(contribution) ? contribution : {};
122
+ const toolId = normalizeProjectToolId(tool.id);
123
+ const type = normalizeProjectToolType(tool.type);
124
+ const context = `${moduleId} project tool ${index + 1}`;
125
+ const command = typeof tool.command === "function" ? tool.command : null;
126
+ const prompt = typeof tool.prompt === "function" || typeof tool.prompt === "string"
127
+ ? tool.prompt
128
+ : null;
129
+
130
+ if (!toolId) {
131
+ throw vibe64Error(
132
+ `Vibe64 ${context} requires an id.`,
133
+ "vibe64_project_tool_invalid"
134
+ );
135
+ }
136
+ if (type === "command" && !command) {
137
+ throw vibe64Error(
138
+ `Vibe64 ${context} command tool requires a command function.`,
139
+ "vibe64_project_tool_invalid"
140
+ );
141
+ }
142
+ if (type === "prompt" && !prompt) {
143
+ throw vibe64Error(
144
+ `Vibe64 ${context} prompt tool requires a prompt string or function.`,
145
+ "vibe64_project_tool_invalid"
146
+ );
147
+ }
148
+
149
+ return Object.freeze({
150
+ command,
151
+ confirmationMessage: normalizeText(tool.confirmationMessage),
152
+ description: normalizeText(tool.description),
153
+ disabledReason: tool.disabledReason,
154
+ enabled: tool.enabled,
155
+ id: toolId,
156
+ label: normalizeText(tool.label || toolId),
157
+ moduleId,
158
+ parameters: normalizeToolParameters(moduleId, toolId, tool.parameters),
159
+ prompt,
160
+ requiresConfirmation: tool.requiresConfirmation === true,
161
+ type
162
+ });
163
+ }
164
+
165
+ function normalizeContributionList(moduleId = "", contributions = []) {
166
+ if (contributions === undefined) {
167
+ return [];
168
+ }
169
+ if (Array.isArray(contributions)) {
170
+ return contributions;
171
+ }
172
+ if (isPlainObject(contributions)) {
173
+ return [contributions];
174
+ }
175
+ throw vibe64Error(
176
+ `Vibe64 project tool module ${moduleId} tools must be an object or array.`,
177
+ "vibe64_project_tool_invalid"
178
+ );
179
+ }
180
+
181
+ function normalizeContributorModules(modules = []) {
182
+ const moduleList = Array.isArray(modules) ? modules : [modules];
183
+ return moduleList.map((module, index) => {
184
+ if (!isPlainObject(module)) {
185
+ throw vibe64Error(
186
+ `Vibe64 project tool module entry ${index + 1} must be an object.`,
187
+ "vibe64_project_tool_invalid"
188
+ );
189
+ }
190
+ return module;
191
+ });
192
+ }
193
+
194
+ async function resolveToolValue(value, context = {}) {
195
+ return typeof value === "function" ? value(context) : value;
196
+ }
197
+
198
+ async function publicProjectToolRecord(record = {}, context = {}) {
199
+ const enabledValue = record.enabled === undefined
200
+ ? true
201
+ : await resolveToolValue(record.enabled, {
202
+ ...context,
203
+ tool: record
204
+ });
205
+ const disabledReason = normalizeText(await resolveToolValue(record.disabledReason, {
206
+ ...context,
207
+ tool: record
208
+ }));
209
+ const enabled = enabledValue !== false && !disabledReason;
210
+ return deepFreeze({
211
+ confirmationMessage: record.confirmationMessage,
212
+ description: record.description,
213
+ disabledReason: enabled ? "" : disabledReason || `${record.label} is disabled.`,
214
+ enabled,
215
+ id: record.id,
216
+ label: record.label,
217
+ parameters: plainClone(record.parameters),
218
+ requiresConfirmation: record.requiresConfirmation,
219
+ type: record.type
220
+ });
221
+ }
222
+
223
+ function sortPublicTools(left, right) {
224
+ return left.label.localeCompare(right.label) ||
225
+ left.id.localeCompare(right.id);
226
+ }
227
+
228
+ function parameterInputValue(parameters = {}, parameter = {}) {
229
+ if (Object.hasOwn(parameters, parameter.id)) {
230
+ return parameters[parameter.id];
231
+ }
232
+ return parameter.defaultValue;
233
+ }
234
+
235
+ function normalizeIntegerParameter(value, parameter = {}) {
236
+ if (value === undefined || value === null || value === "") {
237
+ return null;
238
+ }
239
+ const number = Number(value);
240
+ if (!Number.isSafeInteger(number)) {
241
+ throw vibe64Error(
242
+ `Project tool parameter ${parameter.id} must be an integer.`,
243
+ "vibe64_project_tool_parameter_invalid"
244
+ );
245
+ }
246
+ return number;
247
+ }
248
+
249
+ function normalizeEnumParameter(value, parameter = {}) {
250
+ const normalizedValue = normalizeText(value);
251
+ if (!normalizedValue) {
252
+ return "";
253
+ }
254
+ const allowedValues = new Set(parameter.options.map((option) => option.value));
255
+ if (!allowedValues.has(normalizedValue)) {
256
+ throw vibe64Error(
257
+ `Project tool parameter ${parameter.id} must be one of: ${[...allowedValues].join(", ")}.`,
258
+ "vibe64_project_tool_parameter_invalid"
259
+ );
260
+ }
261
+ return normalizedValue;
262
+ }
263
+
264
+ function normalizeStringParameter(value) {
265
+ if (value === undefined || value === null) {
266
+ return "";
267
+ }
268
+ return String(value);
269
+ }
270
+
271
+ function normalizeParameterValue(value, parameter = {}) {
272
+ if (parameter.type === "integer") {
273
+ return normalizeIntegerParameter(value, parameter);
274
+ }
275
+ if (parameter.type === "enum") {
276
+ return normalizeEnumParameter(value, parameter);
277
+ }
278
+ return normalizeStringParameter(value);
279
+ }
280
+
281
+ function validateKnownParameterInput(tool = {}, parameters = {}) {
282
+ const knownIds = new Set(tool.parameters.map((parameter) => parameter.id));
283
+ for (const parameterId of Object.keys(isPlainObject(parameters) ? parameters : {})) {
284
+ if (!knownIds.has(parameterId)) {
285
+ throw vibe64Error(
286
+ `Unknown project tool parameter ${tool.id}.${parameterId}.`,
287
+ "vibe64_project_tool_parameter_invalid"
288
+ );
289
+ }
290
+ }
291
+ }
292
+
293
+ function normalizeToolInput(tool = {}, parameters = {}) {
294
+ const input = isPlainObject(parameters) ? parameters : {};
295
+ validateKnownParameterInput(tool, input);
296
+ return Object.fromEntries(tool.parameters.map((parameter) => {
297
+ const value = normalizeParameterValue(parameterInputValue(input, parameter), parameter);
298
+ if (
299
+ parameter.required &&
300
+ (value === null || value === "")
301
+ ) {
302
+ throw vibe64Error(
303
+ `Project tool parameter ${tool.id}.${parameter.id} is required.`,
304
+ "vibe64_project_tool_parameter_required"
305
+ );
306
+ }
307
+ return [parameter.id, value];
308
+ }));
309
+ }
310
+
311
+ function createProjectToolRegistry() {
312
+ const toolRecords = new Map();
313
+
314
+ function storeToolContribution(moduleId = "", tool = {}) {
315
+ if (toolRecords.has(tool.id)) {
316
+ throw vibe64Error(
317
+ `Duplicate Vibe64 project tool id: ${tool.id}.`,
318
+ "vibe64_project_tool_duplicate"
319
+ );
320
+ }
321
+ toolRecords.set(tool.id, Object.freeze({
322
+ ...tool,
323
+ moduleId
324
+ }));
325
+ }
326
+
327
+ function registerTools(moduleId = "", tools = []) {
328
+ const normalizedModuleId = normalizeText(moduleId);
329
+ if (!normalizedModuleId) {
330
+ throw vibe64Error(
331
+ "Vibe64 project tool modules require an id.",
332
+ "vibe64_project_tool_invalid"
333
+ );
334
+ }
335
+ const contributions = normalizeContributionList(normalizedModuleId, tools)
336
+ .map((tool, index) => normalizeProjectToolContribution(normalizedModuleId, tool, index));
337
+ for (const tool of contributions) {
338
+ storeToolContribution(normalizedModuleId, tool);
339
+ }
340
+ return deepFreeze(contributions.map((tool) => ({
341
+ confirmationMessage: tool.confirmationMessage,
342
+ description: tool.description,
343
+ disabledReason: "",
344
+ enabled: tool.enabled !== false,
345
+ id: tool.id,
346
+ label: tool.label,
347
+ parameters: plainClone(tool.parameters),
348
+ requiresConfirmation: tool.requiresConfirmation,
349
+ type: tool.type
350
+ })));
351
+ }
352
+
353
+ async function listTools(context = {}) {
354
+ const tools = await Promise.all([...toolRecords.values()].map((record) => {
355
+ return publicProjectToolRecord(record, context);
356
+ }));
357
+ return tools.sort(sortPublicTools);
358
+ }
359
+
360
+ function toolRecord(toolId = "") {
361
+ return toolRecords.get(normalizeProjectToolId(toolId)) || null;
362
+ }
363
+
364
+ async function resolveToolRun(toolId = "", {
365
+ context = {},
366
+ parameters = {}
367
+ } = {}) {
368
+ const record = toolRecord(toolId);
369
+ if (!record) {
370
+ throw vibe64Error(
371
+ `Unknown Vibe64 project tool: ${normalizeText(toolId) || "(empty)"}.`,
372
+ "vibe64_project_tool_unknown"
373
+ );
374
+ }
375
+ const tool = await publicProjectToolRecord(record, context);
376
+ if (tool.enabled !== true) {
377
+ throw vibe64Error(
378
+ tool.disabledReason || `${tool.label} is disabled.`,
379
+ "vibe64_project_tool_disabled"
380
+ );
381
+ }
382
+ const input = normalizeToolInput(record, parameters);
383
+ const runContext = {
384
+ ...context,
385
+ input,
386
+ parameters: input,
387
+ tool
388
+ };
389
+ if (record.type === "command") {
390
+ return {
391
+ input,
392
+ spec: await record.command(runContext),
393
+ tool,
394
+ type: "command"
395
+ };
396
+ }
397
+ return {
398
+ input,
399
+ prompt: normalizeText(await resolveToolValue(record.prompt, runContext)),
400
+ tool,
401
+ type: "prompt"
402
+ };
403
+ }
404
+
405
+ return Object.freeze({
406
+ listTools,
407
+ registerTools,
408
+ resolveToolRun
409
+ });
410
+ }
411
+
412
+ function registerProjectToolContributorModules(registry, {
413
+ toolModules = []
414
+ } = {}) {
415
+ const normalizedToolModules = normalizeContributorModules(toolModules);
416
+ normalizedToolModules.forEach((module) => {
417
+ if (!Object.hasOwn(module, "tools")) {
418
+ throw vibe64Error(
419
+ `Vibe64 project tool module ${normalizeText(module.id) || "(unknown)"} must define tools.`,
420
+ "vibe64_project_tool_invalid"
421
+ );
422
+ }
423
+ registry.registerTools(module.id, module.tools);
424
+ });
425
+ return registry;
426
+ }
427
+
428
+ export {
429
+ PROJECT_TOOL_PARAMETER_TYPES,
430
+ PROJECT_TOOL_TYPES,
431
+ createProjectToolRegistry,
432
+ normalizeProjectToolId,
433
+ registerProjectToolContributorModules
434
+ };
@@ -39,6 +39,7 @@ import {
39
39
  import { WorkflowMachine } from "./workflowMachine.js";
40
40
  import {
41
41
  applyStepMachineView,
42
+ currentStepInputConversationText,
42
43
  currentStepPromptInputInstruction,
43
44
  recordStepMachineActionFinished,
44
45
  recordStepMachineActionStarted,
@@ -49,6 +50,9 @@ import {
49
50
  applyWorkflowPresentation,
50
51
  runWorkflowIntent
51
52
  } from "./workflowPresentation.js";
53
+ import {
54
+ sessionHasWorktree
55
+ } from "./sessionWorktreeState.js";
52
56
  import {
53
57
  vibe64SessionDebugDurationMs,
54
58
  vibe64SessionDebugError,
@@ -64,6 +68,10 @@ function promptActionIsBlocked(action = {}, session = {}) {
64
68
  return action.type === "prompt" && metadataFlagIsOn(session.metadata?.terminal_active);
65
69
  }
66
70
 
71
+ function promptActionMissingWorktree(action = {}, session = {}) {
72
+ return action.type === "prompt" && !sessionHasWorktree(session);
73
+ }
74
+
67
75
  function promptActionHasUnfinishedRun(action = {}, session = {}) {
68
76
  void action;
69
77
  void session;
@@ -100,6 +108,9 @@ function defaultActionReadiness({ action = {}, session = {} } = {}) {
100
108
  if (promptActionHasUnfinishedRun(action, session)) {
101
109
  return disabledAction("Codex prompt is waiting to continue.");
102
110
  }
111
+ if (promptActionMissingWorktree(action, session)) {
112
+ return disabledAction("Create the session worktree before asking Codex.");
113
+ }
103
114
  if (actionCapabilityIsMissing(action, session)) {
104
115
  return disabledAction(adapterCapabilityDisabledReason(action, session));
105
116
  }
@@ -182,14 +193,28 @@ function actionLogEntry(action, session, actionResult) {
182
193
  };
183
194
  }
184
195
 
196
+ function actionResultCompleted(actionResult = {}) {
197
+ return normalizeText(actionResult.status || "completed") === "completed";
198
+ }
199
+
200
+ function actionCanAdvanceOnSuccess(action = {}, actionResult = {}, session = {}) {
201
+ return action.advanceOnSuccess === true &&
202
+ actionResultCompleted(actionResult) &&
203
+ session.next?.visible !== false &&
204
+ session.next?.enabled === true &&
205
+ Boolean(session.next?.stepId);
206
+ }
207
+
185
208
  function actionResultRecord(action, session, input, handlerResult = {}) {
186
209
  const result = { ...(handlerResult || {}) };
187
210
  delete result.recordsConversationTurn;
188
211
  const recordsConversationTurn = action.recordsConversationTurn === true;
212
+ const auditMessage = normalizeText(action.auditMessage);
189
213
  return {
190
214
  ...result,
191
215
  actionLabel: action.label,
192
216
  actionType: action.type,
217
+ ...(auditMessage ? { auditMessage } : {}),
193
218
  input,
194
219
  message: normalizeText(result.message),
195
220
  ...(recordsConversationTurn ? { recordsConversationTurn: true } : {}),
@@ -350,26 +375,20 @@ function inputObject(input = {}) {
350
375
  return input && typeof input === "object" && !Array.isArray(input) ? input : {};
351
376
  }
352
377
 
353
- function inputFields(input = {}) {
354
- const source = inputObject(input);
355
- return inputObject(source.fields || {});
356
- }
357
-
358
- function currentStepInputText(input = {}) {
359
- const source = inputObject(input);
360
- const fields = inputFields(input);
361
- return normalizeText(fields.response || source.text || source.message);
362
- }
363
-
364
- async function recordCurrentStepConversationMessage(runtime, sessionId = "", input = {}) {
378
+ async function recordCurrentStepConversationMessage(runtime, session = {}, input = {}) {
365
379
  const source = inputObject(input);
366
380
  const inputSource = normalizeText(source.source);
367
- const text = currentStepInputText(source);
381
+ const text = currentStepInputConversationText(runtime, session, source);
368
382
  if (!text) {
369
383
  return null;
370
384
  }
371
385
  if (inputSource === "codex") {
372
- return runtime.store.writeConversationAssistantMessage(sessionId, {
386
+ return runtime.store.writeConversationAssistantMessage(session.sessionId, {
387
+ text
388
+ });
389
+ }
390
+ if (inputSource === "ui") {
391
+ return runtime.store.writeConversationUserMessage(session.sessionId, {
373
392
  text
374
393
  });
375
394
  }
@@ -922,8 +941,12 @@ class Vibe64SessionRuntime {
922
941
  );
923
942
  await recordStepMachineActionFinished(this, actionSession, actionAfterStart.id, actionResult);
924
943
 
944
+ const actionCompletedSession = await this.runActionSessionView(actionSession.sessionId);
945
+ const finalSession = actionCanAdvanceOnSuccess(actionAfterStart, actionResult, actionCompletedSession)
946
+ ? await this.advance(actionSession.sessionId)
947
+ : actionCompletedSession;
925
948
  const viewedSession = {
926
- ...await this.runActionSessionView(actionSession.sessionId),
949
+ ...finalSession,
927
950
  actionResult
928
951
  };
929
952
  vibe64SessionDebugLog("server.runtime.runAction.done", {
@@ -1165,7 +1188,8 @@ class Vibe64SessionRuntime {
1165
1188
  try {
1166
1189
  return await this.store.mutateSession(sessionId, async () => {
1167
1190
  await saveStepMachineInput(this, sessionId, input);
1168
- await recordCurrentStepConversationMessage(this, sessionId, input);
1191
+ const savedSession = await this.getSession(sessionId);
1192
+ await recordCurrentStepConversationMessage(this, savedSession, input);
1169
1193
  const session = await this.getSession(sessionId);
1170
1194
  vibe64SessionDebugLog("server.runtime.submitCurrentStepInput.done", {
1171
1195
  ...vibe64SessionDebugSummary(session),
@@ -0,0 +1,25 @@
1
+ import {
2
+ normalizeText
3
+ } from "@local/vibe64-core/server/core";
4
+
5
+ function sessionWorktreePath(session = {}) {
6
+ return normalizeText(
7
+ session.metadata?.worktree_path ||
8
+ session.metadata?.worktree ||
9
+ session.worktree ||
10
+ session.worktreePath
11
+ );
12
+ }
13
+
14
+ function sessionHasWorktree(session = {}) {
15
+ return Boolean(
16
+ sessionWorktreePath(session) ||
17
+ session.worktreeReady === true ||
18
+ (Array.isArray(session.completedSteps) && session.completedSteps.includes("worktree_created"))
19
+ );
20
+ }
21
+
22
+ export {
23
+ sessionHasWorktree,
24
+ sessionWorktreePath
25
+ };